| Quintiq file version 2.0 | 
| #parent: #root | 
| Method InitConstraintsForInventorySpecification ( | 
|   CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program, | 
|   const LibOpt_Scope scope, | 
|   const RunContextForCapacityPlanning runcontext, | 
|   const constcontent ProductInStockingPointInPeriodPlannings pispipsinrun | 
| ) const | 
| { | 
|   Description: 'The constraint for target inventory on the active pispip' | 
|   TextBody: | 
|   [* | 
|      | 
|     targetconstname := typeof( MPTargetInventoryLevelConstraint ); | 
|     minconstname := typeof( MPMinInventoryLevelConstraint ); | 
|     maxconstname := typeof( MPMaxInventoryLevelConstraint ); | 
|      | 
|     scalefactor_targetinvqty_targetconst := this.ScaleConstraintTerm( typeof( MPTargetInvQtyVariable ), targetconstname ); | 
|     scalefactor_invqtyundertarget_targetconst := this.ScaleConstraintTerm( typeof( MPInvQtyUnderTargetVariable ), targetconstname ); | 
|     scalefactor_invqty_minconst := this.ScaleConstraintTerm( typeof( MPTargetInvQtyVariable ), minconstname ); | 
|     scalefactor_mininvqtyunder_minconst := this.ScaleConstraintTerm( typeof( MPMinInvQtyUnderVariable ), minconstname ); | 
|     scalefactor_invqty_maxconst := this.ScaleConstraintTerm( typeof( MPTargetInvQtyVariable ), maxconstname ); | 
|     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 ); | 
|      | 
|     leafpispips := null( ProductInStockingPointInPeriodPlannings, constcontent, owning ); | 
|     pispips := this.GetPISPIPsForInventorySpecifications( scope, true, &leafpispips ); | 
|     traverse( pispips, Elements.astype( ProductInStockingPointInPeriodPlanningLeaf ), pispip ) | 
|     { | 
|       // Penalty of not fulfilling the target | 
|       if( pispip.GetTargetUnderDefined( scope, runcontext ) ) | 
|       { | 
|         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: PISP | 
|         targetconst := program.TargetInventoryLevelConstraints().New( pispip ); | 
|         targetconst.Sense( '=' ); | 
|      | 
|         // Term UoM: PISP | 
|         if ( scope.Contains( pispip.PISPIPInOptimizerRun() ) )  | 
|         { | 
|           targetconst.NewTerm( 1.0 * scalefactor_targetinvqty_targetconst, program.TargetInvQtyVariables().Get( pispip ) ); | 
|         } | 
|         else // pispips is prior to scope, but still needs to be considered because it has a target in days that is affected | 
|         { | 
|           targetconst.Sense( '>=' );  | 
|           rhs := rhs - pispip.InventoryLevelEnd();   | 
|         } | 
|         // Term UoM: PISP | 
|         targetconst.NewTerm( 1.0 * scalefactor_invqtyundertarget_targetconst, program.InvQtyUnderTargetVariables().Get( pispip ) ); | 
|          | 
|         // RHS UoM: PISP | 
|         targetconst.RHSValue( rhs * scalefactor_rhs_targetconst ); | 
|       } | 
|      | 
|       // Penalty of not reaching the minimum inventory level | 
|       if( pispip.GetMinUnderDefined( scope, runcontext ) )  | 
|       { | 
|         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: PISP | 
|         minconst := program.MinInventoryLevelConstraints().New( pispip ); | 
|         minconst.Sense( '>=' ); | 
|         // Term UoM: PISP | 
|         if ( scope.Contains( pispip.PISPIPInOptimizerRun() ) )  | 
|         { | 
|           minconst.NewTerm( 1.0 * scalefactor_invqty_minconst, program.InvQtyVariables().Get( pispip ) ); | 
|         } | 
|         else  | 
|         { | 
|           rhs := rhs - pispip.InventoryLevelEnd();  | 
|         } | 
|         // Term UoM: PISP | 
|         minconst.NewTerm( 1.0 * scalefactor_mininvqtyunder_minconst, program.MinInvQtyUnderVariables().Get( pispip ) ); | 
|      | 
|         // RHS UoM: PISP | 
|         minconst.RHSValue( rhs * scalefactor_rhs_minconst ); | 
|       } | 
|      | 
|       // Penalty of exceeding the maximum inventory level | 
|       if( pispip.GetMaxOverDefined( scope, runcontext ) ) | 
|       { | 
|         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: PISP | 
|         maxconst := program.MaxInventoryLevelConstraints().New( pispip ); | 
|         maxconst.Sense( '<=' ); | 
|          | 
|         // Term UoM: PISP | 
|         if ( scope.Contains( pispip.PISPIPInOptimizerRun() ) )  | 
|         { | 
|           maxconst.NewTerm( 1.0 * scalefactor_invqty_maxconst, program.InvQtyVariables().Get( pispip ) ); | 
|         } | 
|         else  | 
|         { | 
|           rhs := rhs - pispip.InventoryLevelEnd();    | 
|         } | 
|         // Term UoM: PISP | 
|         maxconst.NewTerm( -1.0 * scalefactor_maxinvqtyover_maxconst, program.MaxInvQtyOverVariables().Get( pispip ) ); | 
|      | 
|         // RHS UoM: PISP | 
|         maxconst.RHSValue( rhs * scalefactor_rhs_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 | 
|         // Get variable names | 
|       demandfulfillmentinpispip_varname := typeof( MPDemandFulfillmentInPISPIPVariable ); | 
|       // Get constraint namea | 
|       demandfulfillmentinpispip_constrname := typeof( MPDemandFulfillmentInPISPIPConstraint ); | 
|       // Get scaling factors - for performance we dont want to recompute for each pispip | 
|       scalefactor_demandfulfillmentinpispip_constr := this.ScaleConstraintTerm( demandfulfillmentinpispip_varname, demandfulfillmentinpispip_constrname ); | 
|       scalefactor_rhs_constr := this.ScaleConstraintRHS( demandfulfillmentinpispip_constrname, 1.0 ); | 
|       this.AddTermsToInventorySpecificationConstraints( program, pispip, scope, scalefactor_demandfulfillmentinpispip_constr, scalefactor_rhs_constr ); | 
|     } | 
|   *] | 
|   InterfaceProperties { Accessibility: 'Module' } | 
| } |