Quintiq file version 2.0 
 | 
#parent: #root 
 | 
Method CapacityPlanningAlgorithmHandleFeasibleSalesDemand ( 
 | 
  CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program, 
 | 
  const RunContextForCapacityPlanning runcontext, 
 | 
  LibOpt_Scope scope, 
 | 
  ProductInStockingPointInPeriodPlannings pispipsinrun 
 | 
) 
 | 
{ 
 | 
  Description: 'Set the sales demand fulfillment quantity, and postpone sales demands if optimizer are allowed to do so, and choose to do so' 
 | 
  TextBody: 
 | 
  [* 
 | 
    /* 
 | 
    REMOVE := true; cmt := 'tmp';   
 | 
    if ( REMOVE )  
 | 
    { 
 | 
      count := 0;  
 | 
      traverse( this, MacroPlan.SalesDemand.SalesDemandInPeriod, s )  
 | 
      { 
 | 
        count++;  
 | 
        s.OptimizerMetaDebugOldFulfilledQuantity( s.FulfilledQuantity() );  
 | 
        if ( count < 10 )  
 | 
        { 
 | 
          debuginfo( s.SalesSegmentName(), s.OptimizerMetaDebugOldFulfilledQuantity() );  
 | 
        } 
 | 
      } 
 | 
    } 
 | 
    */ 
 | 
     
 | 
    this.MergeSalesDemands(scope, pispipsinrun ); // removes postponed sd for all sd in scope (provided the postponedsd has its pispip in scope)  
 | 
     
 | 
    // Leaf Sales Demands  
 | 
    traverse( scope.GetLeafSalesDemandInPeriodInRun(), Elements, sd, isnull( sd.OriginalSalesDemand() ) or sd.IsManuallyPostponed() ) 
 | 
    { 
 | 
      qty := this.GetOptimalValue( program.SalesDemandQtyVariables().Get( sd ) ); 
 | 
      sd.UpdateOptimizerFulfillment( true, qty ); 
 | 
       
 | 
      this.CapacityPlanningAlgorithmHandleFeasibleDelayedSalesDemand( sd, program, runcontext, scope, 1 ); 
 | 
    } 
 | 
     
 | 
    // Aggregated sales demands for higher product level 
 | 
    traverse( scope.GetAggregatedSalesDemandInPeriodInRun(), Elements, asdip ) // Aggregated does not have pisp asdip.ProductInStockingPoint_MP().GetIsInOptimizerRun() 
 | 
    {  
 | 
      // No optimizer variables for AggregatedSalesDemandInPeriod 
 | 
      // Traverse the children ( Disaggregated Sales demands ) 
 | 
      // skip postponed sales demand. Instead of using IsPostponed which requires a transaction propagate, we will just check for null OriginalSalesDemand 
 | 
      traverse ( asdip, DisaggregatedSalesDemandInPeriod, dasdip,  
 | 
                 isnull( dasdip.OriginalSalesDemand() ) 
 | 
                 and scope.Contains( dasdip.AsPlanningBaseSalesDemandInPeriod().PISPIPInOptimizerRun() ) )  
 | 
      { 
 | 
        // Type    : DisaggregatedSalesDemandInPeriod 
 | 
        // Variable: 'DisaggregatedSalesDemandQty' UoM: PISP 
 | 
        var := this.GetOptimalValue( program.DisaggregatedSalesDemandQtyVariables().Get( dasdip ) ); 
 | 
        dasdip.UpdateOptimizerFulfillment( true, var ); 
 | 
        // Type    : DelayedDisaggregatedSalesDemandInPeriod 
 | 
        // Variable: 'DelayedDisaggregatedSalesDemandQty' UoM: PISP 
 | 
        this.CapacityPlanningAlgorithmHandleFeasibleDelayedSalesDemand( dasdip, program, runcontext, scope, 1 ); 
 | 
      } 
 | 
    } 
 | 
     
 | 
    // Sales demand before the optimization horizon, including those before the planning horizon. 
 | 
    // Leaf sales demands 
 | 
    traverse( scope.GetSDIPBeforeScopeInRun(), Elements.astype( LeafSalesDemandInPeriod ), lsdip ) 
 | 
    { 
 | 
      this.CapacityPlanningAlgorithmHandleFeasibleDelayedSalesDemand( lsdip, program, runcontext, scope, lsdip.SDIPBeforeScopeInRun().OptMinPostponementPeriod() ); 
 | 
    } 
 | 
     
 | 
    // Aggregated sales demands for higher product level 
 | 
    traverse( scope.GetSDIPBeforeScopeInRun(), Elements.astype( AggregatedSalesDemandInPeriod ).DisaggregatedSalesDemandInPeriod, dasdip ) 
 | 
    { 
 | 
      this.CapacityPlanningAlgorithmHandleFeasibleDelayedSalesDemand( dasdip, program, runcontext, scope, 
 | 
                                                                      dasdip.AggregatedSalesDemandInPeriod().SDIPBeforeScopeInRun().OptMinPostponementPeriod() ); 
 | 
    } 
 | 
  *] 
 | 
  InterfaceProperties { Accessibility: 'Module' } 
 | 
} 
 |