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