| Quintiq file version 2.0 | 
| #parent: #root | 
| Method InitConstraintsForSupplySpecifications ( | 
|   CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program, | 
|   const RunContextForCapacityPlanning runcontext, | 
|   const LibOpt_Scope scope | 
| ) const | 
| { | 
|   Description: 'The constraint to calculate deviation of supply specification' | 
|   TextBody: | 
|   [* | 
|     if( runcontext.UseSupplySpecification() ) | 
|     { | 
|       targetconstname := typeof( MPSupplyTargetConstraint ); | 
|       minconstname := typeof( MPMinSupplyConstraint ); | 
|       maxconstname := typeof( MPMaxSupplyConstraint ); | 
|      | 
|       scalefactor_supplytargetqtyunder_targetconst := this.ScaleConstraintTerm( typeof( MPSupplyTargetQtyUnderVariable ), targetconstname ); | 
|       scalefactor_minsupplyqtyunder_minconst := this.ScaleConstraintTerm( typeof( MPMinSupplyQtyUnderVariable ), minconstname ); | 
|       scalefactor_maxsupplyqtyover_maxconst := this.ScaleConstraintTerm( typeof( MPMaxSupplyQtyOverVariable ), maxconstname ); | 
|       scalefactor_tripnewsupply_targetconst := this.ScaleConstraintTerm( typeof( MPTripNewSupplyVariable ), targetconstname ); | 
|       scalefactor_tripnewsupply_minconst := this.ScaleConstraintTerm( typeof( MPTripNewSupplyVariable ), minconstname ); | 
|       scalefactor_tripnewsupply_maxconst := this.ScaleConstraintTerm( typeof( MPTripNewSupplyVariable ), maxconstname ); | 
|       scalefactor_periodtaskqty_targetconst := this.ScaleConstraintTerm( typeof( MPPTQtyVariable ), targetconstname ); | 
|       scalefactor_periodtaskqty_minconst := this.ScaleConstraintTerm( typeof( MPPTQtyVariable ), minconstname ); | 
|       scalefactor_periodtaskqty_maxconst := this.ScaleConstraintTerm( typeof( MPPTQtyVariable ), 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 ); | 
|        | 
|       // The supply specification should only be considered if at least one unit in this optimizer runs influences this supply specification | 
|       traverse( this.MacroPlan().GetUnitsConst(), Elements.SupplySpecification, supplyspec, | 
|                 exists( supplyspec, Unit.AllChildren.AsChildren, unit, | 
|                         scope.Contains( unit.UnitInOptimizerRun()) ) ) | 
|       { | 
|         //penalty of not reaching the target quantity of the supply specification | 
|         // targetconst constraint UoM: Unit | 
|         targetconst := program.SupplyTargetConstraints().New( supplyspec ); | 
|         targetconst.Sense( ">=" ); | 
|         // RHS UoM: Unit | 
|         targetconst.RHSValue( supplyspec.TargetQuantity() * scalefactor_rhs_targetconst ); | 
|         // Term UoM: Unit | 
|         targetconst.NewTerm( scalefactor_supplytargetqtyunder_targetconst, | 
|                              program.SupplyTargetQtyUnderVariables().Get( supplyspec ) ); | 
|      | 
|         //penalty of not reaching the minimum quantity of the supply specification | 
|         // minconst constraint UoM: Unit | 
|         minconst := program.MinSupplyConstraints().New( supplyspec ); | 
|         minconst.Sense( ">=" ); | 
|         // RHS UoM: Unit | 
|         minconst.RHSValue( supplyspec.MinQuantity() * scalefactor_rhs_minconst ); | 
|         // Term UoM: Unit | 
|         minconst.NewTerm( scalefactor_minsupplyqtyunder_minconst, | 
|                           program.MinSupplyQtyUnderVariables().Get( supplyspec ) ); | 
|      | 
|         //penalty of exceeding the maximum quantity of the supply specification | 
|         // maxconst constraint UoM: Unit | 
|         maxconst := program.MaxSupplyConstraints().New( supplyspec ); | 
|         maxconst.Sense( "<=" ); | 
|         // RHS UoM: Unit | 
|         maxconst.RHSValue( supplyspec.MaxQuantity() * scalefactor_rhs_maxconst ); | 
|         // Term UoM: Unit | 
|         maxconst.NewTerm( -1.0 * scalefactor_maxsupplyqtyover_maxconst, | 
|                           program.MaxSupplyQtyOverVariables().Get( supplyspec ) ); | 
|      | 
|         if ( supplyspec.HasRegularProductForOptimizer() or supplyspec.Product_MP().GetIsInOptimizerRun( runcontext.IsPostProcessing() ) )  | 
|         { | 
|           traverse( supplyspec.GetProductInStockingPointInPeriodsConst(), Elements.astype( ProductInStockingPointInPeriodPlanning ), pispip,   | 
|                     scope.Contains( pispip.PISPIPInOptimizerRun() ) )  | 
|           { | 
|             // Operations | 
|             traverse( pispip, ProductInStockingPoint_MP.OperationOutputAvailableForOptimization, output, | 
|                       output.Operation().Unit().IsIncludedInSupplySpecification()       // unit is included in the supply specification | 
|                       and supplyspec.Unit().IsParent( output.Operation().Unit() ) )     // unit is the descendant of target unit | 
|             { | 
|               uomconversion := output.UnitConversionFactor(); | 
|               // Term:   uomconversion    *       factor        * PTQty variable | 
|               // UoM: [Output PISP to Unit] * [Unit to Output PISP] *     [Unit]  | 
|               this.AddConstraintForOperationNewSupplies( output, pispip.Period_MP(), null( Period_MP ), program, uomconversion, targetconst, scalefactor_periodtaskqty_targetconst, scope ); | 
|               this.AddConstraintForOperationNewSupplies( output, pispip.Period_MP(), null( Period_MP ), program, uomconversion, minconst, scalefactor_periodtaskqty_minconst, scope ); | 
|        | 
|               if( supplyspec.HasMaxQuantity() ) | 
|               { | 
|                 // Term:   uomconversion    *       factor        * PTQty variable | 
|                 // UoM: [Output PISP to Unit] * [Unit to Output PISP] *     [Unit] | 
|                 this.AddConstraintForOperationNewSupplies( output, pispip.Period_MP(), null( Period_MP ), program, uomconversion, maxconst, scalefactor_periodtaskqty_maxconst, scope ); | 
|               } | 
|             } | 
|        | 
|             // Trips | 
|             traverse( pispip, astype( ProductInStockingPointInPeriodPlanningLeaf ).NewSupply.ProductInTrip, productintrip,  | 
|                       scope.Contains( productintrip.ProductInTripInOptimizerRun() )  | 
|                       and productintrip.Trip().LaneLeg().Lane().Unit().IsIncludedInSupplySpecification() | 
|                       and supplyspec.Unit().IsParent( productintrip.Trip().LaneLeg().Lane().Unit() ) ) | 
|             { | 
|                | 
|               uomconversion := productintrip.UnitConversionFactor(); | 
|               // Term:   uomconversion    *  TripNewSupply variable | 
|               // UoM: [Output PISP to Unit] *       [Output PISP] | 
|               targetconst.NewTerm( uomconversion * scalefactor_tripnewsupply_targetconst, program.TripNewSupplyVariables().Get( productintrip ) ); | 
|               minconst.NewTerm( uomconversion * scalefactor_tripnewsupply_minconst, program.TripNewSupplyVariables().Get( productintrip ) ); | 
|        | 
|               if( supplyspec.HasMaxQuantity() ) | 
|               { | 
|                 // Term:   uomconversion    *  TripNewSupply variable | 
|                 // UoM: [Output PISP to Unit] *       [Output PISP] | 
|                 maxconst.NewTerm( uomconversion * scalefactor_tripnewsupply_maxconst, program.TripNewSupplyVariables().Get(  productintrip ) ); | 
|               } | 
|             } | 
|           } | 
|         } | 
|          | 
|          | 
|         // Update the RHS based on those Period Tasks that cannot be influenced by the optimizer | 
|         // These Period Tasks either do not have a PTQty variable or their trip is not part of the optimizer run | 
|         periodtaskcorrections := construct( PeriodTask_MPs, constcontent );  | 
|         traverse( supplyspec.GetProductInStockingPointInPeriodsConst(),  | 
|                   Elements.astype( ProductInStockingPointInPeriodPlanningLeaf ).NewSupply,  | 
|                   ns,  | 
|                   ns.PeriodTask_MP().Process_MP().AsProcess_MP().IsIncludedInSupplySpecification()  | 
|                   and supplyspec.Unit().IsParent( ns.PeriodTask_MP().UnitPeriod().Unit() ) | 
|                   )  | 
|         { | 
|           uomconversion := 1.0;  | 
|           pt_inscope := true;  | 
|           if ( ns.IsNewSupplyOfOperation() | 
|                and not scope.Contains( ns.PeriodTaskOperation().PeriodTaskOperationInOptimizerRun() ) ) | 
|           { | 
|             periodtaskcorrections.Add(  ns.PeriodTask_MP() );  | 
|             operationoutput := ns.ProcessOutput().astype(  OperationOutput );  | 
|             uomconversion := operationoutput.UnitConversionFactor();       | 
|             pt_inscope := false;                                       | 
|                                          | 
|           } | 
|           if ( ns.PeriodTask_MP().istype( PeriodTaskLaneLeg )  | 
|                and not scope.Contains( ns.PeriodTask_MP().astype( PeriodTaskLaneLeg ).Trip().TripInOptimizerRun() ) ) | 
|           { | 
|             periodtaskcorrections.Add( ns.PeriodTask_MP() );   | 
|             uomconversion := ns.ProductInTrip().UnitConversionFactor();   | 
|             pt_inscope := false;  | 
|           } | 
|            | 
|           if ( not pt_inscope )  | 
|           { | 
|             nsqty := ns.Quantity();  | 
|              | 
|             // RHS UoM: Unit | 
|             targetrhs := this.GetConstraintRHS( targetconst, scalefactor_rhs_targetconst ) - nsqty * uomconversion; | 
|             targetconst.RHSValue( targetrhs * scalefactor_rhs_targetconst ); | 
|        | 
|             minrhs := this.GetConstraintRHS( minconst, scalefactor_rhs_minconst ) - nsqty * uomconversion; | 
|             minconst.RHSValue( minrhs * scalefactor_rhs_minconst ); | 
|        | 
|             if( supplyspec.HasMaxQuantity() ) | 
|             { | 
|               maxrhs := this.GetConstraintRHS( maxconst, scalefactor_rhs_maxconst ) - nsqty * uomconversion; | 
|               maxconst.RHSValue( maxrhs * scalefactor_rhs_maxconst ); | 
|             } | 
|           } | 
|         } | 
|       } | 
|     } | 
|   *] | 
|   InterfaceProperties { Accessibility: 'Module' } | 
| } |