| 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() ); | 
|   *] | 
| } |