Skip to main content
Answer

"Another process has updated the 'SOOrder' record. Your changes will be lost."

  • August 14, 2025
  • 7 replies
  • 167 views

Forum|alt.badge.img

I've overridden the RunCaptureActions method of the ARPaymentAfterProcessingManager and intend to add my own logic, such as FunctionA, before base.RunCaptureActions.
FunctionA's logic involves adding a SOLine to the current SOOrder. I also need to modify the Applied To Order and Payment Amount fields under the Payments tab to match the added SOLine. How can I resolve this error?

 

public class TestARPaymentAfterProcessingManager : ARPaymentAfterProcessingManager
{
    [PXOverride]
    public override void RunCaptureActions(IBqlTable table, bool success)
    {
        ARPaymentEntry graph = base.CreateGraphIfNeeded(table);
        FunctionA(graph, table);
        base.RunCaptureActions(table, success);
    }
 }

FunctionA:

 //---"Another process has updated the 'SOOrder' record. Your changes will be lost."-----
 SOLine soLine = new SOLine();
 soLine.InventoryID = item.InventoryID;
 soLine.OrderNbr = soOrder.OrderNbr;
 soLine.OrderType = soOrder.OrderType;
 soLine.BranchID = soOrder.BranchID;
 soLine.Qty = 1;
 soLine.CuryUnitPrice = testamount;
 soLine.CuryExtPrice = testamount;
 soLine = soEntry.Transactions.Insert(soLine);
 soEntry.SelectTimeStamp();
 soEntry.Save.Press();

 CCProcTran cCProcTran = SelectFrom<CCProcTran>.Where<CCProcTran.refNbr.IsEqual<@P.AsString>.And<CCProcTran.pCTranNumber.IsEqual<@P.AsString>>>.View.ReadOnly.Select(aRPaymentEntry, aRPayment.RefNbr, "key");
 if (cCProcTran != null)
 {
     cCProcTran.Amount = totalamt;
     soEntry.ccProcTran.Update(cCProcTran);
 }
 ExternalTransaction externalTransaction = SelectFrom<ExternalTransaction>.Where<ExternalTransaction.refNbr.IsEqual<@P.AsString>.And<ExternalTransaction.tranNumber.IsEqual<@P.AsString>>>.View.ReadOnly.Select(aRPaymentEntry, aRPayment.RefNbr, "key");
 if (externalTransaction != null)
 {
     externalTransaction.Amount = totalamt;
     externalTransaction.SyncMessage = string.Empty;
     soEntry.ExternalTran.Update(externalTransaction);
 }


 aRPayment.CuryOrigDocAmt = totalamt;
 aRPaymentEntry.Document.Update(aRPayment);
 aRPaymentEntry.SelectTimeStamp();
 aRPaymentEntry.Save.Press();

 sOAdjust.CuryAdjdAmt= totalamt;
 sOAdjust.CuryOrigDocAmt = totalamt;
 soEntry.Adjustments.Update(sOAdjust);
 soEntry.SelectTimeStamp();
 soEntry.Save.Press(); 
 //---

Best answer by aiwan

There is no associated ARAdjust in the ARPayment in SOOrder. In addition, there is a validation event SOAdjust_CuryAdjdAmt_FieldVerifying in the Acumatica source code for CuryAdjdAmt. This event verifies itself and the modified value. I updated the balance in an attempt to circumvent it.

That’s fine, but you are grabbing a record from the cache when you use SOAdjust sOAdjust = graph.Caches<SOAdjust>().Cached.Cast<SOAdjust>().FirstOrDefault();

When you update this record, it ends up with a higher value than the ARPayment value, apologies this is what I meant rather than ARAdjust value.

 

If you assign the value of the ARPayment prior to the SOAdjust record, you should not get the error.

 

Regarding this in my previous reply “You will also need to find the ARAdjust record, and update the CuryAdjgAmt field, otherwise, your document will be out of balance.” I did a recent project with invoices in which this caused an issue but if you do not have an ARAdjust record, or an invoice, then it should be fine.

7 replies

darylbowman
Captain II
Forum|alt.badge.img+15

Since you’re inheriting the RunCaptureActions method from ARPaymentAfterProcessingManager, you don’t need to use PXOverride. That can only be used in a graph extension.

 

In this statement, you’re using aRPaymentEntry as the graph to select cCProcTran, but attempting to update it in soEntry. I’d recommend selecting from soEntry.

CCProcTran cCProcTran = SelectFrom<CCProcTran>.
Where<CCProcTran.refNbr.IsEqual<@P.AsString>.
And<CCProcTran.pCTranNumber.IsEqual<@P.AsString>>>.
View.ReadOnly.Select(aRPaymentEntry, aRPayment.RefNbr, "key");
 if (cCProcTran != null)
 {
     cCProcTran.Amount = totalamt;
     soEntry.ccProcTran.Update(cCProcTran);
 }

Same with this one:

ExternalTransaction externalTransaction = SelectFrom<ExternalTransaction>.
Where<ExternalTransaction.refNbr.IsEqual<@P.AsString>.
And<ExternalTransaction.tranNumber.IsEqual<@P.AsString>>>.
View.ReadOnly.Select(aRPaymentEntry, aRPayment.RefNbr, "key");
 if (externalTransaction != null)
 {
     externalTransaction.Amount = totalamt;
     externalTransaction.SyncMessage = string.Empty;
     soEntry.ExternalTran.Update(externalTransaction);
 }

Not certain this is causing the error, but I’d fix those to start with.


darylbowman
Captain II
Forum|alt.badge.img+15

Also, aRPayment and sOAdjust aren’t initialized in the code you posted, but I’d make sure you aren’t cross contaminating caches with those as well.


Forum|alt.badge.img
  • Author
  • Freshman I
  • August 18, 2025

@darylbowman 

I made the following changes and no longer get the "Another process has updated the 'SOOrder' record. Your changes will be lost." error.
Because the graph in the current thread is an ARPaymentEntry, I had to use the following method to retrieve the cached data: graph.Caches<SOOrder>().Cached.Cast<SOOrder>().FirstOrDefault()
When saving, use:
soEntry.TimeStamp = soOrder.tstamp;
Is this the best approach?

Also, when calling soEntry.Adjustments.Update(sOAdjust);, I get the "AR Error: Entry must be less than or equal to 500.0000" error.
It seems this validation is done in Acumatica's SOAdjust_CuryAdjdAmt_FieldVerifying.
How can I circumvent it?

 

public override void RunCaptureActions(IBqlTable table, bool success)
   {
       ARPaymentEntry graph = base.CreateGraphIfNeeded(table);
       FunctionA(graph, table);
       base.RunCaptureActions(table, success);
   }

private void FunctionA(ARPaymentEntry graph, IBqlTable table)
{
    PX.Objects.AR.ARPayment aRPayment = table as PX.Objects.AR.ARPayment;
    SOOrderEntry soEntry = PXGraph.CreateInstance<SOOrderEntry>();
    SOOrder soOrder=graph.Caches<SOOrder>().Cached.Cast<SOOrder>().FirstOrDefault();
    SOAdjust sOAdjust = graph.Caches<SOAdjust>().Cached.Cast<SOAdjust>().FirstOrDefault();
    soEntry.Document.Current = soOrder;
    soEntry.Adjustments.Current = sOAdjust;

    CCProcTran cCProcTran = SelectFrom<CCProcTran>.Where<CCProcTran.refNbr.IsEqual<@P.AsString>>.View.ReadOnly.Select(soEntry, aRPayment.RefNbr);

    decimal testamount = 5m;
    SOLine soLine = new SOLine();
    soLine.InventoryID = 10322;
    soLine.OrderNbr = soOrder.OrderNbr;
    soLine.OrderType = soOrder.OrderType;
    soLine.BranchID = soOrder.BranchID;
    soLine.Qty = 1;
    soLine.CuryUnitPrice = testamount;
    soLine.CuryExtPrice = testamount;
    soLine = soEntry.Transactions.Insert(soLine);

    PFESOLine_Ext solineExt = soLine.GetExtension<PFESOLine_Ext>();
    solineExt.UsrPFETempPaymentKey = $"{aRPayment.DocType}-{aRPayment.RefNbr}";
    soLine = soEntry.Transactions.Update(soLine);
    decimal FinalAmount = 505m;
    if (cCProcTran != null)
    {
        cCProcTran.Amount = FinalAmount;
        soEntry.ccProcTran.Update(cCProcTran);
    }
    ExternalTransaction externalTransaction = SelectFrom<ExternalTransaction>.Where<ExternalTransaction.refNbr.IsEqual<@P.AsString>>.View.ReadOnly.Select(soEntry, aRPayment.RefNbr);
    if (externalTransaction != null)
    {
        externalTransaction.Amount = FinalAmount;
        externalTransaction.SyncMessage = string.Empty;
        soEntry.ExternalTran.Update(externalTransaction);
    }
    sOAdjust.CuryAdjdAmt = FinalAmount;
    sOAdjust.CuryOrigDocAmt = FinalAmount;
    soEntry.Adjustments.Update(sOAdjust);
    soLine = soEntry.Transactions.Insert(soLine);
    if (soEntry.TimeStamp != soOrder.tstamp)
    {
        soEntry.TimeStamp = soOrder.tstamp;
    }
    if (soEntry.Adjustments.Current.tstamp != sOAdjust.tstamp)
    {
        soEntry.Adjustments.Current.tstamp = sOAdjust.tstamp;
    }
    soEntry.Save.Press();

    graph.Document.Current = aRPayment;
    aRPayment.CuryOrigDocAmt = FinalAmount;
    graph.Document.Cache.Update(aRPayment);

    graph.Save.Press();
}

 


Forum|alt.badge.img+8
  • Captain II
  • August 18, 2025

@AndrewZ 

 

You are updating your amount for the Sales Order which must be lowering the total to below what is already applied, or the amount on the payment is 500 and your new Sales Order value is above it.

 

You should update your aRPayment.CuryOrigDocAmt first, then update sOAdjust.CuryAdjdAmt.

 

You will also need to find the ARAdjust record, and update the CuryAdjgAmt field, otherwise, your document will be out of balance.


Forum|alt.badge.img
  • Author
  • Freshman I
  • August 19, 2025

@AndrewZ 

 

You are updating your amount for the Sales Order which must be lowering the total to below what is already applied, or the amount on the payment is 500 and your new Sales Order value is above it.

 

You should update your aRPayment.CuryOrigDocAmt first, then update sOAdjust.CuryAdjdAmt.

 

You will also need to find the ARAdjust record, and update the CuryAdjgAmt field, otherwise, your document will be out of balance.

There is no associated ARAdjust in the ARPayment in SOOrder. In addition, there is a validation event SOAdjust_CuryAdjdAmt_FieldVerifying in the Acumatica source code for CuryAdjdAmt. This event verifies itself and the modified value. I updated the balance in an attempt to circumvent it.


darylbowman
Captain II
Forum|alt.badge.img+15

I not certain of the situation, but you could write a blank FieldVerifying extension handler and simply not call the base, or more complex logic, depending upon your needs.


Forum|alt.badge.img+8
  • Captain II
  • Answer
  • August 19, 2025

There is no associated ARAdjust in the ARPayment in SOOrder. In addition, there is a validation event SOAdjust_CuryAdjdAmt_FieldVerifying in the Acumatica source code for CuryAdjdAmt. This event verifies itself and the modified value. I updated the balance in an attempt to circumvent it.

That’s fine, but you are grabbing a record from the cache when you use SOAdjust sOAdjust = graph.Caches<SOAdjust>().Cached.Cast<SOAdjust>().FirstOrDefault();

When you update this record, it ends up with a higher value than the ARPayment value, apologies this is what I meant rather than ARAdjust value.

 

If you assign the value of the ARPayment prior to the SOAdjust record, you should not get the error.

 

Regarding this in my previous reply “You will also need to find the ARAdjust record, and update the CuryAdjgAmt field, otherwise, your document will be out of balance.” I did a recent project with invoices in which this caused an issue but if you do not have an ARAdjust record, or an invoice, then it should be fine.