Quintiq file version 2.0
|
#parent: #root
|
Method InitConstraintsForShelfLifeSumConstraints (
|
CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program,
|
const constcontent ProductInStockingPointInPeriods smartplanpispips,
|
constcontent ProductInStockingPoint_MPs intermediatepisps,
|
const ProductInStockingPointInPeriodPlanning pispip,
|
DateTime firstpispipstart,
|
DateTime lastpispipstart,
|
const LibOpt_Scope scope,
|
Real scalefactor_mass,
|
Real scalefactor_rhs_constr
|
) const
|
{
|
Description: 'sum constraints split variables'
|
TextBody:
|
[*
|
// >> sum of split InvQty = InvQty
|
{
|
constr := program.InvQtyShelfLifeSumConstraints().New( pispip );
|
if ( scope.Contains( pispip.PISPIPInOptimizerRun() ) )
|
{
|
constr.NewTerm( -1.0 * scalefactor_mass, program.InvQtyVariables().Get( pispip ) );
|
}
|
else
|
{
|
constr.RHSValue( pispip.InventoryLevelEnd() * scalefactor_rhs_constr ); // optimizer itself figure out what has expired - so just sum to the total inventory quantity.
|
}
|
traverse( pispip, ProductInStockingPoint_MP.IncomingShelfLifeDay, islday )
|
{
|
constr.NewTerm( 1.0 * scalefactor_mass, program.InvQtyShelfLifeVariables().Get( pispip, islday ) );
|
}
|
}
|
|
// sum of split dependent demand = dependent demand
|
{
|
constr := program.DependentDemandInPISPIPShelfLifeSumConstraints().New( pispip );
|
if ( scope.Contains( pispip.PISPIPInOptimizerRun() ) )
|
{
|
constr.NewTerm( -1.0 * scalefactor_mass, program.DependentDemandInPISPIPVariables().Get( pispip ) );
|
}
|
else
|
{
|
constr.RHSValue( scalefactor_rhs_constr * pispip.DependentDemandQuantity() );
|
}
|
traverse( pispip, ProductInStockingPoint_MP.IncomingShelfLifeDay, islday )
|
{
|
traverse( pispip, ProductInStockingPoint_MP.OutgoingShelfLifeDay, oslday )
|
{
|
constr.NewTerm( 1.0 * scalefactor_mass, program.DependentDemandInPISPIPShelfLifeVariables().Get( pispip, islday, oslday ) );
|
}
|
}
|
}
|
// sum of split expired = expired on pispip
|
{
|
constr := program.ExpiredConstraints().New( pispip );
|
constr.NewTerm( -1.0 * scalefactor_mass, program.ExpiredVariables().Get( pispip ) );
|
traverse( pispip, ProductInStockingPoint_MP.IncomingShelfLifeDay, islday )
|
{
|
constr.NewTerm( 1.0 * scalefactor_mass, program.ExpiredForAgeVariables().Get( pispip, islday ) );
|
}
|
}
|
|
|
traverse( pispip.GetLeafSalesDemandInPeriod(), Elements, lsdip, not lsdip.IsPostponed() )
|
{
|
constr := program.SalesDemandQtyShelfLifeSumConstraints().New( lsdip );
|
if( scope.Contains( pispip.PISPIPInOptimizerRun() ) )
|
{
|
constr.NewTerm( -1.0 * scalefactor_mass, program.SalesDemandQtyVariables().Get( lsdip ) );
|
}
|
else
|
{
|
constr.RHSValue( lsdip.FulfilledQuantity() * scalefactor_rhs_constr );
|
}
|
traverse( lsdip, ProductInStockingPoint_MP.IncomingShelfLifeDay, islday )
|
{
|
constr.NewTerm( 1.0 * scalefactor_mass, program.SalesDemandShelfLifeQtyVariables().Get( lsdip, islday ) );
|
}
|
|
if( lsdip.CanBePostponed() and lsdip.NeedsToBePlanned() )
|
{
|
nextpispip := lsdip.AsPlanningBaseSalesDemandInPeriod().NextPlanningPISPIP();
|
minpostponement := guard( lsdip.SDIPBeforeScopeInRun().OptMinPostponementPeriod(), 1 ); // if object null, then no min postponement
|
for( i := 2; i <= minpostponement and not isnull( nextpispip ); i++ )
|
{
|
nextpispip := nextpispip.NextPlanningPISPIP();
|
}
|
|
for( i := minpostponement;
|
i <= lsdip.MaxPostponementPeriod() // within the maximum number of postponement periods
|
and not isnull( nextpispip ); // the next pispip exists
|
i++ )
|
{
|
constrsum := program.DelayedSalesDemandQtyShelfLifeSumConstraints().New( lsdip, nextpispip.Period_MP() );
|
if ( scope.Contains( nextpispip.PISPIPInOptimizerRun() ) )
|
// can avoid scope.Contains( nextpispip.PISPIPInOptimizerRun() ) ) because we are in the same transaction
|
{
|
constrsum.NewTerm( -1.0 * scalefactor_mass, program.DelayedSalesDemandQtyVariables().Get( lsdip, nextpispip.Period_MP() ) );
|
}
|
else
|
{
|
postponedty := sum( lsdip, PostponedSalesDemand, psd, psd.ProductInStockingPointInPeriodPlanning() = nextpispip, psd.QuantityToPlan() );
|
constrsum.RHSValue( postponedty * scalefactor_rhs_constr );
|
}
|
traverse( lsdip, ProductInStockingPoint_MP.IncomingShelfLifeDay, islday )
|
{
|
splitvar := program.DelayedSalesDemandShelfLifeQtyVariables().Get( lsdip, nextpispip.Period_MP(), islday );
|
constrsum.NewTerm( 1.0 * scalefactor_mass, splitvar );
|
}
|
nextpispip := nextpispip.NextPlanningPISPIP();
|
}
|
}
|
}
|
|
traverse( pispip.GetDisaggregatedSalesDemandInPeriod(), Elements, dsdip )
|
{
|
constr := program.DisAggregatedSalesDemandQtyShelfLifeSumConstraints().New( dsdip );
|
if ( scope.Contains( pispip.PISPIPInOptimizerRun() ) )
|
// can avoid scope.Contains( pispip.PISPIPInOptimizerRun() ) ) because we are in the same transaction
|
{
|
constr.NewTerm( -1.0 *scalefactor_mass, program.DisaggregatedSalesDemandQtyVariables().Get( dsdip ) );
|
}
|
else
|
{
|
constr.RHSValue( dsdip.FulfilledQuantity() * scalefactor_rhs_constr );
|
}
|
traverse( dsdip, ProductInStockingPoint_MP.IncomingShelfLifeDay, islday )
|
{
|
program.DisaggregatedSalesDemandShelfLifeQtyVariables().Get( dsdip, islday );
|
}
|
|
if ( dsdip.CanBePostponed() and dsdip.NeedsToBePlanned() )
|
{
|
|
nextperiod := dsdip.AsSalesDemandInPeriodBase().Period_MP().NextPlanningPeriod(); // It is not possible to traverse PISPIP from disaggregated but not from Aggregated.
|
minpostponement := guard( dsdip.AggregatedSalesDemandInPeriod().SDIPBeforeScopeInRun().OptMinPostponementPeriod(), 1 ); // if object null, then no min postponement
|
for( i := 2; i <= minpostponement and not isnull( nextperiod ); i++ )
|
{
|
nextperiod := nextperiod.NextPlanningPeriod();
|
}
|
|
for( i := minpostponement;
|
i <= dsdip.MaxPostponementPeriod() // within the maximum number of postponement periods
|
and not isnull( nextperiod ); // the next pispip exists
|
i++ )
|
{
|
constrsum := program.DelayedDisaggregatedSalesDemandQtyShelfLifeSumConstraints().New( dsdip, nextperiod );
|
var := program.DelayedDisaggregatedSalesDemandQtyVariables().Get( dsdip, nextperiod );
|
if ( not isnull( var ) ) // if we are in the optimizer scope we need to use te var other obtain from model
|
{
|
constrsum.NewTerm( -1.0 * scalefactor_mass, var );
|
}
|
else
|
{
|
postponedqty := sum( dsdip, PostponedSalesDemand, psd, psd.ProductInStockingPointInPeriodPlanning().Period_MP() = nextperiod, psd.QuantityToPlan() );
|
constrsum.RHSValue( postponedqty * scalefactor_rhs_constr );
|
}
|
traverse( dsdip, ProductInStockingPoint_MP.IncomingShelfLifeDay, islday )
|
{
|
constrsum.NewTerm( 1.0 * scalefactor_mass, program.DelayedDisaggregatedSalesDemandShelfLifeQtyVariables().Get( dsdip, nextperiod, islday ) );
|
}
|
nextperiod := nextperiod.NextPlanningPeriod();
|
}
|
}
|
}
|
*]
|
InterfaceProperties { Accessibility: 'Module' }
|
}
|