Quintiq file version 2.0
|
#parent: #root
|
StaticMethod SetAvailableAgeAndQuantityVectorAfterDemand (
|
RealVector quantityvector,
|
RealVector agevector,
|
RealVector quantityconsumedvector,
|
RealVector ageconsumedvector,
|
Real demand,
|
Boolean isignorematuration,
|
Boolean isconsumeoldeststockfirst,
|
ProductInStockingPointInPeriodPlanningLeaf pispippl,
|
Real agetobereduced
|
) declarative
|
{
|
Description: 'Set the remaining age and quantity vector after being consumed by sales demand'
|
TextBody:
|
[*
|
product := pispippl.ProductInStockingPoint_MP().Product_MP();
|
delta := demand;
|
|
agevectorasvalues := agevector.AsValues();
|
agevectordummyasvalues := agevector.AsValues();
|
// Sort the age values as ascending
|
agevectordummyasvalues := agevectordummyasvalues.Sort();
|
// If the the oldest stocks are to be consumed first, sort the age values as descending
|
if( isconsumeoldeststockfirst )
|
{
|
agevectordummyasvalues := agevectordummyasvalues.Reverse();
|
}
|
for( i := 0;
|
i < quantityvector.Size()
|
and delta > 0;
|
i++ )
|
{
|
|
age := agevectordummyasvalues.Element( i );
|
index := agevectorasvalues.Find( age );
|
|
// Check if product has shelf life or maturation
|
// Only sales demand or routing dependent demand requires maturation constraint
|
// Laneleg dependent demand doesn't have constraint on maturation because the product can continue to mature in trip
|
if( ( not product.HasShelfLife()
|
or product.GetIsUsableInTargetPeriod( [Real] age, pispippl.Start(), pispippl.Period_MP() )
|
)
|
and ( isignorematuration
|
or not product.HasMaturation()
|
or product.GetIsMaturedInTargetPeriod( [Real] age, pispippl.Start(), pispippl.Period_MP() )
|
)
|
)
|
{
|
avail_qty := quantityvector.Get( index );
|
qtyfulfilled := minvalue( avail_qty, delta );
|
quantityvector.Set( index, avail_qty - qtyfulfilled );
|
|
quantityconsumedvector.Append( qtyfulfilled );
|
ageconsumedvector.Append( age );
|
|
delta := delta - qtyfulfilled;
|
}
|
}
|
|
// Get element in quantity vector with valid value
|
isquantityvalidvector := quantityvector.GreaterThan( 0.0 );
|
validquantityvector := quantityvector.GetSelection( isquantityvalidvector );
|
validagevector := agevector.GetSelection( isquantityvalidvector );
|
|
// Set the vectors with new elements
|
quantityvector.Resize( 0 );
|
agevector.Resize( 0 );
|
quantityvector.Append( validquantityvector );
|
agevector.Append( validagevector );
|
|
// When allocating to DependentDemands, the passed in age vector has been aged according to the trip's lead time.
|
// Here, we will un-age those supply so that the remaining supplies can still be used.
|
// E.g. assuming shelf life is 6 days, DD qty is 7.033, trip's lead time is 3 days.
|
// Supply before aged:
|
// 178.9(7), 192.967(4), 7.033(3)
|
// when being passed into this method, you will get
|
// 178.9(10), 192.967(7), 7.033(6)
|
// 7.033(6) is the only suitable candidate for the DD because it will not expire when arrives at destination
|
// You are left with
|
// 178.9(10), 192.967(7)
|
// By right in this period, we should have remaining 178.9(7), 192.967(4)
|
// If you don't unage them, MergeVectorAccordingToAgeAndExpiration will return 0
|
ageconsumedvector_mod := ageconsumedvector.Minus( agetobereduced );
|
ageconsumedvector.Resize( 0 );
|
ageconsumedvector.Append( ageconsumedvector_mod );
|
|
agevector_mod := agevector.Minus( agetobereduced );
|
agevector.Resize( 0 );
|
agevector.Append( agevector_mod );
|
|
// Merge the elements in vector according to age
|
ShelfLife::MergeVectorAccordingToAgeAndExpiration( quantityvector, agevector,
|
pispippl,
|
pispippl.Start() );
|
*]
|
}
|