diff --git a/SeaHaven.Services/Implementation/WorkOrderBoardUpdateService.cs b/SeaHaven.Services/Implementation/WorkOrderBoardUpdateService.cs index edbc3c8..f2c5bfb 100644 --- a/SeaHaven.Services/Implementation/WorkOrderBoardUpdateService.cs +++ b/SeaHaven.Services/Implementation/WorkOrderBoardUpdateService.cs @@ -841,6 +841,10 @@ namespace SeaHaven.Services.Implementation DateOnly? previousTargetWeek, List changes) { + // An unmoved schedule keeps Add-On, including the create-time hint on unscheduled WOs (SH-412). + if (workOrder.ScheduledDate == previousScheduledDate && workOrder.TargetWeek == previousTargetWeek) + return; + var oldValue = workOrder.IsAddOn.ToString(); var newIsAddOn = WorkOrderAddonCutoff.RecalculateIsAddOnOnReschedule( workOrder.IsAddOn, diff --git a/SeaHavenIndustries.Tests/WorkOrderBoardUpdateServiceTests.cs b/SeaHavenIndustries.Tests/WorkOrderBoardUpdateServiceTests.cs index 821ab59..28ecab4 100644 --- a/SeaHavenIndustries.Tests/WorkOrderBoardUpdateServiceTests.cs +++ b/SeaHavenIndustries.Tests/WorkOrderBoardUpdateServiceTests.cs @@ -2303,6 +2303,40 @@ public class WorkOrderBoardUpdateServiceTests Assert.Empty(await context.WorkOrderAuditLogs.Where(a => a.FieldName == "IsAddOn").ToListAsync()); } + [Theory] + [InlineData("true")] + [InlineData("false")] + public async Task PatchField_ScheduleWeekOnlyToggle_Unscheduled_KeepsAddOnHint(string weekOnly) + { + var (context, service) = CreateSut(new FixedTimeProvider()); + var wo = new WorkOrder + { + Id = 1, + LifecycleStatus = LifecycleStatus.Pending, + WorkOrderType = WorkOrderType.PM, + ScheduleWeekOnly = weekOnly != "true", + CreatedDate = new DateTime(2026, 6, 1, 0, 0, 0, DateTimeKind.Utc), + IsAddOn = true, + RowVersion = new byte[] { 1, 0, 0, 0, 0, 0, 0, 1 } + }; + context.workOrders.Add(wo); + await context.SaveChangesAsync(); + + var result = await service.PatchFieldAsync(1, new WorkOrderBoardPatchRequestDto + { + Field = WorkOrderBoardFieldNames.ScheduleWeekOnly, + Value = weekOnly, + WorkOrderVersion = ToVersion(wo) + }, "actor-1"); + + Assert.True(result.IsAddOn); + var persisted = await context.workOrders.SingleAsync(w => w.Id == 1); + Assert.Null(persisted.ScheduledDate); + Assert.Null(persisted.TargetWeek); + Assert.True(persisted.IsAddOn); + Assert.Empty(await context.WorkOrderAuditLogs.Where(a => a.FieldName == "IsAddOn").ToListAsync()); + } + [Theory] [InlineData("2026-07-08", false, "2026-06-25", true)] // into the current week, past its cutoff [InlineData("2026-06-24", true, "2026-07-01", false)] // into next week, before its cutoff