CanBatch MRP customization

Customizing MRP batching logic in a customization

This guide will step through the process of coding a CanBatchCapacity customization. If you are just getting started, you can learn about getting started with customizations

Creating the Class

To start, we will need to create a new class that inherits from PT.Scheduler.Simulation.Customizations.MRP.CanBatchCustomization.

Here is what a  basic class should look like:

public class CanBatchCust : PT.Scheduler.Simulation.Customizations.MRP.CanBatchCustomization
{
public override string Name => "CanBatch Customization";

public override string Description => $"Determines if demands can be batched during MRP.";

protected override bool CanBatch(ScenarioDetail a_sd, PT.Scheduler.Schedule.InventoryManagement.MRP.SupplyOrder a_supplyOrder, Adjustment a_adjustment, decimal a_qty, bool a_allowPartialSupply)
{
return true;
}
}

There is one function to override

CanBatch returns whether a demand can be batched with other demands already planned in the batch.

Let's take a look at the parameters for CanBatch :
  • ScenarioDetail a_sd: The current scenario data. This can be used to reference objects within the system, however, the data cannot be changed.
  • MRP.SupplyOrder a_supplyOrder: The collection of demands that MRP is batching. This contains the demand parts, each one is an individual demand.
  • Adjustment a_adjustment: The current demand attempting to batch. This includes the time, quantity, and Reason of the demand. Reason is a reference to the object, for example, the SalesOrderLineDistribution, InternalActivity or TransferOrderDistribution.
  • decimal a_qty: Rounded quantity needed to satisfy the demand.
  • bool a_allowPartialSupply: Whether the demand can be satisfied from multiple sources.

Example

namespace PlanetTogether.Sample.CanBatch
{
public class CanBatchCust : PT.Scheduler.Simulation.Customizations.MRP.CanBatchCustomization
{
public override string Name => "BatchCode";

public override string Description => $"Demand from two Operations can batch only if they have the same value specified in '{c_batchCodeUdf}' UDF field.";

const string c_batchCodeUdf = "Staging";

protected override bool CanBatch(ScenarioDetail a_sd, PT.Scheduler.Schedule.InventoryManagement.MRP.SupplyOrder a_supplyOrder, Adjustment a_adjustment, decimal a_qty, bool a_allowPartialSupply)
{
string code = GetBatchCodeFromDemandParts(a_supplyOrder);
if (code != null && code != GetBatchCode(a_adjustment.Reason))
{
return false;
}
return true;
}

string GetBatchCodeFromDemandParts(PT.Scheduler.Schedule.InventoryManagement.MRP.SupplyOrder a_supplyOrder)
{
foreach (var d in a_supplyOrder.DemandParts)
{
string code = GetBatchCode(d.Demand.Reason);
if (code == null) continue;
return code;
}
return null;
}

string GetBatchCode(BaseIdObject a_obj)
{
if (a_obj is InternalActivity act)
{
return (string)act.Operation.UserFields?.Find(c_batchCodeUdf)?.DataValue;
}
return null;
}
}
}

Next Steps

Take a look at other customization that can be used to modify the way orders schedule after MRP: Customization Index