Reputation: 31
I've been tasked with adding the default vendor inventory ID to grids in multiple screens in Acumatica. The field does not need to be bound and is disabled. I've gotten it as far as showing the field correctly, but only on saved records. Adding a new line and even refreshing the grid will not display the ID, I have to close the screen or switch to another record and come back before the vendor ID will display, even clicking the save button and refreshing will not cause it show. The client is using this field as a reference point so it's important it shows as soon as they select an item.
Below is the code I have for the Kit Specification screen, I need to figure out a way to make it a little more reactive, at least show properly on a refresh. I have tried using Current<> in the where statement, but that just breaks it entirely and always shows nothing.
public class INKitSpecStkDetExt : PXCacheExtension<PX.Objects.IN.INKitSpecStkDet>
{
#region VendorInventoryCode
public abstract class vendorInventoryCode: IBqlField { }
[PXDBScalar(typeof(Search2<PO.POVendorInventory.vendorInventoryID,
InnerJoin<IN.InventoryItem,
On<PO.POVendorInventory.vendorID, Equal<IN.InventoryItem.preferredVendorID>, And<PO.POVendorInventory.inventoryID, Equal<IN.InventoryItem.inventoryID>>>>,
Where<IN.InventoryItem.inventoryID,Equal<IN.INKitSpecStkDet.compInventoryID>>,
OrderBy<Desc<PO.POVendorInventory.vendorInventoryID>>>))]
[PXString(40, IsUnicode = true)]
[PXUIField(DisplayName = "Vendor Inventory Code", Enabled=false)]
public string VendorInventoryCode{ get; set; }
#endregion
}
Once I have the code nailed down it will be used in several other places. Help very much appreciated! Frustrating to have it so close and not be able to cross the finish line...
Follow up based on feedback from HB_Acumatica, working code is below for reference:
public void INKitSpecStkDet_VendorInventoryCode_FieldSelecting(PXCache sender, PXFieldSelectingEventArgs e)
{
var row = e.Row as INKitSpecStkDet;
if (e.Row != null)
{
PO.POVendorInventory vendorInventory = PXSelectReadonly2<PO.POVendorInventory,
InnerJoin<IN.InventoryItem,
On<PO.POVendorInventory.vendorID, Equal<IN.InventoryItem.preferredVendorID>, And<PO.POVendorInventory.inventoryID, Equal<IN.InventoryItem.inventoryID>>>>,
Where<IN.InventoryItem.inventoryID, Equal<Required<IN.INKitSpecStkDet.compInventoryID>>>,
OrderBy<Desc<PO.POVendorInventory.vendorInventoryID>>>.Select(Base, row.CompInventoryID);
e.ReturnValue = vendorInventory != null ? vendorInventory.VendorInventoryID : null;
}
}
Upvotes: 1
Views: 209
Reputation: 8299
PXDBScalar
attribute doesn't refresh by itself. Maybe explicitly calling RaiseFieldDefaulting
method will refresh it:
object newValue = null;
base.Caches[typeof(INKitSpecStkDet)].RaiseFieldDefaulting<INKitSpecStkDetExt.vendorInventoryCode>(rowINKitSpecStkDet, out newValue);
Using PXFormula
instead of PXDBScalar
if possible will yield better automatic refresh behavior but has it's own set of limitation as well.
If you're looking for the simplest way that works in most contexts (except when no graph is used like in reports and generic inquiry) that would be the FieldSelecting event. You can execute BQL and return any desired value from the event. It will be called each time the field is referenced so it should update by itself.
public void INKitSpecStkDet_VendorInventoryCode_FieldSelecting(PXCache sender, PXFieldSelectingEventArgs e)
{
PO.POVendorInventory vendorInventory = PXSelectReadonly2<Po.POVendorInventory […]>.Select(Base);
e.ReturnValue = vendorInventory != null ? vendorInventory.VendorInventoryCode : null;
}
Upvotes: 1