Add quote-changed banner with re-sync to job details

When a source quote is edited after a job was created from it, the job
details page now shows a warning banner with the date of the change and
a link to the quote. Two actions are offered:

- Re-sync from Quote: replaces all job items, coats, prep services, and
  pricing from the current quote. Only available while the job is still
  in a pre-production status (Pending, Quoted, Approved); hidden once
  shop work has started (InPreparation or beyond).
- Dismiss: acknowledges the change without altering the job, clearing
  the banner by advancing the stored snapshot timestamp.

Implemented via Job.QuoteSnapshotUpdatedAt (new nullable column), set at
quote→job conversion time. The banner fires when quote.UpdatedAt exceeds
this baseline. Migration: AddJobQuoteSnapshotUpdatedAt.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-29 18:02:46 -04:00
parent ac3e4452b2
commit 9221fcc783
6 changed files with 9648 additions and 1 deletions
@@ -0,0 +1,71 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace PowderCoating.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class AddJobQuoteSnapshotUpdatedAt : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<DateTime>(
name: "QuoteSnapshotUpdatedAt",
table: "Jobs",
type: "datetime2",
nullable: true);
migrationBuilder.UpdateData(
table: "PricingTiers",
keyColumn: "Id",
keyValue: 1,
column: "CreatedAt",
value: new DateTime(2026, 4, 29, 22, 0, 14, 747, DateTimeKind.Utc).AddTicks(4877));
migrationBuilder.UpdateData(
table: "PricingTiers",
keyColumn: "Id",
keyValue: 2,
column: "CreatedAt",
value: new DateTime(2026, 4, 29, 22, 0, 14, 747, DateTimeKind.Utc).AddTicks(4884));
migrationBuilder.UpdateData(
table: "PricingTiers",
keyColumn: "Id",
keyValue: 3,
column: "CreatedAt",
value: new DateTime(2026, 4, 29, 22, 0, 14, 747, DateTimeKind.Utc).AddTicks(4886));
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "QuoteSnapshotUpdatedAt",
table: "Jobs");
migrationBuilder.UpdateData(
table: "PricingTiers",
keyColumn: "Id",
keyValue: 1,
column: "CreatedAt",
value: new DateTime(2026, 4, 28, 16, 40, 22, 359, DateTimeKind.Utc).AddTicks(5055));
migrationBuilder.UpdateData(
table: "PricingTiers",
keyColumn: "Id",
keyValue: 2,
column: "CreatedAt",
value: new DateTime(2026, 4, 28, 16, 40, 22, 359, DateTimeKind.Utc).AddTicks(5063));
migrationBuilder.UpdateData(
table: "PricingTiers",
keyColumn: "Id",
keyValue: 3,
column: "CreatedAt",
value: new DateTime(2026, 4, 28, 16, 40, 22, 359, DateTimeKind.Utc).AddTicks(5065));
}
}
}