| Quintiq file version 2.0 | 
| #parent: #root | 
| Method AddTermsToServiceLevelConstraints ( | 
|   CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program, | 
|   MPConstraint constr, | 
|   const ServiceLevelBase sl, | 
|   Real scalefactor_salesdemandqty_constfromsd, | 
|   Real scalefactor_rhs_constr, | 
|   output Real rhsfromtarget_o, | 
|   const LibOpt_Scope scope | 
| ) const as Number | 
| { | 
|   Description: 'Add the sales demand term to the service level from sales demand constraints' | 
|   TextBody: | 
|   [* | 
|     // Only define the constraints if the sd needs to be planned and is on a pispip that is part of this optimizer run | 
|     constantterm := 0.0;  | 
|     addedvariableterms := 0;  | 
|     traverse( sl.GetSalesDemandInPeriodsConst(), Elements, sd, | 
|               sd.NeedsToBePlanned() | 
|               and sd.IsWithinThresholdQuantity() ) | 
|     { | 
|       uomconversion := sd.DefaultUOMConversionFactor(); | 
|      | 
|       inscope := guard( scope.Contains( sd.AsPlanningBaseSalesDemandInPeriod().PISPIPInOptimizerRun() ) , false );  | 
|      | 
|       if ( inscope )  | 
|       {    | 
|         if( sd.istype( LeafSalesDemandInPeriod ) ) | 
|         { | 
|             constr.NewTerm( -uomconversion * scalefactor_salesdemandqty_constfromsd, program.SalesDemandQtyVariables().Get( sd.astype( LeafSalesDemandInPeriod ) ) ); | 
|         } | 
|         else if( sd.istype( DisaggregatedSalesDemandInPeriod ) ) | 
|         { | 
|             constr.NewTerm( -uomconversion * scalefactor_salesdemandqty_constfromsd, program.DisaggregatedSalesDemandQtyVariables().Get( sd.astype( DisaggregatedSalesDemandInPeriod ) ) ); | 
|         } | 
|         addedvariableterms++;  | 
|       } | 
|       else | 
|       { | 
|         constantterm := constantterm + sd.FulfilledQuantityInDefaultUOM();  | 
|       } | 
|       // For the rhs of the target constraint of the fulfillment target constraint we need to sum over all sales demand quantities | 
|       rhsfromtarget_o := rhsfromtarget_o + sd.QuantityInDefaultUOM(); // note note used for current constraint 'constr' - just to collect total sales demand qty | 
|     } | 
|      | 
|     newrhs := this.GetConstraintRHS( constr, scalefactor_rhs_constr ) + constantterm; // variable is added on the right, so we *add* constantterm to the RHS | 
|     constr.RHSValue( newrhs * scalefactor_rhs_constr ); | 
|     return addedvariableterms; | 
|   *] | 
|   InterfaceProperties { Accessibility: 'Module' } | 
| } |