| Quintiq file version 2.0 | 
| #parent: #root | 
| StaticMethod CreateOrUpdateForUnitPeriodTime ( | 
|   UnitPeriodTime unitperiodtime, | 
|   Boolean isbatcheditmaintenance, | 
|   String timeunit, | 
|   Duration maintenance, | 
|   Boolean isbatcheditefficiency, | 
|   Real efficiency, | 
|   Boolean isbatcheditallocation, | 
|   Real allocation, | 
|   Boolean isbatcheditshiftpattern, | 
|   ShiftPattern shiftpattern, | 
|   Boolean isbatcheditmaxloadpercentage, | 
|   Real maxloadpercentage, | 
|   Boolean isbatcheditnrofunitsopen, | 
|   Number nrofunitsopen, | 
|   Boolean isthisperiodonwards, | 
|   Boolean isbatcheditminimumloadthreshold, | 
|   Real minimumloadthreshold | 
| ) | 
| { | 
|   Description: "Create or update the unit availability when we want only the particular unit period time user's value ( get from unit availability ) change." | 
|   TextBody: | 
|   [* | 
|     // soh yee Feb-20-2013 (modified) | 
|     // This method can be used to change either shift pattern or number of units open / close for the unit period time too. | 
|      | 
|     unitavailability := unitperiodtime.UnitAvailability(); | 
|     unit := unitperiodtime.Unit(); | 
|      | 
|     // If the batch edit checkbox in UI is unchecked, we get back the current unit availability data. | 
|     // Did not use guard for better readability. | 
|     if( not isbatcheditmaintenance ) | 
|     { | 
|       timeunit := unitperiodtime.Period_MP().TimeUnit() ; | 
|       maintenance := Duration::Zero(); | 
|      | 
|       if( unitperiodtime.HasCapacityDefinition() ) | 
|       { | 
|         timeunit := unitavailability.TimeUnit(); | 
|         maintenance := unitavailability.Maintenance(); | 
|       } | 
|     } | 
|      | 
|     if( not isbatcheditefficiency ) | 
|     { | 
|       efficiency := unitperiodtime.Efficiency(); | 
|      | 
|       if( unitperiodtime.HasCapacityDefinition() ) | 
|       { | 
|         efficiency := unitavailability.Efficiency(); | 
|       } | 
|     } | 
|      | 
|     if( not isbatcheditallocation ) | 
|     { | 
|       allocation := unitperiodtime.Allocation(); | 
|      | 
|       if( unitperiodtime.HasCapacityDefinition() ) | 
|       { | 
|         allocation := unitavailability.Allocation(); | 
|       } | 
|     } | 
|      | 
|     if( not isbatcheditshiftpattern ) | 
|     { | 
|       shiftpattern := unitperiodtime.ShiftPattern(); | 
|      | 
|       if( unitperiodtime.HasCapacityDefinition() ) | 
|       { | 
|         shiftpattern := unitavailability.ShiftPattern(); | 
|       } | 
|     } | 
|      | 
|     if( not isbatcheditmaxloadpercentage ) | 
|     { | 
|       maxloadpercentage := unitperiodtime.MaximumLoadPercentage(); | 
|      | 
|       if( unitperiodtime.HasCapacityDefinition() ) | 
|       { | 
|         maxloadpercentage := unitavailability.MaximumLoadPercentage(); | 
|       } | 
|     } | 
|      | 
|     if( not isbatcheditnrofunitsopen ) | 
|     { | 
|       nrofunitsopen := unitperiodtime.NrOfOpen(); | 
|      | 
|       if( unitperiodtime.HasCapacityDefinition() ) | 
|       { | 
|         nrofunitsopen := unitavailability.NrOfUnitsOpen(); | 
|       } | 
|     } | 
|      | 
|     if( not isbatcheditminimumloadthreshold ) | 
|     {   | 
|       minimumloadthreshold := unitperiodtime.MinimumLoadThreshold(); | 
|      | 
|       if( unitperiodtime.HasCapacityDefinition() ) | 
|       { | 
|         minimumloadthreshold := unitavailability.MinimumLoadThreshold(); | 
|       } | 
|     } | 
|      | 
|     /* | 
|     Case1: all unit period time are referring to Jan, S12 | 
|     Unit period time      Unit availability | 
|       Jan                     Jan, S12 | 
|       Feb | 
|       Mar | 
|       Apr | 
|      | 
|     Case2: when user drop S15 to Mar, (a) and (b) are created. | 
|     Unit period time      Unit availability | 
|       Jan                     Jan, S12 | 
|       Feb                     Mar, S15 (a) | 
|       Mar                     Apr, S12 (b) | 
|       Apr | 
|      | 
|      | 
|     Case3: when user drop S15 to Jan, (c) is updated. | 
|     Unit period time      Unit availability | 
|       Jan                     Jan, S15 (c) | 
|       Feb                     Mar, S15 (a) | 
|       Mar                     Apr, S12 (b) | 
|       Apr | 
|      | 
|     Special case: When the scenario have parallel periods, for example Weeks and Days. | 
|     Unit period quantity      Unit capacity | 
|     Week 1 (isbase)           Week 1 | 
|     Week 2 (isbase)           Week 2 | 
|     Week 3 (not base)         Day 1, Day 2, Day 3, Day 5, Day 6, Day 7 | 
|     Week 4 (not base)         Day 1, Day 2, Day 3, Day 5, Day 6, Day 7 | 
|     */ | 
|      | 
|     nextupt := unitperiodtime.Next().astype( UnitPeriodTime ); | 
|     nextunitavailability := guard( nextupt.UnitAvailability(), null( UnitAvailability ) ); | 
|      | 
|     // Get all period dimension children's unit capacity, for handling special case and when isthisperiodonwads is true | 
|     unitavailabilities := selectset( unit, UnitAvailability, ua, | 
|                                      ua.Start() >= unitperiodtime.Start() | 
|                                      and ( ua.Start() < unitperiodtime.Period_MP().End() // Ignore the end if isthisperiodonwards | 
|                                            or isthisperiodonwards ) ); | 
|      | 
|     // To handle special case and when isthisperiodonwads is true | 
|     if( unitavailabilities.Size() > 0 | 
|         and not isnull( nextupt ) ) | 
|     { | 
|       lastchilduc := null( UnitAvailability ); | 
|      | 
|       // If have next uc, we want to shift the last uc from the childuc as next period uc | 
|       if( not isthisperiodonwards ) | 
|       { | 
|         // Shift the last uc of the child period to next period | 
|         lastchilduc := maxselect( unit, UnitAvailability, ua, unitperiodtime.End() >= ua.Start(), ua.Start() ); | 
|      | 
|         if( UnitAvailability::IsPrimaryKeysUnique( unit, nextupt.Start(), null( UnitAvailability ) ) ) | 
|         { | 
|           // Keep all value except the start, to handle period > day where it have uc start in the middle of the period | 
|           // We will shift the last uc to next period | 
|           lastchilduc.Update( lastchilduc.Unit(), | 
|                               nextupt.Start(), | 
|                               lastchilduc.TimeUnit(), | 
|                               lastchilduc.Maintenance(), | 
|                               lastchilduc.Efficiency(), | 
|                               lastchilduc.Allocation(), | 
|                               lastchilduc.ShiftPattern(), | 
|                               lastchilduc.MaximumLoadPercentage(), | 
|                               lastchilduc.NrOfUnitsOpen(), | 
|                               lastchilduc.MinimumLoadThreshold(), | 
|                               false  | 
|                             ); | 
|         } | 
|       } | 
|      | 
|       // Delete all uc except the shifted one (also for handle isthisperiodonwads for week 3, 4 Day 1~7 for the given example) | 
|       traverse( unitavailabilities, Elements, e, | 
|                 e <> unitavailability | 
|                 and e <> lastchilduc ) | 
|       { | 
|         e.Delete(); | 
|       } | 
|      | 
|       // Propogate the relation to unit period quantity. | 
|       // This is needed for the following checking. | 
|       Transaction::Transaction().Propagate(); | 
|     } | 
|      | 
|     if( not isthisperiodonwards | 
|         and not isnull( nextupt ) | 
|         and nextunitavailability = unitavailability | 
|         and UnitAvailability::IsPrimaryKeysUnique( unit, nextupt.Start(), null( UnitAvailability ) ) ) | 
|     { | 
|       // Case2: creating (b) | 
|       periodspec := nextupt.Period_MP().PeriodSpecification_MP();  | 
|       nexttimeunit := ifexpr( not isnull( periodspec ), periodspec.TimeUnit(), nextupt.Period_MP().TimeUnit() ); | 
|       nextmaintenance := Duration::Zero(); | 
|       nextefficiency := nextupt.Efficiency(); | 
|       nextallocation := nextupt.Allocation(); | 
|       nextshiftpattern := nextupt.ShiftPattern(); | 
|       nextmaxloadpercentage := nextupt.MaximumLoadPercentage() | 
|       nextnrofunitsopen := nextupt.NrOfOpen(); | 
|       nextminimumloadthreshold := nextupt.MinimumLoadThreshold(); | 
|      | 
|       if( unitperiodtime.HasCapacityDefinition() ) | 
|       { | 
|         nexttimeunit := unitavailability.TimeUnit(); | 
|         nextmaintenance := unitavailability.Maintenance(); | 
|         nextefficiency := unitavailability.Efficiency(); | 
|         nextallocation := unitavailability.Allocation(); | 
|         nextshiftpattern := unitavailability.ShiftPattern(); | 
|         nextmaxloadpercentage := unitavailability.MaximumLoadPercentage(); | 
|         nextnrofunitsopen := unitavailability.NrOfUnitsOpen(); | 
|         nextminimumloadthreshold := unitavailability.MinimumLoadThreshold(); | 
|       } | 
|      | 
|       UnitAvailability::Create( unit, | 
|                                 nextupt.Start(), | 
|                                 nexttimeunit, | 
|                                 nextmaintenance, | 
|                                 nextefficiency, | 
|                                 nextallocation, | 
|                                 nextshiftpattern, | 
|                                 nextmaxloadpercentage, | 
|                                 nextnrofunitsopen, | 
|                                 nextminimumloadthreshold, | 
|                                 false | 
|                               ); | 
|      | 
|       // Propogate the relation to unit period time. | 
|       // This is needed for the following checking. | 
|       Transaction::Transaction().Propagate(); | 
|     } | 
|      | 
|     // Create a new unit availability for that particular unit period time if it does not bind to any unit availability, or if it has a unit availability, | 
|     // the related unit availability doesn't have the same start as the unit period time. | 
|     if( not unitperiodtime.HasCapacityDefinition() | 
|         or UnitAvailability::IsPrimaryKeysUnique( unit, unitperiodtime.Start(), null( UnitAvailability ) ) ) | 
|     { | 
|       // Case2: creating (a) | 
|       UnitAvailability::Create( unit, | 
|                                 unitperiodtime.Start(), | 
|                                 timeunit, | 
|                                 maintenance, | 
|                                 efficiency, | 
|                                 allocation, | 
|                                 shiftpattern, | 
|                                 maxloadpercentage, | 
|                                 nrofunitsopen, | 
|                                 minimumloadthreshold, | 
|                                 false | 
|                               ); | 
|     } | 
|      | 
|     else | 
|     { | 
|       // Case3 | 
|       unitavailability.Update( unit, | 
|                                unitavailability.Start(), | 
|                                timeunit, | 
|                                maintenance, | 
|                                efficiency, | 
|                                allocation, | 
|                                shiftpattern, | 
|                                maxloadpercentage, | 
|                                nrofunitsopen, | 
|                                minimumloadthreshold, | 
|                                false | 
|                              ); | 
|     } | 
|   *] | 
| } |