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
Quintiq file version 2.0
#parent: #root
MethodOverride Operation (
  LibOpt_Task task
) as stream[JSON]
{
  TextBody:
  [*
    pispipssmartplan := task.Scope().GetSmartPlanPISPIPsInOptimizerRun();
    lanelegs_foroptimization := task.Scope().GetLaneLegForOptimization();
    runcontext := this.GetRunContext();   
    units := runcontext.GetSelectedUnits();  
    isusingselectedunits := runcontext.IsUsingSelectedUnits(); 
    periods := task.Scope().GetPeriodInOptimizerRun(); 
    process := runcontext.Process_MP(); 
    
    this.UpdateSupplyUser( pispipssmartplan, runcontext ); // sets the manual specified quantity to be planned on the pispip (if there is only one)
    
    cleanscope := LibOpt_Scope::Create(  task.Run() ); 
    cleanscope.AddLaneLegsForOptimizationToScope( lanelegs_foroptimization ); 
    cleanscope.AddPeriodsToScope( periods ); 
    cleanscope.AddOptimizerAccountsToScope( task.Scope().GetAccountsInOptimizerRun() ); 
    
    cleanscope.AddSmartPlanPISPIPsToScope( pispipssmartplan ); 
    
    this.SelectOptimizerInputForSmartPlan( pispipssmartplan, 
                                           lanelegs_foroptimization, 
                                           periods, 
                                           isusingselectedunits, 
                                           units, 
                                           false /* skip fill gaps */, 
                                           process, 
                                           cleanscope,  
                                           runcontext, 
                                           true /* reset visited */ );    
    
    cleanscope.CompleteForPTO_PIT(); // add in unitperiods, units, operations, trips based on pto and pit 
    cleanscope.CompleteFor_PISPIP(); // ensure scope contains period, pisp, spip and sales demand objects for pispip in scope
    
    runcontext.SetPeriodTaskOperationUser( runcontext.HasOverwrittenManualPlanning(), cleanscope, false ); 
    runcontext.SetProductInTripManualQuantity( runcontext.HasOverwrittenManualPlanning(), cleanscope, false ); 
    
    // Reset the total available supply user for the non smart plan pispips
    // or for all pispips if this is not a downstream smart plan
    isupstream := this.GetIsUpstream(); 
    traverse( cleanscope.GetPISPIPInOptimizerRun(), Elements, pispip, 
              pispip.HasTotalAvailableSupplyUser()
              and ( isupstream
                    or not exists( pispipssmartplan, Elements, smartplanpispip, smartplanpispip = pispip ) ) )
    {
      pispip.UpdateTotalAvailableSupplyUser( false, 0.0 );
    }
    
    if ( runcontext.IsSmartPlan() ) // if this is an actual smart plan ( and we are not just using the transformer ) we delay extending pisp horizon for shelf life
    {                             // until we know the scope and extend only there for performance reasons 
      pisps := cleanscope.GetProductInStockingPointInOptimizerRun(); 
      this.Optimization().astype( Optimization ).ShelfLifeExtendHistoricalPeriods( false, &pisps );
      
      // we need to add pisp to all ancestor scopes, so that in case of shelf life planning, in the OptimizerPrePostProcessing.OnFinalize( ) the scope
      // contains all the pisps and we can restore the historical pispips only there (for efficiency)
      traverse( pisps, Elements, pisp ) 
      {
        LibOpt_ScopeElement::Transform( task, construct(  LibOpt_ScopeElements ), pisp.PISPInOptimizerRun() ); 
      }
    }
    
    taskcontext := task.TaskContext( relnew, TaskContextSmartPlan ); 
    taskcontext.AddCleanUpFromScope( cleanscope ); // we save pit and period tasks scope so we can clean up unused ones in onfinalize
    
    return this.Continue( task, cleanscope );
  *]
}