mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-09-30 09:33:13 +00:00
The strict date range made undated open work orders disappear for every client that predates the includeDateless flag. The frontend on main sends the all-weeks window (2000-01-01..2099-12-31) for "no range", the 1970-01-01..2099-12-31 window for the pinned Unassigned queue, and no date input at all for the WO# duplicate lookup. None of those send the flag, so deploying this backend before the frontend would have dropped undated WOs from all three flows. includeDateless is now optional. An explicit value still wins. When it is omitted, a request with no date input or with an all-weeks Custom window keeps its open undated rows, as before SH-391. Any other range stays strict. The backend and frontend can therefore deploy in either order.
125 lines
4.9 KiB
C#
125 lines
4.9 KiB
C#
namespace SeaHaven.Services.Helpers
|
|
{
|
|
public enum WorkOrderAdvancedSearchDatePreset
|
|
{
|
|
ThisWeek,
|
|
LastWeek,
|
|
ThisMonth,
|
|
Last3Months,
|
|
NextWeek,
|
|
NextMonth,
|
|
Custom
|
|
}
|
|
|
|
public record WorkOrderSearchDateRange(DateOnly From, DateOnly To);
|
|
|
|
public static class WorkOrderSearchDateRangeResolver
|
|
{
|
|
// Widest windows the frontend sends for "every week": the no-range search
|
|
// (ADVANCED_SEARCH_ALL_WEEKS_FROM/TO, 2000-01-01..2099-12-31) and the pinned
|
|
// Unassigned queue (UNASSIGNED_QUEUE_DATE_FROM/TO, 1970-01-01..2099-12-31).
|
|
private static readonly DateOnly AllWeeksFrom = new(2000, 1, 1);
|
|
private static readonly DateOnly AllWeeksTo = new(2099, 12, 31);
|
|
|
|
/// <summary>
|
|
/// Whether a board search adds open undated rows to its date range (SH-391).
|
|
/// An explicit <paramref name="includeDateless"/> wins. When it is omitted,
|
|
/// as by clients that predate the flag, a search with no date input or with
|
|
/// an all-weeks Custom window still returns undated rows, as before SH-391:
|
|
/// those requests mean "no range selected". Any other range is strict.
|
|
/// </summary>
|
|
public static bool ResolveIncludeDateless(
|
|
bool? includeDateless,
|
|
WorkOrderAdvancedSearchDatePreset? preset,
|
|
DateOnly? dateFrom,
|
|
DateOnly? dateTo)
|
|
{
|
|
if (includeDateless.HasValue)
|
|
return includeDateless.Value;
|
|
|
|
if (!preset.HasValue && !dateFrom.HasValue && !dateTo.HasValue)
|
|
return true;
|
|
|
|
return preset == WorkOrderAdvancedSearchDatePreset.Custom
|
|
&& dateFrom <= AllWeeksFrom
|
|
&& dateTo >= AllWeeksTo;
|
|
}
|
|
|
|
public static WorkOrderSearchDateRange Resolve(
|
|
WorkOrderAdvancedSearchDatePreset? preset,
|
|
DateOnly? dateFrom,
|
|
DateOnly? dateTo,
|
|
DateOnly? referenceDate = null)
|
|
{
|
|
var today = referenceDate ?? DateOnly.FromDateTime(DateTime.UtcNow);
|
|
var resolvedPreset = preset ?? WorkOrderAdvancedSearchDatePreset.ThisWeek;
|
|
|
|
if (resolvedPreset == WorkOrderAdvancedSearchDatePreset.Custom)
|
|
{
|
|
if (!dateFrom.HasValue || !dateTo.HasValue)
|
|
throw new ArgumentException("dateFrom and dateTo are required when datePreset is custom.");
|
|
|
|
if (dateTo.Value < dateFrom.Value)
|
|
throw new ArgumentException("dateTo must be on or after dateFrom.");
|
|
|
|
return new WorkOrderSearchDateRange(dateFrom.Value, dateTo.Value);
|
|
}
|
|
|
|
return resolvedPreset switch
|
|
{
|
|
WorkOrderAdvancedSearchDatePreset.ThisWeek => ThisIsoWeek(today),
|
|
WorkOrderAdvancedSearchDatePreset.LastWeek => LastIsoWeek(today),
|
|
WorkOrderAdvancedSearchDatePreset.ThisMonth => ThisMonth(today),
|
|
WorkOrderAdvancedSearchDatePreset.Last3Months => Last3Months(today),
|
|
WorkOrderAdvancedSearchDatePreset.NextWeek => NextIsoWeek(today),
|
|
WorkOrderAdvancedSearchDatePreset.NextMonth => NextMonth(today),
|
|
_ => ThisIsoWeek(today)
|
|
};
|
|
}
|
|
|
|
public static DateOnly GetIsoWeekStart(DateOnly date)
|
|
{
|
|
var diff = (7 + (date.DayOfWeek - DayOfWeek.Monday)) % 7;
|
|
return date.AddDays(-diff);
|
|
}
|
|
|
|
private static WorkOrderSearchDateRange ThisIsoWeek(DateOnly today)
|
|
{
|
|
var start = GetIsoWeekStart(today);
|
|
return new WorkOrderSearchDateRange(start, start.AddDays(4));
|
|
}
|
|
|
|
private static WorkOrderSearchDateRange LastIsoWeek(DateOnly today)
|
|
{
|
|
var start = GetIsoWeekStart(today).AddDays(-7);
|
|
return new WorkOrderSearchDateRange(start, start.AddDays(4));
|
|
}
|
|
|
|
private static WorkOrderSearchDateRange NextIsoWeek(DateOnly today)
|
|
{
|
|
var start = GetIsoWeekStart(today).AddDays(7);
|
|
return new WorkOrderSearchDateRange(start, start.AddDays(4));
|
|
}
|
|
|
|
private static WorkOrderSearchDateRange ThisMonth(DateOnly today)
|
|
{
|
|
var start = new DateOnly(today.Year, today.Month, 1);
|
|
var end = start.AddMonths(1).AddDays(-1);
|
|
return new WorkOrderSearchDateRange(start, end);
|
|
}
|
|
|
|
private static WorkOrderSearchDateRange NextMonth(DateOnly today)
|
|
{
|
|
var start = new DateOnly(today.Year, today.Month, 1).AddMonths(1);
|
|
var end = start.AddMonths(1).AddDays(-1);
|
|
return new WorkOrderSearchDateRange(start, end);
|
|
}
|
|
|
|
private static WorkOrderSearchDateRange Last3Months(DateOnly today)
|
|
{
|
|
var end = today;
|
|
var start = today.AddMonths(-3);
|
|
return new WorkOrderSearchDateRange(start, end);
|
|
}
|
|
}
|
|
}
|