Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
    /// <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];
        }
    }
Пример #4
0
    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();
    }
Пример #5
0
    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));
        }
    }
Пример #6
0
        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.
                }
            }
        }
Пример #7
0
        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);
        }
Пример #8
0
    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));
        }
    }
Пример #9
0
        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()));
            }
        }
Пример #10
0
    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);
        }
    }
Пример #11
0
        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;
        }
Пример #14
0
        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);
        }
Пример #15
0
 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();
 }
Пример #16
0
        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);
        }
Пример #17
0
        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;
            }
        }
Пример #18
0
        /// <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);
        }
Пример #19
0
    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();
    }
Пример #20
0
        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);
                    }
                }
            }
        }
Пример #21
0
    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;
    }
Пример #22
0
        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);
        }
Пример #23
0
        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);
        }
Пример #24
0
        /// <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);
        }
Пример #25
0
        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();
            }
        }
Пример #26
0
        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);
        }
Пример #27
0
        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);
        }
Пример #28
0
    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;
            }
        }
    }
Пример #29
0
    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;
    }
Пример #30
0
        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);
        }