Quintiq file version 2.0
|
#parent: #root
|
MethodOverride Update (
|
Real quantity
|
)
|
{
|
TextBody:
|
[*
|
// soh yee Sep-25-2015 (created)
|
nonlockingsupplies := selectset( this.GetNewSupplies(), Elements, ns,
|
not ns.GetHasUserQuantity() );
|
|
|
// ************ Locking with current quantity ratio ************
|
// For those with user quantity, the quantity will be adjusted accordingly based on its previous ratio
|
// Porportional disaggregation
|
lockingsupplies := this.GetNewSupplies().Difference( nonlockingsupplies );
|
totallockingquantity := 0.0;
|
thisquantity := this.Quantity();
|
|
|
if( thisquantity > 0 )
|
{
|
traverse( lockingsupplies, Elements, ns )
|
{
|
newquantity := quantity * ns.Quantity() / thisquantity;
|
ns.Update( newquantity );
|
|
totallockingquantity := totallockingquantity + newquantity;
|
}
|
}
|
else
|
{
|
// In case of aggregated supply quantity is 0, we will treat the locked supply as nonlock to disaggregate using default factor
|
nonlockingsupplies := lockingsupplies.Union( nonlockingsupplies );
|
}
|
|
// ************ Locking using default factor ************
|
// The remaining quantity will be disaggregated to the new supplies not set by the user, using the default factor specified by user
|
// Manual disaggregation
|
remainingquantity := quantity - totallockingquantity;
|
|
// Disaggregation based on pisp
|
// To keep it simply, take the effective accumulated disggregation factor that belongs to the supply period.
|
period := this.ProductInStockingPointInPeriod().Period_MP();
|
totalpispfactor := sum( nonlockingsupplies,
|
Elements.ProcessOutput.ProductInStockingPoint_MP,
|
pisp,
|
pisp.GetAccumulateDisaggregationFactor( period ) );
|
|
traverse( nonlockingsupplies, Elements, ns )
|
{
|
pisp := ns.ProcessOutput().ProductInStockingPoint_MP();
|
|
// Disaggregation on period dimension
|
// If there is at least a unit period planned infinite, we will distribute the quantity based on the duration of the period to planned infinite periods.
|
totalavailability := sum( nonlockingsupplies, Elements, nns,
|
nns.ProcessOutput().ProductInStockingPoint_MP() = pisp
|
and nns.PeriodTask_MP().UnitPeriod().IsPlannedInfinite(),
|
nns.PeriodTask_MP().UnitPeriod().Duration().DaysAsReal() );
|
|
hasinfiniteperiod := totalavailability > 0;
|
|
if( totalavailability = 0 )
|
{
|
// The disaggregated quantity on pisp will be disaggregated to each period based on unit period availability of the period
|
totalavailability := sum( nonlockingsupplies, Elements, nns, nns.ProcessOutput().ProductInStockingPoint_MP() = pisp,
|
nns.GetUnitPeriodAvailableCapacity() );
|
}
|
disaggqty := 0.0;
|
|
if( totalpispfactor > 0 and totalavailability > 0 )
|
{
|
availability := 0.0;
|
unitperiod := ns.PeriodTask_MP().UnitPeriod();
|
|
if( hasinfiniteperiod )
|
{
|
if( unitperiod.IsPlannedInfinite() )
|
{
|
availability := unitperiod.Duration().DaysAsReal();
|
}
|
}
|
else
|
{
|
availability := ns.GetUnitPeriodAvailableCapacity();
|
}
|
disaggqty := remainingquantity
|
* ns.GetProductAccumulateDisaggregationFactor() / totalpispfactor
|
* availability / totalavailability;
|
|
/*
|
debuginfo('disaggr qty:', disaggqty , '=',
|
'*', ns.GetProductAccumulateDisaggregationFactor(), 'adf',
|
'/', totalpispfactor, 'ttlpispf',
|
'*', availability, 'av',
|
'/', totalavailability, 'ttlav'
|
);
|
*/
|
}
|
ns.Update( disaggqty );
|
}
|
|
// ********** Create new supplies that belongs to this aggregated supplies but do not exist yet ***********
|
// The quantity on the leaf level will be locked whenever its aggregated supply is manually edited.
|
// Thus, the new supplies will be created and will be locked (set to 0 with hasuser flag) to prevent the optimizer overrides it
|
operation := guard( this.Process_MP().astype( Operation ), null( Operation ) );
|
|
if( not isnull( operation ) )
|
{
|
this.ProductInStockingPointInPeriod().CreateOperationNewSupplies( operation, 0.0, true );
|
}
|
*]
|
}
|