I have a customization to add user fields to the Employee Time Card screen (EP305000) grid area that's been working through several versions / upgrades - but now in version 20.102.0015 it fails to bring in the data into the user fields.
The user fields are defined as follows:
public class EPTimecardDetailExt : PXCacheExtension<EPTimecardDetail>
{
#region UsrStartDate
public abstract class usrStartDate : IBqlField { }
[PXDBDateAndTime(DisplayNameDate = "Start Date", DisplayNameTime = "Start Time*", UseTimeZone = true)]
//[PXDBTime(DisplayMask = "t", InputMask = "t")]
[PXUIField(DisplayName = "Start Time*")]
public virtual DateTime? UsrStartDate { get; set; }
#endregion
#region UsrEndDate
public abstract class usrEndDate : IBqlField { }
[PXDBDateAndTime(DisplayNameDate = "End Date", DisplayNameTime = "End Time*", UseTimeZone = true)]
//[PXDBTime(DisplayMask = "t", InputMask = "t")]
[PXUIField(DisplayName = "End Time*")]
public virtual DateTime? UsrEndDate { get; set; }
#endregion
#region UsrRelatedCase
public abstract class usrRelatedCase : IBqlField { }
[PXDBString(10)]
[PXUIField(DisplayName = "Related Case*")]
[PXSelector(typeof(Search2<CRCase.caseCD,
InnerJoin<PMProject,
On<CRCase.customerID, Equal<PMProject.customerID>>>,
Where<PMProject.contractID, Equal<Current<EPTimecardDetail.projectID>>>,
OrderBy<Desc<CRCase.caseCD>>>),
typeof(CRCase.caseCD),
typeof(CRCase.subject),
typeof(CRCase.createdDateTime),
typeof(CRCase.caseClassID),
typeof(CRCase.status),
typeof(CRCase.contactID),
typeof(CRCase.ownerID),
DescriptionField = typeof(CRCase.subject))]
//typeof(CRCase.status),
//typeof(CRCase.priority),
//typeof(CRCase.severity),
//typeof(CRCase.caseClassID),
//typeof(BAccount.acctName),
//Filterable = true)]
public virtual string UsrRelatedCase { get; set; }
#endregion
}
The values are in the database - they save correctly - but they won't show up in the grid.
Any idea why this would happen?
The solution to this was provided by Acumatica support.
In my customization, I was creating a Cache Extension for a 'Projection' DAC, namely EPTimeCardDetail. The solution was to create an extension of the DAC which represented the actual table to which the user fields were actually added, which is PMTimeActivity.
Once I created the Cache Extension to PMTimeActivity, the problem was solved and the values were displayed in the grid.
It is unknown why this worked fine in previous versions.
Related
I have customization project in Acumatica 2021R1 (v21.104.0018). I have a parent DAC that has an ID and multiple child DACs that use this ID with a PXParent attribute. Whenever I select the screen in the customization project editor to design it, I get an error message that says, "An item with the same key has already been added." Then, I'm not able to design the screen in the Screen Editor. The weird thing is that I don't get this message when I open the actual screen.
I'm not sure what this is referring to because there are no records in the database in the tables that I'm using for the views of the graph for the screen.
Not sure if anyone else has had this problem and knows what causes it, but Acumatica could really use some more specific error messages.
Here is my parent DAC (note: I left out the system fields here for purposes of space):
public class PSImport : IBqlTable
{
#region Import ID
[PXDBString(15, IsKey = true, IsUnicode = true, InputMask = ">CCCCCCCCCCCCCCC")]
[PXDefault(PersistingCheck = PXPersistingCheck.NullOrBlank)]
[PXUIField(DisplayName = "Import No.", Visibility = PXUIVisibility.SelectorVisible, Enabled = true)]
[AutoNumber(typeof(PSSetup.numberingID), typeof(AccessInfo.businessDate))]
[PXSelector(
typeof(PSImport.importID),
typeof(PSImport.description),
typeof(PSImport.fileFormat),
typeof(PSImport.status),
typeof(PSImport.description)
)]
public virtual string ImportID { get; set; }
public abstract class importID : PX.Data.BQL.BqlString.Field<importID> { }
#endregion
#region Description
[PXDBString(IsUnicode = true, IsFixed = false)]
[PXUIField(DisplayName = "Description")]
public virtual string Description { get; set; }
public abstract class description : PX.Data.BQL.BqlString.Field<description> { }
#endregion
#region File Format
[PXDBString(2, IsFixed = true, IsUnicode = true)]
[PXUIField(DisplayName = "File Format", Enabled = true)]
[PXDefault]
[PXStringList(
new string[]
{
FileFormatTypes.Flats,
FileFormatTypes.IDOA,
FileFormatTypes.MMS,
FileFormatTypes.OCR,
FileFormatTypes.Pressero
},
new string[]
{
FileFormatTypeDisplayNames.Flats,
FileFormatTypeDisplayNames.IDOA,
FileFormatTypeDisplayNames.MMS,
FileFormatTypeDisplayNames.OCR,
FileFormatTypeDisplayNames.Pressero
}
)]
public virtual string FileFormat { get; set; }
public abstract class fileFormat : PX.Data.BQL.BqlString.Field<fileFormat> { }
#endregion
#region Status
[PXDBString(2, IsFixed = true, IsUnicode = true)]
[PXUIField(DisplayName = "Status", Enabled = false)]
[PXDefault(ImportStatusTypes.Unvalidated)]
[PXStringList(
new string[]
{
ImportStatusTypes.Unvalidated,
ImportStatusTypes.Invalid,
ImportStatusTypes.Valid,
ImportStatusTypes.Released
},
new string[]
{
ImportStatusTypeDisplayNames.Unvalidated,
ImportStatusTypeDisplayNames.Invalid,
ImportStatusTypeDisplayNames.Valid,
ImportStatusTypeDisplayNames.Released
}
)]
public virtual string Status { get; set; }
public abstract class status : PX.Data.BQL.BqlString.Field<status> { }
#endregion
#region Date Imported
[PXDBDate]
[PXUIField(DisplayName = "Date Imported", Enabled = false)]
public virtual DateTime? DateImported { get; set; }
public abstract class dateImported : PX.Data.BQL.BqlDateTime.Field<dateImported> { }
#endregion
#region Date of Last Validation
[PXDBDate]
[PXUIField(DisplayName = "Date of Last Validation", Enabled = false)]
public virtual DateTime? DateOfLastValidation { get; set; }
public abstract class dateOfLastValidation : PX.Data.BQL.BqlDateTime.Field<dateOfLastValidation> { }
#endregion
#region Date Released
[PXDBDate]
[PXUIField(DisplayName = "Date Released", Enabled = false)]
public virtual DateTime? DateReleased { get; set; }
public abstract class dateReleased : PX.Data.BQL.BqlDateTime.Field<dateReleased> { }
#endregion
}
Here is one of the child DACs (right now I only have the key because I don't know all of the fields that I need yet, and I'm just trying to start designing the screens):
public class PSTranFlats : IBqlTable
{
#region Import ID
[PXDBString(15, IsKey = true, IsUnicode = true, InputMask = "")]
[PXDBDefault(typeof(PSImport.importID))]
[PXParent(typeof(SelectFrom<PSImport>.
Where<PSImport.importID.IsEqual<PSTranFlats.importID.FromCurrent>>)
)]
public virtual string ImportID { get; set; }
public abstract class importID : PX.Data.BQL.BqlString.Field<importID> { }
#endregion
}
Here is my setup DAC:
[PXPrimaryGraph(typeof(PSSetupMaint))]
public class PSSetup : IBqlTable
{
#region NumberingID
[PXDBString(10, IsUnicode = true)]
[PXDefault("PSIMPORT")]
[PXUIField(DisplayName = "Import Numbering Sequence")]
[PXSelector(typeof(Numbering.numberingID), DescriptionField = typeof(Numbering.descr))]
public virtual string NumberingID { get; set; }
public abstract class numberingID : PX.Data.BQL.BqlString.Field<numberingID> { }
#endregion
}
Here is my setup graph:
public class PSSetupMaint : PXGraph<PSSetupMaint>
{
#region Selects / Views
public PXSave<PSSetup> Save;
public PXCancel<PSSetup> Cancel;
public SelectFrom<PSSetup>.View Setup;
#endregion
}
And here is my main graph:
public class PSImportEntry : PXGraph<PSImportEntry>
{
#region Selects / Views
public PXCancelClose<PSImport> CancelClose;
public PXSaveClose<PSImport> SaveClose;
public PXSave<PSImport> Save;
public PXCancel<PSImport> Cancel;
public PXInsert<PSImport> Insert;
public PXDelete<PSImport> Delete;
public PXFirst<PSImport> First;
public PXPrevious<PSImport> Previous;
public PXNext<PSImport> Next;
public PXLast<PSImport> Last;
public PXSetup<PSSetup> PSSetup;
public SelectFrom<PSImport>.View Import;
[PXImport(typeof(PSTranFlats))]
public SelectFrom<PSTranFlats>.
Where<PSTranFlats.importID.IsEqual<PSImport.importID.FromCurrent>>.View
FlatsTransactions;
[PXImport(typeof(PSTranIDOA))]
public SelectFrom<PSTranIDOA>.
Where<PSTranIDOA.importID.IsEqual<PSImport.importID.FromCurrent>>.View
IDOATransactions;
[PXImport(typeof(PSTranMMS))]
public SelectFrom<PSTranMMS>.
Where<PSTranMMS.importID.IsEqual<PSImport.importID.FromCurrent>>.View
MMSTransactions;
[PXImport(typeof(PSTranOCR))]
public SelectFrom<PSTranOCR>.
Where<PSTranOCR.importID.IsEqual<PSImport.importID.FromCurrent>>.View
OCRTransactions;
[PXImport(typeof(PSTranPressero))]
public SelectFrom<PSTranPressero>.
Where<PSTranPressero.importID.IsEqual<PSImport.importID.FromCurrent>>.View
PresseroTransactions;
#endregion
}
I am not 100% certain, but I think this is about the ID's in the ASPX rather than the database data. For example:
<px:PXLayoutRule LabelsWidth="S" ControlSize="SM" ID="PXLayoutRule1" runat="server" StartRow="True"></px:PXLayoutRule>
Notice ID="PXLayoutRule1" in that sample. If this "ID" value of any entry in the ASPX is duplicated anywhere in the screen as an ID of another entry, you will get an error.
I had similar issues in an earlier version, especially when I would try to customize a screen and have the customization screen interface crash on me in the middle of it. I'd try deleting the screen, but I'd get orphaned files in the CstDesigner and CstPublished folder, which would really compound my issues.
Hopefully, you know how to look through your ASPX file and the Customization Project XML to check all the ID's. If you do know how to walk through all that, just add something to all of your ID values, like an X at the end. (i.e. PXLayoutRule1X) If not, gaining that familiarity is a worthy side-objective as you continue on.
If your issue is the same as I had in the past and you cannot simply find and edit the duplicate ID in the ASPX file or Project XML, here are some steps to take AFTER you backup your project and the affected folders noted in these steps. And, of course, this also assumes you are working in a development copy of your instance. (I often clone my main DEV instance to my laptop to test things like this if I am unsure so that my DEV instance stays unaffected. It just takes extra time you may or may not have.)
Delete the screen from your customization project.
Locate the folder CstDesigner and CstPublished under your instance's root folder (i.e. AcumticaDEV, Sandbox, etc. where your site exists)
Go into the Pages_XX folder (where XX is the 2 character code for your 1st 2 letters of the screen ID)
Delete the screen file(s) from there, if you find them.
If this is a custom screen, go into the Pages folder which is located in the same root folder of your instance as those folders in step 2 and repeat steps 3 and 4 in that folder.
Check for any reference to your screen in the Project XML from the file menu in the Customization Project screen and remove those sections if they exist. (This tends to relate more for customizing an existing screen.)
Publish your project.
Start over on your page and see if you still get the error.
Again, be sure to get a backup before taking these steps so that you can easily put it back if that does not resolve your problem.
I have added custom fields in customization form using the customization form, steps i have added:
1) Go to shipment form and select Transaction Grid.
2) Select Add fields.
3) Select custome and Add 4 fields and save and publish.
4) Add all 4 fields and select used and save.
5) and publish again and all 4 columns are visible.
6) I have added a user fields name Aloow (PXDBBool), UsrPClocation(Location) and UsrPCwarehouse(Site),
and i set the below attribute in warehour and location.
7) But on SOSHipLine_InventotyID_FieldUpdate event, i am setting Allow, location, warehouse all 3 values, but values are not showing in Grid, what is the resoon?
#region UsrQCSiteID
[PXUIField(DisplayName = "PC Warehouse")]
[SiteAvail(typeof(SOShipLine.inventoryID), typeof(SOShipLine.subItemID))]
[PXUIRequired(typeof(Where<usrAllow, Equal<True>>))]
[PXUIEnabled(typeof(Where<usrAllow, Equal<True>>))]
[PXDefault()]
public virtual int? UsrPCSiteID {
get; set;
}
public abstract class usrPCSiteID:PX.Data.BQL.BqlInt.Field<usrPCSiteID> {
}
#endregion UsrPCSiteID
#region UsrPCLocationID
[PXUIField(DisplayName = "PC Location")]
[SOLocationAvail(typeof(SOShipLine.inventoryID), typeof(SOShipLine.subItemID), typeof(SOShipLineExt.usrPCSiteID), typeof(SOLine.tranType), typeof(SOShipLine.invtMult))]
[PXUIRequired(typeof(Where<usrQCRequired, Equal<True>>))]
[PXUIEnabled(typeof(Where<usrQCRequired, Equal<True>>))]
[PXDefault()]
public virtual int? UsrPCLocationID {
get; set;
}
public abstract class usrPCLocationID:PX.Data.BQL.BqlInt.Field<usrPCLocationID> {
}
#endregion UsrPCLocationID
#region Allow
[PXDBBool]
[PXUIField(DisplayName = "Allow")]
public virtual bool? UsrAllow {
get; set;
}
public abstract class usrAllow:PX.Data.BQL.BqlBool.Field<usrAllow> {
}
#endregion
IS SOShipLine allow updating custom values?
The steps that you described look correct.
I recreated this scenario locally:
1 - My DAC extension looks as follows:
public class SOShipLineExt : PXCacheExtension<PX.Objects.SO.SOShipLine>
{
#region UsrPCSiteID
[PXUIField(DisplayName = "PC Warehouse")]
[SiteAvail(typeof(SOShipLine.inventoryID), typeof(SOShipLine.subItemID))]
public virtual int? UsrPCSiteID {
get; set;
}
public abstract class usrPCSiteID:PX.Data.BQL.BqlInt.Field<usrPCSiteID> {
}
#endregion UsrPCSiteID
#region UsrPCLocationID
[PXUIField(DisplayName = "PC Location")]
[SOLocationAvail(typeof(SOShipLine.inventoryID), typeof(SOShipLine.subItemID), typeof(SOShipLineExt.usrPCSiteID), typeof(SOShipLine.tranType), typeof(SOShipLine.invtMult))]
public virtual int? UsrPCLocationID {
get; set;
}
public abstract class usrPCLocationID:PX.Data.BQL.BqlInt.Field<usrPCLocationID> {
}
#endregion UsrPCLocationID
#region Allow
[PXDBBool]
[PXUIField(DisplayName = "Allow")]
public virtual bool? UsrAllow {
get; set;
}
public abstract class usrAllow:PX.Data.BQL.BqlBool.Field<usrAllow> {
}
#endregion
}
Notes about the DAC Extension:
I removed references to PXUIEnabled and PXUIRequired. If you are looking to disable the Site and the Location based on the checkbox's value, I recommend you manage this logic in the RowSelected event. (it may be feasible with your approach but I have not used it before)
The PXDefault references were also removed, given that in most cases the Shipment is created directly from the Sales Order page. As you have it right now, the field is mandatory but no default value is being assigned which will cause an error. You have 2 options: 1) indicate the value in the PXDefault() attribute, or 2) Set the property PXPersistingCheck.Nothing.
Note that your SOLocationAvail attribute has an error in the 4th parameter. You should use typeof(SOShipLine.tranType) instead of typeof(SOLine.tranType). This was generating an error when the shipment was created from the SO.
2 - My FieldUpdated event looks as follows:
public class SOShipmentEntry_Extension : PXGraphExtension<SOShipmentEntry>
{
protected virtual void SOShipLine_InventoryID_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e)
{
if (e.Row == null) return;
SOShipLine line = (SOShipLine)e.Row;
SOShipLineExt lineExt = cache.GetExtension<SOShipLineExt>(line);
if (lineExt != null)
{
lineExt.UsrAllow = true;
lineExt.UsrPCSiteID=154;
lineExt.UsrPCLocationID=155;
}
}
}
Notes about the Graph extension:
I hard-coded the Warehouse and Location values. I recommend you do the same on your end while testing is being done, just make sure that the IDs exist in your DB, or that you query the CD value and then use its corresponding ID value.
Results:
When the Shipment is created from a SO, the values are being correctly assigned:
I am referring to Send Case Reminder project in GitHub where it has LastActivity and LastActivityAge for each case based on which it calculates days and send automatic email notifications.
However, for some reason it is not present in my cases when I implemented the project. So here is what I did.
I created a simple GI from CRCase table and just added three columns to the ResultsGrid, viz. CaseCD, LastActivity & LastActivityAge. What I get is there is no values in LastActivity & LastActivityAge columns for all cases. I am not sure how it works or how should I get the values for these two fields.
I have also checked CRActivityStatistics table for LastIncomingActivityDate and LastOutgoingActivityDate fields. And these two fields has values for all the cases.
Any suggestions would be much appreciated.
PS. I am using 2018 R2 ver 18.201.0050.
Since you do see expected data within the CRActivityStatistics but don’t see the proper values on your GI that would suggest that your join relationship might be incorrect. This could be the issue in your GI and in your code. The proper join is CRCASE.NOTEID = CRACTIVITYSTATISTICS.NOTEID.
I was able to get this through DAC extension
#region LastIncomingActivityDate
public abstract class lastIncomingActivityDate : PX.Data.IBqlField
{
}
[PXDBDate(BqlField = typeof(CRActivityStatistics.lastIncomingActivityDate), PreserveTime = true, UseSmallDateTime = false)]
[PXUIField(DisplayName = "Last Incoming Activity")]
public virtual DateTime? LastIncomingActivityDate { get; set; }
#endregion
#region LastOutgoingActivityDate
public abstract class lastOutgoingActivityDate : PX.Data.IBqlField
{
}
[PXDBDate(BqlField = typeof(CRActivityStatistics.lastOutgoingActivityDate), PreserveTime = true, UseSmallDateTime = false)]
[PXUIField(DisplayName = "Last Outgoing Activity")]
public virtual DateTime? LastOutgoingActivityDate { get; set; }
#endregion
#region LastActivityDate
public abstract class lastActivityDate : IBqlField { }
[PXDBCalced(typeof(Switch<
Case<Where<lastIncomingActivityDate, IsNotNull, And<lastOutgoingActivityDate, IsNull>>, lastIncomingActivityDate,
Case<Where<lastOutgoingActivityDate, IsNotNull, And<lastIncomingActivityDate, IsNull>>, lastOutgoingActivityDate,
Case<Where<lastIncomingActivityDate, Greater<lastOutgoingActivityDate>>, lastIncomingActivityDate>>>,
lastOutgoingActivityDate>),
typeof(DateTime))]
[PXUIField(DisplayName = "Last Activity Date", Enabled = false)]
[PXDate]
public virtual DateTime? LastActivityDate { get; set; }
#endregion
#region UsrLastActivityAge
public abstract class usrLastActivityAge : PX.Data.IBqlField
{
}
[PXTimeSpanLong(InputMask = "#### ds ## hrs ## mins")]
[PXFormula(typeof(Sub<PXDateAndTimeAttribute.now, lastActivityDate>))]
[PXDefault(0)]
[PXUIField(DisplayName = "Last Activity Age")]
public virtual Int32? UsrLastActivityAge { get; set; }
#endregion
I have an extension graph onto INReceiptEntry. I set up a view for the custom DAC that I want a cache generated for that will get objects inserted into. After I generate one of the objects I want to insert into the cache, I use ViewName.Insert(Object); (also used ViewName.Cache.Insert(Object) with same results) within the graph extension's RowPersisting handler. This normally would store the data items in the corresponding database data table associated to the DAC, but nothing is stored in the DB. Instead of If statement fires and I get a popup stating that the object wasn't inserted. Here is my code:
public class INReceiptEntry_Extension : PXGraphExtension<INReceiptEntry>
{
public PXSelect<EMPWorkOrderINRegister> WorkOrderINRegisters;
#region Event Handlers
protected void INRegister_RowPersisting(PXCache cache, PXRowPersistingEventArgs e)
{
var row = (INRegister)e.Row;
var rowExt = PXCache<INRegister>.GetExtension<INRegisterExt>(row);
//Get Target Objects
foreach (INTranSplit split in PXSelect<INTranSplit, Where<INTranSplit.refNbr,
Equal<Required<INRegister.refNbr>>, And<INTranSplit.tranType, Equal<TranType>>>>
.Select(Base, Base.CurrentDocument.Current.RefNbr))
{
EMPWorkOrderINRegister WOINR = new EMPWorkOrderINRegister();
WOINR.Woid = rowExt.Usrwoid;
WOINR.RefNbr = split.RefNbr;
WOINR.SplitLineNbr = split.SplitLineNbr;
if (WorkOrderINRegisters.Insert(WOINR) == null)
{
Base.CurrentDocument.Ask("Did not insert WOINR:" + WOINR.RefNbr.ToString() + ", " + WOINR.SplitLineNbr.ToString(), MessageButtons.OK);
return;
}
}
}
#endregion
}
Any reason this isn't inserting into the custom cache? Does using a graph extension or executing this cache insert in a Persisting function have anything to do with why this is failing?
By request, the DAC:
using System;
using PX.Data;
using PX.Objects.IN;
namespace Manufacturing
{
[Serializable]
public class EMPWorkOrderINRegister : IBqlTable
{
#region Id
[PXDBIdentity()]
[PXUIField(DisplayName = "Id")]
public int? Id { get; set; }
public class id : IBqlField { }
#endregion
#region Woid
[PXDBInt()]
[PXUIField(DisplayName = "Woid")]
public int? Woid { get; set; }
public class woid : IBqlField { }
#endregion
#region RefNbr
[PXDBString(15, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Receipt Number")]
public string RefNbr { get; set; }
public class refNbr : IBqlField { }
#endregion
#region SplitLineNbr
[PXDBInt()]
[PXUIField(DisplayName = "Split Line Nbr")]
public int? SplitLineNbr { get; set; }
public class splitLineNbr : IBqlField { }
#endregion
#region AvailableSNs
[PXString()]
[PXUIField(DisplayName = "Available SNs")]
public string AvailableSNs { get; set; }
public class availableSNs : IBqlField { }
#endregion
[PXString()]
[PXDBScalar(typeof(Search<INTranSplit.lotSerialNbr, Where<INTranSplit.refNbr, Equal<EMPWorkOrderINRegister.refNbr>,
And<INTranSplit.splitLineNbr, Equal<EMPWorkOrderINRegister.splitLineNbr>>>>))]
public string SelectedSN { get; set; }
public class selectedSN : IBqlField { }
}
}
Eric, there is one major issue with your DAC, which is the lack of key fields.
Additional area of improvement in the INRegister_RowPersisting handler. RowPersisting handlers are designed to either validate the data record before it's committed to database or cancel the commit operation of a specific data record. For more details, please refer to the Acumatica Framework API Reference
The better approach for your scenario is to override the Persist method and insert missing EMPWorkOrderINRegister records before execution of the base Persist method. It's also a good idea to use a try-catch statement and delete EMPWorkOrderINRegister records with the Inserted status if base Persist method had failed.
I have a custom processing page. The main DAC of the data view is ARRegister, but there is the data view delegate. Both the view & delegate join ARCashSale & ARInvoice to the main DAC, The reason for this is...some records are cash sales, and others are invoices, overdue charges, ect. A few grid columns are included, which displays data specific to a cash sale. I invoke a static method in my process graph to assign the process delegate. The method runs with no errors.
In the data view delegate, I check the doc type for each record returned from the BQL.
If cash sale, then
yield return new PXResult<ARRegister, ARCashSale>(register, cashsale)
ELSE
yield return new PXResult<ARRegister>(register)
The reason for the delegate is to check some other conditions which cannot be determined using standard BQL. I notice the data in the column specific to a cash sale disappears after the user selects 'Process All'. I am unable to determine the reason. Checking to see if others have experienced this.
DataView
public PXProcessingJoin<ARRegister,
LeftJoin<cs.ARCashSale, On<ARRegister.docType, Equal<cs.ARCashSale.docType>, And<ARRegister.refNbr, Equal<cs.ARCashSale.refNbr>>>,
LeftJoin<ARInvoice, On<ARRegister.docType, Equal<ARInvoice.docType>, And<ARRegister.refNbr, Equal<ARInvoice.refNbr>>>,
InnerJoin<Customer,On<ARRegister.customerID,Equal<Customer.bAccountID>>>>>,
Where2<Where<ARRegister.released, Equal<True>, And<ARRegister.branchID, Equal<Current<AccessInfo.branchID>>>>,
And<Where<Customer.finChargeApply,Equal<True>>>>> Registers;
This is an older question, but I had a similar issue.
You need to add a boolean field named "Selected" to DACs you want to process.
The way I solved it was using a local DAC.
You can make it inherit from ARRegister and just add the required field.
In my case I used PXProjection, inherited from the main DAC and added the fields I needed from the joined DACs. Note that you need to add the BqlField = typeof(DAC.field) property to the type attribute of these fields to map them to the correct DAC.
Then in the PXProcessing view you just use your local DAC.
Also, it is very useful to try the Request Profiler screen (SM205070) when troubleshooting BQL.
Basically in processing screens sub DAC (other than Main DAC in view), filed values will not persist once the process completed.
In this case, the PXProjection will help us to persist the values even after completion of the process for the rows/records in processing screens.
Please find the sample Projection View and DAC below.
[PXProjection(typeof(Select2<SOShipment, InnerJoin<SOOrderShipment,
On<SOOrderShipment.shipmentNbr, Equal<SOShipment.shipmentNbr>,
And<SOShipment.status, Equal<SOShipmentStatus.confirmed>>>,
InnerJoin<SOOrder, On<SOOrderShipment.orderType, Equal<SOOrder.orderType>,
And<SOOrderShipment.orderNbr, Equal<SOOrder.orderNbr>>>>>>))]
Projection DAC:
[Serializable]
public class ProjectionShipmentDAC : IBqlTable
{
#region Selected
public abstract class selected : IBqlField
{
}
protected bool? _Selected = false;
[PXBool]
[PXDefault(false, PersistingCheck = PXPersistingCheck.Nothing)]
[PXUIField(DisplayName = "Selected")]
public virtual bool? Selected
{
get
{
return _Selected;
}
set
{
_Selected = value;
}
}
#endregion
#region Status
[PXDBString(1, IsFixed = true, BqlField = typeof(SOShipment.status))]
[PXUIField(DisplayName = "Status")]
[SOShipmentStatus.List()]
public virtual string Status { get; set; }
public abstract class status : IBqlField { }
#endregion
#region ShipmentNbr
[PXDBString(15, IsKey = true, IsUnicode = true, BqlField = typeof(SOShipment.shipmentNbr))]
[PXUIField(DisplayName = "Shipment Nbr.")]
public virtual string ShipmentNbr { get; set; }
public abstract class shipmentNbr : IBqlField { }
#endregion
#region ShipDate
[PXDBDate(BqlField = typeof(SOShipment.shipDate))]
[PXUIField(DisplayName = "Shipment Date")]
public virtual DateTime? ShipDate { get; set; }
public abstract class shipDate : IBqlField { }
#endregion
#region CustomerID
[PXDBInt(BqlField = typeof(SOShipment.customerID))]
[PXUIField(DisplayName = "Customer")]
[PXSelector(typeof(Customer.bAccountID), new Type[] { typeof(Customer.acctCD), typeof(Customer.acctName) },
SubstituteKey = typeof(Customer.acctCD), DescriptionField = typeof(BAccount.acctName))]
public virtual int? CustomerID { get; set; }
public abstract class customerID : IBqlField { }
#endregion
#region Shipped Quantity
[PXDBDecimal(BqlField = typeof(SOShipment.shipmentQty))]
[PXUIField(DisplayName = "Shipped Quantity")]
public virtual decimal? ShipmentQty { get; set; }
public abstract class shipmentQty : IBqlField { }
#endregion
}
Have you played around with MatrixMode and/or SyncPosition on your page grid? You might need SyncPosition="True"
Also, does the issue occur if not using process all? (process 1 or 2 rows)