Quintiq file version 2.0 
 | 
#parent: #root 
 | 
Method GetBaseAvailableCapacity ( 
 | 
  const ShiftPattern shiftpattern 
 | 
) const declarative as Duration 
 | 
{ 
 | 
  TextBody: 
 | 
  [* 
 | 
    value := Duration::Zero(); 
 | 
     
 | 
    datetimevector := DateTimeVector::Construct(); 
 | 
    durationvector := RealVector::Construct(); 
 | 
     
 | 
    planningup := ifexpr( this.IsPlanning(),  
 | 
                            this,                                             // Case 1: planning UnitPeriod: aggregate values from associated period tasks  
 | 
                            this.PlanningUP().astype( UnitPeriodTimeBase ) ); // Case 2: base, non planning UnitPeriod: disaggregate value from planning UnitPeriod 
 | 
                            
 | 
    if( not isnull( planningup ) ) 
 | 
    { 
 | 
      if( not isnull( planningup.Period_MP() )  
 | 
          and not isnull( 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 := shiftpattern.ShiftDay( relsize ); 
 | 
      
 | 
        if( not isnull( planningup.Previous() ) ) 
 | 
        { 
 | 
          lastshiftday := planningup.Previous().astype( UnitPeriodTimeBase ).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( shiftpattern, ShiftDay, shift, shift.Day() = shiftday, true ); 
 | 
          unavailable := planningup.Unit().UnavailableTime( firstday + Duration::Days( i ), firstday + Duration::Days( i + 1 ) ); 
 | 
     
 | 
          if( not isnull( shift ) ) 
 | 
          { 
 | 
            shiftduration := maxvalue( ( shift.Capacity() - unavailable ), Duration::Zero() ); 
 | 
            //value := value + shiftduration; 
 | 
            datetimevector.Append( firstday + Duration ::Days( i ) ); 
 | 
            durationvector.Append( shiftduration.HoursAsReal() ); 
 | 
          } 
 | 
        } // for  
 | 
        
 | 
        value := this.GetPlanningCapacity( datetimevector, durationvector ); 
 | 
      }// if planning period not in hour 
 | 
      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.Efficiency() * planningup.Allocation()  -  ( planningup.Maintenance() * this.PlanningSystemRatio() ) )* planningup.NrOfOpen(), Duration::Zero() );    
 | 
    } 
 | 
     
 | 
    return value; 
 | 
  *] 
 | 
} 
 |