public override void ExamineFlight(ExaminerFlightRow cfr) { bool fIsAirplane = CategoryClass.IsAirplane(cfr.idCatClassOverride); bool fIsIFRSim = (fIsAirplane && cfr.fIsFTD); if (fIsAirplane || cfr.fIsRealAircraft) { miMinInstrumentTime.AddTrainingEvent(cfr.IMC + cfr.IMCSim, ATPMaxIFRSimulator, fIsIFRSim); } if (fIsAirplane && cfr.idCatClassOverride == requiredCatClassID) { bool fIsFullSim = !cfr.fIsRealAircraft && cfr.fIsCertifiedLanding; if (fIsAirplane && (cfr.fIsRealAircraft || fIsFullSim)) { miMinTimeInClass.AddTrainingEvent(cfr.Total, ATPMinTimeInClassFullSimulator, fIsFullSim); } } // Above are the only things to which we will alow training devices. if (!cfr.fIsRealAircraft) { return; } miTotal.AddEvent(Math.Max(CanCreditSICAndFlightEngineer ? cfr.SIC : 0, cfr.Total)); miMinXCTime.AddEvent(cfr.XC); miMinNightTime.AddEvent(cfr.Night); if (CanCreditSICAndFlightEngineer) { decimal flightEngineerTime = 0.0M; cfr.ForEachEvent((pe) => { if (pe.PropTypeID == (int)CustomPropertyType.KnownProperties.IDPropFlightEngineerTime) { flightEngineerTime += pe.DecValue; } }); if (flightEngineerTime > 0) { miTotal.AddTrainingEvent(flightEngineerTime / 3.0M, ATPMaxFlightEngineer, true); } } // Remainder must be done in a real aircraft and it must be in an airplane. // Not clear if the night takeoffs/landings need to be in a real aircraft / airplane, but I'll require it to be safe. if (fIsAirplane) { miMinPIC.AddEvent(cfr.PIC); miMinPICXC.AddEvent(Math.Min(cfr.PIC, cfr.XC)); miMinPICNight.AddEvent(Math.Min(cfr.PIC, cfr.Night)); cfr.ForEachEvent((pe) => { if (pe.PropertyType.IsNightTakeOff) { miNightTO.AddEvent(pe.IntValue); } }); miNightLanding.AddEvent(cfr.cFullStopNightLandings); } }
public override void ExamineFlight(ExaminerFlightRow cfr) { if (cfr == null) { throw new ArgumentNullException("cfr"); } m_fCacheValid = false; // 401.05(3)(a) - IPC or equivalent cfr.ForEachEvent((pfe) => { // add any IPC or IPC equivalents if (pfe.PropertyType.IsIPC) { fc401_05_3_a.AddRecentFlightEvents(cfr.dtFlight, 1.0M); } }); decimal IFRTime = cfr.IMC + cfr.IMCSim; decimal IFRCFITime = Math.Min(IFRTime, cfr.CFI); // 401.05(3)(b) - flight in a real aircraft or sim fc401_05_3_bTime.AddRecentFlightEvents(cfr.dtFlight, Math.Max(0, IFRTime - IFRCFITime)); fc401_05_3_bApproaches.AddRecentFlightEvents(cfr.dtFlight, cfr.cApproaches); // 401.05(3)(c) - IFR instruction in a real aircraft if (cfr.fIsRealAircraft) { fc401_05_3_cTime.AddRecentFlightEvents(cfr.dtFlight, IFRCFITime); fc401_05_3_cApproaches.AddRecentFlightEvents(cfr.dtFlight, cfr.CFI > 0 ? cfr.cApproaches : 0); } }
public override void ExamineFlight(ExaminerFlightRow cfr) { if (cfr == null) { throw new ArgumentNullException("cfr"); } // No training devices for sport pilots if (!cfr.fIsRealAircraft) { return; } // Keep track of heavier-than-air time, reduce minimums if achieved if (CategoryClass.IsHeavierThanAir(cfr.idCatClassOverride)) { TotalHeavierThanAir += cfr.Total; if (!QualifiesByHeavierThanAir && TotalHeavierThanAir >= 20) { QualifiesByHeavierThanAir = true; miMinTime.Threshold = 3; miMinTrainingFlights.Threshold = 5; miMinSolo.Threshold = 1; miMinSolo.Threshold = 3; } } // now reject anything not in a glider if (CatClassID != cfr.idCatClassOverride) { return; } miMinTime.AddEvent(cfr.Total); if (cfr.Dual > 0) { miMinTrainingFlights.AddEvent(Math.Max(1, cfr.cLandingsThisFlight)); if (DateTime.Now.AddCalendarMonths(-2).CompareTo(cfr.dtFlight) <= 0) { miTestPrep.AddEvent(cfr.Dual); } } decimal soloTime = 0.0M; cfr.ForEachEvent(pf => { if (pf.PropertyType.IsSolo) { soloTime += pf.DecValue; } }); if (soloTime > 0) { miMinSolo.AddEvent(soloTime); miMinSoloFlights.AddEvent(cfr.cLandingsThisFlight); // assuming no touch-and-go in a glider! } }
public override void ExamineFlight(ExaminerFlightRow cfr) { cfr.ForEachEvent((pfe) => { if (pfe.PropertyType.IsIPC) { AddRecentFlightEvents(cfr.dtFlight, 1); } }); }
public override void ExamineFlight(ExaminerFlightRow cfr) { cfr.ForEachEvent((pfe) => { if (pfe.PropTypeID == (int)CustomPropertyType.KnownProperties.IDProp135293Competency || pfe.PropertyType.IsIPC) { AddRecentFlightEvents(cfr.dtFlight, 1); } }); }
public override void ExamineFlight(ExaminerFlightRow cfr) { if (cfr == null) { throw new ArgumentNullException("cfr"); } // No training devices for sport pilots if (!cfr.fIsRealAircraft) { return; } // Minimum time can be in anything miMinTime.AddEvent(cfr.Total); // Everything else must be in matching category/class // allow perfect match or ASEL->ASES match if (CatClassID != cfr.idCatClassOverride && !(CatClassID == CategoryClass.CatClassID.ASEL && cfr.idCatClassOverride == CategoryClass.CatClassID.ASES)) { return; } miMinInstruction.AddEvent(cfr.Dual); decimal soloTime = 0.0M; cfr.ForEachEvent(pf => { if (pf.PropertyType.IsSolo) { soloTime += pf.DecValue; } }); miMinSolo.AddEvent(soloTime); int cFSLandings = cfr.cFullStopLandings + cfr.cFullStopNightLandings; miMinCrossCountry.AddEvent(Math.Min(cfr.XC, cfr.Dual)); miMinLandings.AddEvent(cFSLandings); if (soloTime > 0 && cFSLandings > 1) { AirportList al = AirportListOfRoutes.CloneSubset(cfr.Route, true); if (al.DistanceForRoute() > MinXCDistance && al.MaxSegmentForRoute() > 25) { miSoloXCFlight.AddEvent(1); miSoloXCFlight.MatchingEventID = cfr.flightID; miSoloXCFlight.MatchingEventText = String.Format(CultureInfo.CurrentCulture, Resources.MilestoneProgress.MatchingXCFlightTemplate, cfr.dtFlight.ToShortDateString(), cfr.Route); } } if (DateTime.Now.AddCalendarMonths(-2).CompareTo(cfr.dtFlight) <= 0) { miTestPrep.AddEvent(cfr.Dual); } }
public override void ExamineFlight(ExaminerFlightRow cfr) { if (cfr == null) { throw new ArgumentNullException("cfr"); } decimal ifrTraining = Math.Min(cfr.Dual, cfr.IMC + cfr.IMCSim); // Aeronautical experience - can be in any aircraft or certified sim if (cfr.fIsCertifiedIFR) // includes real aircraft { miAeronauticalExperience.AddEvent(Math.Max(cfr.GroundSim, cfr.Total)); } // total pilot time and IFR time can both be in any real aircraft if (miPilotTime != null && cfr.fIsRealAircraft) { miPilotTime.AddEvent(cfr.Total); } miDualInstrumentTime.AddEvent((cfr.fIsRealAircraft || cfr.fIsCertifiedIFR) ? ifrTraining : 0); // everything else must be in a matching category AND must be in a real aircraft if (IsMatchingCategory(cfr.idCatClassOverride) && cfr.fIsRealAircraft) { decimal soloTime = 0.0M; cfr.ForEachEvent(pf => { if (pf.PropertyType.IsSolo) { soloTime += pf.DecValue; } }); miTimeInCategory.AddEvent(cfr.Total); miSoloTimeInCategory.AddEvent(soloTime); miSoloXCTimeInCategory.AddEvent(Math.Min(soloTime, cfr.XC)); miDualInstrumentTimeInCategory.AddEvent(ifrTraining); bool fAllowLongXC = (soloTime > 0 || (!fLongCrossCountryMustBeSolo && cfr.PIC > 0)); // solo is always OK for cross country, otherwise need PIC. if (fAllowLongXC && !miSoloLongCrossCountry.IsSatisfied) { AirportList al = AirportListOfRoutes.CloneSubset(cfr.Route); int cRequiredLandings = fXCLandingsMustBeFullStop ? cfr.cFullStopLandings + cfr.cFullStopNightLandings : cfr.cLandingsThisFlight; if (al.DistanceForRoute() >= reqXCDistance && al.GetAirportList().Length >= 3 && cRequiredLandings >= 2) { miSoloLongCrossCountry.MatchFlightEvent(cfr); } } } }
public override void ExamineFlight(ExaminerFlightRow cfr) { if (cfr == null) { throw new ArgumentNullException("cfr"); } // Normal currency fcPIC.AddRecentFlightEvents(cfr.dtFlight, cfr.PIC); if (cfr.PIC > 0) { fcLandings.AddRecentFlightEvents(cfr.dtFlight, cfr.cLandingsThisFlight); } fcDual.AddRecentFlightEvents(cfr.dtFlight, cfr.Dual); // If we aren't current above, we still want to count any landings or time spent as dual, solo, or DPIC with an Instructor on board. bool fHasProficiencyCheck = false; decimal dPIC = 0.0M; bool fInstructorOnBoard = false; cfr.ForEachEvent((cfp) => { if (cfp.PropertyType.IsPICProficiencyCheck6158) { fHasProficiencyCheck = true; } if (cfp.PropTypeID == (int)CustomPropertyType.KnownProperties.IDPropInstructorOnBoard && !cfp.IsDefaultValue) { fInstructorOnBoard = true; // instructor-on-board time only counts if you are acting as PIC } if (cfp.PropTypeID == (int)CustomPropertyType.KnownProperties.IDPropDutiesOfPIC && !cfp.IsDefaultValue) { dPIC += cfp.DecValue; } }); if (fHasProficiencyCheck) { fcProficiencyCheck.AddRecentFlightEvents(cfr.dtFlight, 1); } if (!fInstructorOnBoard) { dPIC = 0.0M; // only counts if instructor on board. } if (cfr.Dual + dPIC > 0) { fcAlternateLandings.AddRecentFlightEvents(cfr.dtFlight, cfr.cLandingsThisFlight); fcAlternatePIC.AddRecentFlightEvents(cfr.dtFlight, Math.Min(cfr.Total, cfr.Dual + dPIC)); } }
public override void ExamineFlight(ExaminerFlightRow cfr) { if (cfr == null) { throw new ArgumentNullException("cfr"); } if (!cfr.fIsRealAircraft) { return; } // 61.99 miMinTime.AddEvent(cfr.Total); // 61.99(a) miMinInstruction.AddEvent(cfr.Dual); // 61.99(a)(1) if (cfr.cLandingsThisFlight >= 4 && cfr.Dual > 0) { AirportList al = AirportListOfRoutes.CloneSubset(cfr.Route, true); if (al.MaxDistanceForRoute() >= 25.0) { miXCFlight.AddEvent(cfr.Dual); } } if (cfr.idCatClassOverride == CatClassID) { // 61.99(a)(2) if (DateTime.Now.AddCalendarMonths(-2).CompareTo(cfr.dtFlight) <= 0) { miTestPrep.AddEvent(cfr.Dual); } // 61.99(b) decimal soloTime = 0.0M; cfr.ForEachEvent(pf => { if (pf.PropertyType.IsSolo) { soloTime += pf.DecValue; } }); miMinSolo.AddEvent(soloTime); } }
public void ExamineFlight(ExaminerFlightRow cfr) { cfr.ForEachEvent((cfp) => { if (cfp.PropTypeID == (int)CustomPropertyType.KnownProperties.IDPropUASKnowledgeTest10773) { KnowledgeTest.AddRecentFlightEvents(cfr.dtFlight, 1); } if (cfp.PropTypeID == (int)CustomPropertyType.KnownProperties.IDPropUASTrainingCourse10774) { TrainingCourse.AddRecentFlightEvents(cfr.dtFlight, 1); } if (cfp.PropertyType.IsBFR && cfr.fIsRealAircraft) { BFR.AddRecentFlightEvents(cfr.dtFlight, 1); } }); }
public void ExamineFlight(ExaminerFlightRow cfr) { if (cfr.dtFlight.CompareTo(DateTime.Now.AddYears(-5)) < 0) { return; } fHasPICExperience = fHasPICExperience || (cfr.PIC + cfr.SIC > 0); // Alternative to having PIC experience is having a flight review in the prior year if (cfr.dtFlight.CompareTo(DateTime.Now.AddYears(-1)) > 0) { cfr.ForEachEvent((pe) => { if (pe.PropertyType.IsBFR) { fHasFlightReview = true; } }); } }
public override void ExamineFlight(ExaminerFlightRow cfr) { if (cfr == null) { throw new ArgumentNullException("cfr"); } // no provision for training devices. if (!cfr.fIsRealAircraft) { return; } // Must be a glider; motorgliders ("powered sailplanes") are subsets of gliders if (cfr.idCatClassOverride != CategoryClass.CatClassID.Glider) { return; } // Treat TMG time as if it were a training device. miTotal.AddTrainingEvent(cfr.Total, maxTMGTime, cfr.fMotorGlider); miDual.AddEvent(cfr.Dual); decimal soloTime = 0.0M; bool fInstructorOnBoard = false; decimal dutiesOfPICTime = 0.0M; cfr.ForEachEvent(pf => { if (pf.PropertyType.IsSolo) { soloTime += pf.DecValue; } if (pf.PropTypeID == (int)CustomPropertyType.KnownProperties.IDPropInstructorOnBoard && !pf.IsDefaultValue) { fInstructorOnBoard = true; // instructor-on-board time only counts if you are acting as PIC } if (pf.PropTypeID == (int)CustomPropertyType.KnownProperties.IDPropDutiesOfPIC && !pf.IsDefaultValue) { dutiesOfPICTime += pf.DecValue; } }); if (fInstructorOnBoard) { soloTime += Math.Max(Math.Min(dutiesOfPICTime, cfr.Total - cfr.Dual), 0); // dual received does NOT count as duties of PIC time here } miSolo.AddEvent(soloTime); miLandings.AddEvent(cfr.cLandingsThisFlight); if (!miCrossCountry.IsSatisfied) { AirportList al = AirportListOfRoutes.CloneSubset(cfr.Route); double distance = al.GetAirportList().Length > 1 ? al.DistanceForRoute() : 0.0; if ((soloTime > 0.0M && distance > minSoloXC) || (cfr.Dual > 0 && distance > minDualXC)) { miCrossCountry.MatchFlightEvent(cfr); } } }
public override void ExamineFlight(ExaminerFlightRow cfr) { if (cfr == null) { throw new ArgumentNullException("cfr"); } // no provision for training devices. if (!cfr.fIsRealAircraft) { return; } if (MatchesClassDual(cfr)) { miMinDualInClass.AddEvent(cfr.Dual); } if (MatchesSoloOrTotalDual(cfr)) { miMinTime.AddEvent(cfr.Total); decimal soloTime = 0.0M; bool fInstructorOnBoard = false; decimal dutiesOfPICTime = 0.0M; cfr.ForEachEvent(pf => { if (pf.PropertyType.IsSolo) { soloTime += pf.DecValue; } if (pf.PropTypeID == (int)CustomPropertyType.KnownProperties.IDPropInstructorOnBoard && !pf.IsDefaultValue) { fInstructorOnBoard = true; // instructor-on-board time only counts if you are acting as PIC } if (pf.PropTypeID == (int)CustomPropertyType.KnownProperties.IDPropDutiesOfPIC && !pf.IsDefaultValue) { dutiesOfPICTime += pf.DecValue; } }); if (fInstructorOnBoard) { soloTime += Math.Max(Math.Min(dutiesOfPICTime, cfr.Total - cfr.Dual), 0); // dual received does NOT count as duties of PIC time here } if (soloTime > 0.0M) { miMinSolo.AddEvent(soloTime); miMinSoloXC.AddEvent(Math.Min(soloTime, cfr.XC)); if (cfr.cFullStopLandings >= 1 && !miMinSoloXCMinDist.IsSatisfied) { AirportList al = AirportListOfRoutes.CloneSubset(cfr.Route); if (al.GetAirportList().Length > 1 && al.DistanceForRoute() >= MinSoloDistance) { miMinSoloXCMinDist.MatchFlightEvent(cfr); } } } } }
public override void ExamineFlight(ExaminerFlightRow cfr) { bool fIsMatch = CatClassMatchesRatingSought(cfr.idCatClassOverride); bool fIsSim = cfr.fIsCertifiedIFR && !cfr.fIsRealAircraft; if (!fIsMatch || !cfr.fIsCertifiedIFR) { return; } miTotal.AddTrainingEvent(Math.Min(cfr.Dual, cfr.fIsRealAircraft ? cfr.Total : cfr.GroundSim), JAASimSub, fIsSim); // Everything below here must be done in a real aircraft if (!cfr.fIsRealAircraft) { return; } miDual.AddEvent(cfr.Dual); miInstrumentDual.AddEvent(Math.Min(cfr.Dual, cfr.IMC + cfr.IMCSim)); // Get solo time decimal soloTime = 0.0M; decimal instructorOnBoardTime = 0.0M; bool fInstructorOnBoard = false; decimal dutiesOfPICTime = 0.0M; int nightTakeoffs = 0; cfr.ForEachEvent(pf => { if (pf.PropertyType.IsSolo) { soloTime += pf.DecValue; } if (pf.PropTypeID == (int)CustomPropertyType.KnownProperties.IDPropInstructorOnBoard && !pf.IsDefaultValue) { fInstructorOnBoard = true; // instructor-on-board time only counts if you are acting as PIC } if (pf.PropTypeID == (int)CustomPropertyType.KnownProperties.IDPropDutiesOfPIC && !pf.IsDefaultValue) { dutiesOfPICTime += pf.DecValue; } if (pf.PropertyType.IsNightTakeOff) { nightTakeoffs += pf.IntValue; } }); if (fInstructorOnBoard) { instructorOnBoardTime = Math.Max(Math.Min(dutiesOfPICTime, cfr.Total - cfr.Dual), 0); // dual received does NOT count as duties of PIC time here } decimal supervisedSolo = soloTime + Math.Min(instructorOnBoardTime, dutiesOfPICTime); miSolo.AddEvent(supervisedSolo); miSoloXC.AddEvent(Math.Min(supervisedSolo, cfr.XC)); AirportList al = null; if (!miSoloLongXC.IsSatisfied && supervisedSolo > 0) { al = AirportListOfRoutes.CloneSubset(cfr.Route); if (al.DistanceForRoute() >= (double)miSoloLongXC.Threshold && al.GetAirportList().Length >= 3 && (cfr.cFullStopLandings + cfr.cFullStopNightLandings) >= 2) { miSoloLongXC.MatchFlightEvent(cfr); } } // Night - optional if (cfr.Night > 0) { miNightTime.AddEvent(cfr.Night); decimal nightDual = Math.Min(cfr.Night, cfr.Dual); miNightDual.AddEvent(nightDual); miNightXC.AddEvent(Math.Min(nightDual, cfr.XC)); if (soloTime > 0) { miNightSoloTakeoffs.AddEvent(nightTakeoffs); miNightSoloLandings.AddEvent(cfr.cFullStopNightLandings); } if (nightDual > 0) { if (al == null) { al = AirportListOfRoutes.CloneSubset(cfr.Route); } if (al.DistanceForRoute() > (double)JAALongNightXCDistanceAirplane) { miNightLongXC.MatchFlightEvent(cfr); } } } }