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
|
*]
|
}
|