chenqinghong
2024-05-07 3ec06a830367465068963156dcc1d8e522571c13
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
Quintiq file version 2.0
#parent: #root
Method AddMaximumInventoryValue (
  LibSCIScenario scenario,
  MacroPlan macroplan,
  InventorySpecifications inventoryspec,
  Boolean isactual
)
{
  Description: 'Create separated method to ease the calculation of start and end. Nothing will be exported if InventoryValueCost is not defined.'
  TextBody:
  [*
    /*
    if IsActual
      StartTime = maxvalue( InventoryTarget.Start, InventoryValueAndCost.Start, CurrencyRate.Start ) 
      EndTime = minvalue( ( InventoryTarget.End, InventoryValueAndCost.End, CurrencyRate.End, startofplanning )
    else
      StartTime = maxvalue ( InventoryTarget.Start, InventoryValueAndCost.Start, CurrencyRate.Start, startofplanning ) 
      EndTime = minvalue( InventoryTarget.End, InventoryValueAndCost.End, CurrencyRate.End, endofplanninghorizon )
    */
    startofplanning:= macroplan.StartOfPlanning(); 
    scenarioname := ifexpr( isactual, LibSCIIntegration_Utility::SCI_CurrentSOPPlan(), scenario.Name() );
    appliedtometric := ifexpr( isactual, LibSCIIntegration_Utility::SCI_Metric_ActualInventoryValue(), LibSCIIntegration_Utility::SCI_Metric_PlannedInventoryValue() );
    traverse( inventoryspec, Elements, spec )
    {
      
      endofspec := guard( spec.NextInventorySpecification().Start().DateTime(), macroplan.End() );
      /* select InventoryValueCosts that are overlapped with the InventorySpecification, if isactual only select InventoryValueCost that valid before startofplanning,
      if not isactual, the InventoryValueCost need End after startofplanning
      */
      inventoryvalues := selectsortedset( spec, ProductInStockingPoint_MP.InventoryValueAndCost, cost,
                                          Period_MP::IsInPeriod( cost.Start().DateTime(), cost.End().DateTime(), 
                                                                 spec.Start().DateTime(), 
                                                                 ifexpr( isactual, startofplanning, endofspec ) ) 
                                          and ifexpr( not isactual, cost.End().DateTime()> startofplanning, true ), 
                                          spec.Start() );
                                           
      
      traverse( inventoryvalues, Elements, inv )
      {
       
       start := maxvalue( inv.Start().DateTime(), spec.Start().DateTime() );
       end := minvalue( inv.End().DateTime(), endofspec );
       currency := inv.AccountAssignment().Currency_MP();
       product := inv.Product_MP().Name();
       stockingpoint := inv.StockingPoint_MP().Name();
       cost := inv.Cost() * spec.MaxLevelInQuantity();
      
       if ( currency.IsBase() )
       {
          if ( not isactual )
          {
            start := maxvalue( startofplanning, start )
          }
          else
          {
            end := minvalue( end, startofplanning );
          }
          
          this.AddMaximumInventoryValueForExport( scenarioname, appliedtometric, product, stockingpoint, start, end, cost )  
       }    
       
       else
       {
         currencyrates := currency.GetCurrencyRates( inv.Start(), inv.End() );
         i := 0;
         traverse( currencyrates, Elements, rate )
         {
           start := maxvalue( inv.Start().DateTime(), rate.Start().DateTime() );
           end := guard( currencyrates.Element(i+1).Start().DateTime(), inv.End().DateTime() );
           end := minvalue( inv.End().DateTime(), end );
           cost := inv.Cost() * rate.Rate() * spec.MaxLevelInQuantity();
           // if inventoryvaluecost cost with end > start of planning
           if ( not isactual and end > startofplanning )
           {
             start := maxvalue( start, startofplanning );
             this.AddMaximumInventoryValueForExport( scenarioname, appliedtometric, product, stockingpoint, start, end, cost )
           }
           else if ( isactual and scenario.IsCurrent() )// only export actual for current scenario
           {
             end := minvalue( end, startofplanning );
             this.AddMaximumInventoryValueForExport( scenarioname, appliedtometric, product, stockingpoint, start, end, cost )
           }
          
           i := i +1;
         }
       }
      }
    }
  *]
  InterfaceProperties { Accessibility: 'Module' }
}