lazhen
2025-01-09 8afe90b633046db39042aada36b88193062f8cff
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
Quintiq file version 2.0
#parent: #root
Method GenerateMoves
{
  Description: 'Creates the moves that will be used in the inventory optimization algorithm. Each move adjust the target inventory of one or more inventory specificaitons.'
  TextBody:
  [*
    // edz1 Aug-31-2016 (created)
    
    // Create the missing inventory specifications 
    // Any PISP with IsSafetyStockKept to true, should have an inventory specification
    traverse( this, MacroPlan.Product_MP.ProductInStockingPoint_MP, pisp, 
              pisp.IsSafetyStockKept()
              and pisp.InventorySpecification( relsize ) = 0 )
    {
      invspec := InventorySpecification::Create( pisp.Product_MP(),
                                                 pisp.StockingPoint_MP(),
                                                 this.MacroPlan().StartOfPlanning().Date(),
                                                 false, 0.0, 0.0,            // Does not have a target in days, the initial targets are 0
                                                 false, 0.0, 0.0,            // Does not have a minimum in days, the initial minimums are 0
                                                 false, false, 0.0, 0.0,     // Does not have a maximum, does not have a maximum in days, the initial maximums are 0
                                                 true, false );            // Is calculated and is not from database 
                                                 
      // We need to make sure HasKeepSafetyStockPISP value is set properly, otherwise we will not create the moves
      invspec.CalcHasKeepSafetyStockPISP();                             
    }
    
    // The relation between PISPIP and InventorySpecification must be updated, otherwise the inventory specifications in service level cannot be created
    Transaction::Transaction().Propagate( relation( ProductInStockingPointInPeriod, InventorySpecification ) );
    
    // Synchronize the InventorySpecificationInServiceLevel instances based on the latest data
    traverse( this, MacroPlan.AllServiceLevelBase, servicelevel )
    {
      servicelevel.SynchronizeInventorySpecInServiceLevel();
    }
    
    // Delete all existing moves before creating new moves
    traverse( this, Move, move )
    {
      Move::Delete( move );
    }
    
    // Update the relation from 
    
    // Create an increase/decrease move for all inventory specifications that can impact at least one service level
    traverse( this, MacroPlan.Product_MP.InventorySpecification, inventoryspecification, 
              inventoryspecification.InventorySpecificationInServiceLevel( relsize ) > 0
              and inventoryspecification.HasKeepSafetyStockPISP() ) 
    {
      MoveStep::Create( inventoryspecification, this, true );  // increase 
      MoveStep::Create( inventoryspecification, this, false ); // decrease
    }
    
    // Create a swap move between each pair of inventory specifications that are linked by at least one inventoryspecification in servicelevel
    traverse( this, MacroPlan.Product_MP.InventorySpecification, invspec1,
              invspec1.HasKeepSafetyStockPISP() )
    {
      relatedinvspecs := selectset( invspec1, InventorySpecificationInServiceLevel.ServiceLevelBase.InventorySpecificationInServiceLevel.InventorySpecification, invspec2,
                                    invspec2.HasKeepSafetyStockPISP()
                                    and invspec1 <> invspec2 ).Unique();
    
      traverse( relatedinvspecs, Elements, invspec2 )
      {
        MoveSwap::Create( invspec1, invspec2, this )
      }
    }
  *]
}