using Data.SeaHavenIndustries;
using Data.SeaHavenIndustries.Enums;
namespace SeaHaven.Services.Helpers
{
public static class WorkOrderDerivedFields
{
///
/// Past due overlay — never a WorkOrderType. Matches SHOC board design.
///
public static bool IsPastDue(WorkOrder workOrder, DateOnly? asOf = null)
{
var today = asOf ?? DateOnly.FromDateTime(DateTime.UtcNow);
if (workOrder.ScheduledDate == null)
return false;
if (LifecycleStatusMapper.IsTerminal(workOrder.LifecycleStatus))
return false;
return DateOnly.FromDateTime(workOrder.ScheduledDate.Value.Date) < today;
}
public static bool IsPastDue(
DateTime? scheduledDate,
LifecycleStatus? lifecycleStatus,
DateTime? utcNow = null)
{
if (!scheduledDate.HasValue)
return false;
if (LifecycleStatusMapper.IsTerminal(lifecycleStatus))
return false;
var today = (utcNow ?? DateTime.UtcNow).Date;
return scheduledDate.Value.Date < today;
}
///
/// Sets initial lifecycle on create. New WOs start Incomplete unless auto-scheduled.
///
public static void SetInitialLifecycleStatus(WorkOrder workOrder)
{
workOrder.LifecycleStatus ??= LifecycleStatus.Incomplete;
ApplyAutoScheduleIfEligible(workOrder);
}
///
/// SHOC rule: specific scheduled date + assignee + Incomplete → Scheduled.
/// Week-only targets do not auto-schedule.
///
public static bool ApplyAutoScheduleIfEligible(WorkOrder workOrder)
{
if (workOrder.LifecycleStatus != LifecycleStatus.Incomplete)
return false;
if (workOrder.ScheduleWeekOnly == true)
return false;
if (workOrder.ScheduledDate == null)
return false;
if (string.IsNullOrWhiteSpace(workOrder.AssignTo))
return false;
workOrder.LifecycleStatus = LifecycleStatus.Scheduled;
return true;
}
public static string? GetDayGroup(DateTime? scheduledDate)
{
if (!scheduledDate.HasValue)
return null;
return scheduledDate.Value.DayOfWeek switch
{
DayOfWeek.Monday => "monday",
DayOfWeek.Tuesday => "tuesday",
DayOfWeek.Wednesday => "wednesday",
DayOfWeek.Thursday => "thursday",
DayOfWeek.Friday => "friday",
_ => null
};
}
public static string? FormatApptTime(DateTime? start, DateTime? end)
{
if (!start.HasValue)
return null;
if (end.HasValue)
return $"{start.Value:HH:mm} – {end.Value:HH:mm}";
return start.Value.ToString("HH:mm");
}
public static string GetLifecycleStatusLabel(LifecycleStatus? status)
=> status.HasValue ? LifecycleStatusMapper.ToFeLabel(status.Value) : "";
}
}