Quintiq file version 2.0 
 | 
#parent: #root 
 | 
Method InitConstraintsForUserTotalSupply ( 
 | 
  CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program, 
 | 
  const RunContextForCapacityPlanning runcontext, 
 | 
  const LibOpt_Scope scope, 
 | 
  const constcontent ProductInStockingPointInPeriodPlannings pispipsinrun 
 | 
) const 
 | 
{ 
 | 
  Description: 
 | 
  [* 
 | 
    Initialize the constraint related to the total (user) supply in a base PISPIP 
 | 
    This constraint is used in the Smart plan functionality. 
 | 
  *] 
 | 
  TextBody: 
 | 
  [* 
 | 
    // For each PISPIP, if it has a total user supply and it should be considered in this run 
 | 
    // Then the sum of all supply into this pispip ( Inventory Supply, TripNewSupply, OperationNewSupply and InvQty of the previous period) 
 | 
    // should be equal to the total supply user 
 | 
     
 | 
    if( runcontext.GetConsiderTotalUserSupply( scope ) ) 
 | 
    { 
 | 
      pispipsforconstraint := runcontext.GetPISPISPForUserSupplyConstraint( scope, pispipsinrun );  
 | 
       
 | 
      constrname := typeof( MPUserTotalSupplyConstraint ); 
 | 
       
 | 
      scalefactor_invqty_constr := this.ScaleConstraintTerm( typeof( MPInvQtyVariable ), constrname ); 
 | 
      scalefactor_tripnewsupply_constr := this.ScaleConstraintTerm( typeof( MPTripNewSupplyVariable ), constrname ); 
 | 
      scalefactor_usertotalsupplyover_constr := this.ScaleConstraintTerm( typeof( MPUserTotalSupplyOverVariable ), constrname ); 
 | 
      scalefactor_usertotalsupplyunder_constr := this.ScaleConstraintTerm( typeof( MPUserTotalSupplyUnderVariable ), constrname ); 
 | 
      scalefactor_periodtaskqty_constr := this.ScaleConstraintTerm( typeof( MPPTQtyVariable ), constrname ); 
 | 
       
 | 
      scalefactor_rhs_constr := this.ScaleConstraintRHS( constrname, 1.0 ); 
 | 
       
 | 
      traverse( pispipsforconstraint, Elements, pispip )  
 | 
      { 
 | 
        // constr constraint UoM: PISP 
 | 
        constr := program.UserTotalSupplyConstraints().New( pispip ); 
 | 
        constr.Sense( '=' ); 
 | 
       
 | 
        rhs := pispip.TotalSupplyUser() - pispip.InventorySupplyQuantity(); 
 | 
        // RHS UoM: PISP 
 | 
        constr.RHSValue( rhs * scalefactor_rhs_constr ); 
 | 
       
 | 
        previouspispip := pispip.PreviousPlanningPISPIP(); 
 | 
       
 | 
        // Inventory end of the previous period 
 | 
        if( not isnull( previouspispip ) ) 
 | 
          { 
 | 
          // If the previous pipsip is part of the optimizer run, add the inventory quantity variable to the constraint 
 | 
          if( scope.Contains( previouspispip.PISPIPInOptimizerRun() ) ) 
 | 
          { 
 | 
            // Term UoM: PISP 
 | 
            constr.NewTerm( scalefactor_invqty_constr, 
 | 
                            program.InvQtyVariables().Get( previouspispip ) ); 
 | 
            if ( pispip.ProductInStockingPoint_MP().IsOptShelfLife() )  
 | 
            { 
 | 
              constr.NewTerm( -scalefactor_invqty_constr, program.ExpiredVariables().Get( pispip ) );  
 | 
            }                         
 | 
          } 
 | 
          // Otherwise update the RHS to include the frozen inventory end 
 | 
          else 
 | 
          { 
 | 
            newrhs := this.GetConstraintRHS( constr, scalefactor_rhs_constr ) - previouspispip.InventoryLevelEnd(); 
 | 
            constr.RHSValue( newrhs * scalefactor_rhs_constr ); 
 | 
          } 
 | 
        } 
 | 
       
 | 
        // New supplies from trips 
 | 
        traverse( pispip, astype(ProductInStockingPointInPeriodPlanningLeaf ).NewSupply.ProductInTrip, productintrip ) 
 | 
        { 
 | 
          // If the productintrip is part of the optimizer run, add its tripnewsupply quantity variable to the constraint 
 | 
          if( scope.Contains( productintrip.ProductInTripInOptimizerRun() ) )  
 | 
          { 
 | 
            // Term UoM: Output PISP 
 | 
            constr.NewTerm( scalefactor_tripnewsupply_constr, program.TripNewSupplyVariables().Get( productintrip ) ); 
 | 
          } 
 | 
          // Otherwise update the RHS with the frozen productintrip supply quantity 
 | 
          else 
 | 
          { 
 | 
            newrhs := this.GetConstraintRHS( constr, scalefactor_rhs_constr ) - productintrip.Quantity(); 
 | 
            constr.RHSValue( newrhs * scalefactor_rhs_constr ); 
 | 
          } 
 | 
        } 
 | 
       
 | 
        // New supplies from operations 
 | 
        traverse( pispip, ProductInStockingPoint_MP.OperationOutputAvailableForOptimization, output ) 
 | 
        { 
 | 
          // Term UoM: Output PISP 
 | 
          this.AddConstraintForOperationNewSupplies( output, pispip.Period_MP(), null( Period_MP ), 
 | 
                                                     program, 1.0, constr, scalefactor_periodtaskqty_constr, scope ); 
 | 
       
 | 
          // If there is a new supply of this output in this pispips that is not part of the optimization run, then this new supply should be subtracted from the RHS 
 | 
          // Comment from MvE: this should follow the summing of RHS new supply in GetInventoryRHSForBalanceConstraint 
 | 
          traverse( output, NewSupply, newsupply, 
 | 
                    newsupply.PeriodTask_MP().UnitPeriod().Period_MP() = pispip.Period_MP()                 
 | 
                    and( not scope.Contains(  newsupply.PeriodTaskOperation().PeriodTaskOperationInOptimizerRun() ) 
 | 
                         and not scope.Contains( newsupply.PeriodTask_MP().UnitPeriod().UnitPeriodInOptimizerRun() ) ) // If this is a regular optimizer run, the PTOperations are not added to the algorithm run 
 | 
                    or ( ifexpr( runcontext.IsSmartPlanForPeriodTask(), not newsupply.GetHasAllDDInOptimizerScope( runcontext, scope ), false ) ) // Only check this for period task smart plan 
 | 
                    )   
 | 
          { 
 | 
            newrhs := this.GetConstraintRHS( constr, scalefactor_rhs_constr ) - newsupply.Quantity(); 
 | 
            constr.RHSValue( newrhs * scalefactor_rhs_constr ); 
 | 
          } 
 | 
        } 
 | 
       
 | 
        // Add slack variables 
 | 
        // Term UoM: Output PISP 
 | 
        constr.NewTerm( -1.0 * scalefactor_usertotalsupplyover_constr, program.UserTotalSupplyOverVariables().Get( pispip ) ); 
 | 
        constr.NewTerm( scalefactor_usertotalsupplyunder_constr, program.UserTotalSupplyUnderVariables().Get( pispip ) ); 
 | 
      } 
 | 
    } 
 | 
  *] 
 | 
  InterfaceProperties { Accessibility: 'Module' } 
 | 
} 
 |