| Quintiq file version 2.0 | 
| #parent: #root | 
| Method InitConstraintsForCampaignPTQtyTransitionTotal ( | 
|   CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program, | 
|   const LibOpt_Scope scope | 
| ) const | 
| { | 
|   TextBody: | 
|   [* | 
|     totalptconstname := typeof( MPPTQtyCampaignsTotalConstraint ); | 
|      | 
|     scalefactor_periodtaskqty_totalptconst := this.ScaleConstraintTerm( typeof( MPPTQtyVariable ), totalptconstname ); | 
|     scalefactor_PTQtyInCampaignElementTypeStart_totalptconst := this.ScaleConstraintTerm( typeof( MPPTQtyInCampaignElementTypeStartVariable ), totalptconstname ); | 
|     scalefactor_PTQtyInCampaignElementTypeMid_totalptconst := this.ScaleConstraintTerm( typeof( MPPTQtyInCampaignElementTypeMidVariable ), totalptconstname ); | 
|     scalefactor_PTQtyInCampaignElementTypeEnd_totalptconst := this.ScaleConstraintTerm( typeof( MPPTQtyInCampaignElementTypeEndVariable ), totalptconstname ); | 
|     scalefactor_PTQtyInCampaignSlack_totalptconst := this.ScaleConstraintTerm( typeof( MPPTQtyInCampaignSlackVariable ), totalptconstname ); | 
|      | 
|     scalefactor_rhs_totalptconst := this.ScaleConstraintRHS( totalptconstname, 1.0 ); | 
|      | 
|     nrlogged := 0; // keep upper bound on log info | 
|     nrcreatedslackvar := 0;  | 
|     traverse( scope.GetUnitInOptimizerRunConst(), Elements.Operation, operation, | 
|               operation.OperationInCampaignType( relsize ) > 0  | 
|               or operation.OperationInTransitionType( relsize ) > 0 ) | 
|     { | 
|       // Only select those periods that are relevant for this operation for the optimizer run | 
|       periods := this.GetPeriodsForOperation( scope, operation ); | 
|      | 
|       traverse( periods, Elements, period, | 
|                 period.GetIsInCampaignTypeHorizonUnit( operation.Unit() ) ) | 
|       { | 
|         // total quantity planned in different campaign (pt in campaign) and transitions ( pt in transition) must match period task quantity | 
|         // Totalptconst constraint UoM: Unit | 
|         totalptconst := program.PTQtyCampaignsTotalConstraints().New( operation, period ); | 
|         totalptconst.Sense( '=' ); | 
|         totalptconst.RHSValue( 0.0 * scalefactor_rhs_totalptconst ); | 
|      | 
|         // Term UoM: Unit | 
|         varptqty := program.PTQtyVariables().Find( operation, period );  | 
|         if ( not isnull( varptqty ) )  | 
|         { | 
|           totalptconst.NewTerm( -1.0 * scalefactor_periodtaskqty_totalptconst, program.PTQtyVariables().Get( operation, period ) ); | 
|         } | 
|         else | 
|         { | 
|           newrhsval := guard( PeriodTaskOperation::FindPeriodTaskOperationTypeIndex( period.Start(), operation.ID() ).Quantity(), 0.0 ) | 
|           totalptconst.RHSValue( scalefactor_rhs_totalptconst * newrhsval );   | 
|         } | 
|          | 
|         nrtripletermsadded := 0;  | 
|         traverse( period, UnitPeriod.OptCampaignUnitSubPeriod, optsubperiod, guard( optsubperiod.UnitPeriod().GetIsWithinCampaignHorizonConstraint(), false ) and optsubperiod.UnitPeriod().Unit() = operation.Unit() ) | 
|         { | 
|           traverse( optsubperiod, OptCampaignCombiElementActive.OptCampaignElementType.OptCampaignOperationInElementType, oiet, oiet.Operation() = operation )  | 
|           { | 
|               totalptconst.NewTerm( 1.0 * scalefactor_PTQtyInCampaignElementTypeStart_totalptconst, program.PTQtyInCampaignElementTypeStartVariables().Get( oiet, optsubperiod ) );  | 
|               totalptconst.NewTerm( 1.0 * scalefactor_PTQtyInCampaignElementTypeMid_totalptconst, program.PTQtyInCampaignElementTypeMidVariables().Get( oiet, optsubperiod ) );  | 
|               totalptconst.NewTerm( 1.0 * scalefactor_PTQtyInCampaignElementTypeEnd_totalptconst, program.PTQtyInCampaignElementTypeEndVariables().Get( oiet, optsubperiod ) );  | 
|               nrtripletermsadded++;  | 
|           } | 
|         } | 
|         if ( nrtripletermsadded = 0 ) // don't apply restriction on PTQty if combis subset has no coverage | 
|         { | 
|           pto := PeriodTaskOperation::FindPeriodTaskOperationTypeIndex( period.Start(), operation.ID() );  | 
|           if ( not guard( pto.Quantity() = 0, false ) ) | 
|           { | 
|             if ( nrlogged <= 10 )  | 
|             { | 
|               nrlogged++;  | 
|               debuginfo(  'Creating pt in campaign slack var', period.Start(), operation.ID() );  | 
|             } | 
|             nrcreatedslackvar++;  | 
|             varslack := program.PTQtyInCampaignSlackVariables().New(  operation, period );  | 
|             totalptconst.NewTerm( 1.0 * scalefactor_PTQtyInCampaignSlack_totalptconst, varslack );  | 
|           } | 
|         } | 
|       }  | 
|     } | 
|     program.StoreReal( CapacityPlanningSuboptimizer::LoggedNrPTQtyCampaignSlackVarName(), [Real]nrcreatedslackvar );  | 
|     debuginfo(  'Nr created pt in campaign slack var:', nrcreatedslackvar ); | 
|   *] | 
|   InterfaceProperties { Accessibility: 'Module' } | 
| } |