Is it possible to change the Transaction Description (ARTran.TranDesc) for the invoices created when using Credit Terms with the Multiple Installment Type?
Currently it generates the invoices with “Multiple Installment Split” as the description. Ideally, we’d like it to either copy the transaction description from the original invoice or not automatically post the invoice so that we have the opportunity to manually adjust the description (i.e. maybe we’d write 1st Installment/2nd Installment/etc., or Installment for Dec-2025/Installment for Jan-2026/etc.).
Hi @natwi Here is how you can implement the logic I described above using a low-code approach through the Customization Project Editor:
Then, in the opened form, replace the code template with the following complete code snippet:
using PX.Data; using PX.Data.BQL; using PX.Data.BQL.Fluent; using PX.Objects.AR; using PX.Objects.CS; using System; using System.Collections.Generic; using System.Linq;
namespace Test { public class ARReleaseProcessExt : PXGraphExtension<PX.Objects.AR.ARReleaseProcess> { [PXOverride] public virtual List<ARRegister> CreateInstallments( PXResult<ARInvoice, PX.Objects.CM.Extensions.CurrencyInfo, Terms, Customer> res, Func<PXResult<ARInvoice, PX.Objects.CM.Extensions.CurrencyInfo, Terms, Customer>, List<ARRegister>> baseMethod) { var results = baseMethod(res);
var firstRegister = results.FirstOrDefault(); var firstInvoice = ARInvoice.PK.Find(Base, firstRegister.DocType, firstRegister.RefNbr); var masterTran = new SelectFrom<ARTran> .Where<ARTran.tranType.IsEqual<@P.AsString> .And<ARTran.refNbr.IsEqual<@P.AsString>>> .View(Base) .SelectSingle(firstInvoice.DocType, firstInvoice.MasterRefNbr);
foreach (var register in results) { var installmentTran = new SelectFrom<ARTran> .Where<ARTran.tranType.IsEqual<@P.AsString> .And<ARTran.refNbr.IsEqual<@P.AsString>>> .View(Base) .SelectSingle(register.DocType, register.RefNbr);
namespace Test { public class ARInvoiceEntry_Extension : PXGraphExtension<PX.Objects.AR.ARInvoiceEntry> { protected virtual void _(Events.RowSelected<ARInvoice> e) { if (!(e.Row is ARInvoice row)) return;
FYI: this code is based on version 25R2. If you are using a different version, you may encounter additional issues. If you are unable to publish your customization, feel free to share the Acumatica version you’re using along with the errors you’re getting — we’ll help adjust the code. The code snippets above should generally work for you, but if anything doesn’t, we can correct the logic to achieve the result you need.
To override the transaction description, you can override the CreateInstallments method as follows:
public class ARReleaseProcessExt : PXGraphExtension<PX.Objects.AR.ARReleaseProcess> { [PXOverride] public virtual List<ARRegister> CreateInstallments( PXResult<ARInvoice, PX.Objects.CM.Extensions.CurrencyInfo, Terms, Customer> res, Func<PXResult<ARInvoice, PX.Objects.CM.Extensions.CurrencyInfo, Terms, Customer>, List<ARRegister>> baseMethod) { var results = baseMethod(res);
var firstRegister = results.FirstOrDefault(); var firstInvoice = ARInvoice.PK.Find(Base, firstRegister.DocType, firstRegister.RefNbr); var masterTran = new SelectFrom<ARTran> .Where<ARTran.tranType.IsEqual<@P.AsString> .And<ARTran.refNbr.IsEqual<@P.AsString>>> .View(Base) .SelectSingle(firstInvoice.DocType, firstInvoice.MasterRefNbr);
foreach (var register in results) { var installmentTran = new SelectFrom<ARTran> .Where<ARTran.tranType.IsEqual<@P.AsString> .And<ARTran.refNbr.IsEqual<@P.AsString>>> .View(Base) .SelectSingle(register.DocType, register.RefNbr);
invoke the base method and get the results (the Installment ARRegisters you created);
select the master (original) transaction by the MasterRefNbr value;
set the installment transaction description using the master transaction.
As far as I have noticed, the Installment Invoices contain only one transaction (I didn’t dig deeper into the business logic), which is why I used SelectSingle to get the transaction. However, you can adjust the code if you need to handle additional cases.
Original InvoiceInstallment
Additionally, if you want to allow users to manually adjust the description after the installments are generated, you can enable your field in the RowSelected event handler as follows:
public class ARInvoiceEntry_Extension : PXGraphExtension<PX.Objects.AR.ARInvoiceEntry> { protected virtual void _(Events.RowSelected<ARInvoice> e) { if (!(e.Row is ARInvoice row)) return;
To override the transaction description, you can override the CreateInstallments method as follows:
public class ARReleaseProcessExt : PXGraphExtension<PX.Objects.AR.ARReleaseProcess> { [PXOverride] public virtual List<ARRegister> CreateInstallments( PXResult<ARInvoice, PX.Objects.CM.Extensions.CurrencyInfo, Terms, Customer> res, Func<PXResult<ARInvoice, PX.Objects.CM.Extensions.CurrencyInfo, Terms, Customer>, List<ARRegister>> baseMethod) { var results = baseMethod(res);
var firstRegister = results.FirstOrDefault(); var firstInvoice = ARInvoice.PK.Find(Base, firstRegister.DocType, firstRegister.RefNbr); var masterTran = new SelectFrom<ARTran> .Where<ARTran.tranType.IsEqual<@P.AsString> .And<ARTran.refNbr.IsEqual<@P.AsString>>> .View(Base) .SelectSingle(firstInvoice.DocType, firstInvoice.MasterRefNbr);
foreach (var register in results) { var installmentTran = new SelectFrom<ARTran> .Where<ARTran.tranType.IsEqual<@P.AsString> .And<ARTran.refNbr.IsEqual<@P.AsString>>> .View(Base) .SelectSingle(register.DocType, register.RefNbr);
Thanks @aleksandrsechin - I have a skills gap in that I am not sure how/where to override methods. I am comfortable with the code, but in Acumatica project customisations I have mostly only completed low/no code changes. If you could point me in the right direction for updating this please (or learning material if it’s not a simple answer), thank you.
Hi @natwi Here is how you can implement the logic I described above using a low-code approach through the Customization Project Editor:
Then, in the opened form, replace the code template with the following complete code snippet:
using PX.Data; using PX.Data.BQL; using PX.Data.BQL.Fluent; using PX.Objects.AR; using PX.Objects.CS; using System; using System.Collections.Generic; using System.Linq;
namespace Test { public class ARReleaseProcessExt : PXGraphExtension<PX.Objects.AR.ARReleaseProcess> { [PXOverride] public virtual List<ARRegister> CreateInstallments( PXResult<ARInvoice, PX.Objects.CM.Extensions.CurrencyInfo, Terms, Customer> res, Func<PXResult<ARInvoice, PX.Objects.CM.Extensions.CurrencyInfo, Terms, Customer>, List<ARRegister>> baseMethod) { var results = baseMethod(res);
var firstRegister = results.FirstOrDefault(); var firstInvoice = ARInvoice.PK.Find(Base, firstRegister.DocType, firstRegister.RefNbr); var masterTran = new SelectFrom<ARTran> .Where<ARTran.tranType.IsEqual<@P.AsString> .And<ARTran.refNbr.IsEqual<@P.AsString>>> .View(Base) .SelectSingle(firstInvoice.DocType, firstInvoice.MasterRefNbr);
foreach (var register in results) { var installmentTran = new SelectFrom<ARTran> .Where<ARTran.tranType.IsEqual<@P.AsString> .And<ARTran.refNbr.IsEqual<@P.AsString>>> .View(Base) .SelectSingle(register.DocType, register.RefNbr);
namespace Test { public class ARInvoiceEntry_Extension : PXGraphExtension<PX.Objects.AR.ARInvoiceEntry> { protected virtual void _(Events.RowSelected<ARInvoice> e) { if (!(e.Row is ARInvoice row)) return;
FYI: this code is based on version 25R2. If you are using a different version, you may encounter additional issues. If you are unable to publish your customization, feel free to share the Acumatica version you’re using along with the errors you’re getting — we’ll help adjust the code. The code snippets above should generally work for you, but if anything doesn’t, we can correct the logic to achieve the result you need.
Dovetailing on this, can this also be done for the intercompany transactions?
Currently the transaction description is “Balancing entry for: BRANCH” but the branch is the same branch that the transaction posts to. It would be more helpful to people reviewing the general ledger transactions to know what branch that the balancing entry was from.
These two descriptions should be swapped to be useful:
It is not helpful to see PRODWHOLE has a transaction that is a balancing entry for PRODWHOLE. It would be more useful to the person reviewing the transaction to know that the branch PRODWHOLE has a balancing entry that came from PRODRETAIL.
Hi @rena98 Probably yes, but I think it would be better to create a separate topic for this issue with more detailed information, since it differs from the current one.
Hi @rena98 Probably yes, but I think it would be better to create a separate topic for this issue with more detailed information, since it differs from the current one.