| Quintiq file version 2.0 | 
| #parent: #root | 
| StaticMethod GenerateDailyCapacity ( | 
|   MacroPlan macroPlan, | 
|   Date indexDate, | 
|   String unitID | 
| ) as Duration | 
| { | 
|   TextBody: | 
|   [* | 
|     returnCapacity := Duration::Zero(); | 
|          | 
|     traverse ( macroPlan, Unit.UnitPeriod.astype( UnitPeriodTimeBase ), this, this.UnitID() = unitID and  | 
|                                                                               this.StartDate() <= indexDate and  | 
|                                                                               this.End().Date() > indexDate and | 
|                                                                               /*this.IsBase() and*/ | 
|                                                                               this.IsPlanning() ) { | 
|       // Determined by the used shift pattern, the efficiency rate, maintenance considering its maintenance factor, allocation, max load percentage and calendar elements. | 
|       //  debuginfo( "遍历的时间节点(开始时间):", this.StartDate(), "    结束时间:", this.End() ); | 
|       value := Duration::Zero(); | 
|            | 
|       datetimevector := DateTimeVector::Construct(); | 
|       durationvector := RealVector::Construct(); | 
|            | 
|       if( this.IsPlanning() or this.IsBase() ) | 
|       { | 
|         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( 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( 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( 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 ) ) | 
|                { | 
|                  shiftduration := maxvalue( ( shift.Capacity() - unavailable ), Duration::Zero() ); | 
|                  //value := value + shiftduration; | 
|                  datetimevector.Append( firstday + Duration ::Days( i ) ); | 
|                  durationvector.Append( shiftduration.HoursAsReal() ); | 
|                } | 
|                if ( /*this.UnitID() = unitID and this.IsBase() and this.IsPlanning() and*/ ( this.StartDate() + i ) = indexDate ) { | 
|           //          debuginfo( "当前开始时间:", this.StartDate() + i, "    当前产能:", maxvalue( ( shift.Capacity() - unavailable ), Duration::Zero() ) ); | 
|           //          this.MacroPlan().UnitPeriodTimeBaseDailyCapacity( relnew, startDate := this.StartDate() + i, | 
|           //                                                                    capacity := maxvalue( ( shift.Capacity() - unavailable ), Duration::Zero() ) ); | 
|                     returnCapacity := maxvalue( ( shift.Capacity() - unavailable ), Duration::Zero() ); | 
|                 } | 
|              } // 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() );    | 
|         } | 
|       } | 
|       else | 
|       { | 
|              | 
|         value := sum( this.GetChildrenOfPeriodDimension(), Elements.astype( UnitPeriodTimeBase ), e, e.BaseAvailableCapacity() ); | 
|       } | 
|            | 
|       //  this.BaseAvailableCapacity( value );   | 
|     } | 
|          | 
|     return returnCapacity; | 
|   *] | 
| } |