Skip to main content
Answer

How to enable LotserialNbr on a line-item grid in a custom form with a custom DAC?

  • May 21, 2025
  • 2 replies
  • 60 views

Forum|alt.badge.img

Hello Community, 

I am working on a custom transactional screen that will essentially act like inventory adjustments with a bit more info attached\tracked and allow for continuous updates to the record to create actual receipts\issues from. To accomplish this, I created a custom header and detail table, attempting to bypass the usual line-item table and then line-item split table I’ve seen and going straight to the “splits” table. I have most of everything working except the ability to get the LotSerialNbr column unlocked. Has anyone ran into issues getting the LotSerialNbr enabled on the line-item grid level? Below is my current DAC definition for this field. 

        #region LotSerialNbr
public abstract class lotSerialNbr : PX.Data.BQL.BqlString.Field<lotSerialNbr> { }
protected String _LotSerialNbr;
[POLotSerialNbr(typeof(inventoryID), typeof(subItemID), typeof(locationID), typeof(lotSerialNbr), typeof(NXINPallets.costCenterID))]
public virtual String LotSerialNbr
{
get
{
return this._LotSerialNbr;
}
set
{
this._LotSerialNbr = value;
}
}
#endregion

Then the PK and FK entries for this DAC:

  public class NXINPalletsSplit : PXBqlTable, IBqlTable, ILSDetail
{
public class PK : PrimaryKeyOf<NXINPalletsSplit>.By<palletNo, lineNbr, splitLineNbr>
{
public static NXINPalletsSplit Find(PXGraph graph, string palletNo, int? lineNbr, int? splitLineNbr, PKFindOptions options = PKFindOptions.None)
=> FindBy(graph, palletNo, lineNbr, splitLineNbr, options);
}
public static class FK
{
public class Receipt : NXINPallets.PK.ForeignKeyOf<NXINPalletsSplit>.By<palletNo> { }
public class Branch : PX.Objects.GL.Branch.PK.ForeignKeyOf<NXINPalletsSplit>.By<branchID> { }
public class LotSerialStatus : INLotSerialStatus.PK.ForeignKeyOf<NXINPalletsSplit>.By<inventoryID, subItemID, siteID, locationID, lotSerialNbr> { }
public class LocationStatus : INLocationStatus.PK.ForeignKeyOf<NXINPalletsSplit>.By<inventoryID, subItemID, siteID, locationID> { }
public class SiteStatus : INSiteStatus.PK.ForeignKeyOf<NXINPalletsSplit>.By<inventoryID, subItemID, siteID> { }
public class InventoryItem : PX.Objects.IN.InventoryItem.PK.ForeignKeyOf<NXINPalletsSplit>.By<inventoryID> { }
public class Site : INSite.PK.ForeignKeyOf<NXINPalletsSplit>.By<siteID> { }
public class SubItem : INSubItem.PK.ForeignKeyOf<NXINPalletsSplit>.By<subItemID> { }
public class Location : INLocation.PK.ForeignKeyOf<NXINPalletsSplit>.By<locationID> { }
}

Any help or direction would be awesome, thanks in advance!

Best answer by darylbowman

POLotSerialNbrAttribute is derived from INLotSerialNbrAttribute which has a FieldSelecting event configured to disable the selector if Lot Tracking is not enabled for the Item you’re using. Is the Item you’re using lot tracked?

 

public virtual void FieldSelecting(PXCache sender, PXFieldSelectingEventArgs e)
{
ILSMaster iLSMaster = (ILSMaster)e.Row;
if (iLSMaster != null)
{
PXResult<InventoryItem, INLotSerClass> pXResult = ReadInventoryItem(sender, iLSMaster.InventoryID);
((PXUIFieldAttribute)_Attributes[_UIAttrIndex]).Enabled = !ForceDisable && pXResult != null && sender.AllowUpdate && IsTracked(iLSMaster, pXResult, iLSMaster.TranType, iLSMaster.InvtMult);
}
}

 

Also, for what it’s worth, your field definition can be a lot cleaner:

#region LotSerialNbr
[POLotSerialNbr(typeof(inventoryID), typeof(subItemID), typeof(locationID), typeof(lotSerialNbr), typeof(NXINPallets.costCenterID))]
public virtual string LotSerialNbr { get; set; }
public abstract class lotSerialNbr : PX.Data.BQL.BqlString.Field<lotSerialNbr> { }
#endregion

 

2 replies

darylbowman
Captain II
Forum|alt.badge.img+15
  • Answer
  • May 22, 2025

POLotSerialNbrAttribute is derived from INLotSerialNbrAttribute which has a FieldSelecting event configured to disable the selector if Lot Tracking is not enabled for the Item you’re using. Is the Item you’re using lot tracked?

 

public virtual void FieldSelecting(PXCache sender, PXFieldSelectingEventArgs e)
{
ILSMaster iLSMaster = (ILSMaster)e.Row;
if (iLSMaster != null)
{
PXResult<InventoryItem, INLotSerClass> pXResult = ReadInventoryItem(sender, iLSMaster.InventoryID);
((PXUIFieldAttribute)_Attributes[_UIAttrIndex]).Enabled = !ForceDisable && pXResult != null && sender.AllowUpdate && IsTracked(iLSMaster, pXResult, iLSMaster.TranType, iLSMaster.InvtMult);
}
}

 

Also, for what it’s worth, your field definition can be a lot cleaner:

#region LotSerialNbr
[POLotSerialNbr(typeof(inventoryID), typeof(subItemID), typeof(locationID), typeof(lotSerialNbr), typeof(NXINPallets.costCenterID))]
public virtual string LotSerialNbr { get; set; }
public abstract class lotSerialNbr : PX.Data.BQL.BqlString.Field<lotSerialNbr> { }
#endregion

 


Forum|alt.badge.img
  • Author
  • Jr Varsity III
  • May 22, 2025

@darylbowman That code snippet to the iLSMaster was actually exactly what I needed. It was actually “Transaction Type” that wasn’t setup correctly and it looks like iLSMaster relies on that and InvtMult heavily. Thanks a bunch Daryl!