Solved

Copy Custom Field From Sales Order To Invoice When Invoice Created

  • 12 September 2023
  • 7 replies
  • 229 views

I have created a custom field called GTRInvoice in my sales orders table and my invoices table and I would like that field to copy to the invoice when it is created from the sales order. I Cannot find any existing examples of how to do this that show the working code.

I did override the  SOInvoiceEntry InvoiceOrder method but it is not the same as the old examples.

This is what I have

    public delegate void InvoiceOrderDelegate(InvoiceOrderDelegateArgs args);
    [PXOverride]
    public void InvoiceOrder(InvoiceOrderArgs args, InvoiceOrderDelegate baseMethod)
    {
      baseMethod(args);
    }

 

Any help is greatly appreciated.

icon

Best answer by Vignesh Ponnusamy 13 September 2023, 22:38

View original

7 replies

Userlevel 7
Badge +17

Hi @TimMarkiw  In the Invoices screen, we have a feasibility to add the Multiple Orders to the Single Invoice. In this case, you wanted to display comma-separated values in the Invoice header section.

 

 

Hello Naveen,

 

We will always only put a single sales order on a single invoice so i only need to know how to copy the GTRInvoice field exactly as it is in the sales order being invoiced. 

Thanks

 

Userlevel 7
Badge +10

Hi @TimMarkiw ,

You can use below code snippet to pass custom field from SO to invoice.

    public delegate void PersistDelegate();

[PXOverride]
public void Persist(PersistDelegate baseMethod)
{
baseMethod();
SOOrderEntry soOrderEntryGraph = PXGraph.CreateInstance<SOOrderEntry>();

SOOrder soOrder = soOrderEntryGraph.Document.Current;

if (soOrder != null)
{
ARInvoice arInvoice = new ARInvoice();

// Copy the custom field value from Sales Order to Invoice
arInvoice.GetExtension<ARRegisterExt>().UsrCustomField = soOrder.GetExtension<SOOrderExt>().UsrCustomField ;

Base.ARInvoice_CustomerID_DocType_RefNbr.Cache.Insert(arInvoice);
}
}

Hope, it helps!

Regards,

Sweta

@sweta68 

 

Hello Sweta,

I haven’t gotten this to work yet but I wanted to give you an update.

When I add this code

   public delegate void PersistDelegate();

[PXOverride]
public void Persist(PersistDelegate baseMethod)
{
baseMethod();
SOOrderEntry soOrderEntryGraph = PXGraph.CreateInstance<SOOrderEntry>();

SOOrder soOrder = soOrderEntryGraph.Document.Current;

if (soOrder != null)
{
ARInvoice arInvoice = new ARInvoice();

// Copy the custom field value from Sales Order to Invoice
arInvoice.GetExtension<ARRegisterExt>().UsrGTRInvoice = soOrder.GetExtension<SOOrderExt>().UsrGTRInvoice ;

Base.ARInvoice_CustomerID_DocType_RefNbr.Cache.Insert(arInvoice);
} else
{

}
}

to the SOInvoiceEntry the code compiles, published and runs, however the GTRInvoice was not copied across and the soOrder is always null so the if condition is never fulfilled. I added the else for testing and the code within it was always the code that was executed.

I am going to continue to try more things this afternoon and I will let you know if works or if I need further help.

 

Thank You!

 

Badge +11

Your SOOrder will always be null because soOrderEntryGraph.Document.Current is null in a newly created graph instance.

 

Use:

SOOrder order = soOrderEntryGraph.Document.Search<SOOrder.orderType, SOOrder.orderNbr>(order.OrderType, order.OrderNbr, order.OrderType);

 

Userlevel 7
Badge +4

Hi @TimMarkiw,

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

Below is a quick example,

    public class SOOrderEntry_Extension : PXGraphExtension<PX.Objects.SO.SOOrderEntry>
{
#region Event Handlers
public delegate IEnumerable PrepareInvoiceDelegate(PXAdapter adapter);
[PXOverride]
public IEnumerable PrepareInvoice(PXAdapter adapter, PrepareInvoiceDelegate baseMethod)
{
PXGraph.InstanceCreated.AddHandler<SOInvoiceEntry>((invoiceGraph) =>
{
invoiceGraph.RowPersisting.AddHandler<ARRegister>((sender, e) =>
{
ARRegister currentInvoice = (ARRegister)e.Row;
ARRegisterExt registerExt = currentInvoice.GetExtension<ARRegisterExt>();
SOOrderExt orderExt = Base.Document.Cache.GetExtension<SOOrderExt>(Base.Document.Current);
registerExt.UsrGTRInvoice = orderExt.UsrGTRInvoice;
});
});
return baseMethod(adapter);
}
#endregion
}

I have also attached the customization package for reference. 

Good Luck.!

Here is my final code mostly taken from a post by @darylbowman  

 

  public static string GTRInvoiceNumber = "";
#region Event Handlers
public delegate IEnumerable PrepareInvoiceDelegate(PXAdapter adapter);

[PXOverride]
public IEnumerable PrepareInvoice(PXAdapter adapter, PrepareInvoiceDelegate baseMethod)
{
PXGraph.InstanceCreated.AddHandler<SOInvoiceEntry>((graph) =>
{
graph.RowPersisting.AddHandler<ARInvoice>((cache, e) =>
{
var invoice = e.Row as ARInvoice;
if (invoice is null) return;
string gtrInvoiceNumber = GTRInvoiceNumber;
cache.SetValue<ARRegisterExt.usrGTRInvoice>(invoice, gtrInvoiceNumber);
cache.Update(invoice);
});
graph.RowInserted.AddHandler<ARTran>((cache, e) =>
{
var tran = e.Row as ARTran;
if (tran is null) return;
var invoice = graph.Caches[typeof(ARInvoice)].Current as ARInvoice;
ARRegisterExt registerExt = invoice.GetExtension<ARRegisterExt>();
SOOrderExt orderExt = Base.Document.Cache.GetExtension<SOOrderExt>(Base.Document.Current);
GTRInvoiceNumber = orderExt.UsrGTRInvoice;
});
});
return baseMethod(adapter);
}
#endregion

 

 

Thank you all for your help.

Reply


About Acumatica ERP system
Acumatica Cloud ERP provides the best business management solution for transforming your company to thrive in the new digital economy. Built on a future-proof platform with open architecture for rapid integrations, scalability, and ease of use, Acumatica delivers unparalleled value to small and midmarket organizations. Connected Business. Delivered.
© 2008 — 2024  Acumatica, Inc. All rights reserved