mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-09-30 09:33:13 +00:00
Merge pull request #104 from Sea-Haven-Industries/feat/sh-169-board-create-lifecycle
feat(work-orders): persist board create lifecycleStatus (SH-169)
This commit is contained in:
commit
6d66737211
4 changed files with 105 additions and 2 deletions
|
|
@ -41,6 +41,8 @@ namespace SeaHaven.Services.DTOs
|
|||
public DateOnly? TargetWeek { get; set; }
|
||||
public bool? ScheduleWeekOnly { get; set; }
|
||||
public DocStatus? DocStatus { get; set; }
|
||||
/// <summary>Optional create-time lifecycle. When omitted, server defaults to Incomplete.</summary>
|
||||
public LifecycleStatus? LifecycleStatus { get; set; }
|
||||
public int? VendorId { get; set; }
|
||||
public DateTime? ApptDate { get; set; }
|
||||
public string? ApptTime { get; set; }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
using Data.SeaHavenIndustries;
|
||||
using Data.SeaHavenIndustries.Enums;
|
||||
using SeaHaven.Services.Exceptions;
|
||||
|
||||
namespace SeaHaven.Services.Helpers
|
||||
{
|
||||
public static class WorkOrderBoardCreateLifecycleRules
|
||||
{
|
||||
private static readonly HashSet<LifecycleStatus> AllowedCreateStatuses =
|
||||
[
|
||||
LifecycleStatus.Incomplete,
|
||||
LifecycleStatus.Pending,
|
||||
LifecycleStatus.Scheduled,
|
||||
];
|
||||
|
||||
public static void ApplyRequestedOrInitialLifecycleStatus(
|
||||
WorkOrder workOrder,
|
||||
LifecycleStatus? requested,
|
||||
DateTime? scheduledDate,
|
||||
bool? scheduleWeekOnly)
|
||||
{
|
||||
if (!requested.HasValue)
|
||||
{
|
||||
WorkOrderBoardFieldMutations.SetInitialLifecycleStatus(workOrder);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!AllowedCreateStatuses.Contains(requested.Value))
|
||||
{
|
||||
throw new WorkOrderBoardValidationException(
|
||||
"InvalidLifecycleStatus",
|
||||
"lifecycleStatus must be Incomplete, Pending, or Scheduled at create.");
|
||||
}
|
||||
|
||||
if (requested == LifecycleStatus.Scheduled
|
||||
&& (!scheduledDate.HasValue || scheduleWeekOnly == true))
|
||||
{
|
||||
throw new WorkOrderBoardValidationException(
|
||||
"ScheduledRequiresDate",
|
||||
"Scheduled requires a concrete scheduledDate when scheduleWeekOnly is not true.");
|
||||
}
|
||||
|
||||
workOrder.LifecycleStatus = requested.Value;
|
||||
workOrder.Status = WorkOrderDerivedFields.GetLifecycleStatusLabel(requested.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -108,7 +108,11 @@ namespace SeaHaven.Services.Implementation
|
|||
workOrder.VendorNotes = vendorNotes;
|
||||
}
|
||||
|
||||
WorkOrderBoardFieldMutations.SetInitialLifecycleStatus(workOrder);
|
||||
WorkOrderBoardCreateLifecycleRules.ApplyRequestedOrInitialLifecycleStatus(
|
||||
workOrder,
|
||||
request.LifecycleStatus,
|
||||
request.ScheduledDate,
|
||||
request.ScheduleWeekOnly);
|
||||
|
||||
workOrder.IsAddOn = WorkOrderAddonCutoff.ComputeIsAddOnAtCreation(
|
||||
workOrder.CreatedDate!.Value,
|
||||
|
|
@ -121,7 +125,7 @@ namespace SeaHaven.Services.Implementation
|
|||
WorkOrderBoardFieldMutations.BoardFieldChange.Changed("InternalWONumber", "", woNumber),
|
||||
WorkOrderBoardFieldMutations.BoardFieldChange.Changed("WorkOrderType", "", request.WorkOrderType.ToString()),
|
||||
WorkOrderBoardFieldMutations.BoardFieldChange.Changed("SiteCode", "", siteCode),
|
||||
WorkOrderBoardFieldMutations.BoardFieldChange.Changed("LifecycleStatus", "", LifecycleStatus.Incomplete.ToString())
|
||||
WorkOrderBoardFieldMutations.BoardFieldChange.Changed("LifecycleStatus", "", workOrder.LifecycleStatus?.ToString() ?? LifecycleStatus.Incomplete.ToString())
|
||||
};
|
||||
|
||||
if (workOrder.Description != null)
|
||||
|
|
|
|||
|
|
@ -654,4 +654,54 @@ public class WorkOrderBoardCreateServiceTests
|
|||
Assert.Equal("+1 555-0101", result.Info.AdditionalContacts[0].Phone);
|
||||
Assert.Equal("Security Desk", result.Info.AdditionalContacts[1].Name);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Create_WithPendingLifecycle_PersistsPending()
|
||||
{
|
||||
var (_, service) = CreateSut();
|
||||
|
||||
var result = await service.CreateAsync(new WorkOrderBoardCreateRequestDto
|
||||
{
|
||||
WorkOrderType = WorkOrderType.PM,
|
||||
SiteCode = "BK5",
|
||||
LocationId = 1,
|
||||
LifecycleStatus = LifecycleStatus.Pending,
|
||||
}, WorkOrderAccountTestHelpers.AccountUser(), "actor-1");
|
||||
|
||||
Assert.Equal(LifecycleStatus.Pending, result.LifecycleStatus);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Create_WithScheduledLifecycleAndDate_PersistsWithoutAssignee()
|
||||
{
|
||||
var (_, service) = CreateSut();
|
||||
|
||||
var result = await service.CreateAsync(new WorkOrderBoardCreateRequestDto
|
||||
{
|
||||
WorkOrderType = WorkOrderType.PM,
|
||||
SiteCode = "BK5",
|
||||
LocationId = 1,
|
||||
LifecycleStatus = LifecycleStatus.Scheduled,
|
||||
ScheduledDate = new DateTime(2026, 7, 15),
|
||||
ScheduleWeekOnly = false,
|
||||
}, WorkOrderAccountTestHelpers.AccountUser(), "actor-1");
|
||||
|
||||
Assert.Equal(LifecycleStatus.Scheduled, result.LifecycleStatus);
|
||||
Assert.Equal(new DateTime(2026, 7, 15), result.ScheduledDate?.Date);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Create_WithScheduledLifecycleWithoutDate_Throws()
|
||||
{
|
||||
var (_, service) = CreateSut();
|
||||
|
||||
await Assert.ThrowsAsync<WorkOrderBoardValidationException>(() =>
|
||||
service.CreateAsync(new WorkOrderBoardCreateRequestDto
|
||||
{
|
||||
WorkOrderType = WorkOrderType.PM,
|
||||
SiteCode = "BK5",
|
||||
LocationId = 1,
|
||||
LifecycleStatus = LifecycleStatus.Scheduled,
|
||||
}, WorkOrderAccountTestHelpers.AccountUser(), "actor-1"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue