Quintiq file version 2.0
|
#parent: #root
|
Method CalculateSalesDemandFulfillmentOnHigherLevel
|
{
|
TextBody:
|
[*
|
// Only "Propagate" the updated scope: The Product family
|
updateScope := selectsortedset( this.ProductInStockingPoint_MP().GetAllParent(), Elements, e,
|
not e.IsLeaf() and e.SalesDemand( relsize ) > 0,
|
-e.Product_MP().Level() );
|
|
if( updateScope.Size() > 0 )
|
{
|
traverse( updateScope, Elements, e )
|
{
|
e.ResetSalesDemandFulfilledQuantity( this.Period_MP() );
|
}
|
|
// Propagate all PISPIP quantities before calculate for fulfillment on demand on higher level
|
Transaction::Transaction().Propagate();
|
|
// Initialize SystemRemainingQuantity
|
traverse( updateScope, Elements.SalesDemand.SalesDemandInPeriod.astype( AggregatedSalesDemandInPeriod ), sdip )
|
{
|
sdip.SystemRemainingQuantity( sdip.Quantity() - sdip.FulfilledQuantity() );
|
}
|
|
// Go through the PISPIP and onwards
|
traverse( updateScope, Elements.ProductInStockingPointInPeriodPlanning, parentPispip,
|
parentPispip.Period_MP().SequenceNr() >= this.Period_MP().SequenceNr() )
|
{
|
|
traverse( parentPispip.GetLeavesOfProductDimension(), Elements.astype( ProductInStockingPointInPeriodPlanningLeaf ), pispip )
|
{
|
// The supply quantity will be updated when the algorithm used the supply to fulfill the demand in previous period.
|
Transaction::Transaction().Propagate( attribute( ProductInStockingPointInPeriod, SupplyQuantity) );
|
remainingQuantity := pispip.SupplyQuantity()
|
/* We dont care about optimizer in this scope, manual planning will reset all optimizer fulfillments
|
- pispip.OptimizerFulfilledDemandQuantity()
|
- pispip.OptimizerReservedQuantity() */
|
|
// We don't allow total remaining qty to go below -ve
|
// Although totalremaining = 0, still need to proceed with the greedy to reset the demands systemfulfilledquantity to 0
|
remainingQuantity := maxvalue( remainingQuantity, 0.0 );
|
|
// We will consider all Greedy algorithm sorting here which includes Leaf & Disaagregated sales demand in periods
|
salesdemands := selectsortedset( pispip, PlanningBaseSalesDemandInPeriod, sd,
|
sd.NeedsToBePlanned() and sd.IsNotRestricted(), //Should not consider DSDIP that is restricted by FR
|
guard( -sd.Priority().Weight(), 0 ),
|
-sd.BasePricePerQuantity(),
|
( not sd.MasterSalesDemand().IsLeaf() ).AsQUILL() /*Always fulfill leaf first*/ );
|
|
traverse( salesdemands, Elements, sdip )
|
{
|
ontype( sdip )
|
{
|
LeafSalesDemandInPeriod as leafsalesdemandinperiod:
|
{
|
// The fulfillment of the leaf sales demand in period will be assign by the greedy from PISPIP.CalcSystemFulfilledQuantity
|
// We dont assign any fulfillment to leaf sales demand in period from here but only use it to reduce the totalremaining supply quantity
|
qtyToFulfill := leafsalesdemandinperiod.Quantity();
|
qtyAbleToFulfill := minvalue( remainingQuantity, qtyToFulfill );
|
|
remainingQuantity := remainingQuantity - qtyAbleToFulfill;
|
}
|
DisaggregatedSalesDemandInPeriod as disaggregatedsalesdemandinperiod:
|
{
|
qtyToFulfill := disaggregatedsalesdemandinperiod.AggregatedSalesDemandInPeriod().SystemRemainingQuantity();
|
qtyAbleToFulfill := minvalue( remainingQuantity, qtyToFulfill );
|
|
disaggregatedsalesdemandinperiod.SystemAssignedQuantity( qtyAbleToFulfill );
|
disaggregatedsalesdemandinperiod.AggregatedSalesDemandInPeriod().SystemRemainingQuantity( qtyToFulfill - qtyAbleToFulfill );
|
|
remainingQuantity := remainingQuantity - qtyAbleToFulfill;
|
}
|
}
|
}
|
}
|
}
|
}
|
*]
|
}
|