Quintiq file version 2.0 
 | 
#parent: #root 
 | 
Method GetPISPIPsForInventorySpecifications ( 
 | 
  const LibOpt_Scope scope, 
 | 
  Boolean leafpispipsonly, 
 | 
  constcontent output owning ProductInStockingPointInPeriodPlannings leafpispips 
 | 
) const as constcontent owning ProductInStockingPointInPeriodPlannings 
 | 
{ 
 | 
  Description: 'Get all pispips for which an inventory specification should be considered' 
 | 
  TextBody: 
 | 
  [* 
 | 
    // Select all leaf pispips that are in the optimizer run and have an inventory specification 
 | 
     
 | 
    leafpisps := selectset(  scope.GetProductInStockingPointInOptimizerRunConst(), Elements, pisp, true, pisp.IsLeaf() );  
 | 
    leafpispips := construct( ProductInStockingPointInPeriodPlannings, constcontent );  
 | 
    traverse( leafpisps, Elements, pisp, pisp.HasInventorySpecification() )  
 | 
    { 
 | 
      current := pisp.EarliestPISPIPInScope();  
 | 
      laststart := guard( pisp.LatestPISPIPInScope().Start(), DateTime::MinDateTime() );  
 | 
      while ( not isnull( current ) and current.Start() <= laststart )  
 | 
      { 
 | 
        leafpispips.Add( current );  
 | 
        current := current.NextPlanningPISPIP();  
 | 
      } 
 | 
    } 
 | 
     
 | 
     
 | 
    // Select all non leaf pispips that have an inventory specification and that should be part of this optimizer run 
 | 
    // Select them by looking at all the parents of all the leaf pispips that are in the optimizer run 
 | 
    nonleafpispips := construct( ProductInStockingPointInPeriodPlannings, constcontent ); 
 | 
     
 | 
    if ( not leafpispipsonly )  
 | 
    { 
 | 
      nrofproductlevels := this.MacroPlan().ProductLevel_MP( relsize ); 
 | 
       
 | 
      traverse( leafpisps, Elements, pisp, pisp.HasAncestorWithInventorySpecification() )  
 | 
      { 
 | 
        firstpispip := pisp.EarliestPISPIPInScope(); 
 | 
        lastpispip := pisp.LatestPISPIPInScope();  
 | 
        currentpisp := pisp;  
 | 
        // In principle the for loop should terminate because at some point we reach a pispip that does not have a parent anymore 
 | 
        // As a safety check we make sure that the for loop also terminates once i has reached the number of product levels 
 | 
        for( i := 1; 
 | 
             not isnull( currentpisp.ParentOfProductDimension() ) 
 | 
             and i <= nrofproductlevels; 
 | 
             i++ ) 
 | 
        { 
 | 
          currentpisp := currentpisp.ParentOfProductDimension();  
 | 
          firstpispip := firstpispip.ParentOfProductDimension().astype( ProductInStockingPointInPeriodPlanning ) 
 | 
          lastpispip := lastpispip.ParentOfProductDimension().astype( ProductInStockingPointInPeriodPlanning ) 
 | 
          if( currentpisp.HasInventorySpecification() ) 
 | 
          { 
 | 
            // add from first to last to nonleafpispips 
 | 
            current := firstpispip;  
 | 
            laststart := lastpispip.Start();  
 | 
            while ( not isnull( current ) and current.Start() <= laststart )  
 | 
            { 
 | 
              nonleafpispips.Add( current );  
 | 
              current := current.NextPlanningPISPIP();  
 | 
            } 
 | 
          } 
 | 
        } 
 | 
      } 
 | 
    } 
 | 
     
 | 
    pispips := leafpispips.Union( nonleafpispips ); 
 | 
    additionalpispips := construct( ProductInStockingPointInPeriodPlannings, constcontent );  
 | 
     
 | 
    additionalpispips := this.GetAdditionalPISPIPSInventorySpecification( scope, pispips ); // for meta optimizer we add pispips prior to scope to deal with specifications in days 
 | 
     
 | 
    allpispips := pispips.Union( additionalpispips );  
 | 
    return &allpispips; 
 | 
  *] 
 | 
  InterfaceProperties { Accessibility: 'Module' } 
 | 
} 
 |