| 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' } | 
| } |