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(); 
 | 
    } 
 | 
  *] 
 | 
} 
 |