Fix two production billing bugs: invoice missing oven cost, quote stuck in Draft after send

Bug 1 — Invoice total didn't match job total for direct jobs:
- Root cause: all three item-save paths in JobsController passed null for
  ovenCostId, so FinalPrice/ShopSuppliesAmount were stored without oven cost
  while the Details page recalculated live with OvenCostId and showed higher.
- Add OvenBatchCost stored field to Job entity (migration AddJobOvenBatchCost,
  default 0 for existing rows).
- Fix Create, Edit, and UpdateItems to pass job.OvenCostId and save OvenBatchCost.
- Fix InvoicesController.Create GET for direct jobs to use stored OvenBatchCost
  and ShopSuppliesAmount as separate labeled lines instead of recalculating
  shop supplies from scratch (which excluded the oven cost base).

Bug 2 — Quote status stayed Draft after "Send Quote via Email":
- ResendQuote advanced the approval token and sent the email but never
  updated the status. Added Draft → Sent advancement (same guard used by
  the SMS send path) so the status updates on successful email send.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-11 10:39:49 -04:00
parent 656f830898
commit 17da692dce
7 changed files with 10722 additions and 16 deletions
@@ -463,6 +463,12 @@ namespace PowderCoating.Infrastructure.Migrations
b.Property<bool>("CanCreateQuotes")
.HasColumnType("bit");
b.Property<bool>("CanManageAccounting")
.HasColumnType("bit");
b.Property<bool>("CanManageBills")
.HasColumnType("bit");
b.Property<bool>("CanManageCalendar")
.HasColumnType("bit");
@@ -4183,6 +4189,9 @@ namespace PowderCoating.Infrastructure.Migrations
b.Property<int?>("OriginalJobId")
.HasColumnType("int");
b.Property<decimal>("OvenBatchCost")
.HasColumnType("decimal(18,2)");
b.Property<int?>("OvenCostId")
.HasColumnType("int");
@@ -6565,7 +6574,7 @@ namespace PowderCoating.Infrastructure.Migrations
{
Id = 1,
CompanyId = 0,
CreatedAt = new DateTime(2026, 5, 10, 16, 55, 8, 322, DateTimeKind.Utc).AddTicks(966),
CreatedAt = new DateTime(2026, 5, 11, 14, 23, 23, 221, DateTimeKind.Utc).AddTicks(5837),
Description = "Standard pricing for regular customers",
DiscountPercent = 0m,
IsActive = true,
@@ -6576,7 +6585,7 @@ namespace PowderCoating.Infrastructure.Migrations
{
Id = 2,
CompanyId = 0,
CreatedAt = new DateTime(2026, 5, 10, 16, 55, 8, 322, DateTimeKind.Utc).AddTicks(974),
CreatedAt = new DateTime(2026, 5, 11, 14, 23, 23, 221, DateTimeKind.Utc).AddTicks(5846),
Description = "5% discount for preferred customers",
DiscountPercent = 5m,
IsActive = true,
@@ -6587,7 +6596,7 @@ namespace PowderCoating.Infrastructure.Migrations
{
Id = 3,
CompanyId = 0,
CreatedAt = new DateTime(2026, 5, 10, 16, 55, 8, 322, DateTimeKind.Utc).AddTicks(976),
CreatedAt = new DateTime(2026, 5, 11, 14, 23, 23, 221, DateTimeKind.Utc).AddTicks(5847),
Description = "10% discount for premium customers",
DiscountPercent = 10m,
IsActive = true,