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, I have created an override method but I get this error, any help would be appreciated!
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
// This method overrides the existing method tied to the Generate button
[PXOverride]
public virtual void GenerateNumbers(Action baseMethod)
{
// Call the base method to keep existing functionality (optional)
baseMethod?.Invoke();
// Custom logic to generate Lot/Serial numbers based on production number
var currentOrder = PXSelect<AMProdItem>.Select(Base).TopFirst;
if (currentOrder == null) return;
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();
}
#endregion
} }
Error: [2024-10-07 03:16:01.919] The Void GenerateNumbers(System.Action) 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-07 03:16:08.479] Validation failed.
Thank you!
New Code
{
public class ProdMaint_Extension : PXGraphExtension<ProdMaint.ItemLineSplittingExtension,PX.Objects.AM.ProdMaint>
{
#region Event Handlers
//public IEnumerable GenerateNumbersDelegate(PXAdapter adapter);
//public delegate IEnumerable GenerateNumbersDelegate(PXAdapter adapter);
[PXOverride]
public IEnumerable GenerateNumbers(PXAdapter adapter, Func<PXAdapter, IEnumerable> baseMethod)
{
//var result = baseMethod(adapter);
//return result;
// Call the base method to ensure the original functionality is executed
var baseResult = baseMethod.Invoke(adapter);
// Retrieve the current production order
var currentProductionOrder = PXSelect<AMProdItem>.Select(Base).TopFirst;
if (currentProductionOrder == null)
{
throw new PXException("No Production Order found.");
}
// Get the production order number
var productionOrderNbr = currentProductionOrder.ProdOrdID; // Adjust this field as needed
if (string.IsNullOrEmpty(productionOrderNbr))
{
throw new PXException("Production Order Number is required.");
}
// Prepare a list to store the updated rows
var resultList = new List<AMProdMatl>();
int sequenceNumber = 1;
// Iterate over the results returned by the base method
foreach (AMProdMatl row in baseResult.OfType<AMProdMatl>())
{
// Generate the custom Lot/Serial number
row.LotSerialNbr = $"{productionOrderNbr}-{sequenceNumber:D6}";
// Add the updated row to the result list
resultList.Add(row);
sequenceNumber++;
}
// Return the updated result list
return resultList;
}
#endregion
}
}```
You get this error because GenerateNumbers
is not declared in ProdMaint
graph, but it is declared in ItemLineSplittingExtension
. You need to override it in this way:
public class ProdMaint_Extension : PXGraphExtension<ProdMaint.ItemLineSplittingExtension, PX.Objects.AM.ProdMaint>
{
// This method overrides the existing method tied to the Generate button
[PXOverride]
public virtual IEnumerable GenerateNumbers(PXAdapter adapter, Func<PXAdapter, IEnumerable> baseMethod)
{
var baseResult = baseMethod.Invoke(adapter);
var currentProductionOrder = Base.ProdMaintRecords.Current;
if (currentProductionOrder == null) // I don't think it is possible
{
// Acuminator disable once PX1050 HardcodedStringInLocalizationMethod [Justification]
throw new PXException("No Production Order found.");
}
// Get the production order number
var productionOrderNbr = currentProductionOrder.ProdOrdID; // Adjust this field as needed
if (string.IsNullOrEmpty(productionOrderNbr))
{
// Acuminator disable once PX1050 HardcodedStringInLocalizationMethod [Justification]
throw new PXException("Production Order Number is required.");
}
int sequenceNumber = 1;
// Iterate over the splits records
foreach (var row in Base.splits.Select().RowCast<AMProdItemSplit>())
{
// Generate the custom Lot/Serial number
row.LotSerialNbr = $"{productionOrderNbr}-{sequenceNumber:D6}";
Base.splits.Update(row);
sequenceNumber++;
}
return baseResult; // or adapter.Get(); if you don't call baseMethod
}
}