yanweiyuan3
2023-08-09 588bc7829387dfc761cc25f06f77d4c81818bd10
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Quintiq file version 2.0
#parent: #root
Function CalcShelfLifePlannedEndAgeAndQuantityVectorAsBinaryValue
{
  TextBody:
  [*
    // Get the shelf life supply vectors
    quantityvector := RealVector::Construct( this.ShelfLifeSupplyAfterDDQuantityVectorAsBinaryValue() );
    agevector := RealVector::Construct( this.ShelfLifeSupplyAfterDDAgeVectorAsBinaryValue() );
    pispippl := this.ProductInStockingPointInPeriodPlanningLeaf();
    
    // Check if the product has shelf life or maturation
    product := pispippl.ProductInStockingPoint_MP().Product_MP();
    if( product.HasShelfLifeOrMaturation() )
    {
      // Deduct the values of the elements in the shelf life supply vectors with the values of sales demand and operation demand  
      salesdemands := pispippl.GetSortedLeafSalesDemandsInPeriod();
      salesdemand := sum( salesdemands, Elements, e,
                          true,
                          ifexpr( e.HasOptimizerFulfillment() or not e.IsWithinThresholdQuantity(),
                                  e.OptimizerFulfilledQuantity(),
                                  e.QuantityForSystemFulfilledQuantity() ) );
    
      salesdemandforaggregated := sum ( pispippl.GetDisaggregatedSalesDemandInPeriod(), 
                                     Elements, 
                                     e, 
                                     true, 
                                     ifexpr( e.HasOptimizerFulfillment() or not e.IsWithinThresholdQuantity(),
                                     e.OptimizerFulfilledQuantity(),
                                     e.QuantityForSystemFulfilledQuantity() ) ); 
    
      salesdemandfornegativesupply := sum( pispippl, InventorySupply, invsup, invsup.Quantity() < 0, abs( invsup.Quantity() ) );     
    
      salesdemand := salesdemand + salesdemandforaggregated + salesdemandfornegativesupply; 
            
      // The quantity and age consumed by sales demand
      source_quantityconsumedvector := RealVector::Construct();
      source_ageconsumedvector := RealVector::Construct();
      
      ShelfLife::SetAvailableAgeAndQuantityVectorAfterDemand( quantityvector, agevector,
                                                              source_quantityconsumedvector, source_ageconsumedvector,
                                                              salesdemand,
                                                              false, // do not ignore maturation
                                                              true, // consume oldest product first if possible
                                                              pispippl,
                                                              0.0 // the passed in source_agevector has not been aged so there is need to un-age 
                                                            );
      
      // Get the age that is considered expired
      if( product.HasShelfLife() )
      {
        isnonexpiredinperiodvector := BooleanVector::Construct();
        traverse( agevector.AsValues(), Elements, age )
        {
          isusableinperiod := product.GetIsUsableInTargetPeriod( [Real] age, pispippl.Start(), pispippl.Period_MP() );
          isnonexpiredinperiodvector.Append( isusableinperiod );
        }
            
        agevector := agevector.GetSelection( isnonexpiredinperiodvector );
        quantityvector := quantityvector.GetSelection( isnonexpiredinperiodvector );
      }
      
      durationindays := pispippl.Period_MP().DurationInDays();
      durationindays := durationindays;
      agevector := agevector.Plus( durationindays );
    }
    
    this.ShelfLifePlannedEndAgeVectorAsBinaryValue( agevector.AsBinaryValue() );
    this.ShelfLifePlannedEndQuantityVectorAsBinaryValue( quantityvector.AsBinaryValue() );
  *]
}