Quintiq file version 2.0 
 | 
#parent: #root 
 | 
Method InitConstraintsForInventorySpecificationHighLevel ( 
 | 
  CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program, 
 | 
  const LibOpt_Scope scope, 
 | 
  const RunContextForCapacityPlanning runcontext, 
 | 
  const constcontent ProductInStockingPointInPeriodPlannings pispipsinrun 
 | 
) const 
 | 
{ 
 | 
  Description: 'adds constraints for inventory target and minimum inventory, for high level products that are aggregates over lower level products' 
 | 
  TextBody: 
 | 
  [* 
 | 
    // These are high level constraints, so leaf pisps should not be considered 
 | 
     
 | 
    targetconstname := typeof( MPTargetInventoryLevelConstraint ); 
 | 
    minconstname := typeof( MPMinInventoryLevelConstraint ); 
 | 
    maxconstname := typeof( MPMaxInventoryLevelConstraint ); 
 | 
      
 | 
    scalefactor_invqtyundertarget_targetconst := this.ScaleConstraintTerm( typeof( MPInvQtyUnderTargetVariable ), targetconstname ); 
 | 
    scalefactor_mininvqtyunder_minconst := this.ScaleConstraintTerm( typeof( MPMinInvQtyUnderVariable ), minconstname ); 
 | 
    scalefactor_maxinvqtyover_maxconst := this.ScaleConstraintTerm( typeof( MPMaxInvQtyOverVariable ), maxconstname ); 
 | 
     
 | 
    scalefactor_rhs_targetconst := this.ScaleConstraintRHS( targetconstname, 1.0 ); 
 | 
    scalefactor_rhs_minconst := this.ScaleConstraintRHS( minconstname, 1.0 ); 
 | 
    scalefactor_rhs_maxconst := this.ScaleConstraintRHS( maxconstname, 1.0 ); 
 | 
     
 | 
    demandfulfillmentinpispip_varname := typeof( MPDemandFulfillmentInPISPIPVariable ); 
 | 
    demandfulfillmentinpispip_constrname := typeof( MPDemandFulfillmentInPISPIPConstraint ); 
 | 
    // Get scaling factors. For performance we dont want to recompute this for each pispip  
 | 
    scalefactor_demandfulfillmentinpispip_constr := this.ScaleConstraintTerm( demandfulfillmentinpispip_varname, demandfulfillmentinpispip_constrname ); 
 | 
    scalefactor_rhs_constr := this.ScaleConstraintRHS( demandfulfillmentinpispip_constrname, 1.0 ); 
 | 
     
 | 
    scalefactor_invqty_constr_targetconst := this.ScaleConstraintTerm( typeof( MPInvQtyVariable ), targetconstname ); 
 | 
    scalefactor_rhs_constr_targetconst := this.ScaleConstraintRHS( targetconstname, 1.0 ); 
 | 
     
 | 
    scalefactor_invqty_constr_minconst := this.ScaleConstraintTerm( typeof( MPInvQtyVariable ), minconstname ); 
 | 
    scalefactor_rhs_constr_minconst := this.ScaleConstraintRHS( minconstname, 1.0 ); 
 | 
     
 | 
    scalefactor_invqty_constr_maxconst := this.ScaleConstraintTerm( typeof( MPInvQtyVariable ), maxconstname ); 
 | 
    scalefactor_rhs_constr_maxconst := this.ScaleConstraintRHS( maxconstname, 1.0 ); 
 | 
     
 | 
    leafpispips := null( ProductInStockingPointInPeriodPlannings, constcontent, owning ); 
 | 
    pispips := this.GetPISPIPsForInventorySpecifications( scope, false, &leafpispips  ) 
 | 
    traverse( pispips, Elements.astype( ProductInStockingPointInPeriodPlanningNonLeaf ), pispip, not pispip.IsLeafPlanning() ) 
 | 
    { 
 | 
      // Penalty of not fulfilling the target 
 | 
      if( pispip.GetHasTargetInventory()  
 | 
          and (pispip.GetHasTargetInDays() or scope.Contains( pispip.PISPIPInOptimizerRun() ) ) ) 
 | 
      { 
 | 
        rhs := ifexpr( not pispip.GetHasTargetInDays(), pispip.TargetInQuantity(), 0.0 );  // If specified in days, the target inventory is calculated based on next period demand fulfillment 
 | 
        // targetconst constraint UoM: target PISP 
 | 
        targetconst := program.TargetInventoryLevelConstraints().New( pispip ); 
 | 
        // RHS UoM: target PISP 
 | 
        targetconst.RHSValue( rhs * scalefactor_rhs_targetconst ); 
 | 
        targetconst.Sense( '>=' ); 
 | 
         // Term UoM: SP 
 | 
        targetconst.NewTerm( 1.0 * scalefactor_invqtyundertarget_targetconst, program.InvQtyUnderTargetVariables().Get( pispip ) ); 
 | 
        // sum of inventory quantity of active pispips 
 | 
        this.AddTermsToInventorySpecificationHighLevelConstraint( program, targetconst, pispip, scope, scalefactor_invqty_constr_targetconst, scalefactor_rhs_constr_targetconst ); 
 | 
      } 
 | 
     
 | 
      // Penalty of not reaching the minimum inventory level 
 | 
      if( pispip.GetHasMinLevel() 
 | 
          and ( pispip.InventorySpecification().HasMinLevelInDays() or scope.Contains( pispip.PISPIPInOptimizerRun()  ) ) ) 
 | 
      { 
 | 
        rhs := ifexpr( not pispip.GetHasMinLevelInDays(), pispip.MinLevelInQuantity(), 0.0 );  // If specified in days, the target inventory is calculated based on next period demand fulfillment 
 | 
        // minconst constraint UoM: target PISP 
 | 
        minconst := program.MinInventoryLevelConstraints().New( pispip ); 
 | 
        minconst.Sense( '>=' ); 
 | 
        // RHS UoM: target PISP 
 | 
        minconst.RHSValue( rhs * scalefactor_rhs_minconst ); 
 | 
        // Term UoM: target PISP 
 | 
        minconst.NewTerm( 1.0 * scalefactor_mininvqtyunder_minconst, program.MinInvQtyUnderVariables().Get( pispip ) ); 
 | 
        // sum of inventory quantity of active pispips 
 | 
        this.AddTermsToInventorySpecificationHighLevelConstraint( program, minconst, pispip, scope, scalefactor_invqty_constr_minconst, scalefactor_rhs_constr_minconst ); 
 | 
      } 
 | 
       
 | 
      // Penalty of exceeding the maximum inventory level 
 | 
      if( pispip.GetHasMaxLevel()  
 | 
          and ( pispip.InventorySpecification().HasMaxLevelInDays() or scope.Contains( pispip.PISPIPInOptimizerRun() ) ) ) 
 | 
      { 
 | 
        rhs := ifexpr( not pispip.GetHasMaxLevelInDays(), pispip.MaxLevelInQuantity(), 0.0 );  // If specified in days, the target inventory is calculated based on next period demand fulfillment 
 | 
        // maxconst constraint UoM: target PISP 
 | 
        maxconst := program.MaxInventoryLevelConstraints().New( pispip ); 
 | 
        maxconst.Sense( '<=' ); 
 | 
        // RHS UoM: target PISP 
 | 
        maxconst.RHSValue( rhs * scalefactor_rhs_maxconst ); 
 | 
        // Term UoM: target PISP 
 | 
        maxconst.NewTerm( -1.0 * scalefactor_maxinvqtyover_maxconst, program.MaxInvQtyOverVariables().Get( pispip ) ); 
 | 
        // sum of inventory quantity of active pispips 
 | 
        this.AddTermsToInventorySpecificationHighLevelConstraint( program, maxconst, pispip, scope, scalefactor_invqty_constr_maxconst, scalefactor_rhs_constr_maxconst ); 
 | 
      } 
 | 
       
 | 
      // For inventory specifications in days, add terms for the target / min / max inventory level 
 | 
      // based on the fulfilled sales demands and dependent demands on next periods 
 | 
      this.AddTermsToInventorySpecificationConstraints( program, pispip, scope, scalefactor_demandfulfillmentinpispip_constr, scalefactor_rhs_constr ); 
 | 
    } 
 | 
  *] 
 | 
  InterfaceProperties { Accessibility: 'Module' } 
 | 
} 
 |