Fix invoice re-creation after void; add payment terms selector and shop supplies line

- Voided invoices no longer block creating a new invoice for the same job: voided invoice's
  JobId FK is cleared so the unique index slot is freed for the replacement
- Invoice Details view shows voided invoices as history rather than hiding them
- Payment terms: standardized SelectList (Due on Receipt, Net 15/30/45/60/90, 2% 10 Net 30,
  COD) with custom-term preservation; invoice-due-date.js auto-updates Due Date on term change
- Shop supplies on direct (no-quote) jobs: InvoicesController derives the shop supplies line
  from the company rate when the job has no source quote to read the pre-agreed amount from
- Job entity: ShopSuppliesAmount + ShopSuppliesPercent fields preserved through job lifecycle
- Migration: AddShopSuppliesAmountToJob

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-08 20:47:34 -04:00
parent fc35fd123c
commit 3278152d83
10 changed files with 9972 additions and 74 deletions
@@ -0,0 +1,83 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace PowderCoating.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class AddShopSuppliesAmountToJob : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<decimal>(
name: "ShopSuppliesAmount",
table: "Jobs",
type: "decimal(18,2)",
nullable: false,
defaultValue: 0m);
migrationBuilder.AddColumn<decimal>(
name: "ShopSuppliesPercent",
table: "Jobs",
type: "decimal(18,2)",
nullable: false,
defaultValue: 0m);
migrationBuilder.UpdateData(
table: "PricingTiers",
keyColumn: "Id",
keyValue: 1,
column: "CreatedAt",
value: new DateTime(2026, 5, 8, 14, 21, 51, 589, DateTimeKind.Utc).AddTicks(4358));
migrationBuilder.UpdateData(
table: "PricingTiers",
keyColumn: "Id",
keyValue: 2,
column: "CreatedAt",
value: new DateTime(2026, 5, 8, 14, 21, 51, 589, DateTimeKind.Utc).AddTicks(4424));
migrationBuilder.UpdateData(
table: "PricingTiers",
keyColumn: "Id",
keyValue: 3,
column: "CreatedAt",
value: new DateTime(2026, 5, 8, 14, 21, 51, 589, DateTimeKind.Utc).AddTicks(4426));
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ShopSuppliesAmount",
table: "Jobs");
migrationBuilder.DropColumn(
name: "ShopSuppliesPercent",
table: "Jobs");
migrationBuilder.UpdateData(
table: "PricingTiers",
keyColumn: "Id",
keyValue: 1,
column: "CreatedAt",
value: new DateTime(2026, 5, 8, 1, 37, 3, 534, DateTimeKind.Utc).AddTicks(1857));
migrationBuilder.UpdateData(
table: "PricingTiers",
keyColumn: "Id",
keyValue: 2,
column: "CreatedAt",
value: new DateTime(2026, 5, 8, 1, 37, 3, 534, DateTimeKind.Utc).AddTicks(1863));
migrationBuilder.UpdateData(
table: "PricingTiers",
keyColumn: "Id",
keyValue: 3,
column: "CreatedAt",
value: new DateTime(2026, 5, 8, 1, 37, 3, 534, DateTimeKind.Utc).AddTicks(1865));
}
}
}