Quintiq file version 2.0
|
#parent: #root
|
Method GetUpstreamPISPIPs (
|
Number depth,
|
ProductInStockingPointInPeriods pispips_o
|
)
|
{
|
Description:
|
[*
|
Selects all upstream PISPIPs related to this pispip.
|
Please note that this will create the required PeriodTaskOperations/Trips to be able to follow the dependent demand.
|
Therefore, it is recommended to delete any unused PeriodTaskOperations/Trips after calling this method
|
*]
|
TextBody:
|
[*
|
// Martijn Oct-18-2016 (created)
|
// Martijn: I think we could remove some code duplication between this method and the SetOptimizerInputSmartPlan methods
|
|
depth := depth - 1;
|
|
if( depth > 0 )
|
{
|
pispips_o.Add( this );
|
period := this.Period_MP();
|
// Traverse over the operations that produce this product as an output
|
// If this product is a byproduct, we do not want to add its operations, unless they only produce byproduct.
|
// This is to avoid adding products to the smart plan that are only related to the smart plan input pispips because they are produced together with the same byproduct
|
traverse( this, ProductInStockingPoint_MP.OperationOutput.Operation, operation,
|
operation.GetIsAvailableForOptimization() // The operation must be available
|
and PeriodTaskOperation::GetIsValidPeriodTask( operation, period ) // The resulting period task must be valid
|
and ( not this.ProductInStockingPoint_MP().Product_MP().IsByProduct() // This product is not a byproduct
|
or forall( operation, OperationOutput.ProductInStockingPoint_MP.Product_MP, product, product.IsByProduct() ) ) ) // or all outputs are byproducts
|
{
|
// Create/Select the related periodtaskoperation
|
periodtaskoperation := PeriodTaskOperation::FindPeriodTaskOperationTypeIndex( period.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 );
|
// I think this transaction propagate is necessary, we need to get the dependent demand from the newly created periodtask
|
Transaction::Transaction().Propagate( relation( PeriodTaskOperation, DependentDemand ) )
|
}
|
|
traverse( periodtaskoperation, DependentDemand.ProductInStockingPointInPeriodPlanningLeaf, newpispip )
|
{
|
if( pispips_o.Find( newpispip ) < 0 ) //PISPIP not already added to the set
|
{
|
newpispip.GetUpstreamPISPIPs( depth, pispips_o );
|
}
|
}
|
}
|
|
|
// Traverse over the lanelegs that supply this PISPIP
|
traverse( this, ProductInStockingPoint_MP.LaneLegOutput.LaneLeg, laneleg, laneleg.GetIsAvailableForOptimization() )
|
{
|
unit := laneleg.Lane().Unit();
|
unitperiod := UnitPeriod::FindUnitPeriodTypeIndex( unit.ID(), period.Start(), period.End() );
|
|
// Select the existing trips of this laneleg on this unit period
|
// Normally there should only be a single trip, but the user may have created multiple trips for a single unit period
|
trips := selectset( laneleg, Trip, trip, trip.ArrivalUnitPeriod() = unitperiod );
|
|
// If no such trip exists and it would be a valid nonfrozen trip, then create a new trip
|
if( trips.Elements( relsize ) = 0
|
and Trip::GetIsValidNonFrozenTrip( laneleg, period ) )
|
{
|
trips.Add( Trip::Create( laneleg, period ) );
|
// Without the Transaction.Propagate() the trips will not have the required relations
|
Transaction::Transaction().Propagate( relation( Trip, PeriodTaskLaneLeg ) );
|
}
|
|
// Add the current product to the trips (if it is not yet part of these trips)
|
traverse( trips, Elements, trip,
|
not exists( trip, ProductInTrip.Product_MP, product,
|
product = this.ProductInStockingPoint_MP().Product_MP() ) )
|
{
|
trip.AddProduct( this.ProductInStockingPoint_MP().Product_MP(), 0.0, false );
|
|
// Without the Transaction.Propagate() the trips will not have the required relations
|
Transaction::Transaction().Propagate( relation( ProductInTrip, DependentDemand ) );
|
}
|
|
// Add the trips to the optimizer run
|
traverse( trips, Elements, trip, trip.GetIsValidNonFrozenTrip() )
|
{
|
// Add the related productintrip to productintripsforoptimization
|
traverse( trip, ProductInTrip, productintrip,
|
productintrip.ProductID() = this.ProductInStockingPoint_MP().ProductID() )
|
{
|
newpispip := null(ProductInStockingPointInPeriod )
|
newpispip := guard( productintrip.DependentDemand().ProductInStockingPointInPeriodPlanningLeaf(), null(ProductInStockingPointInPeriodPlanningLeaf) );
|
if( isnull( newpispip ) )
|
{
|
newpispip := this;
|
}
|
if( pispips_o.Find( newpispip ) < 0 ) //PISPIP not already added to the set
|
{
|
newpispip.GetUpstreamPISPIPs( depth, pispips_o );
|
}
|
}
|
}
|
}
|
}
|
*]
|
}
|