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
Quintiq file version 2.0
#parent: #root
Method GetAverageSalesDemandQtyPerDay () const declarative remote as Real
{
  Description:
  [*
    The average daily sales demand over the next "target in days" days.
    If not target in days has been defined, then the default number of periods will be used.
    If there is no sales demand in that horizon, then the average daily sales demand over the whole horizon will be calculated.
  *]
  TextBody:
  [*
    demandperday := 1.0
    
    // If this PISPIP is not related to a product in stocking point with demand then the average sales demand qty per day is not relevant
    // If this is not a leading period, then it will not be considered by the optimizer and the avg sales demand qty per day is also not relevant
    if( this.ProductInStockingPoint_MP().HasSalesDemand() )
    {
      // By default, we will balance the inventory number of demand days based on the average daily demand in the next X periods
      numberofdays := this.ProductInStockingPoint_MP().Product_MP().MacroPlan().GlobalParameters_MP().DefaultNumberOfPeriodsForAvgDemand() * this.Period_MP().DurationInDays();
      
      // If there is a target in days, then we will calculate the average sales demand over the next "target in days" days
      if( this.GetHasTargetInDays() and this.TargetInDays() > 0 )
      {
        numberofdays := this.TargetInDays();
      }
      // Set the numberofdays to 1 if it was zero, to avoid a division by 0
      else if( numberofdays = 0.0 )
      {
        numberofdays := 1.0;
      }
    
      // otherwise it is based on the defaultnumberofdays
      nextpispips := this.GetNextPlanningPISPIPs( numberofdays )
            
      // If there are no next pispips, calculate the average sales demand qty based on the current period
      if( nextpispips.Size() = 0 )
      {
        nextpispips := selectset( this, ProductInStockingPoint_MP.ProductInStockingPointInPeriodPlanning, pispip, pispip = this );
      }
      
      // Calculate the total demand in the next numberofdays days
      totaldemand := ProductInStockingPointInPeriodPlanning::GetTotalDemandInRemainingDays( nextpispips, numberofdays );
    
      // The demand per day is equal to the average sales demand per day over these days
      demandperday := totaldemand / numberofdays;
      
      // If the demandperday is 0, then use the average demand per day over the whole horizon
      if( demandperday = 0 )
      {
        demandperday := average( this, ProductInStockingPoint_MP.ProductInStockingPointInPeriodPlanning, pispip,
                                 guard( pispip.SalesDemandQuantity() / pispip.Period_MP().DurationInDays(), 0.0 ) );
      }
    }
    
    return demandperday;
  *]
}