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;
        }
Example #2
0
        /// <summary>
        /// Computes the overall currency
        /// </summary>
        public void RefreshCurrency()
        {
            // Compute currency according to 61.57(c)(6) ( => (c)(3)) (i) and (ii) including each one's expiration.

            if (m_fCacheValid)
            {
                return;
            }

            // 61.57(c)(6)(i) => (c)(3)(i) -  no passengers.  IPC covers this.
            FlightCurrency fc6157c6i = fcGliderIFRTime.AND(fcGliderInstrumentManeuvers).OR(fcGliderIPC);

            // 61.57(c)(6)(ii) => (c)(3)(ii) -  passengers.  Above + two more.  Again, IPC covers this too.
            FlightCurrency fc6157c6ii = fc6157c6i.AND(fcGliderIFRTimePassengers).AND(fcGliderInstrumentPassengers).OR(fcGliderIPC);

            m_fCurrentSolo       = fc6157c6i.IsCurrent();
            m_fCurrentPassengers = fc6157c6ii.IsCurrent();

            if (m_fCurrentSolo || m_fCurrentPassengers)
            {
                if (m_fCurrentPassengers)
                {
                    m_csCurrent     = fc6157c6ii.CurrentState;
                    m_dtExpiration  = fc6157c6ii.ExpirationDate;
                    m_szDiscrepancy = fc6157c6ii.DiscrepancyString;
                }
                else // must be current solo)
                {
                    m_csCurrent     = fc6157c6i.CurrentState;
                    m_dtExpiration  = fc6157c6i.ExpirationDate;
                    m_szDiscrepancy = fc6157c6i.DiscrepancyString;
                }

                // check to see if there is an embedded gap that needs an IPC
                CurrencyPeriod[] rgcpMissingIPC = fc6157c6i.FindCurrencyGap(fcGliderIPC.MostRecentEventDate, 6);
                if (rgcpMissingIPC != null && m_szDiscrepancy.Length == 0)
                {
                    m_szDiscrepancy = String.Format(CultureInfo.CurrentCulture, Resources.Currency.IPCMayBeRequired, rgcpMissingIPC[0].EndDate.ToShortDateString(), rgcpMissingIPC[1].StartDate.ToShortDateString());
                }
            }
            else
            {
                // And expiration date is the later of the passenger/no-passenger date
                m_dtExpiration = fc6157c6i.ExpirationDate.LaterDate(fc6157c6ii.ExpirationDate);

                // see if we need an IPC
                // if more than 6 calendar months have passed since expiration, an IPC is required.
                // otherwise, just name the one that is short
                if (DateTime.Compare(m_dtExpiration.AddCalendarMonths(6).Date, DateTime.Now.Date) > 0)
                {
                    m_szDiscrepancy = String.Format(CultureInfo.CurrentCulture, Resources.Currency.DiscrepancyTemplateGliderIFRPassengers, fcGliderIFRTime.Discrepancy, fcGliderInstrumentManeuvers.Discrepancy);
                }
                else
                {
                    m_szDiscrepancy = Resources.Currency.IPCRequired;
                }
            }

            m_fCacheValid = true;
        }
        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);
            }
        }
Example #4
0
        /// <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;
            }
        }
Example #5
0
        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;
        }
        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;
        }