/// <summary> /// Computes the overall currency /// </summary> protected override void ComputeComposite() { // Compute currency according to 61.57(c)(1)-(5) and 61.57(e) // including each one's expiration. The one that expires latest is the expiration date if you are current, the one that // expired most recently is the expiration date since when you were not current. // 61.57(c)(1) (66-HIT in airplane, flight simulator, ATD, or FTD) OR an IPC. FlightCurrency fcIFR = fcIPCOrCheckride.OR(fcIFRApproach.AND(fcIFRHold)); CompositeCurrencyState = fcIFR.CurrentState; CompositeExpiration = fcIFR.ExpirationDate; if (fcIPCOrCheckride.IsCurrent() && fcIPCOrCheckride.ExpirationDate.CompareTo(CompositeExpiration) >= 0) { Query.HasHolds = Query.HasApproaches = false; Query.PropertiesConjunction = GroupConjunction.Any; Query.PropertyTypes.Clear(); foreach (CustomPropertyType cpt in CustomPropertyType.GetCustomPropertyTypes()) { if (cpt.IsIPC) { Query.PropertyTypes.Add(cpt); } } } if (CompositeCurrencyState == CurrencyState.NotCurrent) { // if more than 6 calendar months have passed since expiration, an IPC is required. // otherwise, just assume 66-HIT. if (DateTime.Compare(CompositeExpiration.AddCalendarMonths(6).Date, DateTime.Now.Date) > 0) { CompositeDiscrepancy = String.Format(CultureInfo.CurrentCulture, Resources.Currency.DiscrepancyTemplateIFR, fcIFRHold.Discrepancy, (fcIFRHold.Discrepancy == 1) ? Resources.Currency.Hold : Resources.Currency.Holds, fcIFRApproach.Discrepancy, (fcIFRApproach.Discrepancy == 1) ? Resources.Totals.Approach : Resources.Totals.Approaches); } else { CompositeDiscrepancy = Resources.Currency.IPCRequired; } } else { // Check to see if IPC is required by looking for > 6 month gap in IFR currency. // For now, we won't make you un-current, but we'll warn. // (IPC above, though, is un-current). CurrencyPeriod[] rgcpMissingIPC = fcIFR.FindCurrencyGap(fcIPCOrCheckride.MostRecentEventDate, 6); CompositeDiscrepancy = rgcpMissingIPC != null ? String.Format(CultureInfo.CurrentCulture, Resources.Currency.IPCMayBeRequired, rgcpMissingIPC[0].EndDate.ToShortDateString(), rgcpMissingIPC[1].StartDate.ToShortDateString()) : string.Empty; } }
/// <summary> /// Computes the overall currency /// </summary> protected override void ComputeComposite() { if (fcLandings.HasBeenCurrent || fcHours.HasBeenCurrent) { FlightCurrency fcAggregate = fcHours.OR(fcLandings); CompositeCurrencyState = fcAggregate.CurrentState; CompositeExpiration = fcAggregate.ExpirationDate; // By definition, if we are not current then both are not current. Arbitrarily pick hours as instructor as discrepancy CompositeDiscrepancy = (CompositeCurrencyState == CurrencyState.NotCurrent) ? String.Format(CultureInfo.CurrentCulture, Resources.Currency.DiscrepancyTemplate, fcHours.Discrepancy, Resources.Currency.HoursAsInstructor) : string.Empty; } }
private void RefreshCurrency() { if (m_fCacheValid) { return; } // Compute both loose (ignores takeoffs) and strict (requires takeoffs) night currencies. // Discrepancy can't be counted on after AND/OR so we set that to the one we wish to expose FlightCurrency fc6157b = this; // just for clarity that the "this" object does the basic 61.57(b) implementation. FlightCurrency fc6157e4i = m_fc6157eTotalTime.AND(m_fc6157Passenger).AND(m_fc6157TimeInType).AND(m_fc6157ei); FlightCurrency fc6157e4ii = m_fc6157eTotalTime.AND(m_fc6157Passenger).AND(m_fc6157TimeInType).AND(m_fc6157eii); FlightCurrency fcLoose = fc6157b.OR(fc6157e4i.OR(fc6157e4ii)); fcLoose.Discrepancy = fc6157b.Discrepancy; FlightCurrency fc6157bStrict = fc6157b.AND(NightTakeoffCurrency); FlightCurrency fc6157e4iStrict = fc6157e4i.AND(m_fc6157eiTakeoffs); FlightCurrency fc6157e4iiStrict = fc6157e4ii.AND(m_fc6157eiiTakeoffs); FlightCurrency fcStrict = fc6157bStrict.OR(fc6157e4iStrict).OR(fc6157e4iiStrict); // Loose rules for purposes of determining state m_csCurrent = fcLoose.CurrentState; m_dtExpiration = fcLoose.ExpirationDate; m_szDiscrepancy = fcLoose.DiscrepancyString; // determine the correct discrepancy string to show // if we've met the strict definition, we're fine - no discrepancy if (fcStrict.CurrentState.IsCurrent()) { m_szDiscrepancy = string.Empty; m_dtExpiration = fcStrict.ExpirationDate; } // else if we met the loose definition but not strict - meaning takeoffs were not found; Give a reminder about required takeoffs else if (m_csCurrent.IsCurrent()) { if (NightTakeoffCurrency.Discrepancy >= NightTakeoffCurrency.RequiredEvents) { m_szDiscrepancy = Resources.Currency.NightTakeoffReminder; } else { m_szDiscrepancy = String.Format(CultureInfo.CurrentCulture, Resources.Currency.DiscrepancyTemplateNight, NightTakeoffCurrency.Discrepancy, (NightTakeoffCurrency.Discrepancy > 1) ? Resources.Currency.Takeoffs : Resources.Currency.Takeoff); } } // else we aren't current at all - use the full discrepancy template using 61.57(b). DON'T CALL DISCREPANCY STRING because that causes an infinite recursion. else { m_szDiscrepancy = String.Format(CultureInfo.CurrentCulture, Resources.Currency.DiscrepancyTemplate, this.Discrepancy, (this.Discrepancy > 1) ? Resources.Totals.Landings : Resources.Totals.Landing); } m_fCacheValid = true; }
public override void Finalize(decimal totalTime, decimal picTime) { FlightCurrency fcNormal = fcLandings.AND(fcPIC).AND(fcDual); FlightCurrency fcAlternate = fcAlternateLandings.AND(fcAlternatePIC); FlightCurrency fcIPCAlternate = fcAlternate.OR(fcProficiencyCheck); fcResult = fcNormal.OR(fcIPCAlternate); // If you're NOT current, then you MUST follow the alternate OR a proficiency check. So don't give a "short by", just say that you need that. if (!fcResult.IsCurrent()) { DiscrepancyOverride = Resources.Currency.LAPLProficiencyCheckRequired; } }
protected override void ComputeComposite() { /* * MUST meet: * - 401.05(1)(a) OR 401.05(1)(b) AND * - 401.05(3) (24 month IPC) AND * - 6 hours and 6 approaches IF the review is more than 12 months old * * To do the latter two, we do this as (12 month IPC) OR (24 month IPC AND 6+6) */ FlightCurrency fcIFRCanada = (fc401_05_3_a_c_12month.OR(fc401_05_3_a_c_24month.AND(fc401_05_3_1_aTime).AND(fc401_05_3_1_bApproaches))).AND(fc401_05_1a.OR(fc401_05_1b)); CompositeCurrencyState = fcIFRCanada.CurrentState; CompositeExpiration = fcIFRCanada.ExpirationDate; // If the IPC is controlling, then display that an IPC is required. CompositeDiscrepancy = fc401_05_3_a_c_24month.IsCurrent() ? string.Empty : Resources.Currency.IPCRequired; }
protected override void ComputeComposite() { // Compute both loose (ignores takeoffs) and strict (requires takeoffs) night currencies. // Discrepancy can't be counted on after AND/OR so we set that to the one we wish to expose FlightCurrency fc6157b = this; // just for clarity that the "this" object does the basic 61.57(b) implementation. FlightCurrency fc6157e4i = m_fc6157eTotalTime.AND(m_fc6157Passenger).AND(m_fc6157TimeInType).AND(m_fc6157ei); FlightCurrency fc6157e4ii = m_fc6157eTotalTime.AND(m_fc6157Passenger).AND(m_fc6157TimeInType).AND(m_fc6157eii); FlightCurrency fcLoose = fc6157b.OR(fc6157e4i.OR(fc6157e4ii)); fcLoose.Discrepancy = fc6157b.Discrepancy; FlightCurrency fc6157bStrict = fc6157b.AND(NightTakeoffCurrency); FlightCurrency fc6157e4iStrict = fc6157e4i.AND(m_fc6157eiTakeoffs); FlightCurrency fc6157e4iiStrict = fc6157e4ii.AND(m_fc6157eiiTakeoffs); FlightCurrency fcStrict = fc6157bStrict.OR(fc6157e4iStrict).OR(fc6157e4iiStrict); // Loose rules for purposes of determining state CompositeCurrencyState = fcLoose.CurrentState; CompositeExpiration = fcLoose.ExpirationDate; CompositeDiscrepancy = fcLoose.DiscrepancyString; // determine the correct discrepancy string to show // if we've EVER met the strict definition, then use that - indicates we've logged at least some takeoffs. if (fcStrict.HasBeenCurrent) { CompositeExpiration = fcStrict.ExpirationDate; CompositeCurrencyState = fcStrict.CurrentState; CompositeDiscrepancy = fcStrict.CurrentState == CurrencyState.NotCurrent ? String.Format(CultureInfo.CurrentCulture, Resources.Currency.DiscrepancyTemplate, Math.Max(NightTakeoffCurrency.Discrepancy, fc6157b.Discrepancy), NightTakeoffCurrency.Discrepancy > fc6157b.Discrepancy ? Resources.Currency.NightTakeoffs : (fc6157b.Discrepancy > 1 ? Resources.Totals.Landings : Resources.Totals.Landing)) : string.Empty; } // else if we met the loose definition but not strict - meaning takeoffs were not found; Give a reminder about required takeoffs else if (CompositeCurrencyState.IsCurrent()) { CompositeDiscrepancy = NightTakeoffCurrency.Discrepancy >= NightTakeoffCurrency.RequiredEvents ? Resources.Currency.NightTakeoffReminder : String.Format(CultureInfo.CurrentCulture, Resources.Currency.DiscrepancyTemplateNight, NightTakeoffCurrency.Discrepancy, (NightTakeoffCurrency.Discrepancy > 1) ? Resources.Currency.Takeoffs : Resources.Currency.Takeoff); } // else we aren't current at all - use the full discrepancy template using 61.57(b). DON'T CALL DISCREPANCY STRING because that causes an infinite recursion. else { CompositeDiscrepancy = String.Format(CultureInfo.CurrentCulture, Resources.Currency.DiscrepancyTemplate, this.Discrepancy, (this.Discrepancy > 1) ? Resources.Totals.Landings : Resources.Totals.Landing); } }
private void RefreshCurrency() { if (m_fCacheValid) { return; } // 401.05(3)(a)-(c) say you have an IPC OR 6approaches+6hours OR 6approaches+6hours instructing. FlightCurrency fcIFRCanada = fc401_05_3_a.OR(fc401_05_3_bTime.AND(fc401_05_3_bApproaches)).OR(fc401_05_3_cTime.AND(fc401_05_3_cApproaches)); m_csCurrent = fcIFRCanada.CurrentState; m_dtExpiration = fcIFRCanada.ExpirationDate; if (m_csCurrent == CurrencyState.NotCurrent) { m_szDiscrepancy = Resources.Currency.IPCRequired; } m_fCacheValid = true; }
/// <summary> /// Computes the overall currency /// </summary> protected void RefreshCurrency() { // Compute currency according to 61.57(c)(1)-(5) and 61.57(e) // including each one's expiration. The one that expires latest is the expiration date if you are current, the one that // expired most recently is the expiration date since when you were not current. if (m_fCacheValid) { return; } // This is ((61.57(c)(1) OR (2) OR (3) OR (4) OR (5) OR 61.57(e)), each of which is the AND of several currencies. // 61.57(c)(1) (66-HIT in airplane) FlightCurrency fc6157c1 = fcIFRApproach.AND(fcIFRHold); // 61.57(c)(2) (66-HIT in an FTD or flight simulator) FlightCurrency fc6157c2 = fcFTDApproach.AND(fcFTDHold); // 61.57(c)(3) - ATD FlightCurrency fc6157c3 = fcATDHold.AND(fcATDApproach).AND(fcUnusualAttitudesAsc).AND(fcUnusualAttitudesDesc).AND(fcInstrumentHours); // 61.57(c)(4) - Combo STRICT - 6 approaches/hold in an ATD PLUS an approach/hold in an airplane PLUS an approach/hold in an FTD FlightCurrency fc6157c4 = fcATDAppch6Month.AND(fcATDHold6Month).AND(fcIFRHold).AND(fcAirplaneApproach6Month).AND(fcFTDApproach6Month).AND(fcFTDHold); // 61.57(c)(4) - Combo LOOSE - any combination that yields 66-HIT, but require at least one aircraft approach and hold. // FlightCurrency fc6157c4Loose = fcComboApproach6Month.AND(fcAirplaneApproach6Month).AND(fcIFRHold.OR(fcATDHold6Month).OR(fcFTDHold)); // 61.57(c)(5) - combo meal, but seems redundant with (c)(2)/(3). I.e., if you've met this, you've met (2) or (3). // 61.57 (e) - IPC; no need to AND anything together for this one. FlightCurrency fcIFR = fc6157c1.OR(fc6157c2).OR(fc6157c3).OR(fc6157c4).OR(fcIPCOrCheckride); /* * if (m_fUseLoose6157c4) * fcIFR = fcIFR.OR(fc6157c4Loose); */ m_csCurrent = fcIFR.CurrentState; m_dtExpiration = fcIFR.ExpirationDate; if (fcIPCOrCheckride.IsCurrent() && fcIPCOrCheckride.ExpirationDate.CompareTo(m_dtExpiration) >= 0) { Query.HasHolds = Query.HasApproaches = false; Query.PropertiesConjunction = GroupConjunction.Any; Query.PropertyTypes.Clear(); foreach (CustomPropertyType cpt in CustomPropertyType.GetCustomPropertyTypes()) { if (cpt.IsIPC) { Query.PropertyTypes.Add(cpt); } } } if (m_csCurrent == CurrencyState.NotCurrent) { // if more than 6 calendar months have passed since expiration, an IPC is required. // otherwise, just assume 66-HIT. if (DateTime.Compare(m_dtExpiration.AddCalendarMonths(6).Date, DateTime.Now.Date) > 0) { m_szDiscrepancy = String.Format(CultureInfo.CurrentCulture, Resources.Currency.DiscrepancyTemplateIFR, fcIFRHold.Discrepancy, (fcIFRHold.Discrepancy == 1) ? Resources.Currency.Hold : Resources.Currency.Holds, fcIFRApproach.Discrepancy, (fcIFRApproach.Discrepancy == 1) ? Resources.Totals.Approach : Resources.Totals.Approaches); } else { m_szDiscrepancy = Resources.Currency.IPCRequired; } } else { // Check to see if IPC is required by looking for > 6 month gap in IFR currency. // For now, we won't make you un-current, but we'll warn. // (IPC above, though, is un-current). CurrencyPeriod[] rgcpMissingIPC = fcIFR.FindCurrencyGap(fcIPCOrCheckride.MostRecentEventDate, 6); if (rgcpMissingIPC != null) { m_szDiscrepancy = String.Format(CultureInfo.CurrentCulture, Resources.Currency.IPCMayBeRequired, rgcpMissingIPC[0].EndDate.ToShortDateString(), rgcpMissingIPC[1].StartDate.ToShortDateString()); } else { m_szDiscrepancy = string.Empty; } } m_fCacheValid = true; }