Solved

Update custom field in linked table in event handler

  • 22 October 2022
  • 7 replies
  • 235 views

Userlevel 3
Badge

Hi,

I create a custom field named UsrInvoiceNote on Sale Order and Shipment. I am implementing a trigger handler when field this field is update on Sale Order. The main target is coping the value to linked Shipment.

configuration of custom field

Here is the snippet code:

    protected void SOOrder_UsrInvoiceNote_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e)
{

var row = (SOOrder)e.Row;
var ext = row.GetExtension<SOOrderExt>();

// handle update shipment
var query = new SelectFrom<SOShipment>.InnerJoin<SOOrderShipment>.On<SOOrderShipment.shipmentNbr.IsEqual<SOShipment.shipmentNbr>>
.Where<Use<SOOrderShipment.orderType>.AsString.IsEqual<@P.AsString>.And<Use<SOOrderShipment.orderNbr>.AsString.IsEqual<@P.AsString>>>
.View(Base);
var shipments = query.Select(row.OrderType, row.OrderNbr);
foreach (SOShipment sm in shipments)
{
sm.UsrInvoiceNote = ext.UsrInvoiceNote;
Base.Caches[typeof(SOShipment)].Update(sm);
}
if (Base.Caches[typeof(SOShipment)].Updated.Cast<SOShipment>().Count() > 0)
{
Base.Caches[typeof(SOShipment)].Persist(PXDBOperation.Update);
}

}

I got the error as following: 

error CS1061: 'PXResult<SOShipment>' does not contain a definition for 'UsrInvoiceNote' and no accessible extension method 'UsrInvoiceNote' accepting a first argument of type 'PXResult<SOShipment>' could be found (are you missing a using directive or an assembly reference?)

I have tried with using GetExtension but it didn’t work.

sm.GetExtension<SOShipmentExt>().UsrInvoiceNote=ext.UsrInvoiceNote;

Could you please give me the instruction how to perform update custom field in Shipment when updating a field in Sale Order?

icon

Best answer by Leonardo Justiniano 24 October 2022, 21:03

View original

7 replies

Userlevel 7
Badge +17

Hi @mrthanhkhoi  You can do this in the Persist method instead of in fieldupated event.

And, When you are updating the NOTES in Sales Order, what is the Status of the Shipment?

If Shipment is Confirmed/Completed, then the system will not allow us to update the field because the shipment document will go to the read-only state.

 

Here is the sample code for your reference.

 


public delegate void PersistDelegate();
[PXOverride]
public void Persist(PersistDelegate del)
{
SOOrder row = Base.Document.Current;

if (row != null)
{
SOOrderExt ext = row.GetExtension<SOOrderExt>();

SOShipmentEntry shipmentGraph = PXGraph.CreateInstance<SOShipmentEntry>();
var query = new SelectFrom<SOShipment>.InnerJoin<SOOrderShipment>.On<SOOrderShipment.shipmentNbr.IsEqual<SOShipment.shipmentNbr>>
.Where<Use<SOOrderShipment.orderType>.AsString.IsEqual<@P.AsString>.And<Use<SOOrderShipment.orderNbr>.AsString.IsEqual<@P.AsString>>>
.View(Base);
var shipments = query.Select(row.OrderType, row.OrderNbr);
foreach (SOShipment sm in shipments)
{
sm.UsrInvoiceNote = ext.UsrInvoiceNote;
shipmentGraph.Document.Cache.Update(sm);
}
shipmentGraph.Save.Press();
}
del();

}

 

Userlevel 3
Badge

Hi @Naveen Boga ,

Thank you for your answer. I just realize that I can’t update SO after I create Shipment for it.

The idea is I want to copy data of custom field to Shipment.

Could we set value for this custom field in event of creating Shipment (take value from Sale Orders)?

Do you have any piece of code similar with goal?

 

Regards,

Khoi

Userlevel 6
Badge +4

Hi @mrthanhkhoi 

 

Try copying the values when the shipment is created:

protected void _(Events.RowPersisting<SOShipment> e)
{
if(e.Row == null) return;
PXEntryStatus entryStatus = e.Cache.GetStatus(e.Row);
if (entryStatus == PXEntryStatus.Inserted)
{
SOShipment shp = e.Row;
SOShipmentExt = shpExt = e.Cache.GetExtension<SOShipmentExt>(shp);

var qSO = new SelectFrom<SOOrder>.
InnerJoin<SOOrderShipment>.
On<SOOrderShipment.orderNbr.IsEqual<SOOrder.orderNbr>.
And<SOOrderShipment.orderType.IsEqual<SOOrder.orderType>>>.
Where<Use<SOShipment.shipmentNbr>.AsString.IsEqual<@P.AsString>>.
View(Base);

SOOrder so = qSO.Select(shp.ShipmentNbr).TopFirst;
if(so != null)
{
SOOrderExt soExt = Base.Caches[typeof(SOOrder)].GetExtension<SOOrderExt>(so);

// Copy soExt to shpExt

shpExt.UsrField1 = soExt.UsrField1;

}
}
}

Hope this help

Userlevel 3
Badge

Hi @Leonardo Justiniano,

thank you for your answer. However, I got error with your code when creating Shipment

Do you have any idea?

 

Thanks,

Userlevel 6
Badge +4

Hi @mrthanhkhoi 

 

My Bad, copy paste error. This is the right code:

 

protected void _(Events.RowPersisting<SOShipment> e)
{
if(e.Row == null) return;
PXEntryStatus entryStatus = e.Cache.GetStatus(e.Row);
if (entryStatus == PXEntryStatus.Inserted)
{
SOShipment shp = e.Row;
SOShipmentExt = shpExt = e.Cache.GetExtension<SOShipmentExt>(shp);

var qSO = new SelectFrom<SOOrder>.
InnerJoin<SOOrderShipment>.
On<SOOrderShipment.orderNbr.IsEqual<SOOrder.orderNbr>.
And<SOOrderShipment.orderType.IsEqual<SOOrder.orderType>>>.
Where<Use<SOOrderShipment.shipmentNbr>.AsString.IsEqual<@P.AsString>>. // <-- error
View(Base);

SOOrder so = qSO.Select(shp.ShipmentNbr).TopFirst;
if(so != null)
{
SOOrderExt soExt = Base.Caches[typeof(SOOrder)].GetExtension<SOOrderExt>(so);

// Copy soExt to shpExt

shpExt.UsrField1 = soExt.UsrField1;

}
}
}

 

Userlevel 3
Badge

Hi @Leonardo Justiniano ,

I have tried with your code. There is no error but it seems like doesn’t work.

Event I try to set value to a hardcode (“aaa”) but the created Shipment still have empty for this field

protected void _(Events.RowPersisting<SOShipment> e)
{
if(e.Row == null) return;
PXEntryStatus entryStatus = e.Cache.GetStatus(e.Row);
if (entryStatus == PXEntryStatus.Inserted)
{
SOShipment shp = e.Row;
SOShipmentExt shpExt = e.Cache.GetExtension<SOShipmentExt>(shp);

var qSO = new SelectFrom<SOOrder>.
InnerJoin<SOOrderShipment>.
On<SOOrderShipment.orderNbr.IsEqual<SOOrder.orderNbr>.
And<SOOrderShipment.orderType.IsEqual<SOOrder.orderType>>>.
Where<Use<SOOrderShipment.shipmentNbr>.AsString.IsEqual<@P.AsString>>. // <-- error
View(Base);

SOOrder so = qSO.Select(shp.ShipmentNbr).TopFirst;
if(so != null)
{
SOOrderExt soExt = Base.Caches[typeof(SOOrder)].GetExtension<SOOrderExt>(so);

// Copy soExt to shpExt

shpExt.UsrSONotes = "test"+soExt.UsrSONotes;//to test if soExt.UsrSONotes

}
else
{
shpExt.UsrSONotes = "Query SalesOrder return null";//to check if salesorder is null
}
shpExt.UsrSONotes="aaa";//check set value to a custom field on shipment
}
}

 

Thanks,

Userlevel 6
Badge +4

Hi @mrthanhkhoi 

Today is not my day. Apologies for not testing. The reason why it did not work is that shp.ShipmentNbr == “<NEW>” when the record is being created. However on the shipment screen you have an useful view “OrderListSimple” that can help to find out where is the required SOOrder.

 

I made a change to the code and I tested it:

protected void _(Events.RowPersisting<SOShipment> e)
{
SOShipment shp = e.Row;
SOShipmentExt shpExt = e.Cache.GetExtension<SOShipmentExt>(shp);
SOOrderShipment soShp = Base.OrderListSimple.Select().TopFirst;
if (soShp != null)
{
SOOrder so = SOOrder.PK.Find(Base, soShp.OrderType, soShp.OrderNbr);
if (so != null)
{
SOOrderExt soExt = Base.Caches[typeof(SOOrder)].GetExtension<SOOrderExt>(so);

shpExt.UsrSONotes = "test"+soExt.UsrSONotes;
}
}
}

 

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