Skip to main content

Trying to override InvoiceOrder and InvoiceCreated on SOInvoiceEntry to copy a value from source SO to invoice.  The client could create invoices from order entry or shipment so I want to make sure it gets copied no matter what so therefore trying to do this without overriding PrepareInvoice action.

This is what I have so far on SOInvoiceEntry graph extension:

        public delegate void InvoiceOrderDelegate(InvoiceOrderArgs args);

PXOverride]
public virtual void InvoiceOrder(InvoiceOrderArgs args)
{
//Code before
Base.InvoiceOrder(args);
//Code after

InvoiceCreated(Base.Document.Current, args);
}

PXOverride]
public virtual void InvoiceCreated(ARInvoice invoice, InvoiceOrderArgs args)
{
// Base.InvoiceCreated(invoice, args);
ARRegisterExt registerExt = PXCache<ARRegister>.GetExtension<ARRegisterExt>(invoice);
SOOrderExt orderExt = PXCache<SOOrder>.GetExtension<SOOrderExt>(args.SOOrder);

registerExt.UsrLumpSumReport = orderExt.UsrLumpSumReport;
}

However, I get an error : 'AR Transactions' cannot be found in the system. and I don’t know what this means.  I think it’s happening on the Base.InvoiceOrder(args) line.

Here is my stack trace:

   at PX.Objects.SO.SOInvoiceEntry.ValidateLinesAdded(Boolean lineAdded)
   at PX.Objects.SO.SOInvoiceEntry.InvoiceOrderImpl(InvoiceOrderArgs args)
   at PX.Objects.SO.SOInvoiceEntry.InvoiceOrder(InvoiceOrderArgs args)
   at Wrapper.PX.Objects.SO.Cst_SOInvoiceEntry.InvoiceOrderGeneratedWrapper(SOInvoiceEntry g, InvoiceOrderArgs )
   at PX.Objects.SO.SOInvoiceEntry_Extension.InvoiceOrder(InvoiceOrderArgs args) in C:\inetpub\wwwroot\AcumaticaDLB\App_Data\Projects\AMEDMatrixCosts]\AME[MatrixCosts]\SOInvoiceEntry.cs:line 61
   at PX.Objects.SO.SOOrderEntry.InvoiceOrder(Dictionary`2 parameters, IEnumerable`1 list, InvoiceList created, Boolean isMassProcess, ActionFlow quickProcessFlow, Boolean groupByCustomerOrderNumber)
   at PX.Objects.SO.SOOrderEntry.InvoiceOrders(List`1 list, Dictionary`2 arguments, Boolean massProcess, ActionFlow quickProcessFlow)
   at PX.Objects.SO.GraphExtensions.SOOrderEntryExt.Blanket.InvoiceOrders(List`1 list, Dictionary`2 arguments, Boolean massProcess, ActionFlow quickProcessFlow, Action`4 baseMethod)
   at Wrapper.PX.Objects.SO.Cst_SOOrderEntry.InvoiceOrdersGeneratedWrapper(SOOrderEntry g, List`1 , Dictionary`2 , Boolean , ActionFlow )
   at PX.Objects.SO.SOOrderEntry.<>c__DisplayClass137_0.<PrepareInvoice>b__0()
   at PX.Concurrency.CancellationIgnorantExtensions.RunWithCancellationViaThreadAbort(Action method, CancellationToken cancellationToken) in C:\build\code_repo\NetTools\PX.Data\Concurrency\CancellationIgnorantExtensions.cs:line 16
   at PX.Concurrency.CancellationIgnorantExtensions.<>c__DisplayClass1_0.<ToCancellationViaThreadAbort>b__0(CancellationToken cancellationToken) in C:\build\code_repo\NetTools\PX.Data\Concurrency\CancellationIgnorantExtensions.cs:line 23
   at PX.Concurrency.Internal.PXLongOperationPars.PopAndRunDelegate(CancellationToken cancellationToken) in C:\build\code_repo\NetTools\PX.Data\Concurrency\Internal\PXLongOperationPars.cs:line 105
   at PX.Concurrency.Internal.RuntimeLongOperationManager.PerformOperation(PXLongOperationPars p) in C:\build\code_repo\NetTools\PX.Data\Concurrency\Internal\RuntimeLongOperationManager.cs:line 159

Hi @rjean09 ,

You can override the PrepareInvoice method in the SOOrderEntry and AddHandler(from PXGraph) then inject the code to copy the custom field. (Suggestion from below post)

https://community.acumatica.com/develop-customizations-288/copy-custom-field-from-sales-order-to-invoice-when-invoice-created-18628?tid=18628&fid=288

This link helps you to copy the custom fields from SO to AR invoice.answer provided by @Vignesh Ponnusamy .

 


Hi @rjean09 ,

You can override the PrepareInvoice method in the SOOrderEntry and AddHandler(from PXGraph) then inject the code to copy the custom field. (Suggestion from below post)

https://community.acumatica.com/develop-customizations-288/copy-custom-field-from-sales-order-to-invoice-when-invoice-created-18628?tid=18628&fid=288

This link helps you to copy the custom fields from SO to AR invoice.answer provided by @Vignesh Ponnusamy .

 

Thanks Dipak.  The final solution from @TimMarkiw does work from the sales order screen.

However, I’m not sure this would work when invoicing from shipment.  I’m working on getting some test data with some inventory levels so I can test it, but this is why I was trying to work it from the InvoiceCreated method as I thought that might be called from anywhere an invoice gets created, including from shipments.  

I was trying to follow this solution here:

from @Dmitrii Naumov but not having much luck.


To clarify, I understand there can be more than one sales order on a shipment, but in this case there won’t be and if there is it will be up to the users to make sure all or none of the custom boolean field are set.  Ideally, I don’t need/want to persist this on the shipment.


More specifically, I tried to follow this example:

https://stackoverflow.com/questions/49970938/acumatica-overriding-business-logic-access-protected-methods

The signature of InvoiceOrder and InvoiceCreated have changed since this example


Got it. Just had to invoke the method on the delegate.  Appears to be working fine now from either SOOrderEntry or from SOShipmentEntry PrepareInvoice action:

        public delegate void InvoiceOrderDelegate(InvoiceOrderArgs args);

        ÂPXOverride]
        public virtual void InvoiceOrder(InvoiceOrderArgs args, InvoiceOrderDelegate baseMethod)
        {
            //Code before
            baseMethod?.Invoke(args);
            //Code after

            InvoiceCreated(Base.Document.Current, args);
        }

        ePXOverride]
        public virtual void InvoiceCreated(ARInvoice invoice, InvoiceOrderArgs args)
        {
            // Base.InvoiceCreated(invoice, args);
            ARRegisterExt registerExt = PXCache<ARRegister>.GetExtension<ARRegisterExt>(invoice);
            SOOrderExt orderExt = PXCache<SOOrder>.GetExtension<SOOrderExt>(args.SOOrder);

            registerExt.UsrLumpSumReport = orderExt.UsrLumpSumReport;
        }


Thank you for sharing your solution with the community @rjean09!


Reply