admin
2025-01-22 7e31442f0e9b07764e9c6a9680d3d4aeba5fe1de
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
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' }
}