mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-09-30 06:03:12 +00:00
122 lines
5.5 KiB
C#
122 lines
5.5 KiB
C#
using Data.SeaHavenIndustries;
|
|
using Data.SeaHavenIndustries.Enums;
|
|
using SeaHaven.Services.Exceptions;
|
|
|
|
namespace SeaHaven.Services.Helpers
|
|
{
|
|
public static class WorkOrderBoardFieldMutations
|
|
{
|
|
public static List<BoardFieldChange> ApplyAssignTo(WorkOrder workOrder, string? value, string auditField = "AssignTo")
|
|
{
|
|
var normalized = string.IsNullOrWhiteSpace(value) ? null : value.Trim();
|
|
var old = workOrder.AssignTo;
|
|
var changes = new List<BoardFieldChange>();
|
|
|
|
if (old != normalized)
|
|
{
|
|
workOrder.AssignTo = normalized;
|
|
changes.Add(BoardFieldChange.AssignmentChanged(auditField, old, normalized));
|
|
}
|
|
|
|
changes.AddRange(ApplyAutoScheduleSideEffects(workOrder));
|
|
return changes;
|
|
}
|
|
|
|
public static List<BoardFieldChange> ApplyScheduledDate(
|
|
WorkOrder workOrder,
|
|
DateTime? parsed,
|
|
string auditField = "ScheduledDate",
|
|
bool incrementRescheduleOnChange = true)
|
|
{
|
|
var previousDate = workOrder.ScheduledDate;
|
|
var changes = new List<BoardFieldChange>();
|
|
var oldFormatted = FormatDate(previousDate);
|
|
var newFormatted = FormatDate(parsed);
|
|
|
|
if (oldFormatted == newFormatted)
|
|
return changes;
|
|
|
|
workOrder.ScheduledDate = parsed;
|
|
changes.Add(BoardFieldChange.Changed(auditField, oldFormatted, newFormatted));
|
|
|
|
if (!workOrder.OriginalDate.HasValue && parsed.HasValue)
|
|
{
|
|
workOrder.OriginalDate = DateOnly.FromDateTime(parsed.Value);
|
|
var originalWeek = WorkOrderBoardMutationRules.ComputeOriginalWeek(parsed);
|
|
if (originalWeek.HasValue)
|
|
workOrder.OriginalWeek = originalWeek;
|
|
}
|
|
|
|
if (incrementRescheduleOnChange && WorkOrderBoardMutationRules.IsReschedule(previousDate, parsed))
|
|
{
|
|
var oldCount = workOrder.RescheduleCount.ToString();
|
|
workOrder.RescheduleCount++;
|
|
changes.Add(BoardFieldChange.Changed(
|
|
WorkOrderBoardFieldNames.RescheduleCount,
|
|
oldCount,
|
|
workOrder.RescheduleCount.ToString()));
|
|
}
|
|
|
|
changes.AddRange(ApplyAutoScheduleSideEffects(workOrder));
|
|
return changes;
|
|
}
|
|
|
|
public static List<BoardFieldChange> ApplyAutoScheduleSideEffects(WorkOrder workOrder)
|
|
=> WorkOrderDerivedFields.ApplyLifecycleFromSchedule(workOrder);
|
|
|
|
public static BoardFieldChange ApplyApptTime(WorkOrder workOrder, Dispatch dispatch, string? value)
|
|
{
|
|
if (!WorkOrderBoardApptTimeParser.TryParse(value, out var start, out var end, out var error))
|
|
throw new WorkOrderBoardValidationException("InvalidValue", error ?? "Invalid apptTime.");
|
|
|
|
var apptDate = dispatch.ScheduledDate ?? workOrder.ScheduledDate;
|
|
var oldStart = FormatDateTime(workOrder.ScheduledStart);
|
|
var oldEnd = FormatDateTime(workOrder.ScheduledEnd);
|
|
|
|
workOrder.ScheduledStart = WorkOrderBoardApptTimeParser.ToScheduledInstant(apptDate, start);
|
|
workOrder.ScheduledEnd = WorkOrderBoardApptTimeParser.ToScheduledInstant(apptDate, end);
|
|
|
|
var newStart = FormatDateTime(workOrder.ScheduledStart);
|
|
var newEnd = FormatDateTime(workOrder.ScheduledEnd);
|
|
var oldCombined = FormatApptRange(oldStart, oldEnd);
|
|
var newCombined = FormatApptRange(newStart, newEnd);
|
|
|
|
if (oldCombined == newCombined)
|
|
return BoardFieldChange.Unchanged("ApptTime", dispatch.Id);
|
|
|
|
return BoardFieldChange.Changed("ApptTime", oldCombined, newCombined, dispatch.Id);
|
|
}
|
|
|
|
public static void SetInitialLifecycleStatus(WorkOrder workOrder)
|
|
{
|
|
workOrder.LifecycleStatus = LifecycleStatus.Incomplete;
|
|
workOrder.Status = WorkOrderDerivedFields.GetLifecycleStatusLabel(LifecycleStatus.Incomplete);
|
|
}
|
|
|
|
private static string? FormatDate(DateTime? value) => value?.ToString("yyyy-MM-dd");
|
|
private static string? FormatDateTime(DateTime? value) => value?.ToString("O");
|
|
private static string? FormatApptRange(string? start, string? end)
|
|
=> start == null && end == null ? null : $"{start}|{end}";
|
|
|
|
public sealed record BoardFieldChange(
|
|
string FieldName,
|
|
string? OldValue,
|
|
string? NewValue,
|
|
AuditActionType Action,
|
|
int? DispatchId,
|
|
bool HasChanged)
|
|
{
|
|
public static BoardFieldChange Unchanged(string fieldName, int? dispatchId = null)
|
|
=> new(fieldName, null, null, AuditActionType.FieldChanged, dispatchId, false);
|
|
|
|
public static BoardFieldChange Changed(string fieldName, string? oldValue, string? newValue, int? dispatchId = null)
|
|
=> new(fieldName, oldValue, newValue, AuditActionType.FieldChanged, dispatchId, true);
|
|
|
|
public static BoardFieldChange StatusChanged(string fieldName, string? oldValue, string? newValue)
|
|
=> new(fieldName, oldValue, newValue, AuditActionType.StatusChanged, null, true);
|
|
|
|
public static BoardFieldChange AssignmentChanged(string fieldName, string? oldValue, string? newValue)
|
|
=> new(fieldName, oldValue, newValue, AuditActionType.AssignmentChanged, null, true);
|
|
}
|
|
}
|
|
}
|