Quintiq file version 2.0 
 | 
#parent: #root 
 | 
MethodOverride GetPeriodTasksToSearch ( 
 | 
  ProductInStockingPointInPeriodPlanningLeaf pispip, 
 | 
  LibOpt_Scope scope, 
 | 
  RunContextForCapacityPlanning runcontext, 
 | 
  Units units, 
 | 
  Boolean isusingselectedunits, 
 | 
  Number depth 
 | 
) as owning PeriodTaskOperations 
 | 
{ 
 | 
  TextBody: 
 | 
  [* 
 | 
    ptforrecursive := construct( PeriodTaskOperations );  
 | 
    if ( runcontext.IsSmartPlan() ) 
 | 
    { 
 | 
      gp := pispip.MacroPlan().GlobalParameters_MP();       
 | 
      period := pispip.Period_MP();  
 | 
      operations := null(  Operations );  
 | 
      // Traverse over the operations that take this product as an input 
 | 
      // If this product is a byproduct, we do not want to add its operations, unless they only take byproducts as inputs. 
 | 
      // This is to avoid adding products to the smart plan that are only related to the smart plan output pispips because they are input together with the same byproduct 
 | 
       
 | 
      
 | 
      operations := selectset( pispip, ProductInStockingPoint_MP.OperationInput.Operation, operation, 
 | 
                               operation.GetIsAvailableForOptimization()                                // The operation must be available 
 | 
                               and ( not pispip.ProductInStockingPoint_MP().Product_MP().IsDerivedByProduct()  // This product is not a byproduct 
 | 
                                     or operation.AllInputsAreDerivedByProducts() )   // or all inputs are byproducts 
 | 
                               and ( not isusingselectedunits or exists( units, Elements, unit, unit = operation.Unit() ) ) ) 
 | 
                                
 | 
      traverse( operations, Elements, operation )  
 | 
      {  
 | 
        // The period in which the period tasks occurs is the period from which the inputs are taken + the lead time 
 | 
        endofpt := period.PeriodEnd() + operation.LeadTime(); 
 | 
         
 | 
        // If the operation lead time logic is either end of period or middle of period 
 | 
        // Then the end of the period task is calculated as the start of the dependent demand period plus the lead time 
 | 
        if( gp.IsOperationLeadTimeLogicFromEnd() or gp.IsOperationLeadTimeLogicFromMiddle() ) 
 | 
        { 
 | 
          endofpt := period.Start() + operation.LeadTime(); 
 | 
        } 
 | 
         
 | 
        nsperiod := period.GetNewSupplyPeriod( endofpt ); 
 | 
     
 | 
        // If the operation lead time logic is middle of the period 
 | 
        // Then the end of the period should be before the middle of the new supply period 
 | 
        // If this is not the case, then the new supply period should be the next period 
 | 
        if( gp.IsOperationLeadTimeLogicFromMiddle()  
 | 
            and guard( endofpt >= nsperiod.End() - 0.5 * nsperiod.Duration(), false ) ) 
 | 
        { 
 | 
          nsperiod := guard( nsperiod.NextPlanningPeriod(), null( Period_MP ) ); 
 | 
        } 
 | 
      
 | 
        if( not isnull( nsperiod )  
 | 
            and PeriodTaskOperation::GetIsValidPeriodTask( operation, nsperiod ) )       // The resulting period task must be valid 
 | 
        {  
 | 
          // Add the operations that can supply to this pispip to operationsforoptimization 
 | 
       
 | 
          // Create/Select the related periodtaskoperation and add it to PTOperationsForOptimization 
 | 
          periodtaskoperation := PeriodTaskOperation::FindPeriodTaskOperationTypeIndex( nsperiod.Start() , operation.ID() ); 
 | 
       
 | 
          if( isnull( periodtaskoperation ) ) 
 | 
          { 
 | 
            unit := operation.Unit();  
 | 
            unitperiod := UnitPeriod::FindUnitPeriodTypeIndex( unit.ID(), period.Start(), period.End() ); 
 | 
            periodtaskoperation := PeriodTaskOperation::Create( operation, unitperiod, 0.0, false ); 
 | 
            // this transaction propagate is necessary, we need to get the new supply from the newly created periodtask 
 | 
            Transaction::Transaction().Propagate( relation( PeriodTaskOperation, NewSupply ) ); 
 | 
            Transaction::Transaction().Propagate( relation( PeriodTaskOperation, DependentDemand ) ); 
 | 
            Transaction::Transaction().Propagate( relation(  NewSupply, ProcessOutput ) );  
 | 
            Transaction::Transaction().Propagate( relation(  DependentDemand, ProcessInput ) );  
 | 
          } 
 | 
          ptforrecursive.Add( periodtaskoperation );  
 | 
        } 
 | 
      }                  
 | 
    } 
 | 
    else 
 | 
    { 
 | 
      // meta optimizer case 
 | 
      if ( this.LimitToNonzeroPlanning() )  
 | 
      { 
 | 
        ptforrecursive := selectset( pispip, DependentDemandOperationForMeta.PeriodTaskOperation, pto, true, not pto.Quantity() = 0.0 );   
 | 
        if (  pispip.ProductInStockingPoint_MP().Product_MP().IsDerivedByProduct() )  
 | 
        { 
 | 
          ptforrecursive := selectset( ptforrecursive, Elements, pto, true, pto.Operation().AllInputsAreDerivedByProducts() );  
 | 
        } 
 | 
      } 
 | 
      else 
 | 
      { 
 | 
        ptforrecursive := selectset( pispip, DependentDemandOperationForMeta.PeriodTaskOperation, pto, true, true );   
 | 
        if (  pispip.ProductInStockingPoint_MP().Product_MP().IsDerivedByProduct() )  
 | 
        { 
 | 
          ptforrecursive := selectset( ptforrecursive, Elements, pto, true, pto.Operation().AllInputsAreDerivedByProducts() );  
 | 
        } 
 | 
        if ( this.OperationSelectLimit().IsFinite() )  
 | 
        {                                                               
 | 
          ptforrecursive.SelectFirst(  this.OperationSelectLimit() );                                                                 
 | 
        }     
 | 
      } 
 | 
    } 
 | 
    return & ptforrecursive 
 | 
  *] 
 | 
} 
 |