shoc-backend/SeaHaven.Services/Implementation/SyncFieldMergePolicy.cs

92 lines
3.5 KiB
C#

using Data.SeaHavenIndustries;
using SeaHaven.Services.Interfaces;
namespace SeaHaven.Services.Implementation
{
public class SyncFieldMergePolicy : ISyncFieldMergePolicy
{
private static readonly HashSet<string> ShocOwnedFieldSet = new(StringComparer.OrdinalIgnoreCase)
{
"LifecycleStatus", "AssignTo", "ScheduledDate", "ScheduledEnd", "TargetWeek", "ScheduleWeekOnly",
"DueDate", "Description", "WorkerOrderTitle", "SiteCode", "Building", "LocationId",
"WorkOrderType", "Service", "DocStatus", "Trade", "Problem", "Priority", "InternalWONumber", "Status"
};
private readonly IWorkOrderFieldLockService _fieldLocks;
private readonly IWorkOrderAuditService _audit;
public SyncFieldMergePolicy(IWorkOrderFieldLockService fieldLocks, IWorkOrderAuditService audit)
{
_fieldLocks = fieldLocks;
_audit = audit;
}
public IReadOnlySet<string> ShocOwnedFields => ShocOwnedFieldSet;
public bool CanSyncOverwrite(int workOrderId, string fieldName)
=> !_fieldLocks.IsLockedAsync(workOrderId, fieldName).GetAwaiter().GetResult();
public async Task<bool> TryApplyAsync(WorkOrderSyncContext context, string fieldName, object? incomingValue)
{
if (incomingValue == null) return false;
if (await context.FieldLocks.IsLockedAsync(context.WorkOrder.Id, fieldName))
{
var current = GetFieldValue(context.WorkOrder, fieldName);
await context.Audit.LogSyncRejectedAsync(
context.WorkOrder.Id,
fieldName,
current,
incomingValue.ToString());
return false;
}
ApplyField(context.WorkOrder, fieldName, incomingValue);
return true;
}
private static string? GetFieldValue(WorkOrder wo, string fieldName) => fieldName switch
{
"Description" => wo.Description,
"WorkerOrderTitle" => wo.WorkerOrderTitle,
"Status" => wo.Status,
"DueDate" => wo.DueDate?.ToString("O"),
"SiteCode" => wo.SiteCode,
"Building" => wo.Building,
"Priority" => wo.Priority,
"Severity" => wo.Severity,
_ => null
};
private static void ApplyField(WorkOrder wo, string fieldName, object incomingValue)
{
switch (fieldName)
{
case "Description":
wo.Description = incomingValue.ToString();
break;
case "WorkerOrderTitle":
wo.WorkerOrderTitle = incomingValue.ToString();
break;
case "Status":
wo.Status = incomingValue.ToString();
break;
case "DueDate" when incomingValue is DateTime dt:
wo.DueDate = dt;
break;
case "SiteCode":
wo.SiteCode = incomingValue.ToString();
break;
case "Building":
wo.Building = incomingValue.ToString();
break;
case "Priority":
wo.Priority = incomingValue.ToString();
break;
case "Severity":
wo.Severity = incomingValue.ToString();
break;
}
}
}
}