Modify Lot/ Serial Number Generation in Production Order Maintenance Screen (AM201500)
I have to do a customization in the production order maintenance screen where in the line details tab there is a generate button to create the line in sequence 000001 and so on.
But I want to change it to grab the production number for example (PP000004) and the lot/serial number generated is PP000004-000001, PP000004-000002, PP000004-000003 and so on till the quantity to generate is satisfied. How to achieve this via customization? The generate button needs to be extended to change the Lot/ Serial number, any help would be appreciated!
Thank you!
Page 1 / 1
I have implemented a new button called “Generate Lot/ Serial” in order to fulfill the requirement but it does not generate the line numbers and no errors are being thrown. I have attached the code which I have used for this button below.
using System; using PX.Data; using PX.Objects.IN; using PX.Objects.CS; using System.Collections; using System.Collections.Generic; using System.Text; using PX.Objects.AM.GraphExtensions; using PX.Common; using PX.Objects.Common; using PX.Objects.SO; using PX.Objects.AM.Attributes; using System.Linq; using PX.Objects.AM.CacheExtensions; using PX.Data.BQL.Fluent; using PX.Data.BQL; using PX.Objects.AR; using PX.Objects.CR; using PX.Objects.GL; using PX.Objects; using PX.Objects.AM;
namespace PX.Objects.AM { public class ProdMaint_Extension : PXGraphExtension<PX.Objects.AM.ProdMaint> { #region Event Handlers
PXButton(CommitChanges = true), PXUIField(DisplayName = "Generate Lot/Serial")] public virtual IEnumerable GenerateCustomLotSerial(PXAdapter adapter) { // Call the base method first
var baseResult = Base.Actionsi"ItemLineSplittingExtension_GenerateNumbers"].Press(adapter);
// Get the current production order var currentOrder = PXSelect<AMProdItem>.Select(Base).TopFirst; if (currentOrder == null) return baseResult;
// Get the production number string productionNumber = currentOrder.ProdOrdID;
// Get all generated material lines PXResultset<AMProdMatl> materialLines = PXSelect<AMProdMatl, Where<AMProdMatl.prodOrdID, Equal<Required<AMProdMatl.prodOrdID>>>> .Select(Base, currentOrder.ProdOrdID);
int sequenceNumber = 1; foreach (AMProdMatl line in materialLines) { if (string.IsNullOrEmpty(line.LotSerialNbr)) continue;
// Generate the new lot/serial number string newLotSerialNbr = $"{productionNumber}-{sequenceNumber:D6}";
// Update the lot/serial number line.LotSerialNbr = newLotSerialNbr;
// Save changes Base.Cachesctypeof(AMProdMatl)].Update(line);
sequenceNumber++; }
// Save changes to the database Base.Actions.PressSave();
I believe the data in the grid is the material Lot/Serial Nbr rather than the manufactured.
Hope this helps,
Aleks
This may be of help, I believe its the method that works behind the button:
Actually, the method button is called ‘GenerateNumbers’ in the LineSplittingExtension class in the PX.Objects.IN.GraphExtensions namespace.
It looks like it could easily be overridden, but I don’t have time to figure out what the code might look like.
Hi @darylbowman thanks for the advice I will try overriding this method and post an update!
Thanks for that @darylbowman
@TharidhiP, you might want to be careful if your business relies on any of those lot numbers for inventory tracking because that is what you will be overriding.
I am not sure if this will change the Inventory Lot/Serial nbr or just for the qty used for the production order, once you have completed the customisation, I would double check with your purchasing/stock team that this will be fine.
I have been burned a few times with assumptions of functionality not affecting other areas.
Aleks
Hi @darylbowman , @aiwan thanks for the advice! I’ve tried overriding the logic but I keep getting this error, could you please give some clarification on this?
using System; using PX.Data; using PX.Objects.IN; using PX.Objects.CS; using System.Collections; using System.Collections.Generic; using System.Text; using PX.Objects.AM.GraphExtensions; using PX.Common; using PX.Objects.Common; using PX.Objects.SO; using PX.Objects.AM.Attributes; using System.Linq; using PX.Objects.AM.CacheExtensions; using PX.Data.BQL.Fluent; using PX.Data.BQL; using PX.Objects.AR; using PX.Objects.CR; using PX.Objects.GL; using PX.Objects; using PX.Objects.AM;
namespace PX.Objects.AM { public class ProdMaint_Extension : PXGraphExtension<PX.Objects.AM.ProdMaint> { #region Event Handlers
>PXOverride] public IEnumerable GenerateNumbers(PXAdapter adapter, Func<PXAdapter, IEnumerable> baseMethod) { var baseResult = baseMethod(adapter); var graph = Base;
// Get the production order number var productionOrder = graph.ProdMaintRecords.Current; var productionOrderNbr = productionOrder?.ProdOrdID;
if (string.IsNullOrEmpty(productionOrderNbr)) { throw new PXException("Production Order Number is required."); }
var resultList = new List<AMProdMatl>(); int sequenceNumber = 1;
foreach (AMProdMatl row in baseResult) { // Format the new Lot/Serial number row.LotSerialNbr = $"{productionOrderNbr}-{sequenceNumber:D6}";
resultList.Add(row); sequenceNumber++; }
return resultList; }
#endregion } }
p2024-10-08 23:28:29.075] The System.Collections.IEnumerable GenerateNumbers(PX.Data.PXAdapter, System.Func`2nPX.Data.PXAdapter,System.Collections.IEnumerable]) method in the PX.Objects.AM.ProdMaint_Extension graph extension is marked as PXOverride], but no original method with this name has been found in PXGraph.
p2024-10-08 23:28:35.286] Validation failed.
Thank you so much!
public IEnumerable GenerateNumbersDelegate(PXAdapter adapter); [PXOverride] public IEnumerable GenerateNumbers(PXAdapter adapter, GenerateNumbersDelegate baseMethod) { var result = baseMethod(adapter);
return result; }
Thanks for the help @darylbowman! So I should declare this override method in which graph, is it ProdMaint_Extension : PXGraphExtension<PX.Objects.AM.ProdMaint> or LineSplittingExtension class in the PX.Objects.IN.GraphExtensions namespace?
Try putting it in here:
public class YourExtensionName : PXGraphExtension<ItemLineSplittingExtension, ProdMaint> {
}
ItemLineSplittingExtension is defined in ProdMaint.cs
Try putting it in here:
public class YourExtensionName : PXGraphExtension<ItemLineSplittingExtension, ProdMaint> {
}
For what it’s worth, if it’s in this graph extension, you don’t need to worry about it interfering with the inventory version.