Add rework pricing type (Fixed vs Per-Item) and inline rework flow on Job Details

Adds a PricingType enum to ReworkRecord (FixedPrice | PerItem), surfaces the
choice in the rework modal on Job Details, and wires the resulting unit/total
price display. Includes migration AddReworkPricingType, updated repository
query for rework history, and help article updates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-23 09:27:34 -04:00
parent 15b070398b
commit f018653c18
13 changed files with 11143 additions and 169 deletions
@@ -150,13 +150,18 @@ public class QuoteAndReworkControllerFlowTests
DefectDescription = "Thin coverage on one edge",
DiscoveredBy = ReworkDiscoveredBy.Internal,
DiscoveredDate = new DateTime(2026, 5, 9),
EstimatedReworkCost = 65m
EstimatedReworkCost = 65m,
CreateReworkJob = true,
ReworkJobItemIds = [10],
ReworkPricingType = ReworkPricingType.CustomerFull
});
Assert.IsType<JsonResult>(result);
var reworkJob = await context.Jobs.SingleAsync(j => j.IsReworkJob);
Assert.Equal(1, reworkJob.OriginalJobId);
Assert.Equal("JOB-2605-0001-R1", reworkJob.JobNumber);
Assert.Equal(2, reworkJob.JobStatusId); // first non-Pending status
var reworkItem = await context.JobItems.SingleAsync(i => i.JobId == reworkJob.Id);
Assert.True(reworkItem.IsSalesItem);
@@ -284,13 +289,9 @@ public class QuoteAndReworkControllerFlowTests
CompanyName = "Acme Fabrication"
});
context.JobStatusLookups.Add(new JobStatusLookup
{
Id = 1,
CompanyId = 1,
StatusCode = "PENDING",
DisplayName = "Pending"
});
context.JobStatusLookups.AddRange(
new JobStatusLookup { Id = 1, CompanyId = 1, StatusCode = "PENDING", DisplayName = "Pending", DisplayOrder = 1 },
new JobStatusLookup { Id = 2, CompanyId = 1, StatusCode = "IN_PREPARATION", DisplayName = "In Preparation", DisplayOrder = 2 });
context.JobPriorityLookups.Add(new JobPriorityLookup
{