Quintiq file version 2.0 
 | 
#parent: #root 
 | 
Method InitConstraintsForServiceLevel ( 
 | 
  CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program, 
 | 
  const RunContextForCapacityPlanning runcontext, 
 | 
  const LibOpt_Scope scope, 
 | 
  const constcontent ProductInStockingPointInPeriodPlanningLeafs leafpispipsinrun 
 | 
) const 
 | 
{ 
 | 
  Description: 'Initialize constraints forservice level' 
 | 
  TextBody: 
 | 
  [* 
 | 
    eis := this.MacroPlan().OptimizerMetaEIS();   
 | 
    if ( ( runcontext.IsMetaIteration()  
 | 
         and ( eis.ServiceLevelWeight() > 0 or eis.FulfillmentTargetWeight() > 0  ) )  
 | 
         or not runcontext.IsMetaIteration()  
 | 
         or this.IsFullPlanMetaPriorFocus() ) // for performance don't define if we don't have the kpi's in the strategy 
 | 
    { 
 | 
      constfromtargetname := typeof( MPServiceLevelFromTargetConstraint ); 
 | 
      constfromsddetname := typeof( MPFulfillmentTargetFromSDQtyConstraint ); 
 | 
      constfromsdstoname := typeof( MPServiceLevelFromSDQtyConstraint ); 
 | 
       
 | 
      scalefactor_servicelevelqty_constfromtarget := this.ScaleConstraintTerm( typeof( MPFulfillmentTargetVariable ), constfromtargetname ); 
 | 
      scalefactor_servicelevelqty_constfromsd_det := this.ScaleConstraintTerm( typeof( MPFulfillmentTargetVariable ), constfromsddetname ); 
 | 
      scalefactor_servicelevelqty_constfromsd_sto := this.ScaleConstraintTerm( typeof( MPServiceLevelQtyVariable ), constfromsdstoname ); 
 | 
      scalefactor_salesdemandqty_constfromsd_det := this.ScaleConstraintTerm( typeof( MPSalesDemandQtyVariable ), constfromsddetname ); 
 | 
      scalefactor_salesdemandqty_constfromsd_sto := this.ScaleConstraintTerm( typeof( MPSalesDemandQtyVariable ), constfromsdstoname ); 
 | 
       
 | 
      scalefactor_rhs_constfromtarget := this.ScaleConstraintRHS( constfromtargetname, 1.0 ); 
 | 
      scalefactor_rhs_constfromsddet := this.ScaleConstraintRHS( constfromsddetname, 1.0 );  
 | 
      scalefactor_rhs_constfromsdsto := this.ScaleConstraintRHS( constfromsdstoname, 1.0 );  
 | 
       
 | 
      // 
 | 
      // step 1: created constraints 
 | 
      // 
 | 
      slbases := selectset(  this,  
 | 
                             MacroPlan.AllServiceLevelBase,  
 | 
                             sl,  
 | 
                             sl.GetIsInOptimizerRun( scope ) );  
 | 
      traverse( slbases, Elements, sl ) 
 | 
      { 
 | 
        vardummy := program.NewVariable( 'OptimizerConstantTerm', sl ); // workaround for const - cant use attribute 
 | 
        vardummy.Enabled( false );   
 | 
        this.StoreValueInVariable( vardummy, 0.0 );  
 | 
     
 | 
        // If this is a fulfillment goal related service level then add the related constraints 
 | 
        if( sl.IsUsedForPlanningFulfillmentSystem() ) 
 | 
        { 
 | 
          // two constraints are added:  
 | 
          // 
 | 
          // constfromtarget, which specifies the fulfilled quantity(sl) is <= target% * total demand qty (sl)              (*) 
 | 
          // 
 | 
          // constfromsd, which specifies fulfilled quantity (sl) <= total demand qty ( sl) 
 | 
       
 | 
          // constraints to calculate fulfilled part of the fulfillmentgoal 
 | 
          // plannedservicelevel <= target% * sum of sd.Quantity 
 | 
          // const constraint UoM: Default 
 | 
          constfromtarget := program.ServiceLevelFromTargetConstraints().New( sl );  
 | 
          constfromtarget.Sense( '<=' ); 
 | 
       
 | 
          // Term UoM: Default 
 | 
          constfromtarget.NewTerm( 1.0 * scalefactor_servicelevelqty_constfromtarget, program.FulfillmentTargetVariables().Get( sl ) ); 
 | 
       
 | 
          // ServiceLevel <= sum of SalesDemandQty 
 | 
          // const constraint UoM: Default 
 | 
          constfromsd := program.FulfillmentTargetFromSDQtyConstraints().New( sl ); 
 | 
          constfromsd.Sense( '<=' ); 
 | 
          constfromsd.RHSValue( 0.0 ); 
 | 
           
 | 
          // Term UoM: Default 
 | 
          constfromsd.NewTerm( 1.0 * scalefactor_servicelevelqty_constfromsd_det, program.FulfillmentTargetVariables().Get( sl ) ); 
 | 
          constfromsd.Enabled( false ); // enable once we add a term 
 | 
        } 
 | 
        // Else, if this is a inventory optimization related service level, add the related constraints 
 | 
        else if( sl.IsUsedForSafetyStockCalculation() ) 
 | 
        { 
 | 
          // ServiceLevel <= SUM( SalesDemandQty ) + SUM ( DisaggregatedSalesDemandQty ) 
 | 
          // const constraint UoM: Default 
 | 
          constr := program.ServiceLevelFromSDQtyConstraints().New( sl ); 
 | 
          constr.Sense( '<=' ); 
 | 
          constr.RHSValue( 0.0 ); 
 | 
           
 | 
          // Term UoM: Default 
 | 
          constr.NewTerm( 1.0 * scalefactor_servicelevelqty_constfromsd_sto , program.ServiceLevelQtyVariables().Get( sl ) ); 
 | 
          constr.Enabled( false ); // enable once we add a term 
 | 
        } 
 | 
      } 
 | 
       
 | 
      //  
 | 
      // step 2: add terms to constraint 
 | 
      // 
 | 
      //bsdips := selectset(  this, MacroPlan.SalesDemand.AsMasterSalesDemand, bsdip, true, true );  
 | 
      bsdips := selectset(  leafpispipsinrun,  
 | 
                            Elements.PlanningBaseSalesDemandInPeriodForOptimization, 
 | 
                            bsdip,  
 | 
                            true,  
 | 
                            not bsdip.MasterSalesDemand().IsExcludedFromFulfillmentKPI() );   
 | 
      this.AddTermsToServiceLevelConstraints( program, 
 | 
                                              bsdips, 
 | 
                                              scalefactor_salesdemandqty_constfromsd_det, 
 | 
                                              scalefactor_salesdemandqty_constfromsd_sto, 
 | 
                                              scope ); 
 | 
      // step 3: set computed rhs for constraint 
 | 
      traverse( slbases, Elements, sl )  
 | 
      { 
 | 
        opt_constant_term := program.Variable( 'OptimizerConstantTerm', sl ).UpperBound(); // workaround because cannot write to attribute  
 | 
        outofscopequantity := sl.TotalFulfilledQuantity() - opt_constant_term; // latter term set in AddTermsToServiceLevelConstraint 
 | 
        if( sl.IsUsedForPlanningFulfillmentSystem() ) 
 | 
        { 
 | 
          constfromtarget := program.ServiceLevelFromTargetConstraints().Get( sl );  
 | 
          desiredservicelevelpercentage := sl.TargetPercentage(); 
 | 
          rhsfromtarget := maxvalue( 0.0, sl.TotalDemandQuantity() * ( desiredservicelevelpercentage / 100.0 ) );   //prevent negative goal 
 | 
          // RHS UoM: Default 
 | 
          constfromtarget.RHSValue( rhsfromtarget * scalefactor_rhs_constfromtarget ); // poses the upper bound mentioned in (*)  
 | 
           
 | 
          constrfromsd := program.FulfillmentTargetFromSDQtyConstraints().Get( sl );  
 | 
     
 | 
          newrhs := this.GetConstraintRHS( constrfromsd, scalefactor_rhs_constfromsddet ) + outofscopequantity; // variable is added on the right, so we *add* constantterm to the RHS 
 | 
          constrfromsd.RHSValue( newrhs * scalefactor_rhs_constfromsddet ); 
 | 
        } 
 | 
        else 
 | 
        { 
 | 
          constr := program.ServiceLevelFromSDQtyConstraints().Get( sl );  
 | 
          newrhs := this.GetConstraintRHS( constr, scalefactor_rhs_constfromsdsto ) + outofscopequantity; // variable is added on the right, so we *add* constantterm to the RHS 
 | 
          constr.RHSValue( newrhs * scalefactor_rhs_constfromsdsto ); 
 | 
        } 
 | 
      } 
 | 
    } 
 | 
  *] 
 | 
  InterfaceProperties { Accessibility: 'Module' } 
 | 
} 
 |