private void CheckDutyIssues(LogbookEntryBase le, CustomFlightProperty cfpBlockIn, CustomFlightProperty cfpBlockOut) { // Look for a new duty start when a prior period is still open or a duty end when a prior period is NOT open CustomFlightProperty cfpDutyStart = le.CustomProperties[CustomPropertyType.KnownProperties.IDPropDutyStart]; CustomFlightProperty cfpFlightDutyStart = le.CustomProperties[CustomPropertyType.KnownProperties.IDPropFlightDutyTimeStart]; CustomFlightProperty cfpDutyEnd = le.CustomProperties[CustomPropertyType.KnownProperties.IDPropDutyEnd]; CustomFlightProperty cfpFlightDutyEnd = le.CustomProperties[CustomPropertyType.KnownProperties.IDPropFlightDutyTimeEnd]; // Starting a new duty period or flight duty period while a prior duty period is open AddConditionalIssue(dutyStart != null && dutyStart.HasValue && cfpDutyStart != null, LintOptions.DateTimeIssues, Resources.FlightLint.warningNewDutyStart); AddConditionalIssue(flightDutyStart != null && flightDutyStart.HasValue && cfpFlightDutyStart != null, LintOptions.DateTimeIssues, Resources.FlightLint.warningNewFlightDutyStart); // Starting a new duty period or flight duty period prior to the close of the prior one. AddConditionalIssue(dutyEnd != null && dutyEnd.HasValue && cfpDutyStart != null && cfpDutyStart.DateValue.CompareTo(dutyEnd.Value) < 0, LintOptions.DateTimeIssues, Resources.FlightLint.warningDutyStartPriorToPreviousDutyEnd); AddConditionalIssue(flightDutyEnd != null && flightDutyEnd.HasValue && cfpFlightDutyStart != null && cfpFlightDutyStart.DateValue.CompareTo(flightDutyEnd.Value) < 0, LintOptions.DateTimeIssues, Resources.FlightLint.warningFlightDutyStartPriorToPreviousFlightDutyEnd); // Ending a duty period or flight duty period that has no corresponding start. AddConditionalIssue(dutyStart == null && cfpDutyStart == null && cfpDutyEnd != null, LintOptions.DateTimeIssues, Resources.FlightLint.warningNewDutyEndNoStart); AddConditionalIssue(flightDutyStart == null && cfpFlightDutyStart == null && cfpFlightDutyEnd != null, LintOptions.DateTimeIssues, Resources.FlightLint.warningNewFlightDutyEndNoStart); DateTime bogusDate = le.FlightStart.LaterDate(le.FlightEnd) .LaterDate(le.EngineStart).LaterDate(le.EngineEnd) .LaterDate(cfpBlockIn == null ? DateTime.MinValue : cfpBlockIn.DateValue).LaterDate(cfpBlockOut == null ? DateTime.MinValue : cfpBlockOut.DateValue) .LaterDate(cfpDutyStart == null ? DateTime.MinValue : cfpDutyStart.DateValue).LaterDate(cfpDutyEnd == null ? DateTime.MinValue : cfpDutyEnd.DateValue) .LaterDate(cfpFlightDutyStart == null ? DateTime.MinValue : cfpFlightDutyStart.DateValue).LaterDate(cfpFlightDutyEnd == null ? DateTime.MinValue : cfpFlightDutyEnd.DateValue); AddConditionalIssue(bogusDate.CompareTo(DateTime.UtcNow.AddDays(5)) > 0, LintOptions.DateTimeIssues, String.Format(CultureInfo.CurrentCulture, Resources.FlightLint.warningTimesSuspectTime, bogusDate.UTCDateFormatString())); UpdateDutyPeriods(cfpDutyStart, cfpFlightDutyStart, cfpDutyEnd, cfpFlightDutyEnd); }
private void CheckDateTimeIssues(LogbookEntryBase le) { CustomFlightProperty cfpBlockOut = le.CustomProperties.GetEventWithTypeID(CustomPropertyType.KnownProperties.IDBlockOut); CustomFlightProperty cfpBlockIn = le.CustomProperties.GetEventWithTypeID(CustomPropertyType.KnownProperties.IDBlockIn); // Block out after block in AddConditionalIssue(cfpBlockIn != null && cfpBlockOut != null && cfpBlockOut.DateValue.CompareTo(cfpBlockIn.DateValue) > 0, LintOptions.DateTimeIssues, Resources.FlightLint.warningDateTimeInvalidBlock); bool fHasEngineStart = le.EngineStart.HasValue(); bool fHasEngineEnd = le.EngineEnd.HasValue(); bool fHasFlightStart = le.FlightStart.HasValue(); bool fHasFlightEnd = le.FlightEnd.HasValue(); // Engine start must be before flight. Can be after block out, but not before block in AddConditionalIssue(fHasEngineStart && fHasFlightStart && le.FlightStart.CompareTo(le.EngineStart) < 0, LintOptions.DateTimeIssues, Resources.FlightLint.warningDateEngineAfterFlight); AddConditionalIssue(fHasEngineStart && fHasFlightEnd && le.FlightEnd.CompareTo(le.EngineStart) < 0, LintOptions.DateTimeIssues, Resources.FlightLint.warningFlightEndBeforeEngineStart); AddConditionalIssue(fHasEngineStart && cfpBlockIn != null && cfpBlockIn.DateValue.CompareTo(le.EngineStart) <= 0, LintOptions.DateTimeIssues, Resources.FlightLint.warningEngineStartAfterBlockIn); // Flight start must be after engine start (checked above) and after block out AddConditionalIssue(fHasFlightStart && cfpBlockOut != null && le.FlightStart.CompareTo(cfpBlockOut.DateValue) < 0, LintOptions.DateTimeIssues, Resources.FlightLint.warningDateBlockAfterFlight); // Flight end must be after engine/flight start (checked in regular validation), after block out, and before block in AddConditionalIssue(fHasFlightEnd && cfpBlockOut != null && le.FlightEnd.CompareTo(cfpBlockOut.DateValue) < 0, LintOptions.DateTimeIssues, Resources.FlightLint.warningFlightEndBeforeBlockOut); AddConditionalIssue(fHasFlightEnd && cfpBlockIn != null && le.FlightEnd.CompareTo(cfpBlockIn.DateValue) > 0, LintOptions.DateTimeIssues, Resources.FlightLint.warningFlightEndAfterBlockIn); AddConditionalIssue(fHasFlightEnd && fHasEngineEnd && le.FlightEnd.CompareTo(le.EngineEnd) > 0, LintOptions.DateTimeIssues, Resources.FlightLint.warningFlightEndAfterEngineEnd); AddConditionalIssue(fHasEngineEnd && cfpBlockIn != null && le.EngineEnd.CompareTo(cfpBlockIn.DateValue) < 0, LintOptions.DateTimeIssues, Resources.FlightLint.warningEngineEndBeforeBlockIn); CheckFlightLengthIssues(le); // Look for issues with sequential flights CheckSequentialFlightIssues(le); }
/// <summary> /// Recreates the combobox and propedit controls so that they exist for postback events. /// </summary> protected void RecreateControls() { if (plcHolderProps.Controls.Count > 0) // don't do this if we've already set them up. { return; } List <CustomPropertyType> lstAll = new List <CustomPropertyType>(CustomPropertyType.GetCustomPropertyTypes()); foreach (int idPropType in ActivePropTypes) { CustomPropertyType cpt = lstAll.Find(c => c.PropTypeID == idPropType); CustomFlightProperty cfp = new CustomFlightProperty(cpt); if (ExistingPropIDs.ContainsKey(idPropType)) { cfp.PropID = ExistingPropIDs[idPropType]; } InsertEditProp(cfp); lstAll.Remove(cpt); // since it's here, make sure it isn't in the list of available types; we'll bind this below. } // recreate combo box - huge viewstate, so we just recreate it each time. // This loses the selected value, so we have to grab that directly from the form. cmbPropsToAdd.DataSource = lstAll; cmbPropsToAdd.DataBind(); if (IsPostBack) { cmbPropsToAdd.SelectedValue = Request.Form[cmbPropsToAdd.UniqueID]; } }
protected void rptPages_ItemDataBound(object sender, RepeaterItemEventArgs e) { if (e == null) { throw new ArgumentNullException("e"); } LogbookPrintedPage lep = (LogbookPrintedPage)e.Item.DataItem; HashSet <int> hsRedundantProps = new HashSet <int>() { (int)CustomPropertyType.KnownProperties.IDPropStudentName, (int)CustomPropertyType.KnownProperties.IDPropNameOfPIC, (int)CustomPropertyType.KnownProperties.IDPropNightTakeoff }; hsRedundantProps.UnionWith(Options.ExcludedPropertyIDs); foreach (LogbookEntryDisplay led in lep.Flights) { List <CustomFlightProperty> lstProps = new List <CustomFlightProperty>(led.CustomProperties); lstProps.RemoveAll(cfp => hsRedundantProps.Contains(cfp.PropTypeID)); led.CustPropertyDisplay = CustomFlightProperty.PropListDisplay(lstProps, CurrentUser.UsesHHMM, PropSeparator); } Repeater rpt = (Repeater)e.Item.FindControl("rptFlight"); rpt.DataSource = lep.Flights; rpt.DataBind(); rpt = (Repeater)e.Item.FindControl("rptSubtotalCollections"); rpt.DataSource = lep.Subtotals; rpt.DataBind(); }
protected void FromForm() { CustomFlightProperty fp = m_fp; switch (fp.PropertyType.Type) { case CFPPropertyType.cfpBoolean: fp.BoolValue = ckValue.Checked; break; case CFPPropertyType.cfpInteger: fp.IntValue = mfbDecEdit.IntValue; break; case CFPPropertyType.cfpDecimal: case CFPPropertyType.cfpCurrency: fp.DecValue = mfbDecEdit.Value; break; case CFPPropertyType.cfpDate: fp.DateValue = mfbTypeInDate.Date; break; case CFPPropertyType.cfpDateTime: fp.DateValue = mfbDateTime.DateAndTime; break; case CFPPropertyType.cfpString: fp.TextValue = txtString.Text; break; default: throw new MyFlightbookException(String.Format(System.Globalization.CultureInfo.InvariantCulture, "Unknown property type: {0}", fp.PropertyType.Type)); } }
private void UpdateDutyPeriods(CustomFlightProperty cfpDutyStart, CustomFlightProperty cfpFlightDutyStart, CustomFlightProperty cfpDutyEnd, CustomFlightProperty cfpFlightDutyEnd) { // Close off a duty period if we have a duty end; if we're starting (or restarting) a duty period (and not closing it in the same flight), reset the duty period if (cfpDutyEnd != null) { dutyStart = null; // don't have an open duty period dutyEnd = cfpDutyEnd.DateValue; } else if (cfpDutyStart != null) { dutyStart = cfpDutyStart.DateValue; if (cfpDutyEnd == null) { dutyEnd = null; // we have a start of the duty period that isn't closed in the same flight - leave the duty end unspecified. } } if (cfpFlightDutyEnd != null) { flightDutyStart = null; // don't have an open flight duty period flightDutyEnd = cfpFlightDutyEnd.DateValue; } else if (cfpFlightDutyStart != null) { flightDutyStart = cfpFlightDutyStart.DateValue; if (cfpFlightDutyEnd == null) { flightDutyEnd = null;// we have a start of the duty period that isn't closed in the same flight - leave the duty end unspecified. } } }
public override LogbookEntry ToLogbookEntry() { PendingFlight pf = new PendingFlight() { Date = blockOut.Date, ModelDisplay = model, TailNumDisplay = tail, Route = String.Format(CultureInfo.InvariantCulture, Resources.LocalizedText.LocalizedJoinWithSpace, dep, arr), TotalFlightTime = Math.Max((decimal)blockIn.Subtract(blockOut).TotalHours, 0) }; if (position.CompareCurrentCultureIgnoreCase("CA") == 0) { pf.PIC = pf.TotalFlightTime; } if (position.CompareCurrentCultureIgnoreCase("FO") == 0) { pf.SIC = pf.TotalFlightTime; } pf.CustomProperties.SetItems(new CustomFlightProperty[] { CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDPropFlightNumber, flightNumber), CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDBlockOut, blockOut, true), CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDBlockIn, blockIn, true) }); return(pf); }
protected void ToForm() { CustomFlightProperty fp = m_fp; lblPropName.Text = fp.PropertyType.Title; mfbTooltip.Visible = !String.IsNullOrEmpty(mfbTooltip.BodyContent = fp.PropertyType.Description); switch (fp.PropertyType.Type) { case CFPPropertyType.cfpBoolean: { lblPropName.AssociatedControlID = ckValue.ID; ckValue.Checked = fp.BoolValue; mvProp.SetActiveView(vwBool); } break; case CFPPropertyType.cfpInteger: mfbDecEdit.IntValue = fp.IntValue; mfbDecEdit.EditingMode = Controls_mfbDecimalEdit.EditMode.Integer; mvProp.SetActiveView(vwDecimal); break; case CFPPropertyType.cfpDecimal: // Set the cross-fill source before setting the editing mode. if (!fp.PropertyType.IsBasicDecimal) { mfbDecEdit.CrossFillSourceClientID = CrossFillSourceClientID; } mfbDecEdit.EditingMode = (!fp.PropertyType.IsBasicDecimal && MyFlightbook.Profile.GetUser(Page.User.Identity.Name).UsesHHMM ? Controls_mfbDecimalEdit.EditMode.HHMMFormat : Controls_mfbDecimalEdit.EditMode.Decimal); mfbDecEdit.Value = fp.DecValue; mvProp.SetActiveView(vwDecimal); break; case CFPPropertyType.cfpCurrency: mfbDecEdit.EditingMode = Controls_mfbDecimalEdit.EditMode.Currency; mfbDecEdit.Value = fp.DecValue; mvProp.SetActiveView(vwDecimal); break; case CFPPropertyType.cfpDate: mfbTypeInDate.Date = fp.DateValue; mvProp.SetActiveView(vwDate); break; case CFPPropertyType.cfpDateTime: mfbDateTime.DateAndTime = fp.DateValue; mvProp.SetActiveView(vwDateTime); break; case CFPPropertyType.cfpString: txtString.Text = fp.TextValue; mvProp.SetActiveView(vwText); autocompleteStringProp.ContextKey = String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0};{1}", Page.User.Identity.Name, fp.PropTypeID.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; default: throw new MyFlightbookException(String.Format(System.Globalization.CultureInfo.InvariantCulture, "Unknown property type: {0}", fp.PropertyType.Type)); } }
private void CheckTimeIssues(LogbookEntryBase le) { if (currentAircraft.InstanceType != AircraftInstanceTypes.RealAircraft) { return; } int totalMinutes = le.TotalFlightTime.ToMinutes(); AddConditionalIssue(le.CrossCountry.ToMinutes() > totalMinutes, LintOptions.TimeIssues, Resources.FlightLint.warningTimesXCGreaterThanTotal); AddConditionalIssue(le.Nighttime.ToMinutes() > totalMinutes, LintOptions.TimeIssues, Resources.FlightLint.warningTimesNightGreaterThanTotal); AddConditionalIssue(le.SimulatedIFR.ToMinutes() > totalMinutes, LintOptions.TimeIssues, Resources.FlightLint.warningTimesSimIFRGreaterThanTotal); AddConditionalIssue(le.IMC.ToMinutes() > totalMinutes, LintOptions.TimeIssues, Resources.FlightLint.warningTimesIMCGreaterThanTotal); AddConditionalIssue(le.IMC.ToMinutes() + le.SimulatedIFR.ToMinutes() > totalMinutes, LintOptions.TimeIssues, Resources.FlightLint.warningTimesSimPlusIMCGreaterThanTotal); AddConditionalIssue(le.Dual.ToMinutes() > totalMinutes, LintOptions.TimeIssues, Resources.FlightLint.warningTimesDualGreaterThanTotal); AddConditionalIssue(le.CFI.ToMinutes() > totalMinutes, LintOptions.TimeIssues, Resources.FlightLint.warningTimesCFIGreaterThanTotal); AddConditionalIssue(le.SIC.ToMinutes() > totalMinutes, LintOptions.TimeIssues, Resources.FlightLint.warningTimesSICGreaterThanTotal); AddConditionalIssue(le.PIC.ToMinutes() > totalMinutes, LintOptions.TimeIssues, Resources.FlightLint.warningTimesPICGreaterThanTotal); AddConditionalIssue(le.PIC.ToMinutes() + le.SIC.ToMinutes() + le.CFI.ToMinutes() + le.Dual.ToMinutes() == 0 && totalMinutes > 0, LintOptions.TimeIssues, Resources.FlightLint.warningTotalTimeButNoOtherTime); CustomFlightProperty cfpSolo = le.CustomProperties.GetEventWithTypeID(CustomPropertyType.KnownProperties.IDPropSolo); if (cfpSolo != null) { int soloMinutes = cfpSolo.DecValue.ToMinutes(); AddConditionalIssue(soloMinutes > le.PIC.ToMinutes(), LintOptions.TimeIssues, Resources.FlightLint.warningSoloTimeExceedsPICTime); AddConditionalIssue(soloMinutes > totalMinutes - le.SIC.ToMinutes() - le.CFI.ToMinutes() - le.Dual.ToMinutes(), LintOptions.TimeIssues, Resources.FlightLint.warningSoloTimeWithNonSoloTime); } foreach (CustomFlightProperty cfp in le.CustomProperties) { AddConditionalIssue(cfp.PropertyType.Type == CFPPropertyType.cfpDecimal && !cfp.PropertyType.IsBasicDecimal && !cfp.PropertyType.IsNoSum && !hsExcludedTimeProps.Contains(cfp.PropTypeID) && cfp.DecValue.ToMinutes() > totalMinutes, LintOptions.TimeIssues, String.Format(CultureInfo.CurrentCulture, Resources.FlightLint.warningPropertyGreaterThanTotal, cfp.PropertyType.Title)); } CustomFlightProperty cfpTachStart = le.CustomProperties.GetEventWithTypeID(CustomPropertyType.KnownProperties.IDPropTachStart); CustomFlightProperty cfpTachEnd = le.CustomProperties.GetEventWithTypeID(CustomPropertyType.KnownProperties.IDPropTachEnd); AddConditionalIssue(cfpTachStart != null && cfpTachEnd != null && cfpTachEnd.DecValue < cfpTachStart.DecValue, LintOptions.TimeIssues, Resources.FlightLint.warningTachEndBeforeTachStart); if (le.TotalFlightTime > 0) { // Look for block time or engine time that varies significantly from total time UNLESS hobbs is present; if so, compare hobbs to that. Ditto tach, if tach is of by more than 30%. const decimal maxHobbsVariation = 0.2M; const decimal maxBlockVariation = 0.1M; CustomFlightProperty cfpBlockOut = le.CustomProperties.GetEventWithTypeID(CustomPropertyType.KnownProperties.IDBlockOut); CustomFlightProperty cfpBlockIn = le.CustomProperties.GetEventWithTypeID(CustomPropertyType.KnownProperties.IDBlockIn); bool fHasHobbs = le.HobbsEnd > 0 && le.HobbsStart > 0 && le.HobbsEnd > le.HobbsStart; decimal hobbsVariation = Math.Abs(le.HobbsEnd - le.HobbsStart - le.TotalFlightTime); decimal blockTimeVariation = (cfpBlockIn != null && cfpBlockOut != null) ? Math.Abs((decimal)cfpBlockIn.DateValue.Subtract(cfpBlockOut.DateValue).TotalHours - le.TotalFlightTime) : 0; AddConditionalIssue(fHasHobbs && hobbsVariation > maxHobbsVariation, LintOptions.TimeIssues, String.Format(CultureInfo.CurrentCulture, Resources.FlightLint.warningHobbsAndTotalsDiffer, hobbsVariation.ToHHMM())); AddConditionalIssue(!fHasHobbs && blockTimeVariation > maxBlockVariation, LintOptions.TimeIssues, String.Format(CultureInfo.CurrentCulture, Resources.FlightLint.warningBlockAndTotalsDiffer, blockTimeVariation.ToHHMM())); } }
protected void CopyToInstructor(LogbookEntry le) { // Now make it look like the CFI's: their username, swap DUAL for CFI time, ensure that PIC time is present. le.FlightID = LogbookEntry.idFlightNew; string szStudentName = MyFlightbook.Profile.GetUser(le.User).UserFullName; List <CustomFlightProperty> lstProps = new List <CustomFlightProperty>(le.CustomProperties); lstProps.ForEach(cfp => cfp.FlightID = le.FlightID); // Add the student's name as a property lstProps.RemoveAll(cfp => cfp.PropTypeID == (int)CustomPropertyType.KnownProperties.IDPropStudentName); lstProps.Add(new CustomFlightProperty(new CustomPropertyType(CustomPropertyType.KnownProperties.IDPropStudentName)) { FlightID = le.FlightID, TextValue = szStudentName }); le.Comment = String.IsNullOrEmpty(le.Comment) ? txtComments.Text : String.Format(CultureInfo.CurrentCulture, Resources.SignOff.StudentNameTemplate, le.Comment, txtComments.Text); le.User = CFIProfile.UserName; // Swap username, of course, but do so AFTER adjusting the comment above (where we had the user's name) le.PIC = le.CFI = Flight.Dual; // Assume you were PIC for the time you were giving instruction. le.Dual = 0.0M; // Swap ground instruction given/ground-instruction received CustomFlightProperty cfpGIReceived = lstProps.FirstOrDefault(cfp => cfp.PropTypeID == (int)CustomPropertyType.KnownProperties.IDPropGroundInstructionReceived); if (cfpGIReceived != null) { CustomFlightProperty cfpGIGiven = lstProps.FirstOrDefault(cfp => cfp.PropTypeID == (int)CustomPropertyType.KnownProperties.IDPropGroundInstructionGiven); if (cfpGIGiven == null) { cfpGIGiven = new CustomFlightProperty(new CustomPropertyType(CustomPropertyType.KnownProperties.IDPropGroundInstructionGiven)); } cfpGIGiven.DecValue = cfpGIReceived.DecValue; cfpGIGiven.FlightID = le.FlightID; cfpGIReceived.DeleteProperty(); lstProps.Remove(cfpGIReceived); lstProps.Add(cfpGIGiven); } le.CustomProperties = lstProps.ToArray(); // Add this aircraft to the user's profile if needed UserAircraft ua = new UserAircraft(CFIProfile.UserName); Aircraft ac = new Aircraft(le.AircraftID); if (!ua.CheckAircraftForUser(ac)) { ua.FAddAircraftForUser(ac); } bool result = le.FCommit(true); if (!result || le.LastError != LogbookEntry.ErrorCode.None) { util.NotifyAdminEvent("Error copying flight to instructor's logbook", String.Format(CultureInfo.CurrentCulture, "Flight: {0}, CFI: {1}, Student: {2}, ErrorCode: {3}, Error: {4}", le.ToString(), le.User, szStudentName, le.LastError, le.ErrorString), ProfileRoles.maskSiteAdminOnly); } }
public override LogbookEntry ToLogbookEntry() { // Always return pending flights PendingFlight pf = new PendingFlight() { Date = FlightDate, Route = JoinStrings(new string[] { DepartureAirportCode.MostDescriptive, DestinationAirportCode.MostDescriptive }), FlightStart = TakeoffTime ?? DateTime.MinValue, FlightEnd = LandingTime ?? DateTime.MinValue, TailNumDisplay = AircraftRegistration ?? String.Empty, ModelDisplay = AircraftType ?? String.Empty, TotalFlightTime = totalFlightTime == null ? 0 : totalFlightTime.SafeParseDecimal(), Nighttime = NightFlightTime == null ? 0 : NightFlightTime.SafeParseDecimal(), PIC = PicTime == null ? 0 : PicTime.SafeParseDecimal(), SIC = SicTime == null ? 0 : SicTime.SafeParseDecimal(), Dual = DualPilotTimeReceived == null ? 0 : DualPilotTimeReceived.SafeParseDecimal(), CFI = DualPilotTimeGiven == null ? 0 : DualPilotTimeGiven.SafeParseDecimal(), FullStopLandings = DayLandingCount, NightLandings = NightLandingCount, Approaches = ApproachList.Length, User = Username }; Aircraft ac = BestGuessAircraftID(Username, pf.TailNumDisplay); List <CustomFlightProperty> lst = new List <CustomFlightProperty>() { CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDPropFlightNumber, FlightNumber), CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDPropDutyStart, DutyStartTime ?? DateTime.MinValue, true), CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDPropDutyEnd, DutyEndTime ?? DateTime.MinValue, true), CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDBlockOut, ActualDepartureTime ?? DateTime.MinValue, true), CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDBlockIn, ActualArrivalTime ?? DateTime.MinValue, true), CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDPropNameOfPIC, Pic == null || String.IsNullOrEmpty(Pic.Surname) ? Commander : Pic.Surname), CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDPropNameOfSIC, Sic == null || Sic.Surname == null ? string.Empty : Sic.Surname), CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDPropMultiPilotTime, MultiPilotFlightTime == null ? 0 : MultiPilotFlightTime.SafeParseDecimal()), CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDPropSolo, SoloFlightTime == null ? 0 : SoloFlightTime.DecimalFromHHMM()), CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDPropNightTakeoff, NightTakeoffCount), CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDPropIFRTime, IfrTime == null ? 0 : IfrTime.SafeParseDecimal()), CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDPropApproachName, ApproachTypeList == null ? string.Empty : JoinStrings(ApproachTypeList)) }; if (ac != null) { pf.AircraftID = ac.AircraftID; if (ac.IsAnonymous) { lst.Add(CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDPropAircraftRegistration, pf.TailNumDisplay)); } } pf.CustomProperties.SetItems(lst); AutoComplete(pf); return(pf); }
private void InsertEditProp(CustomFlightProperty cfp) { Controls_mfbEditProp ep = (Controls_mfbEditProp)LoadControl("~/Controls/mfbEditProp.ascx"); // Add it to the placeholder so that the client ID works, then set the client ID before setting the property so that it picks up cross-fill plcHolderProps.Controls.Add(ep); ep.CrossFillSourceClientID = CrossFillSourceClientID; ep.ID = IDForPropType(cfp.PropertyType); ep.FlightProperty = cfp; }
private void InsertEditProp(CustomFlightProperty cfp) { mfbEditProp ep = (mfbEditProp)LoadControl("~/Controls/mfbEditProp.ascx"); // Add it to the placeholder so that the client ID works, then set the client ID before setting the property so that it picks up cross-fill plcHolderProps.Controls.Add(ep); ep.CrossFillTotalScript = (cfp.PropertyType.IsLanding) ? CrossFillLandingScript : (cfp.PropertyType.IsApproach ? CrossFillApproachScript : CrossFillDefaultScript); ep.ID = IDForPropType(cfp.PropertyType); ep.Username = Username; ep.FlightProperty = cfp; }
protected CustomFlightProperty PropertyWithValue(CustomPropertyType.KnownProperties id, string value) { if (String.IsNullOrEmpty(value)) { return(null); } CustomFlightProperty cfp = new CustomFlightProperty(PropTypes.FirstOrDefault(cpt => cpt.PropTypeID == (int)id)); cfp.InitFromString(value); return((cfp.IsDefaultValue) ? null : cfp); }
protected void RefreshList(CustomFlightProperty cfp = null, bool fStripDefaults = false) { Properties = PropertiesFromPropSet; // Pick up any changes from the existing child controls, to preserve across postback if (cfp != null) { Properties.Add(cfp); } SegregateProperties(fStripDefaults); // add the new property to the list PopulateControls(); // And re-populate. txtFilter.Text = string.Empty; mfbSelectTemplates.Refresh(); }
private void CheckDateTimeIssues(LogbookEntryBase le) { CustomFlightProperty cfpBlockOut = le.CustomProperties.GetEventWithTypeID(CustomPropertyType.KnownProperties.IDBlockOut); CustomFlightProperty cfpBlockIn = le.CustomProperties.GetEventWithTypeID(CustomPropertyType.KnownProperties.IDBlockIn); // Block out after block in AddConditionalIssue(cfpBlockIn != null && cfpBlockOut != null && cfpBlockOut.DateValue.CompareTo(cfpBlockIn.DateValue) > 0, LintOptions.DateTimeIssues, Resources.FlightLint.warningDateTimeInvalidBlock); if (le.EngineStart.HasValue()) { // Engine start must be before flight. Can be after block out, but not before block in AddConditionalIssue(le.FlightStart.HasValue() && le.FlightStart.CompareTo(le.EngineStart) < 0, LintOptions.DateTimeIssues, Resources.FlightLint.warningDateEngineAfterFlight); AddConditionalIssue(le.FlightEnd.HasValue() && le.FlightEnd.CompareTo(le.EngineStart) < 0, LintOptions.DateTimeIssues, Resources.FlightLint.warningFlightEndBeforeEngineStart); AddConditionalIssue(cfpBlockIn != null && cfpBlockIn.DateValue.CompareTo(le.EngineStart) <= 0, LintOptions.DateTimeIssues, Resources.FlightLint.warningEngineStartAfterBlockIn); } // Flight start must be after engine start (checked above) and after block out AddConditionalIssue(le.FlightStart.HasValue() && cfpBlockOut != null && le.FlightStart.CompareTo(cfpBlockOut.DateValue) < 0, LintOptions.DateTimeIssues, Resources.FlightLint.warningDateBlockAfterFlight); // Flight end must be after engine/flight start (checked in regular validation), after block out, and before block in if (le.FlightEnd.HasValue()) { AddConditionalIssue(cfpBlockOut != null && le.FlightEnd.CompareTo(cfpBlockOut.DateValue) < 0, LintOptions.DateTimeIssues, Resources.FlightLint.warningFlightEndBeforeBlockOut); AddConditionalIssue(cfpBlockIn != null && le.FlightEnd.CompareTo(cfpBlockIn.DateValue) > 0, LintOptions.DateTimeIssues, Resources.FlightLint.warningFlightEndAfterBlockIn); AddConditionalIssue(le.EngineEnd.HasValue() && le.FlightEnd.CompareTo(le.EngineEnd) > 0, LintOptions.DateTimeIssues, Resources.FlightLint.warningFlightEndAfterEngineEnd); } if (le.EngineEnd.HasValue()) { AddConditionalIssue(cfpBlockIn != null && le.EngineEnd.CompareTo(cfpBlockIn.DateValue) < 0, LintOptions.DateTimeIssues, Resources.FlightLint.warningEngineEndBeforeBlockIn); } const int MaxHoursDifference = 48; // Check that engine, flight, and block times are all roughly equal to date-of-flight AddConditionalIssue((le.EngineStart.HasValue() && Math.Abs(le.EngineStart.Subtract(le.Date).TotalHours) > MaxHoursDifference) || (le.EngineEnd.HasValue() && Math.Abs(le.EngineEnd.Subtract(le.Date).TotalHours) > MaxHoursDifference), LintOptions.DateTimeIssues, Resources.FlightLint.warningEngineTimeDiffersDate); AddConditionalIssue((le.FlightStart.HasValue() && Math.Abs(le.FlightStart.Subtract(le.Date).TotalHours) > MaxHoursDifference) || (le.FlightEnd.HasValue() && Math.Abs(le.FlightEnd.Subtract(le.Date).TotalHours) > MaxHoursDifference), LintOptions.DateTimeIssues, Resources.FlightLint.warningFlightTimeDiffersDate); AddConditionalIssue((cfpBlockOut != null && Math.Abs(cfpBlockOut.DateValue.Subtract(le.Date).TotalHours) > MaxHoursDifference) || (cfpBlockIn != null && Math.Abs(cfpBlockIn.DateValue.Subtract(le.Date).TotalHours) > MaxHoursDifference), LintOptions.DateTimeIssues, Resources.FlightLint.warningBlockTimeDiffersDate); // Look for issues with sequential flights CheckSequentialFlightIssues(le); }
private void Add11723BTime(ExaminerFlightRow cfr, DateTime dtDutyEnd) { DateTime flightStart, flightEnd; decimal totalHoursTime = Math.Round(cfr.Total * 60.0M) / 60.0M; // Issue #503 - favor block time (which matches the regulation's "flight time" definition), using engine as a secondary proxy CustomFlightProperty cfpBlockOut = cfr.FlightProps.GetEventWithTypeID(CustomPropertyType.KnownProperties.IDBlockOut); CustomFlightProperty cfpBlockIn = cfr.FlightProps.GetEventWithTypeID(CustomPropertyType.KnownProperties.IDBlockIn); if (cfpBlockOut != null && cfpBlockIn != null && cfpBlockIn.DateValue.CompareTo(cfpBlockOut.DateValue) > 0) { flightStart = cfpBlockOut.DateValue; flightEnd = cfpBlockIn.DateValue; totalHoursTime = Math.Round((decimal)flightEnd.Subtract(flightStart).TotalHours * 60.0M) / 60.0M; } else if (cfr.dtEngineStart.HasValue() && cfr.dtEngineEnd.HasValue()) { flightStart = cfr.dtEngineStart; flightEnd = cfr.dtEngineEnd; totalHoursTime = Math.Round((decimal)flightEnd.Subtract(flightStart).TotalHours * 60.0M) / 60.0M; } else if (cfr.dtFlightStart.HasValue() && cfr.dtFlightEnd.HasValue()) { flightStart = cfr.dtFlightStart; flightEnd = cfr.dtFlightEnd; // Don't adjust total minnutes here because flight time is likely and undercount. } else { // use 11:59pm as the flight end time and compute flight start based off of that to pull as much of it as possible // into the 672 hour or 365 day window. (I.e., most conservative) flightEnd = new DateTime(cfr.dtFlight.Year, cfr.dtFlight.Month, cfr.dtFlight.Day, 23, 59, 0, DateTimeKind.Utc); if (dtDutyEnd.HasValue()) { flightEnd = flightEnd.EarlierDate(dtDutyEnd); } flightStart = flightEnd.AddHours((double)-totalHoursTime); } // 117.23(b)(1) - 100 hours of flight time in 672 consecutive if (flightEnd.CompareTo(dt672HoursAgo) > 0) { hoursFlightTime11723b1 += Math.Max((totalHoursTime - Math.Max((decimal)dt672HoursAgo.Subtract(flightStart).TotalHours, 0.0M)), 0.0M); } // 117.23(b)(2) - 1000 hours in 365 consecutive days. This is NOT hour-for-hour, so can simply compare dates. if (flightEnd.Date.CompareTo(dt365DaysAgo) > 0) { hoursFlightTime11723b2 += totalHoursTime; } }
/// <summary> /// Computes the progress against this milestone /// </summary> /// <returns>A list of MilestoneItem objects</returns> public Collection <MilestoneItem> Refresh() { if (String.IsNullOrEmpty(Username)) { throw new MyFlightbookException("Cannot compute milestones on an empty user!"); } // get all custom flight properties that could contribute to currency of one sort or another // and stick them into a dictionary for retrieval down below by flightID. Dictionary <int, List <CustomFlightProperty> > dctFlightEvents = new Dictionary <int, List <CustomFlightProperty> >(); // flight events (IPC, Instrument checkrides, etc.), keyed by flight ID IEnumerable <CustomFlightProperty> rgPfe = CustomFlightProperty.GetFlaggedEvents(Username); foreach (CustomFlightProperty pfe in rgPfe) { List <CustomFlightProperty> lstpf = (dctFlightEvents.ContainsKey(pfe.FlightID) ? dctFlightEvents[pfe.FlightID] : null); if (lstpf == null) { dctFlightEvents.Add(pfe.FlightID, lstpf = new List <CustomFlightProperty>()); } lstpf.Add(pfe); } List <ExaminerFlightRow> lstRows = new List <ExaminerFlightRow>(); StringBuilder sbRoutes = new StringBuilder(); DBHelper dbh = new DBHelper(CurrencyExaminer.CurrencyQuery(CurrencyExaminer.CurrencyQueryDirection.Descending)); dbh.ReadRows( (comm) => { comm.Parameters.AddWithValue("UserName", Username); comm.Parameters.AddWithValue("langID", System.Threading.Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName); }, (dr) => { ExaminerFlightRow cfr = new ExaminerFlightRow(dr); if (dctFlightEvents.ContainsKey(cfr.flightID)) { cfr.AddEvents(dctFlightEvents[cfr.flightID]); } sbRoutes.AppendFormat("{0} ", cfr.Route); lstRows.Add(cfr); // we'll examine it below, after we've populated the routes }); // Set up the airport list once for DB efficiency AirportListOfRoutes = new AirportList(sbRoutes.ToString()); lstRows.ForEach(cfr => { ExamineFlight(cfr); }); return(Milestones); }
protected void SegregateProperties(bool fStripDefault = false) { List <CustomPropertyType> lstRemainingProps = new List <CustomPropertyType>(); ActiveProperties.Clear(); ActivePropTypes.Clear(); PropertyTemplate ptMerged = PropertyTemplate.MergedTemplate(ActiveTemplates); // this is cached so we can do it on every call, postback or not CustomPropertyType[] rgCptAll = CustomPropertyType.GetCustomPropertyTypes(Page.User.Identity.IsAuthenticated ? Username : string.Empty); foreach (CustomPropertyType cpt in rgCptAll) { // see if this either has a value or is in one of the active templates. // if it doesn't have a value but is in a template, give it a value. CustomFlightProperty fp = Properties.Find(cfp => cfp.PropTypeID == cpt.PropTypeID); // To be included, it must be EITHER // a) in the merged set of templates OR // b) in the set of properties with a non-default value (fp != null && !fp.IsDefaultValue) OR // c) in the set of properties with a default value (fp != null && (!fStripDefault && fp.IsDefaultValue) bool fInclude = ptMerged.ContainsProperty(cpt.PropTypeID) || (fp != null && (!fStripDefault || !fp.IsDefaultValue)); if (fp == null) { fp = new CustomFlightProperty(cpt); } if (!fInclude) { lstRemainingProps.Add(cpt); } else { ActiveProperties.Add(fp); ActivePropTypes.Add(fp.PropTypeID); } } ActiveProperties.Sort((cfp1, cfp2) => { return(cfp1.PropertyType.SortKey.CompareCurrentCultureIgnoreCase(cfp2.PropertyType.SortKey)); }); ListItem li = cmbPropsToAdd.Items[0]; cmbPropsToAdd.Items.Clear(); cmbPropsToAdd.Items.Add(li); cmbPropsToAdd.SelectedValue = string.Empty; // reset the selection cmbPropsToAdd.DataSource = lstRemainingProps; cmbPropsToAdd.DataBind(); }
private void PopulateCrewInfo(LogbookEntry le) { if (crew == null) { return; } foreach (CloudAhoyCrewDescriptor cd in crew) { if (cd.currentUser != 0) { if (cd.PIC != 0) { le.PIC = le.TotalFlightTime; } CloudAhoyRoles role = CloudAhoyRoles.None; if (Enum.TryParse <CloudAhoyRoles>(cd.role.Replace(" ", string.Empty), out role)) { switch (role) { case CloudAhoyRoles.Instructor: le.CFI = le.TotalFlightTime; break; case CloudAhoyRoles.Student: le.Dual = le.TotalFlightTime; break; case CloudAhoyRoles.SafetyPilot: DictProps[CustomPropertyType.KnownProperties.IDPropSafetyPilotTime] = CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDPropSafetyPilotTime, le.TotalFlightTime); break; case CloudAhoyRoles.Copilot: le.SIC = le.TotalFlightTime; break; default: break; } } if (cd.solo != 0) { DictProps[CustomPropertyType.KnownProperties.IDPropSolo] = CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDPropSolo, le.TotalFlightTime); } } } }
protected void gvProperties_RowDeleting(object sender, GridViewDeleteEventArgs e) { if (e == null) { throw new ArgumentNullException("e"); } CustomFlightProperty cfp = (CustomFlightProperty)arCfp[e.RowIndex]; arCfp.RemoveAt(e.RowIndex); // remove it from the database (will be a no-op if this has never been saved) cfp.DeleteProperty(); FlightProperties = arCfp; }
public override LogbookEntry ToLogbookEntry() { PendingFlight pf = new PendingFlight() { Date = DATE, Route = String.Format(CultureInfo.CurrentCulture, Resources.LocalizedText.LocalizedJoinWithSpace, DPS, ARS).Trim() }; pf.CustomProperties.SetItems(new CustomFlightProperty[] { CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDPropFlightNumber, FLTNO), CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDBlockOut, FixDateForTime(DATE, DEPL), true), CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDBlockIn, FixDateForTime(DATE, ARRL), true) }); return(pf); }
public override LogbookEntry ToLogbookEntry() { PendingFlight pf = new PendingFlight() { Date = FlightDate, Route = this.Route }; pf.CustomProperties.SetItems(new CustomFlightProperty[] { CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDBlockOut, BlockOut, true), CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDBlockIn, BlockIn, true), CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDPropFlightNumber, FlightNumber) }); return(pf); }
/// <summary> /// Estimates the total distance flown by the user for the subset of flights described by the query /// </summary> /// <param name="fq">The flight query</param> /// <param name="fAutofillDistanceFlown">True to autofill the distance flown property if not found.</param> /// <param name="error">Any error</param> /// <returns>Distance flown, in nm</returns> public static double DistanceFlownByUser(FlightQuery fq, bool fAutofillDistanceFlown, out string error) { if (fq == null) { throw new ArgumentNullException(nameof(fq)); } if (String.IsNullOrEmpty(fq.UserName)) { throw new MyFlightbookException("Don't estimate distance for an empty user!!"); } double distance = 0.0; // Get the master airport list AirportList alMaster = AllFlightsAndNavaids(fq); error = LookAtAllFlights( fq, LogbookEntryCore.LoadTelemetryOption.MetadataOrDB, (le) => { double distThisFlight = 0; // If the trajectory had a distance, use it; otherwise, use airport-to-airport. double dPath = le.Telemetry.Distance(); if (dPath > 0) { distThisFlight = dPath; } else if (!String.IsNullOrEmpty(le.Route)) { distThisFlight = alMaster.CloneSubset(le.Route).DistanceForRoute(); } distance += distThisFlight; if (fAutofillDistanceFlown && distThisFlight > 0 && !le.CustomProperties.PropertyExistsWithID(CustomPropertyType.KnownProperties.IDPropDistanceFlown)) { le.CustomProperties.Add(CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDPropDistanceFlown, (decimal)distThisFlight)); le.FCommit(); } }); return(distance); }
public void gvFlightLogs_RowDataBound(Object sender, GridViewRowEventArgs e) { if (e == null) { throw new ArgumentNullException(nameof(e)); } if (e.Row.RowType == DataControlRowType.DataRow) { if (!(e.Row.DataItem is LogbookEntryBase le)) { throw new InvalidCastException("DataItem is not a logbook entry!"); } // Property summary string szProperties = CustomFlightProperty.PropListDisplay(le.CustomProperties, false, "; "); if (szProperties.Length > 0) { PlaceHolder plcProperties = (PlaceHolder)e.Row.FindControl("plcProperties"); TableCell tc = (TableCell)plcProperties.Parent; tc.Text = szProperties; } // Splice in the custom property types. foreach (CustomFlightProperty cfp in le.CustomProperties) { e.Row.Cells[PropertyColumnMap[cfp.PropTypeID]].Text = HttpUtility.HtmlEncode(cfp.ValueString); } // Add model attributes MakeModel m = MakeModel.GetModel(AircraftForUser[le.AircraftID].ModelID); Aircraft ac = AircraftForUser.ContainsKey(le.AircraftID) ? AircraftForUser[le.AircraftID] : null; ((Label)e.Row.FindControl("lblComplex")).Text = m.IsComplex.FormatBooleanInt(); ((Label)e.Row.FindControl("lblCSP")).Text = m.IsConstantProp.FormatBooleanInt(); ((Label)e.Row.FindControl("lblFlaps")).Text = m.HasFlaps.FormatBooleanInt(); ((Label)e.Row.FindControl("lblRetract")).Text = m.IsRetract.FormatBooleanInt(); ((Label)e.Row.FindControl("lblTailwheel")).Text = m.IsTailWheel.FormatBooleanInt(); ((Label)e.Row.FindControl("lblHP")).Text = m.IsHighPerf.FormatBooleanInt(); ((Label)e.Row.FindControl("lblTurbine")).Text = m.EngineType == MakeModel.TurbineLevel.Piston ? string.Empty : 1.FormatBooleanInt(); ((Label)e.Row.FindControl("lblTAA")).Text = (m.AvionicsTechnology == MakeModel.AvionicsTechnologyType.TAA || (ac != null && (ac.AvionicsTechnologyUpgrade == MakeModel.AvionicsTechnologyType.TAA && (!ac.GlassUpgradeDate.HasValue || le.Date.CompareTo(ac.GlassUpgradeDate.Value) >= 0)))).FormatBooleanInt(); } }
private void CheckSequentialFlightIssues(LogbookEntryBase le) { if (previousFlight == null) { return; } AddConditionalIssue(previousFlight.EngineEnd.HasValue() && le.EngineStart.HasValue() && previousFlight.EngineEnd.CompareTo(le.EngineStart) > 0, LintOptions.DateTimeIssues, Resources.FlightLint.warningPreviousEngineEndsAfterStart); AddConditionalIssue(previousFlight.FlightEnd.HasValue() && le.FlightStart.HasValue() && previousFlight.FlightEnd.CompareTo(le.FlightStart) > 0, LintOptions.DateTimeIssues, Resources.FlightLint.warningPreviousFlightEndsAfterStart); CustomFlightProperty cfpBlockIn = le.CustomProperties[CustomPropertyType.KnownProperties.IDBlockIn]; CustomFlightProperty cfpBlockOut = le.CustomProperties[CustomPropertyType.KnownProperties.IDBlockOut]; CheckBlockIssues(cfpBlockOut); CheckDutyIssues(le, cfpBlockIn, cfpBlockOut); }
private void CheckFlightLengthIssues(LogbookEntryBase le) { CustomFlightProperty cfpBlockOut = le.CustomProperties.GetEventWithTypeID(CustomPropertyType.KnownProperties.IDBlockOut); CustomFlightProperty cfpBlockIn = le.CustomProperties.GetEventWithTypeID(CustomPropertyType.KnownProperties.IDBlockIn); const int MaxHoursDifference = 48; // Check that engine, flight, and block times are all roughly equal to date-of-flight AddConditionalIssue((le.EngineStart.HasValue() && Math.Abs(le.EngineStart.Subtract(le.Date).TotalHours) > MaxHoursDifference) || (le.EngineEnd.HasValue() && Math.Abs(le.EngineEnd.Subtract(le.Date).TotalHours) > MaxHoursDifference), LintOptions.DateTimeIssues, Resources.FlightLint.warningEngineTimeDiffersDate); AddConditionalIssue((le.FlightStart.HasValue() && Math.Abs(le.FlightStart.Subtract(le.Date).TotalHours) > MaxHoursDifference) || (le.FlightEnd.HasValue() && Math.Abs(le.FlightEnd.Subtract(le.Date).TotalHours) > MaxHoursDifference), LintOptions.DateTimeIssues, Resources.FlightLint.warningFlightTimeDiffersDate); AddConditionalIssue((cfpBlockOut != null && Math.Abs(cfpBlockOut.DateValue.Subtract(le.Date).TotalHours) > MaxHoursDifference) || (cfpBlockIn != null && Math.Abs(cfpBlockIn.DateValue.Subtract(le.Date).TotalHours) > MaxHoursDifference), LintOptions.DateTimeIssues, Resources.FlightLint.warningBlockTimeDiffersDate); }
public void gvFlightLogs_RowDataBound(Object sender, GridViewRowEventArgs e) { if (e == null) { throw new ArgumentNullException("e"); } if (e.Row.RowType == DataControlRowType.DataRow) { int idFlight = Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "idflight"), CultureInfo.InvariantCulture); IEnumerable <CustomFlightProperty> rgProps = CustomFlightProperty.PropertiesFromJSONTuples((string)DataBinder.Eval(e.Row.DataItem, "CustomPropsJSON"), idFlight); string szProperties = CustomFlightProperty.PropListDisplay(rgProps, false, "; "); if (szProperties.Length > 0) { PlaceHolder plcProperties = (PlaceHolder)e.Row.FindControl("plcProperties"); TableCell tc = (TableCell)plcProperties.Parent; tc.Text = szProperties; } } }
protected void RefreshLogbookData() { MyFlightbook.Profile pf = MyFlightbook.Profile.GetUser(Page.User.Identity.Name); PrintingOptions printingOptions = PrintOptions1.Options; mvLayouts.ActiveViewIndex = (int)printingOptions.Layout; List <LogbookEntryDisplay> lstFlights = LogbookEntryDisplay.GetFlightsForQuery(LogbookEntry.QueryCommand(mfbSearchForm1.Restriction, fAsc: true), pf.UserName, string.Empty, SortDirection.Ascending, pf.UsesHHMM, pf.UsesUTCDateOfFlight); IPrintingTemplate pt = ActiveTemplate; PrintLayout pl = PrintLayout.LayoutForType(printingOptions.Layout, CurrentUser); bool fCanIncludeImages = pl.SupportsImages; List <int> lstPropsToExclude = new List <int>(printingOptions.ExcludedPropertyIDs); string szPropSeparator = printingOptions.PropertySeparatorText; // set up properties per flight, and compute rough lineheight foreach (LogbookEntryDisplay led in lstFlights) { // Fix up properties according to the printing options List <CustomFlightProperty> lstProps = new List <CustomFlightProperty>(led.CustomProperties); lstProps.RemoveAll(cfp => lstPropsToExclude.Contains(cfp.PropTypeID)); led.CustomProperties = lstProps.ToArray(); led.CustPropertyDisplay = CustomFlightProperty.PropListDisplay(lstProps, pf.UsesHHMM, szPropSeparator); if (printingOptions.IncludeImages) { led.PopulateImages(true); } led.RowHeight = pl.RowHeight(led); } Master.PrintingCSS = pl.CSSPath.ToAbsoluteURL(Request).ToString(); pt.BindPages(LogbookPrintedPage.Paginate(lstFlights, printingOptions.FlightsPerPage, printingOptions.OptionalColumns), CurrentUser, printingOptions.IncludeImages, !SuppressFooter, printingOptions.OptionalColumns); pnlResults.Visible = true; }
public override LogbookEntry ToLogbookEntry() { scheduleddeptime = FixedUTCDateFromTime(date, scheduleddeptime); arrivaltime = FixedUTCDateFromTime(date, arrivaltime, scheduleddeptime); LogbookEntry le = new LogbookEntry() { Date = date, TailNumDisplay = ident, ModelDisplay = type, Route = JoinStrings(new string[] { from, route, to }), TotalFlightTime = Math.Round(total / 60.0M, 2), FullStopLandings = daylandings, NightLandings = nightlandings, Nighttime = Math.Round(night / 60.0M, 2), CFI = Math.Round(dualgiven / 60.0M, 2), Dual = Math.Round(dualreceived / 60.0M, 2), IMC = Math.Round(actualinstrument / 60.0M, 2), Approaches = numberofapproaches, GroundSim = Math.Round(sim / 60.0M, 2), PIC = Math.Round(pic / 60.0M, 2), SIC = Math.Round(sic / 60.0M, 2), CrossCountry = Math.Round(xcountry / 60.0M, 2), Comment = remarks, HobbsStart = hobbsout, HobbsEnd = hobbsin }; le.CustomProperties.SetItems(new CustomFlightProperty[] { CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDPropScheduledDeparture, scheduleddeptime, true), CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDPropScheduledArrival, arrivaltime, true), CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDPropFlightNumber, flt), CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDPropSolo, Math.Round(solo / 60.0M, 2)) }); return(le); }