Skip to main content
Answer

Modify Lot/ Serial Number Generation in Production Order Maintenance Screen (AM201500)

  • October 4, 2024
  • 11 replies
  • 274 views

Forum|alt.badge.img+2

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!

Best answer by darylbowman

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.

11 replies

Forum|alt.badge.img+2
  • Author
  • Pro III
  • October 6, 2024

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.Actions["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.Caches[typeof(AMProdMatl)].Update(line);

sequenceNumber++;
}

// Save changes to the database
Base.Actions.PressSave();

return baseResult;
}


#endregion
}
}

This is the aspx

<px:PXButton runat="server" ID="CstButton3" Text="Generate Lot/Serial" CommandName="GenerateCustomLotSerial" />

Any help would be appreciated, thank you!


Forum|alt.badge.img+8
  • Captain II
  • October 7, 2024

Hi @TharidhiP 

 

I believe the data in the grid is the material Lot/Serial Nbr rather than the manufactured.

 

Hope this helps,

Aleks


Forum|alt.badge.img+8
  • Captain II
  • October 7, 2024

This may be of help, I believe its the method that works behind the button:

 


darylbowman
Captain II
Forum|alt.badge.img+15

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.


Forum|alt.badge.img+2
  • Author
  • Pro III
  • October 7, 2024

Hi @darylbowman thanks for the advice I will try overriding this method and post an update!


Forum|alt.badge.img+8
  • Captain II
  • October 8, 2024

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


Forum|alt.badge.img+2
  • Author
  • Pro III
  • October 8, 2024

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
}
}
[2024-10-08 23:28:29.075] The System.Collections.IEnumerable GenerateNumbers(PX.Data.PXAdapter, System.Func`2[PX.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.
[2024-10-08 23:28:35.286] Validation failed.

 

Thank you so much!


darylbowman
Captain II
Forum|alt.badge.img+15
public IEnumerable GenerateNumbersDelegate(PXAdapter adapter);
[PXOverride]
public IEnumerable GenerateNumbers(PXAdapter adapter, GenerateNumbersDelegate baseMethod)
{
    var result = baseMethod(adapter);

    return result;
}

 


Forum|alt.badge.img+2
  • Author
  • Pro III
  • October 9, 2024

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?


darylbowman
Captain II
Forum|alt.badge.img+15

Try putting it in here:

public class YourExtensionName : PXGraphExtension<ItemLineSplittingExtension, ProdMaint>
{

}

ItemLineSplittingExtension is defined in ProdMaint.cs


darylbowman
Captain II
Forum|alt.badge.img+15
  • Answer
  • October 10, 2024

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.