Skip to main content

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!

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();

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!


Hi @TharidhiP 

 

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.


Reply