| Quintiq file version 2.0 | 
| #parent: #root | 
| MethodOverride SetOptimizerInputSmartPlan ( | 
|   ProductInStockingPointInPeriodPlanningLeaf pispip, | 
|   Boolean isusingselectedunits, | 
|   Units units, | 
|   Number depth, | 
|   LibOpt_Scope scope, | 
|   RunContextForCapacityPlanning runcontext | 
| ) as Boolean | 
| { | 
|   TextBody: | 
|   [* | 
|     // Recursive methods that selects all required instances for the downstream smart plan optimizer run | 
|     // If this pispip is already part of this optimizer run, then we do not need to consider it again | 
|      | 
|     alreadyvisited_in_downstreamsearch := pispip.TransformerSmartPlanDownStreamWhenVisited() = this;  | 
|     done_because_exceeded_size := ifexpr(  this.CheckMaxNeighborhoodSize(), scope.EstimatedNrPISPIPs() > this.MaxPISPIPSNeighborhood(), false );  | 
|     stop_because_loop_protection := depth > 1000;  | 
|     if ( stop_because_loop_protection )  | 
|     { | 
|       info(  'loop in downstream search');  | 
|     } | 
|      | 
|     if ( this.Debug() )  | 
|     { | 
|       debuginfo( depth, ' ',  pispip.ProductInStockingPoint_MP().StockingPointID(),  | 
|                  pispip.ProductInStockingPoint_MP().ProductID(),  | 
|                  pispip.Start(),  | 
|                  'already visited downstream=', alreadyvisited_in_downstreamsearch,  | 
|                  'in scope=', scope.Contains( pispip.PISPIPInOptimizerRun() ),  | 
|                  'dd=', pispip.DependentDemandFulfilledQuantity(),  | 
|                  'ddnontrp=', pispip.DependentDemandNonTripFulfilledQuantity() );  | 
|     } | 
|      | 
|     this.Visit( pispip );  | 
|      | 
|     if ( not alreadyvisited_in_downstreamsearch and not scope.Contains( pispip.PISPIPInOptimizerRun() ) ) | 
|     { | 
|       scope.Add( pispip ); | 
|     } | 
|     if( not stop_because_loop_protection | 
|         and not alreadyvisited_in_downstreamsearch ) | 
|     {   | 
|       if ( not done_because_exceeded_size )  | 
|       { | 
|         ptforrecursive := this.GetPeriodTasksToSearch( pispip, scope, runcontext, units, isusingselectedunits, depth );          | 
|      | 
|         traverse( ptforrecursive, Elements, periodtaskoperation )  | 
|         { | 
|           scope.Add( periodtaskoperation );  // note units, unitperiods, operation we add all the way at the end ( LibOpt_Scope.CompleteForPTO_PIT)    | 
|          | 
|           traverse( periodtaskoperation, DependentDemand.ProductInStockingPointInPeriodPlanningLeaf, p )  | 
|           { | 
|             if ( not scope.Contains( p.PISPIPInOptimizerRun() ) ) | 
|             { | 
|               scope.Add( p );   | 
|             } | 
|           } | 
|      | 
|           traverse( periodtaskoperation, NewSupply.ProductInStockingPointInPeriodPlanningLeaf, newpispip )  | 
|           {  | 
|             // If this new pispip is not part of the optimizer run | 
|             if( newpispip.HasRegularProductForOptimizer() or newpispip.GetProductIsIncludedInOptimizerRun( runcontext.IsPostProcessing() ) ) | 
|             { | 
|               this.SetOptimizerInputSmartPlan( newpispip, isusingselectedunits, units, depth + 1, scope, runcontext ); | 
|             } | 
|           } | 
|         } | 
|      | 
|         pit_to_search := this.GetProductInTripsToSearch( pispip, scope, runcontext, units, isusingselectedunits, depth );  | 
|      | 
|         // Add the trips to the optimizer run | 
|         traverse( pit_to_search, Elements, productintrip ) | 
|         {   | 
|           // Add the related productintrip to productintripsforoptimization | 
|           newpispip := guard( productintrip.NewSupply().ProductInStockingPointInPeriodPlanningLeaf(), null( ProductInStockingPointInPeriodPlanningLeaf ) );  | 
|           if ( not isnull( newpispip ) | 
|                and not newpispip.IsPeriodFrozen() )  | 
|           { | 
|             scope.Add(  productintrip ); // note units, unitperiods, trip we add all the way at the end ( LibOpt_Scope.CompleteForPTO_PIT)  | 
|             departurepispip := productintrip.DeparturePISPIP();  | 
|             scope.Add( departurepispip ); // must add departure to scope, arrival is explored below (and added that way) | 
|      | 
|             this.SetOptimizerInputSmartPlan( newpispip, isusingselectedunits, units, depth + 1, scope, runcontext ); | 
|           } | 
|           else | 
|           { | 
|             debuginfo( 'Suspicious - output pispip of pit null', 'Origin=',  | 
|                        pispip.ProductInStockingPoint_MP().Name(),  | 
|                        pispip.Start(), 'pit = ',  | 
|                        productintrip.ProductID(),  | 
|                        productintrip.Trip().LaneLeg().OriginStockingPointID(),  | 
|                        '->',  | 
|                        productintrip.Trip().LaneLeg().DestinationStockingPointID() );  | 
|           } | 
|         } //end traverse pit_to_search | 
|       } // end if not done because size exceeded | 
|     } // end if explore recursive, etc. | 
|      | 
|     return true; | 
|   *] | 
| } |