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
72
73
74
75
76
77
78
Quintiq file version 2.0
#parent: #root
FunctionOverride CalcTotalAvailableCapacity
{
  TextBody:
  [*
    value := Duration::Zero();
    planningcapacity := 1.0;
    
    if( this.IsPlanning() or this.IsBase() )
    {
      planningup := ifexpr( this.IsPlanning(), 
                            this,                                                  // Case 1: planning UnitPeriod: aggregate values from associated period tasks 
                            this.PlanningUP().astype( UnitPeriodTransportTime ) ); // Case 2: base, non planning UnitPeriod: disaggregate value from planning UnitPeriod
    
    
      if( not isnull( planningup ) )
      {
        // Determined by the used shift pattern, the efficiency rate, maintenance considering its maintenance factor, allocation, max load percentage and calendar elements.
        
        if( not isnull( planningup.Period_MP() ) 
            and not isnull( planningup.ShiftPattern() ) 
            and not planningup.Period_MP().IsInHour() ) //gdn1 HourlyPeriod is not applicable for ShiftPattern
        {
          lastshiftday := planningup.StartDate() - planningup.Period_MP().Start().StartOfWeek().Date() + 1
      
          nrdaysinthisperiod := planningup.Duration().DaysAsReal();
          firstday := planningup.Period_MP().Start();
          numberofshiftday := planningup.ShiftPattern().ShiftDay( relsize );
      
          if( not isnull( planningup.Previous() ) )
          {
            lastshiftday := planningup.Previous().astype( UnitPeriodTransportTime ).PreviousPeriodLastShiftDay() + 1;
          }
      
          for( i := 0; i < nrdaysinthisperiod and firstday + Duration::Days( i ) >= planningup.Unit().StartDate().DateTime() ; i++ )
          {
            shiftday := lastshiftday + i;
      
            if( shiftday > numberofshiftday )
            {
              shiftday := shiftday mod numberofshiftday;
      
              if( shiftday = 0 )
              {
                shiftday := numberofshiftday;
              }
            }
      
            shift := select( planningup.ShiftPattern(), ShiftDay, shift, shift.Day() = shiftday, true );
            unavailable := planningup.Unit().UnavailableTime( firstday + Duration::Days( i ), firstday + Duration::Days( i + 1 ) );
      
            if( not isnull( shift ) )
            {
              value := value + maxvalue( ( shift.Capacity() - unavailable ), Duration::Zero() );
            }
          }
        }
        else if ( planningup.Period_MP().DurationInDays() < 1 )   //gdn1 HourlyPeriod is always same as PeriodDuration 
        {
          value := planningup.Unit().UnitCalendar().AvailableTime( planningup.Start(), planningup.End(), 0.00000001 ); // Check calendar to make hourly period work with the calendar
        }
        
        value := maxvalue( ( value - planningup.Maintenance() ) * planningup.NrOfOpen(), Duration::Zero() );
      
        planningcapacity := value.HoursAsReal() * planningup.MaximumLoadPercentage() / 100;
        
        planningcapacity := this.PlanningSystemRatio() * planningcapacity;
      }
    }
    else
    { // Case 3: aggregated UnitPeriod: aggregate values from base
      planningcapacity := sum( this.GetChildrenOfPeriodDimension(), Elements.astype( UnitPeriodTransportTime ), e, e.TotalAvailableCapacity().HoursAsReal() );
    }
    
    this.TotalAvailableCapacity( Duration::Hours( planningcapacity ) );
  *]
}