Solved

Advice on which event handler to use

  • 3 February 2022
  • 6 replies
  • 602 views

Userlevel 6
Badge +3

I want to add the “Last Vendor Price” that is shown in the Stock Items screen to the data grid on the “Purchase Orders” screen.

I believe this will involve creating a custom non-DB related field in the PX.Objects.PO.POLine DAC.  Then I would get the value from the POVendorInventory table for the respective vendor in the Purchase Orders screen.

 

 

I think I would do this in an POOrderEntry_Extension : PXGraphExtension<POOrderEntry> extension as that is the graph used for the Purchase Orders screen.

I would get the value to store in the custom field and trigger it with one of the row events.  However, I’m not sure which one to use.  Can someone give me advice on which one of these is the most appropriate?

 

Thank you in advance for your help.  Also, if you think my plan is bad, I’d welcome any suggestions.

Joe Schmucker

(Noob)

 

icon

Best answer by Naveen Boga 3 February 2022, 19:16

View original

6 replies

Userlevel 7
Badge +17

Hi Joe,  Hope you are doing well!

You can bring the Last Vendor Price value from the Stock Item screen to the PO screen using the below event.

POLine_InventoryID_FieldUpdated event.

 

Hope this helps!

Userlevel 6
Badge +3

I think I know how to do that.  I’ll give it a try.

Would you create a dummy field for this and populate it with BQL?

Thanks Naveen.  No wonder you got an MVP award!

Userlevel 7
Badge +17

@joe21  Just create a BQL to the “POVendorInventory” table to fetch the Last Vendor Price for the Purchase Order Vendor and assign it to the newly created field at POLine.

 

Userlevel 7
Badge +17

@joe21  Attached code for your reference. 

 

 public class POLineExt : PXCacheExtension<POLine>
{
[PXDBDecimal(2)]
[PXUIField(DisplayName = "Last Vendor Price")]
public virtual decimal? UsrLastVendorPrice { get; set; }
public abstract class usrLastVendorPrice : PX.Data.BQL.BqlDecimal.Field<usrLastVendorPrice> { }
}


public class POOrderEntry_Extension : PXGraphExtension<POOrderEntry>
{
protected virtual void POLine_InventoryID_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e, PXFieldUpdated InvokeBaseHandler)
{
InvokeBaseHandler?.Invoke(cache, e);
POLine row = e.Row as POLine;
if (row != null)
{
POVendorInventory objPOVendorItem = PXSelect<POVendorInventory,Where<POVendorInventory.vendorID,Equal<Required<POVendorInventory.vendorID>>,
And<POVendorInventory.inventoryID,Equal<Required<POVendorInventory.inventoryID>>>>>.Select(Base, Base.Document.Current.VendorID, row?.InventoryID);
if (objPOVendorItem != null)
{
row.GetExtension<POLineExt>().UsrLastVendorPrice = objPOVendorItem.LastPrice ?? 0m;

}
}
}

}

 

Userlevel 6
Badge +3

I simply copy/pasted your code and voila.  You saved me so much trial and error.

The only think I had to do is change PXDBDecimal to PXDecimal because it is an unbound field

I added this section in order to populate that field when viewing an existing order.  It is also just a copy/paste from your script.

        protected void POLine_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
        {
            var row = (POLine)e.Row;

            if (row != null)
            {
                POVendorInventory objPOVendorItem = PXSelect<POVendorInventory, Where<POVendorInventory.vendorID, Equal<Required<POVendorInventory.vendorID>>,
                    And<POVendorInventory.inventoryID, Equal<Required<POVendorInventory.inventoryID>>>>>.Select(Base, Base.Document.Current.VendorID, row?.InventoryID);
                if (objPOVendorItem != null)
                {
                    row.GetExtension<POLineExt>().UsrLastVendorPrice = objPOVendorItem.LastPrice ?? 0m;

                }
            }
        }
 

I’ve never used InvokeBaseHandler?.Invoke(cache, e);  Where would I ever learn about that?  That command was not part of the training series.  Is there another training series that would teach me about things like that?   

Also, in your PXSelect, you have this: row?.InventoryID   What is the reason for the “?” after row?  

Naveen, thank you so much.

 

Userlevel 7
Badge +17

Hi @joe21  Most Welcome :)

Here are my suggestions, please find the details below.

  • Since you wanted to go with the unbound field, you have the logic in the “POLine_UsrLastVendorPrice_FieldSelecting” instead of RowSelected event (No BQL’s allowed to write in this event)
  • When we are writing the event for default Acumatica fields, first we should invoke the Base logic, then our logic should be executed. → To invoke the Base logic code we should use this code → InvokeBaseHandler?.Invoke(cache, e);
  • “?”, this is C# concept i.e. Nullalble type. I always use like this to avoid the Object/Null reference issues.

 

 protected virtual void POLine_UsrLastVendorPrice_FieldSelecting(PXCache cache, PXFieldSelectingEventArgs e)
{
POLine row = e.Row as POLine;
if (row != null)
{
POVendorInventory objPOVendorItem = PXSelect<POVendorInventory, Where<POVendorInventory.vendorID, Equal<Required<POVendorInventory.vendorID>>,
And<POVendorInventory.inventoryID, Equal<Required<POVendorInventory.inventoryID>>>>>.Select(Base, Base.Document.Current.VendorID, row?.InventoryID);
if (objPOVendorItem != null)
{
e.ReturnValue = objPOVendorItem.LastPrice ?? 0m;
}
}
}

In the above field selecting code, “InvokeBaseHandler” this code is not required, since it is our custom field, hence I have not added this code.

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