Skip to main content
Answer

How to add Lot/Serial Nbr selector custom column.

  • April 22, 2025
  • 8 replies
  • 132 views

Forum|alt.badge.img+1

Hi All,
I’ve added a custom field to the Purchase Receipt header, and I want to display this field on the Shipment screen Lot/Serial Nr. selector as a custom column. The idea is to display the value from the Purchase Receipt header where the LotSerial number in the shipment matches the LotSerial number from the Purchase Receipt. If there's a match, the corresponding custom field value from the Purchase Receipt should be shown on the Lot/Serial Nr. custom column.

Has anyone implemented something similar or can guide me on how to achieve new column and customization.

Thanks in advance!

Best answer by aiwan

@noorula77 

 

You can remove the attribute in a cache attached and attach your own selector attribute.

This is the INLotSerialNbr Attribute, it may be useful to re-create this with more parameters which includes your custom field.

public INLotSerialNbrAttribute()
{
}

public INLotSerialNbrAttribute(Type InventoryType, Type SubItemType, Type LocationType, Type CostCenterType)
{
Type type = BqlCommand.GetItemType(InventoryType);
if (!typeof(ILSMaster).IsAssignableFrom(type))
{
throw new PXArgumentException("itemType", "The specified type {0} must implement the {1} interface.", type.GetLongName(), typeof(ILSMaster).GetLongName());
}

_InventoryType = InventoryType;
_SubItemType = SubItemType;
_LocationType = LocationType;
_CostCenterType = CostCenterType;
InitializeSelector(GetLotSerialSearch(InventoryType, SubItemType, LocationType, CostCenterType), typeof(INLotSerialStatusByCostCenter.lotSerialNbr), typeof(INLotSerialStatusByCostCenter.siteID), typeof(INLotSerialStatusByCostCenter.locationID), typeof(INLotSerialStatusByCostCenter.qtyOnHand), typeof(INLotSerialStatusByCostCenter.qtyAvail), typeof(INLotSerialStatusByCostCenter.expireDate));
}

public INLotSerialNbrAttribute(Type InventoryType, Type SubItemType, Type LocationType, Type ParentLotSerialNbrType, Type CostCenterType)
: this(InventoryType, SubItemType, LocationType, CostCenterType)
{
InitializeDefault(ParentLotSerialNbrType);
}

 

Hope this helps,

Aleks

8 replies

Forum|alt.badge.img+1
  • Author
  • Jr Varsity III
  • April 23, 2025

If any one know how to add custom column on lot serial number selector please guide.


Forum|alt.badge.img+8
  • Captain II
  • Answer
  • April 23, 2025

@noorula77 

 

You can remove the attribute in a cache attached and attach your own selector attribute.

This is the INLotSerialNbr Attribute, it may be useful to re-create this with more parameters which includes your custom field.

public INLotSerialNbrAttribute()
{
}

public INLotSerialNbrAttribute(Type InventoryType, Type SubItemType, Type LocationType, Type CostCenterType)
{
Type type = BqlCommand.GetItemType(InventoryType);
if (!typeof(ILSMaster).IsAssignableFrom(type))
{
throw new PXArgumentException("itemType", "The specified type {0} must implement the {1} interface.", type.GetLongName(), typeof(ILSMaster).GetLongName());
}

_InventoryType = InventoryType;
_SubItemType = SubItemType;
_LocationType = LocationType;
_CostCenterType = CostCenterType;
InitializeSelector(GetLotSerialSearch(InventoryType, SubItemType, LocationType, CostCenterType), typeof(INLotSerialStatusByCostCenter.lotSerialNbr), typeof(INLotSerialStatusByCostCenter.siteID), typeof(INLotSerialStatusByCostCenter.locationID), typeof(INLotSerialStatusByCostCenter.qtyOnHand), typeof(INLotSerialStatusByCostCenter.qtyAvail), typeof(INLotSerialStatusByCostCenter.expireDate));
}

public INLotSerialNbrAttribute(Type InventoryType, Type SubItemType, Type LocationType, Type ParentLotSerialNbrType, Type CostCenterType)
: this(InventoryType, SubItemType, LocationType, CostCenterType)
{
InitializeDefault(ParentLotSerialNbrType);
}

 

Hope this helps,

Aleks


Forum|alt.badge.img+1
  • Author
  • Jr Varsity III
  • April 23, 2025

 ​@aiwan Hello,
Thanks for reply I tried like this but not showing lotserial number selector one more column. Can you please suggest.

 public class TSINLotSerialNbrAttribute : INLotSerialNbrAttribute
{
public TSINLotSerialNbrAttribute() : base() { }
public TSINLotSerialNbrAttribute(Type inventoryType, Type subItemType, Type locationType, Type costCenterType)
: base(inventoryType, subItemType, locationType, costCenterType)
{
// Re-initialize the selector with your custom field
base.InitializeSelector(
GetLotSerialSearch(inventoryType, subItemType, locationType, costCenterType),
typeof(INLotSerialStatusByCostCenter.lotSerialNbr),
typeof(INLotSerialStatusByCostCenter.siteID),
typeof(INLotSerialStatusByCostCenter.locationID),
typeof(INLotSerialStatusByCostCenter.qtyOnHand),
typeof(INLotSerialStatusByCostCenter.qtyAvail),
typeof(INLotSerialStatusByCostCenter.expireDate),
typeof(INLotSerialStatusByCostCenterExt.usrCustomField)
);
}

public TSINLotSerialNbrAttribute(Type inventoryType, Type subItemType, Type locationType, Type parentLotSerialNbrType, Type costCenterType)
: base(inventoryType, subItemType, locationType, parentLotSerialNbrType, costCenterType)
{
// Re-initialize the selector with your custom field
base.InitializeSelector(
GetLotSerialSearch(inventoryType, subItemType, locationType, costCenterType),
typeof(INLotSerialStatusByCostCenter.lotSerialNbr),
typeof(INLotSerialStatusByCostCenter.siteID),
typeof(INLotSerialStatusByCostCenter.locationID),
typeof(INLotSerialStatusByCostCenter.qtyOnHand),
typeof(INLotSerialStatusByCostCenter.qtyAvail),
typeof(INLotSerialStatusByCostCenter.expireDate),
typeof(INLotSerialStatusByCostCenterExt.usrCustomField)
);
}

In Shipment graph:
[TSINLotSerialNbrAttribute(typeof(SOShipLine.inventoryID), typeof(SOShipLine.subItemID), typeof(SOShipLine.locationID), typeof(SOShipLine.costCenterID), PersistingCheck = PXPersistingCheck.Nothing)]
protected virtual void SOShipLine_LotSerialNbr_CacheAttached(PXCache cache)
{

}

Thanks


Forum|alt.badge.img+8
  • Captain II
  • April 23, 2025

@noorula77 you have to add another parameter to your TSINLotSerialNbrAttribute i.e

public TSINLotSerialNbrAttribute(Type inventoryType, Type subItemType, Type locationType, Type parentLotSerialNbrType, Type costCenterType, Type usrCustomColumn) : base(inventoryType, subItemType, locationType, parentLotSerialNbrType, costCenterType, usrCustomColumn)


Forum|alt.badge.img+1
  • Author
  • Jr Varsity III
  • April 24, 2025

@aiwan Thanks for suggestion .I tried it is not allowing getting error 

Severity	Code	Description	Project	File	Line	Suppression State
Error (active) CS1729 'INLotSerialNbrAttribute' does not contain a constructor that takes 6 arguments

 


Forum|alt.badge.img+8
  • Captain II
  • April 24, 2025

@noorula77 

 

you need to add your field to InitializeSelector too

base.InitializeSelector( GetLotSerialSearch(inventoryType, subItemType, locationType, costCenterType, usrCustomField), typeof(INLotSerialStatusByCostCenter.lotSerialNbr), typeof(INLotSerialStatusByCostCenter.siteID), typeof(INLotSerialStatusByCostCenter.locationID), typeof(INLotSerialStatusByCostCenter.qtyOnHand), typeof(INLotSerialStatusByCostCenter.qtyAvail), typeof(INLotSerialStatusByCostCenter.expireDate), typeof(INLotSerialStatusByCostCenterExt.usrCustomField) );


Forum|alt.badge.img+1
  • Author
  • Jr Varsity III
  • April 24, 2025

Hi ​@aiwan 
I have added the column in the field list, and it is now visible. I want to display data in this column only when the shipment's lot serial number matches the purchase receipt's lot serial number. In that case, the corresponding custom column data from the purchase receipt should be displayed.
I tried using RowSelected and FieldSelecting but not worked.

 protected void SOShipLine_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
{

var row = (SOShipLine)e.Row;
if (row == null) return;

POReceiptLine pOReceiptline = PXSelect<POReceiptLine,
Where<POReceiptLine.inventoryID, Equal<Required<POReceiptLine.inventoryID>>,
And<POReceiptLine.siteID, Equal<Required<POReceiptLine.siteID>>,
And<POReceiptLine.locationID, Equal<Required<POReceiptLine.locationID>>>>>>
.Select(Base, row.InventoryID, row.SiteID, row.LocationID);

POReceipt pOReceipt = PXSelect<POReceipt,
Where<POReceipt.receiptType, Equal<Required<POReceipt.receiptType>>,
And<POReceipt.receiptNbr, Equal<Required<POReceipt.receiptNbr>>>>>
.Select(Base, pOReceiptline.ReceiptType, pOReceiptline.ReceiptNbr);
if (row.LotSerialNbr == pOReceiptline.LotSerialNbr)
{
INLotSerialStatusByCostCenter iNLotSerialStatus = PXSelect<INLotSerialStatusByCostCenter,
Where<INLotSerialStatusByCostCenter.inventoryID, Equal<Required<INLotSerialStatusByCostCenter.inventoryID>>,
And<INLotSerialStatusByCostCenter.siteID, Equal<Required<INLotSerialStatusByCostCenter.siteID>>,
And<INLotSerialStatusByCostCenter.locationID, Equal<Required<INLotSerialStatusByCostCenter.locationID>>>>>>
.Select(Base, row.InventoryID, row.SiteID, row.LocationID);
iNLotSerialStatus.GetExtension<INLotSerialStatusByCostCenterExt>().UsrCustomField = pOReceipt.GetExtension<POReceiptExtensionsTSExt>().Usrreceiptsad;
}
}

 


Forum|alt.badge.img+8
  • Captain II
  • April 24, 2025

@noorula77 

 

Might be worth trying to declare the extensions seperately, then using e.Cache.SetValue<>() to set the field value.