yanyuan
2023-11-10 143ef74e2eeee697ac8fda3d9032a790fbb4e146
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
Quintiq file version 2.0
#parent: #root
MethodOverride OnFinalize (
  LibOpt_Task task
)
{
  TextBody:
  [*
    macroplan := this.Optimization().astype( Optimization ).MacroPlan(); 
    
    runcontext := RunContextForCapacityPlanning::GetRunContextCapacityPlanning( task.Run() ); 
    rcm := RunContextMeta::GetRunContextMeta( task.Run() ); 
    
    this.Optimization().astype( Optimization ).SetMessageBenchmarking( runcontext ); 
    
    if ( runcontext.UseShiftOptimization() ) 
    {
      this.SetShiftPatterns( macroplan ); 
    }
    
    this.WriteScoresForAutoTestInstances( runcontext, task ); 
    this.DebugFinishForAutoTestInstances();  
    
    if ( runcontext.IsMetaIteration() ) 
    {
      this.ApplyNoiseThreshold( task ); 
    }
    
    userperiodtasks := runcontext.GetUserPeriodTaskOperations(); 
    if ( not runcontext.IsSmartPlan() and not macroplan.Optimization().DebugMode() ) 
    {
      this.RemoveUnusedOperationPeriodTaskAfterOptimizerRun( task.Scope(), runcontext, userperiodtasks );
      if ( guard( not runcontext.IsMetaIteration() or rcm.OptionCleanUpUnusedTripsPeriodTasksAfterwards(), false ) ) 
      {
        this.RemoveUnusedTripsAfterOptimizerRun( task.Scope() );
      }
    }
    
    if ( runcontext.UseCampaignSequenceOptimizer() and not macroplan.Optimization().DebugMode() ) 
    {
      macroplan.Optimization().CampaignCombiGeneration().OptCampaign().Delete();  
    }
    
    pisps := null(  ProductInStockingPoint_MPs, owning ); 
    if ( RunContextForCapacityPlanning::GetRunContextCapacityPlanning( task.Run() ).IsSmartPlan() ) 
    {
      pisps := task.Scope().GetProductInStockingPointInOptimizerRun(); // for smart plan we want to make sure only to work on the relevant set for performance 
    }
    macroplan.Optimization().ShelfLifeExtendHistoricalPeriods( true, &pisps ); // restoring nr of historical periods (in case it was extended for shelf life) 
    
    macroplan.IsOptimizerRunning( false );
    macroplan.UpdateLastPlanningAction( false, true, false, false ); // isReset, isPlan, isRoll, isLockUnlock
    
    //Auto peg all demands to supplies using suggested quantity
    if( macroplan.GlobalParameters_MP().IsPeggingRunAfterOptimization() )
    {
      algorithmrun := macroplan.GetLastAlgorithmRun(); 
      algorithmrun.PeggingStart( DateTime::ActualTime() ); 
      //Propagate to create dependent demand and new supply,
      //also calculate the values required for pegging (supply's quantity, demand's quantity, etc )
      Transaction::Transaction().Propagate();
      macroplan.RunPeggingAlgorithm();
    
      algorithmrun.PeggingEnd( DateTime::ActualTime() ); 
    }
    // Update the scaling
    
    if( runcontext.IsAutoScalingEnabled() 
        and guard( rcm.OptionAllowScalingRecompute(), true )  )
    {
      macroplan.UpdateScaling();
    }
    
    // Update KPI score
    // Do not update the KPIs if this is the autotune copy, since it is only used for tuning and will be deleted after
    // If performance is a concern, we can disable this and manually click on the Refresh KPI button during scenario comparison
    Transaction::Transaction().Propagate(); // we need this because we potentially turned back on cost computation for meta
    if( not runcontext.IsInventoryOptimizationRun()
        or runcontext.IsFrozenRun() )
    {
      if ( runcontext.IsSmartPlan() ) 
      {
        macroplan.SmartPlanStartForUpdateKPI( runcontext.FirstPeriod_MP().Start() ); 
        isdownstream := not runcontext.IsUpstreamSmartPlan() and not runcontext.IsMiddleOutSmartPlan(); 
        smartplanpispips := task.Scope().GetSmartPlanPISPIPsInOptimizerRun(); 
        if ( isdownstream and smartplanpispips.Size() = 1 ) // for downstream we lock, but can only do it afterwards because the current supply is used
        {
          traverse( smartplanpispips, Elements.astype(  ProductInStockingPointInPeriodPlanningLeaf ), pispip ) 
          {
            pispip.LockUnlock( true, false );
          }
        }
      }
      if ( not runcontext.IsSync() ) // we cannot trigger a job when running sync
      {
        macroplan.CalculateKPIScore( runcontext.IsSmartPlan() );
      }
      if( not runcontext.IsInventoryOptimizationRun() )
      {
        info( 'End of propagation', DateTime::ActualTime() );
        info( '=======================================' );     // Seperator for each run
      }
    }
    
    if( not runcontext.IsInventoryOptimizationRun() 
        and not ( runcontext.IsSmartPlan() and runcontext.IsSync() ) )
    {
      debuginfo(  'Getting smmdsid and signal optimizer run completed' ); 
      macroplan.OptimizerRunCompleted();
    }
  *]
}