Quintiq file version 2.0 
 | 
#parent: #root 
 | 
Method NextS ( 
 | 
  Number periodNumber, 
 | 
  ProductInStockingPoint_MP pisp 
 | 
) as owning ProbabilityDistribution 
 | 
{ 
 | 
  TextBody: 
 | 
  [* 
 | 
    // calculates the starting stock distrbution of given period, at given stockingpoint 
 | 
    // if leadtime to stockingpoint is 2 periods 
 | 
    // calculation starts at period - 2 
 | 
    // start by assuming that at period - 2 there is target left 
 | 
    // the loop through periods up to period-1, and at every period 
 | 
    // add expected demand and change in target, substract demand distribution and 
 | 
    // take maximum with 0, to not allow negative inventory 
 | 
     
 | 
    dsum := MEIO_Engine::GetZeroDistribution(); 
 | 
    // if period - stockinpoint.leadtime is after start of planning horizon, we have target set a target that we can use 
 | 
    // based on the simulations, mp hardly ever reached the correct target, and interal service level tries to describe this 
 | 
     
 | 
    if(  periodNumber > pisp.MEIO_Leadtime() )  
 | 
    { 
 | 
      startminleadpispip := pisp.GetPISPIPFromPeriodNumber( periodNumber - pisp.MEIO_Leadtime() ); 
 | 
      dsum := MEIO_Engine::GetDiracDistribution( MEIO_Engine::GetInternalSeviceLevel() * startminleadpispip.MEIO_Target() );  
 | 
    } 
 | 
    //# in other cases we start with the target of the first period that we have set earlier (or manually in mp) 
 | 
    else 
 | 
    { 
 | 
      pispip := pisp.FirstPlanningPISPIP();  
 | 
      dsum := MEIO_Engine::GetDiracDistribution( pispip.TargetInQuantity() ); 
 | 
    } 
 | 
    // we only really calculate anything if leaditme is >0, if leadimte =0 we dont need safetystock at all 
 | 
    if ( pisp.MEIO_Leadtime() > 0) 
 | 
    { 
 | 
      // we collect all the children of the stockingpoint (we will aggregate the demand from these)     
 | 
      listofnodes := MEIO_Engine::GetTreePISP( pisp ); //Traverse(stockingpoint, c('level')) 
 | 
      //#start period is leadtime ago or first period,  
 | 
      startperiod := maxvalue( periodNumber - pisp.MEIO_Leadtime(), 1 ); //(meio_R_internal_period-pisp.MEIO_Leadtime(), 1) 
 | 
      //endperiod is previous period or start period 
 | 
      endperiod := maxvalue(startperiod, periodNumber-1) 
 | 
       
 | 
      //if startperiod is endperiod we would only add the resupply of that and substract the demand 
 | 
      //in other cases we loop through all startperiod -> endperiod 
 | 
      
 | 
      // we will add the expected demand and substract the demand distribution 
 | 
      traverse( listofnodes, Elements, nodepisp ) 
 | 
      { 
 | 
        standarddev := MEIO_Engine::GetDemandStandardDeviation( nodepisp, startperiod );   
 | 
        dsum := ProbabilityDistribution::Sum( dsum,  NormalDistribution::Construct( 0.0, standarddev ), this.MEIO_Parameters().SampleSizeForDistributions() );  
 | 
      }  
 | 
      //# if there are other periods we do the same as for startperiod 
 | 
      for ( p:= startperiod + 1; p<= endperiod;  p++ ) 
 | 
      { 
 | 
        supply := 0.0;  
 | 
         
 | 
        // if period is before leadtime of the stockingpoint, we cannot control the supply anymore and thus we use the values from mp 
 | 
        if ( p <= pisp.MEIO_Leadtime() )   
 | 
        { 
 | 
          supply := maxvalue( pisp.GetPISPIPFromPeriodNumber( p ).NewSupplyQuantity(),  
 | 
                              MEIO_Engine::GetDemandExpectedValue(pisp, p ) ) //);  
 | 
        } 
 | 
        //# in other cases we use as a supply the change in targets + expected demand 
 | 
        else 
 | 
        { 
 | 
          supply := maxvalue( MEIO_Engine::GetDemandExpectedValue( pisp, p )  
 | 
                              + pisp.GetPISPIPFromPeriodNumber( p ).MEIO_Target() 
 | 
                              - pisp.GetPISPIPFromPeriodNumber( p - 1 ).MEIO_Target(),  
 | 
                              0 );  
 | 
        } 
 | 
        // here we add the supply and substract the demand distribution 
 | 
         
 | 
        minusdemanddistr := MEIO_Engine::GetDemandDistributionTimesMinusOne( pisp, p ); // workaround because ProbabilityDistribution::Subtract gives verify errors 
 | 
        dsum := ProbabilityDistribution::Sum( dsum, minusdemanddistr, this.MEIO_Parameters().SampleSizeForDistributions() );  
 | 
        dsum := ProbabilityDistribution::Sum( dsum, DiscreteDistribution::Construct( supply ), this.MEIO_Parameters().SampleSizeForDistributions() );  
 | 
        // for the child nodes we do not add change in targets as supply, only the expected demands 
 | 
        if(p > pisp.MEIO_Leadtime() )  
 | 
        { 
 | 
          if(listofnodes.Size() > 1 )  
 | 
          { 
 | 
            traverse( listofnodes, Elements, node, not node = pisp )  
 | 
            { 
 | 
              nodeminusdemanddistr := MEIO_Engine::GetDemandDistributionTimesMinusOne( node, p ) 
 | 
              dsum := ProbabilityDistribution::Sum( dsum, nodeminusdemanddistr, this.MEIO_Parameters().SampleSizeForDistributions() );  
 | 
              dsum := ProbabilityDistribution::Sum( dsum, DiscreteDistribution::Construct( MEIO_Engine::GetDemandExpectedValue( node, p ) ), this.MEIO_Parameters().SampleSizeForDistributions() );   
 | 
            } // traverse 
 | 
          } // if  
 | 
        } // if  
 | 
      } // for loop 
 | 
    } // if  
 | 
     
 | 
    // we don't allow negative inventory 
 | 
    dsum := ProbabilityDistribution::Max( dsum, MEIO_Engine::GetZeroDistribution(), this.MEIO_Parameters().SampleSizeForDistributions() );  
 | 
     
 | 
    return &dsum; 
 | 
  *] 
 | 
} 
 |