I would like to modify the ShippedQty field by putting the same value as the OpenOrderQty field after adding the line, but that does nothing. I removed the PXDefault. The value stay at 0.00.
protected void SOShipLine_RowInserted(PXCache cache, PXRowInsertedEventArgs e, PXRowInserted InvokeBaseHandler)
{
if(InvokeBaseHandler != null)
InvokeBaseHandler(cache, e);
var row = (SOShipLine)e.Row;
if (row==null) {return;}
row.ShippedQty=row.OpenOrderQty;
}
Thanks.
Xavier
I would like to suggest you to not set the ShippedQty because it might have some implications as it is a calculated field. Instead, you can create a custom field and set the value of OpenOrderQty to that field.
When the RowInserted event is fired, the data has already been inserted into the cache so it's too late to try and edit the data. You should change this to use a RowInserting() event. See more details here
Related
I need to attach custom data into new fields added to INTranCost when the PO Receipt occurs.
Following the breadcrumbs, it seems that POReceiptEntry -> Release Action eventually calls INDocumentRelease.ReleaseDoc that eventually creates INTranCost. I tried extending both POReceiptEntry and INDocumentRelease to add an event for INTranCost_RowInserted to publish a PXTrace message, but the trace doesn't appear, telling me that I'm not hitting the event that I expected. (Which explains why the real business logic I need included didn't fire.)
protected virtual void _(Events.RowInserted<INTranCost> e)
{
PXTrace.WriteInformation("This is it!");
}
Of course, I want to put real code in this spot, but I am just trying to make sure I'm hitting the event properly. This works on pretty much everything else I've done, including attaching similar data to INTranExt fields. I cannot get it to work for INTranCost so that I can add to INTranCostExt. At this point, I can't determine if it is location (which graph extension) or a special methodology required for this special case.
I also tried overriding events and putting a breakpoint on the code, but it's like I'm not even on the same process. (Yes, I checked that I am connected to the right Acumatica instance and that I have no errors.)
What event in which graph is required to capture the creation in INTranCost for a PO Receipt to update custom fields in INTranCostExt?
Using Request Profiler, I was able to determine that I was close but not deep enough. While the INTranCost object to insert was built in INDocumentRelease FILE, the actual insert was processed in INReleaseProcess graph in that same file.
I only need to execute this "push" from the data captured on the POLine when the INTranCost record is created, and LineNbr is a key field and therefore never updated after it is set. I need to be sure that I have enough data to make the connection back, and the primary key links me back to the INTran easily. That subsequently gets back to the POReceiptLine to the POLine where the data is maintained that needs the "current value" to be captured when the transaction is posted. Since I need to update the DAC Extension, I need to use an event that will allow an existing DAC.Update to apply my values. Therefore, I added an event handler on INTranCost_LineNbr_FieldUpdated since that value should not be "updated" after it is set initially.
Code that accomplished the task:
public class INReleaseProcess_Extension : PXGraphExtension<INReleaseProcess>
{
public override void Initialize()
{
base.Initialize();
}
protected virtual void _(Events.FieldUpdated<INTranCost.lineNbr> e)
{
INTranCost row = (INTranCost) e.Row;
INTran tran = PXSelect<INTran,
Where<INTran.docType, Equal<Required<INTran.docType>>,
And<INTran.refNbr, Equal<Required<INTran.refNbr>>,
And<INTran.lineNbr, Equal<Required<INTran.lineNbr>>
>>>>
.SelectSingleBound(Base, null, row.DocType, row.RefNbr, (int?) e.NewValue);
if (tran?.POReceiptType != null && tran?.POReceiptNbr != null)
{
PXResultset<POReceiptLine> Results = PXSelectJoin<POReceiptLine,
InnerJoin<POLine, On<POLine.orderType, Equal<POReceiptLine.pOType>,
And<POLine.orderNbr, Equal<POReceiptLine.pONbr>,
And<POLine.lineNbr, Equal<POReceiptLine.pOLineNbr>>>>,
InnerJoin<POOrder, On<POOrder.orderType, Equal<POLine.orderType>,
And<POOrder.orderNbr, Equal<POLine.orderNbr>>>>>,
Where<POReceiptLine.receiptType, Equal<Required<POReceiptLine.receiptType>>,
And<POReceiptLine.receiptNbr, Equal<Required<POReceiptLine.receiptNbr>>,
And<POReceiptLine.lineNbr, Equal<Required<POReceiptLine.lineNbr>>>>>>.
SelectSingleBound(Base, null, tran.POReceiptType, tran.POReceiptNbr, tran.POReceiptLineNbr);
if (Results != null)
{
foreach (PXResult<POReceiptLine, POLine, POOrder> result in Results)
{
POReceiptLine receipt = result;
POLine line = result;
POOrder order = result;
POLineExt pOLineExt = PXCache<POLine>.GetExtension<POLineExt>(line);
INTranCostExt iNTranCostExt = PXCache<INTranCost>.GetExtension<INTranCostExt>(row);
if (pOLineExt != null && iNTranCostExt != null)
{
Base.Caches[typeof(INTranCost)].SetValueExt<INTranCostExt.usrField>(row, pOLineExt.UsrField);
}
}
}
}
}
}
I have a checkbox on a DAC extension to the BAccount that I want to use to set a checkbox on Case when a customer is selected. Here is what the checkbox looks like on the Business Account screen.
Here is the field on the Case screen that I want to set when the customer is selected.
I found a stack overflow question where a couple of custom fields on a customer screen were to be copied to custom fields on a sales order. I have tried to substitute my fields into the code but I haven't been able to make it work.
Here is what I have tried. I'm not sure what I am missing.
protected void CRCase_CustomerID_FieldUpdated(PXCache sender, PXFieldUpdatedEventArgs e)
{
var crcase = e.Row as CRCase;
if (crcase.CustomerID != null)
{
var customer = PXSelectorAttribute.Select<CRCase.customerID>(sender, crcase) as BAccountR;
if (customer != null)
{
var customerExt = customer.GetExtension<BAccountExt>();
var crcaseExt = crcase.GetExtension<CRCaseExt>();
crcaseExt.UsrContractCustomer = customerExt.UsrSage100;
}
}
}
I do not understand why BAccountR is used instead of just BAccount. Neither works right now.
I solved the issue by combining are response I received on an earlier post. I modified the last two line as follows:
var customerExt = customer.GetExtension<BAccountExt>();
//var crcaseExt = crcase.GetExtension<CRCaseExt>();
//crcaseExt.UsrContractCustomer = customerExt.UsrSage100;
sender.SetValueExt<CRCaseExt.usrContractCustomer>(crcase, customerExt.UsrSage100 != null);
So here is the final issue that I need to resolve. The checkbox I used on the Business Account screen opens a new tab that displays custom fields. These custom fields are an extension of the BAccount DAC called DSDSage100. It is similar to the extension of the BAccount called Customer. In the DSDSage100 extension there is a field called UsrContractCustomer. That is the field that I want to read and set the Case field to the same value. Here is what the Sage 100 Tab looks like. I have a using directive for my project but I can't find the right reference to the DSDSage100 extension.
var customerExt = customer.GetExtension<DSDSage100>();
sender.SetValueExt<CRCaseExt.usrContractCustomer>(crcase, customerExt.UsrContractCustomer != null);
Acumatica provided the answer. While I "extended the BAccount DAC" with my custom table (DSDSage100, similar to the way Customer is an extension of the BAccount DAC), it is it's own DAC. The solution was:
DSDSage100 mydac = PXSelect<DSDSage100, Where<DSDSage100.bAccountID, Equal<Required<DSDSage100.bAccountID>>>>.Select(Base, crcase.CustomerID);
sender.SetValueExt<CRCaseExt.usrContractCustomer>(crcase, mydac.UsrContractCustomer != null);
Thanks for the help and support.
I have added a user defined checkbox UsrContractCustomer to CRCase. My first step is to try to set the checkbox when the user selects the Business Account (CustomerID).
Here is my latest attempt to set the checkbox.
protected void CRCase_CustomerID_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e)
{
var row = (CRCase)e.Row;
if (row.CustomerID != null)
{
//CRCaseExt rowExt = PXCache<CRCase>.GetExtension<CRCaseExt>(row);
CRCaseExt rowExt = row.GetExtension<CRCaseExt>();
rowExt.UsrContractCustomer = true;
}
}
On your field in your dac extension you should be able to use a formula to set the value. This will check or uncheck you field when the customer is entered or removed. Having the logic on the field also removes the need to write graph level changes such as events.
[PXFormula(typeof(IIf<Where<CRCase.customerID, IsNull>, False, True>))]
If you want to use the event as you have it I would try cache set value such as:
cache.SetValueExt<CRCaseExt.usrContractCustomer>(e.Row, row.CustomerID != null);
Brendan's solution is correct. In another post I retrieved the value that I wanted to use to set the user-defined field. The 'false' was replaced with a condition that sets the checkbox field.
sender.SetValueExt<CRCaseExt.usrContractCustomer>(crcase, false);
Thanks for the help and support.
I have had set my custom field 'UsrPrintQty' to be enabled on POReceiptLine_RowSelected event as below:
protected void POReceiptLine_RowSelected(PXCache cache, PXRowSelectedEventArgs e, PXRowSelected InvokeBaseHandler)
{
if (InvokeBaseHandler != null)
InvokeBaseHandler(cache, e);
var row = (POReceiptLine)e.Row;
PXUIFieldAttribute.SetEnabled<POReceiptLineExt.usrPrintQty>(cache, row, true);
//PXUIFieldAttribute.SetEnabled(cache, row, "UsrPrintQty", true);
}
And it is working perfectly on my development server with the Acumatica version 18.200.0075. But when I published the customization to the another instance with the version 18.112.0019, it just doesn't work.
I debug the code and the line is being hit too.
I set the highest customization level guessing there might be chance that other code is overriding this one.
I restart the application via Apply Updates.
I even changed the event from RowSelected to RowSelecting.
I tried the different overloaded method of SetEnabled (which is commented in the above code).
But nothing works.
If I put these two lines:
cache.AllowUpdate = true;
Base.transactions.Cache.AllowUpdate = true;
then it allows me to update but then I can update the whole row which I don't want to.
I also set the field property AllowUpdate to true.
But still no luck.
Thank you.
The cache AllowUpdate method takes precedence on SetEnabled method.
Calling the cache AllowUpdate with false parameter is commonly used on closed document to prevent any modification.
If you require the user to be able to modify one field of a closed document you'll have to jump through some hoops. Setting AllowUpdate to true after the base graph has set it to false is necessary.
Try this pattern:
// Required to enable any field
Base.transactions.Cache.AllowUpdate = true;
// Set all fields to false
PXUIFieldAttribute.SetEnabled(Base.transactions.Cache, null, false);
// Set the only field we want to enable to true
PXUIFieldAttribute.SetEnabled<POReceiptLineExt.usrPrintQty>(Base.transactions.Cache, null, true);
Client has an Customised field called “Approval Type” on the Purchase Order Entry screen (screenshot attached). By Default this field is available when user creates an Order.
We are implementing the Approval Workflow for this client. The client wants that when a new PO is created, this field should be disabled. But once the PO is approved and user wants to make any change in the approved PO, On selecting “Hold” checkbox option, this field should be active and user should then be allowed to set any value from the field list and save the Order. I tried the Automation steps but could not figure out how to achieve it.
Many Thanks
In the rowselected event of the POOrder, add your conditions and use the PXUIFieldAttribute.SetVisible to hide/show your field.
It will be something like below.
protected virtual void POOrder_RowSelected(PXCache sender, PXRowSelectedEventArgs e, PXRowSelected del)
{
if (e.Row == null) return;
if (del != null) del(sender, e);
PXUIFieldAttribute.SetVisible<YOUR custom FIELD>(sender, e.Row, <Your true condition to show>);
}