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