Skip to main content
Solved

Override Pay/Apply Document to Process Multiple Invoices in Customer Details Inquiry Screen


Nilkanth Dipak
Varsity II
Forum|alt.badge.img+10

Hi Community,

I’m working on the Customer Details Inquiry screen in Acumatica, specifically on the Pay/Apply Document action. I’ve overridden this action to handle multiple document selection so I can apply payments to multiple invoices at once. Here’s the code I’m using:

public delegate IEnumerable PayDocumentDelegate(PXAdapter adapter);
[PXOverride]
public virtual IEnumerable PayDocument(PXAdapter adapter, PayDocumentDelegate baseMethod)
{



                 List<ARDocumentEnq.ARDocumentResult> selectedDocuments = Base.Documents.Cache.Updated
          .RowCast<ARDocumentEnq.ARDocumentResult>()
          .Where(shipment => PXCache<ARDocumentEnq.ARDocumentResult>
              .GetExtension<ARDocumentResultExt>(shipment)?.UsrSelect == true)
          .ToList();



     if (!selectedDocuments.Any())
     {
         // Fall back to base behavior if no rows are selected
         return baseMethod(adapter);
     }

     // Iterate through each selected document
     foreach (var doc in selectedDocuments)
     {


         if (ARDocType.Payable(doc.DocType) == true)
         {
             // Create an instance of ARInvoiceEntry for each document
             ARInvoiceEntry invoiceGraph = PXGraph.CreateInstance<ARInvoiceEntry>();

             // Retrieve the ARInvoice for the selected document
             ARInvoice invoice = PXSelect<ARInvoice,
                 Where<ARInvoice.docType, Equal<Required<ARInvoice.docType>>,
                     And<ARInvoice.refNbr, Equal<Required<ARInvoice.refNbr>>>>>
                 .Select(Base, doc.DocType, doc.RefNbr)
                 .FirstOrDefault();

             if (invoice != null)
             {
                 // Assign the retrieved invoice to the graph
                 invoiceGraph.Document.Current = invoice;

                 // Process payment
                 invoiceGraph.PayInvoice(adapter);
             }
         }
     }

     // Return default filter view
     return Base.Filter.Select();
}

The issue I’m facing is that it’s not working as expected — the payment is still only applied to a single document, not multiple. I’d really appreciate any guidance on how I can properly apply payments to multiple invoices from the Customer Details Inquiry screen to the Payments and Applications screen.
I have added custom checkbox field UsrSelect to select multiple documents.

Thanks in advance for your help!

Best answer by Nilkanth Dipak

Hi Community,

I’ve implemented the following code logic to pass multiple records at a time to the Payments and Applications screen from the Customer Details screen when clicking the Pay/Apply Document action, and it’s working as expected.

Previously, I was just transferring the records directly. However, I’ve now created a list and written code to insert those records into the ARAdjust DAC.

 

public delegate IEnumerable PayDocumentDelegate(PXAdapter adapter);
        [PXOverride]
        public virtual IEnumerable PayDocument(PXAdapter adapter, PayDocumentDelegate baseMethod)
        {
            // Get selected documents
            List<ARDocumentEnq.ARDocumentResult> selectedDocuments = Base.Documents.Cache.Updated
                .RowCast<ARDocumentEnq.ARDocumentResult>()
                .Where(doc => PXCache<ARDocumentEnq.ARDocumentResult>
                    .GetExtension<ARDocumentResultExtensionsTSExt>(doc)?.UsrSelected == true)
                .ToList();

            if (!selectedDocuments.Any())
            {
                // Fall back to base behavior if no rows are selected
                return baseMethod(adapter);
            }

            // Create a list to store invoices that need to be processed
            List<ARInvoice> invoicesToProcess = new List<ARInvoice>();
            // Process each selected document
            foreach (var doc in selectedDocuments)
            {
                if (doc.GetExtension<ARDocumentResultExtensionsTSExt>().UsrSelected == true)
                {
                    // Retrieve the ARInvoice for the selected document
                    ARInvoice invoice = PXSelect<ARInvoice,
                        Where<ARInvoice.docType, Equal<Required<ARInvoice.docType>>,
                            And<ARInvoice.refNbr, Equal<Required<ARInvoice.refNbr>>>>>
                        .Select(Base, doc.DocType, doc.RefNbr);

                    if (invoice != null)
                    {
                        invoicesToProcess.Add(invoice);
                    }
                }
            }

            if (invoicesToProcess.Count > 0)
            {
                // Create a payment entry graph
                ARPaymentEntry paymentGraph = PXGraph.CreateInstance<ARPaymentEntry>();

                // Set up the payment with the first invoice
                ARInvoice firstInvoice = invoicesToProcess[0];

                // Create the payment document
                paymentGraph.Document.Insert();
                paymentGraph.Document.Current.CustomerID = firstInvoice.CustomerID;
                paymentGraph.Document.Current.DocType = ARPaymentType.Payment;
                paymentGraph.Document.Current.AdjDate = firstInvoice.DocDate;
                paymentGraph.Document.Current.CuryOrigDocAmt = 0m; // Will be calculated from added adjustments
                paymentGraph.Document.Update(paymentGraph.Document.Current);

                // Add each invoice as an adjustment
                foreach (ARInvoice invoice in invoicesToProcess)
                {
                    // Check if the adjustment already exists
                    ARAdjust existingAdjustment = PXSelect<ARAdjust,
                        Where<ARAdjust.adjdDocType, Equal<Required<ARAdjust.adjdDocType>>,
                            And<ARAdjust.adjdRefNbr, Equal<Required<ARAdjust.adjdRefNbr>>,
                            And<ARAdjust.adjgDocType, Equal<Required<ARAdjust.adjgDocType>>,
                            And<ARAdjust.adjgRefNbr, Equal<Required<ARAdjust.adjgRefNbr>>>>>>>
                        .Select(paymentGraph, invoice.DocType, invoice.RefNbr,
                                paymentGraph.Document.Current.DocType,
                                paymentGraph.Document.Current.RefNbr);

                    if (existingAdjustment == null)
                    {
                        // Create a new adjustment
                        ARAdjust adj = new ARAdjust();
                        adj.AdjdDocType = invoice.DocType;
                        adj.AdjdRefNbr = invoice.RefNbr;
                        adj.AdjdCustomerID = invoice.CustomerID;
                        adj.CuryAdjgAmt = invoice.CuryDocBal;

                        // Insert the adjustment
                        paymentGraph.Adjustments.Insert(adj);
                    }
                }

                // Redirect to the payment screen
                throw new PXRedirectRequiredException(paymentGraph, "Payment & Application");
            }

            // Return default filter view
            return Base.Filter.Select();
        }

Thank you for taking the time to review this!

View original
Did this topic help you find an answer to your question?

4 replies

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

Have you in some way determined if your code is being executed / making it to the foreach?


Nilkanth Dipak
Varsity II
Forum|alt.badge.img+10

Hi ​@darylbowman,

Thanks for your response! Yes, my code is being executed, and it is copying/inserting one record. While debugging, I noticed that it was only processing one record when calling the PayInvoice action.

After some research and digging, I was able to pass multiple records at a time. It’s working now, and I’m testing it further. I’ll post my code once it’s fully resolved.


Nilkanth Dipak
Varsity II
Forum|alt.badge.img+10
  • Author
  • Varsity II
  • 392 replies
  • Answer
  • March 10, 2025

Hi Community,

I’ve implemented the following code logic to pass multiple records at a time to the Payments and Applications screen from the Customer Details screen when clicking the Pay/Apply Document action, and it’s working as expected.

Previously, I was just transferring the records directly. However, I’ve now created a list and written code to insert those records into the ARAdjust DAC.

 

public delegate IEnumerable PayDocumentDelegate(PXAdapter adapter);
        [PXOverride]
        public virtual IEnumerable PayDocument(PXAdapter adapter, PayDocumentDelegate baseMethod)
        {
            // Get selected documents
            List<ARDocumentEnq.ARDocumentResult> selectedDocuments = Base.Documents.Cache.Updated
                .RowCast<ARDocumentEnq.ARDocumentResult>()
                .Where(doc => PXCache<ARDocumentEnq.ARDocumentResult>
                    .GetExtension<ARDocumentResultExtensionsTSExt>(doc)?.UsrSelected == true)
                .ToList();

            if (!selectedDocuments.Any())
            {
                // Fall back to base behavior if no rows are selected
                return baseMethod(adapter);
            }

            // Create a list to store invoices that need to be processed
            List<ARInvoice> invoicesToProcess = new List<ARInvoice>();
            // Process each selected document
            foreach (var doc in selectedDocuments)
            {
                if (doc.GetExtension<ARDocumentResultExtensionsTSExt>().UsrSelected == true)
                {
                    // Retrieve the ARInvoice for the selected document
                    ARInvoice invoice = PXSelect<ARInvoice,
                        Where<ARInvoice.docType, Equal<Required<ARInvoice.docType>>,
                            And<ARInvoice.refNbr, Equal<Required<ARInvoice.refNbr>>>>>
                        .Select(Base, doc.DocType, doc.RefNbr);

                    if (invoice != null)
                    {
                        invoicesToProcess.Add(invoice);
                    }
                }
            }

            if (invoicesToProcess.Count > 0)
            {
                // Create a payment entry graph
                ARPaymentEntry paymentGraph = PXGraph.CreateInstance<ARPaymentEntry>();

                // Set up the payment with the first invoice
                ARInvoice firstInvoice = invoicesToProcess[0];

                // Create the payment document
                paymentGraph.Document.Insert();
                paymentGraph.Document.Current.CustomerID = firstInvoice.CustomerID;
                paymentGraph.Document.Current.DocType = ARPaymentType.Payment;
                paymentGraph.Document.Current.AdjDate = firstInvoice.DocDate;
                paymentGraph.Document.Current.CuryOrigDocAmt = 0m; // Will be calculated from added adjustments
                paymentGraph.Document.Update(paymentGraph.Document.Current);

                // Add each invoice as an adjustment
                foreach (ARInvoice invoice in invoicesToProcess)
                {
                    // Check if the adjustment already exists
                    ARAdjust existingAdjustment = PXSelect<ARAdjust,
                        Where<ARAdjust.adjdDocType, Equal<Required<ARAdjust.adjdDocType>>,
                            And<ARAdjust.adjdRefNbr, Equal<Required<ARAdjust.adjdRefNbr>>,
                            And<ARAdjust.adjgDocType, Equal<Required<ARAdjust.adjgDocType>>,
                            And<ARAdjust.adjgRefNbr, Equal<Required<ARAdjust.adjgRefNbr>>>>>>>
                        .Select(paymentGraph, invoice.DocType, invoice.RefNbr,
                                paymentGraph.Document.Current.DocType,
                                paymentGraph.Document.Current.RefNbr);

                    if (existingAdjustment == null)
                    {
                        // Create a new adjustment
                        ARAdjust adj = new ARAdjust();
                        adj.AdjdDocType = invoice.DocType;
                        adj.AdjdRefNbr = invoice.RefNbr;
                        adj.AdjdCustomerID = invoice.CustomerID;
                        adj.CuryAdjgAmt = invoice.CuryDocBal;

                        // Insert the adjustment
                        paymentGraph.Adjustments.Insert(adj);
                    }
                }

                // Redirect to the payment screen
                throw new PXRedirectRequiredException(paymentGraph, "Payment & Application");
            }

            // Return default filter view
            return Base.Filter.Select();
        }

Thank you for taking the time to review this!


Chris Hackett
Community Manager
Forum|alt.badge.img
  • Acumatica Community Manager
  • 2750 replies
  • March 11, 2025

Thank you for sharing your solution with the community ​@Nilkanth Dipak!


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings