public BurnDown(SiteSettings ss, IEnumerable <DataRow> dataRows) { dataRows.ForEach(dataRow => { var id = dataRow.Long(Rds.IdColumn(ss.ReferenceType)); var ver = dataRow.Int("Ver"); var target = this.Where(o => o.Id == id && o.Ver < ver).LastOrDefault(); var workValue = dataRow.Decimal("WorkValue"); var progressRate = dataRow.Decimal("ProgressRate"); var progressRateAddtions = ProgressRateAddtions(target, progressRate); Add(new BurnDownElement( id, ver, new Title(ss, dataRow).DisplayValue, workValue, dataRow.DateTime("StartTime"), dataRow.DateTime("CompletionTime"), progressRate, progressRateAddtions, dataRow.Int("Status"), dataRow.Int("Updator"), EarnedValueAddtions(workValue, progressRateAddtions), dataRow.DateTime("CreatedTime"), dataRow.DateTime("UpdatedTime"))); }); if (this.Any()) { var latest = Targets(DateTime.MaxValue); MinTime = latest.Select(o => o.StartTime).Min(); MaxTime = latest.Select(o => o.CompletionTime).Max(); LatestUpdatedTime = latest.Select(o => o.UpdatedTime).Max(); Days = Times.DateDiff(Times.Types.Days, MinTime, MaxTime); } }
public bool Delay(Context context, Status status) { if (!status.Incomplete()) { return(false); } var now = VerType == Versions.VerTypes.Latest ? DateTime.Now.ToLocal(context: context) : UpdatedTime.ToLocal(context: context); var start = Start().ToLocal(context: context); var end = CompletionTime.ToLocal(context: context); var range = Times.DateDiff(Times.Types.Seconds, start, end); var plannedValue = PlannedValue(now, start, range); var earnedValue = EarnedValue(); return(plannedValue > earnedValue && Value < 100); }
private static HtmlBuilder DetailsBody( this HtmlBuilder hb, IContext context, SiteSettings ss, BurnDown burnDown, IEnumerable <int> updators, Column column) { var colspan = updators.Count() + 1; var minTime = burnDown.MinTime; var updatedMaxTime = burnDown.LatestUpdatedTime; var count = Times.DateDiff(Times.Types.Days, minTime, updatedMaxTime); var first = true; return(hb.TBody(action: () => { for (var d = count; d >= 0; d--) { var currentTime = minTime.AddDays(d); if (burnDown.Any(o => o.UpdatedTime == currentTime && o.EarnedValueAdditions != 0)) { hb.DetailsRow( context: context, burnDown: burnDown, updators: updators, currentTime: currentTime, column: column); if (first) { hb.BurnDownRecordDetails( context: context, elements: burnDown.Where(o => o.UpdatedTime == currentTime), progressRateColumn: ss.GetColumn( context: context, columnName: "ProgressRate"), statusColumn: ss.GetColumn( context: context, columnName: "Status"), colspan: updators.Count() + 5, unit: column.Unit); first = false; } } } })); }
public TimeSeries( Context context, SiteSettings ss, Column groupBy, string aggregationType, Column value, IEnumerable <DataRow> dataRows) { SiteSettings = ss; AggregationType = aggregationType; dataRows.ForEach(dataRow => Add(new TimeSeriesElement( context: context, userColumn: groupBy?.Type == Column.Types.User, id: dataRow["Id"].ToLong(), ver: dataRow["Ver"].ToInt(), updatedTime: dataRow["UpdatedTime"] .ToDateTime() .ToLocal(context: context) .Date, index: dataRow[groupBy.ColumnName].ToString(), value: dataRow[value.ColumnName].ToDecimal(), isHistory: dataRow["IsHistory"].ToBool()))); if (this.Any()) { MinTime = this.Select(o => o.UpdatedTime).Min().AddDays(-1); MaxTime = DateTime.Today; Days = Times.DateDiff(Times.Types.Days, MinTime, MaxTime); this .OrderByDescending(o => o.Ver) .GroupBy(o => o.Id) .Select(o => o.First()) .ForEach(element => { element.Latest = true; if (element.IsHistory) { element.UpdatedTime = element.UpdatedTime.AddDays(-1); } }); } }
public decimal PlannedValue(DateTime currentTime) { if (StartTime < currentTime) { if (CompletionTime >= currentTime) { return(WorkValue - PlannedValueOfDaily * Times.DateDiff(Times.Types.Days, StartTime, currentTime).ToDecimal()); } else { return(0); } } else { return(WorkValue); } }
private HtmlBuilder Svg(HtmlBuilder hb, Context context, Column column) { var now = VerType == Versions.VerTypes.Latest ? DateTime.Now.ToLocal(context: context) : UpdatedTime.ToLocal(context: context); var start = Start().ToLocal(context: context); var end = CompletionTime.ToLocal(context: context); var range = Times.DateDiff(Times.Types.Seconds, start, end); var plannedValue = PlannedValue(now, start, range); var earnedValue = EarnedValue(); var css = "svg-progress-rate" + (plannedValue > earnedValue && Value < 100 ? " warning" : string.Empty); return(hb.Svg(css: css, action: () => hb .SvgText( text: column.Display( context: context, value: Value, unit: true), x: 0, y: Parameters.General.ProgressRateTextTop) .Rect( x: 0, y: Parameters.General.ProgressRateItemHeight * 2, width: Parameters.General.ProgressRateWidth.ToString(), height: Parameters.General.ProgressRateItemHeight.ToString()) .Rect( x: 0, y: Parameters.General.ProgressRateItemHeight * 2, width: Convert.ToInt32(plannedValue * Parameters.General.ProgressRateWidth) .ToString(), height: Parameters.General.ProgressRateItemHeight.ToString()) .Rect( x: 0, y: Parameters.General.ProgressRateItemHeight * 3, width: Convert.ToInt32(earnedValue * Parameters.General.ProgressRateWidth) .ToString(), height: Parameters.General.ProgressRateItemHeight.ToString()))); }
public TimeSeries( SiteSettings ss, string groupBy, string aggregationType, string value, IEnumerable <DataRow> dataRows) { SiteSettings = ss; GroupByColumn = groupBy; AggregationType = aggregationType; ValueColumn = value; dataRows.ForEach(dataRow => Add(new TimeSeriesElement( SiteSettings.GetColumn(GroupByColumn)?.UserColumn == true, dataRow["Id"].ToLong(), dataRow["Ver"].ToInt(), dataRow["UpdatedTime"].ToDateTime().ToLocal().Date, dataRow["Index"].ToString(), dataRow["Value"].ToDecimal(), dataRow["IsHistory"].ToBool()))); if (this.Any()) { MinTime = this.Select(o => o.UpdatedTime).Min().AddDays(-1); MaxTime = DateTime.Today; Days = Times.DateDiff(Times.Types.Days, MinTime, MaxTime); this .OrderByDescending(o => o.Ver) .GroupBy(o => o.Id) .Select(o => o.First()) .ForEach(element => { element.Latest = true; if (element.IsHistory) { element.UpdatedTime = element.UpdatedTime.AddDays(-1); } }); } }
public BurnDownElement( IContext context, long id, int ver, string title, decimal workValue, DateTime startTime, DateTime completionTime, decimal progressRate, decimal progressRateAdditions, int status, int updatorId, decimal earnedValueAddtions, DateTime createdTime, DateTime updatedTime) { Id = id; Ver = ver; Title = title; WorkValue = workValue; StartTime = startTime.InRange() ? startTime.ToLocal(context: context).Date : createdTime.ToLocal(context: context).Date; CompletionTime = completionTime.ToLocal(context: context).Date; ProgressRate = progressRate; ProgressRateAdditions = progressRateAdditions; Status = status; Updator = updatorId; CreatedTime = createdTime.ToLocal(context: context).Date; UpdatedTime = updatedTime.ToLocal(context: context).AddDays(1).Date; EarnedValue = GetEarnedValue(); EarnedValueAdditions = earnedValueAddtions; DayCount = Times.DateDiff(Times.Types.Days, StartTime, CompletionTime); PlannedValueOfDaily = DayCount != 0 ? WorkValue / DayCount.ToDecimal() : 0; }
private static double Elapsed(DateTime now, DateTime start) { return(Times.DateDiff(Times.Types.Seconds, start, now)); }
private HtmlBuilder LimitText(HtmlBuilder hb) { var value = Value.ToLocal(); if (!Times.InRange(value)) { return(hb); } var now = VerType == Versions.VerTypes.Latest ? DateTime.Now.ToLocal() : UpdatedTime.ToLocal(); var css = LimitCss(now, value); var years = Times.DateDiff(Times.Types.Years, now, value); if (Math.Abs(years) >= 2) { return(years > 0 ? hb.P(css: css, action: () => hb .Text(text: Displays.LimitAfterYears(years.ToString()))) : hb.P(css: css, action: () => hb .Text(text: Displays.LimitBeforeYears((years * -1).ToString())))); } var months = Times.DateDiff(Times.Types.Months, now, value); if (Math.Abs(months) >= 2) { return(months > 0 ? hb.P(css: css, action: () => hb .Text(text: Displays.LimitAfterMonths(months.ToString()))) : hb.P(css: css, action: () => hb .Text(text: Displays.LimitBeforeMonths((months * -1).ToString())))); } var days = Times.DateDiff(Times.Types.Days, now, value); if ((days >= 0 && days >= 2) || (days < 0)) { return(days > 0 ? hb.P(css: css, action: () => hb .Text(text: Displays.LimitAfterDays((days - 1).ToString()))) : hb.P(css: css, action: () => hb .Text(text: Displays.LimitBeforeDays(((days * -1) + 1).ToString())))); } var hours = Times.DateDiff(Times.Types.Hours, now, value); if (Math.Abs(hours) >= 3) { return(hours > 0 ? hb.P(css: css, action: () => hb .Text(text: Displays.LimitAfterHours(hours.ToString()))) : hb.P(css: css, action: () => hb .Text(text: Displays.LimitBeforeHours((hours * -1).ToString())))); } var minutes = Times.DateDiff(Times.Types.Minutes, now, value); if (Math.Abs(minutes) >= 3) { return(minutes > 0 ? hb.P(css: css, action: () => hb .Text(text: Displays.LimitAfterMinutes(minutes.ToString()))) : hb.P(css: css, action: () => hb .Text(text: Displays.LimitBeforeMinutes((minutes * -1).ToString())))); } var seconds = Times.DateDiff(Times.Types.Seconds, now, value); if (Math.Abs(seconds) >= 1) { return(seconds > 0 ? hb.P(css: css, action: () => hb .Text(text: Displays.LimitAfterSeconds(seconds.ToString()))) : hb.P(css: css, action: () => hb .Text(text: Displays.LimitBeforeSeconds((seconds * -1).ToString())))); } return(hb.P(css: "Display-just", action: () => hb .Text(text: Displays.LimitJust()))); }
public static HtmlBuilder ElapsedTime(this HtmlBuilder hb, DateTime value) { if (!Times.InRange(value)) { return(hb); } var now = DateTime.Now.ToLocal(); var css = "elapsed-time" + ((DateTime.Now - value).Days > Parameters.General.SiteMenuHotSpan ? " old" : string.Empty); var displayTime = Displays.UpdatedTime() + " " + value.ToString(Sessions.CultureInfo()); var years = Times.DateDiff(Times.Types.Years, value, now); if (years >= 2) { return(hb.Span( attributes: new HtmlAttributes() .Class(css) .Title(displayTime), action: () => hb .Text(text: Displays.YearsAgo(years.ToString())))); } var months = Times.DateDiff(Times.Types.Months, value, now); if (months >= 2) { return(hb.Span( attributes: new HtmlAttributes() .Class(css) .Title(displayTime), action: () => hb .Text(text: Displays.MonthsAgo(months.ToString())))); } var days = Times.DateDiff(Times.Types.Days, value, now); if (days >= 3) { return(hb.Span( attributes: new HtmlAttributes() .Class(css) .Title(displayTime), action: () => hb .Text(text: Displays.DaysAgo(days.ToString())))); } var hours = Times.DateDiff(Times.Types.Hours, value, now); if (hours >= 3) { return(hb.Span( attributes: new HtmlAttributes() .Class(css) .Title(displayTime), action: () => hb .Text(text: Displays.HoursAgo(hours.ToString())))); } var minutes = Times.DateDiff(Times.Types.Minutes, value, now); if (minutes >= 3) { return(hb.Span( attributes: new HtmlAttributes() .Class(css) .Title(displayTime), action: () => hb .Text(text: Displays.MinutesAgo(minutes.ToString())))); } var seconds = Times.DateDiff(Times.Types.Seconds, value, now); if (seconds >= 1) { return(hb.Span( attributes: new HtmlAttributes() .Class(css) .Title(displayTime), action: () => hb .Text(text: Displays.SecondsAgo(seconds.ToString())))); } return(hb.Span(css: css, action: () => hb .Text(text: Displays.LimitJust()))); }