| Quintiq file version 2.0 | 
| #parent: #root | 
| MethodOverride InitConstraintsForPostponedSalesDemands ( | 
|   const CapacityPlanningSuboptimizer subopt, | 
|   CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program, | 
|   const LibOpt_Scope scope, | 
|   Number optminpostponementperiod | 
| ) const | 
| { | 
|   TextBody: | 
|   [* | 
|     // Aggregated sales demands for higher product level | 
|                    | 
|     // Constraint: Sum of disaggregated and delayed disaggregated should equal or smaller than the aggregated quantity | 
|     // DisaggregatedSalesDemandQty(childrenproducts) + DelayedDisaggregatedSalesDemandQty(childrenproducts) <= AggregatedSalesDemandQty forall Aggregated sdips | 
|     sumofdisaggregatedsalesdemandconstrtype := typeof( MPSumOfDisaggregatedSalesDemandConstraint ); | 
|     scalefactor_disaggregatedsalesdemandqty_const := subopt.ScaleConstraintTerm( typeof( MPDisaggregatedSalesDemandQtyVariable ), sumofdisaggregatedsalesdemandconstrtype ); | 
|      | 
|     constdisaggregated := program.SumOfDisaggregatedSalesDemandConstraints().New( this ); | 
|     constdisaggregated.Sense( '<=' ); | 
|      | 
|     rhs := this.GetQuantityForOptimizer( scope ); | 
|      | 
|     // Traverse the children ( Disaggregated Sales demands ) | 
|     traverse ( this,  | 
|                DisaggregatedSalesDemandInPeriod,  | 
|                dasdip,  | 
|                not dasdip.IsPostponed() ) // note we only define DisaggregatedSalesDemandQtyVariables for unpostponed dasdip | 
|     { | 
|       // If the scope includes the PISPIP, then add its variable, otherwise subtract its fulfilled quantity from RHS | 
|       if( scope.Contains( dasdip.AsPlanningBaseSalesDemandInPeriod().PISPIPInOptimizerRun() ) )  | 
|       { | 
|         constdisaggregated.NewTerm( 1.0 * scalefactor_disaggregatedsalesdemandqty_const, | 
|                                     program.DisaggregatedSalesDemandQtyVariables().Get( dasdip ) ); | 
|       } | 
|       else | 
|       { | 
|         rhs := maxvalue( rhs - dasdip.FulfilledQuantity(), 0.0 ); | 
|       } | 
|        | 
|       // If the scope includes the PISP, then add the delayed variables, otherwise subtract the postponed quantity | 
|       if( scope.Contains( dasdip.ProductInStockingPoint_MP().PISPInOptimizerRun() ) ) | 
|       { | 
|         // add delayeddisaggregatedsalesdemand | 
|         // add all delayed variables within the scope (outside of scope is not part of quantity computed above) | 
|         dasdip.AddTermsForDelayedSalesDemandsForward( program, constdisaggregated, 1.0, scope, subopt, optminpostponementperiod ); | 
|       } | 
|       else | 
|       { | 
|         postponedqty_inscope := sum( dasdip,  | 
|                                      PostponedSalesDemand.astype( DisaggregatedSalesDemandInPeriod ),  | 
|                                      postponed_dasdip,  | 
|                                      scope.Contains( postponed_dasdip.ProductInStockingPointInPeriodPlanning().PISPIPInOptimizerRun() ),  | 
|                                      postponed_dasdip.FulfilledQuantity() );  | 
|         rhs := maxvalue( rhs - postponedqty_inscope, 0.0 ); // take away from computed asdip quantity the postponed qty in scope | 
|       } | 
|     } | 
|     constdisaggregated.RHSValue( subopt.ScaleConstraintRHS( sumofdisaggregatedsalesdemandconstrtype, rhs ) ); | 
|   *] | 
| } |