diff --git a/scripts/042426_deploy_migration.sql b/scripts/042426_deploy_migration.sql
new file mode 100644
index 0000000..3712d2f
--- /dev/null
+++ b/scripts/042426_deploy_migration.sql
@@ -0,0 +1,5860 @@
+IF OBJECT_ID(N'[__EFMigrationsHistory]') IS NULL
+BEGIN
+ CREATE TABLE [__EFMigrationsHistory] (
+ [MigrationId] nvarchar(150) NOT NULL,
+ [ProductVersion] nvarchar(32) NOT NULL,
+ CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId])
+ );
+END;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260316155002_Baseline'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-16T15:49:58.7377851Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260316155002_Baseline'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-16T15:49:58.7377856Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260316155002_Baseline'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-16T15:49:58.7377858Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260316155002_Baseline'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260316155002_Baseline', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260317121938_AddAiContextProfile'
+)
+BEGIN
+ ALTER TABLE [CompanyOperatingCosts] ADD [AiContextProfile] nvarchar(2000) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260317121938_AddAiContextProfile'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-17T12:19:34.4894690Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260317121938_AddAiContextProfile'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-17T12:19:34.4894696Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260317121938_AddAiContextProfile'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-17T12:19:34.4894698Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260317121938_AddAiContextProfile'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260317121938_AddAiContextProfile', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260317205927_FixLaborItemQuantityDecimal'
+)
+BEGIN
+ DECLARE @var0 sysname;
+ SELECT @var0 = [d].[name]
+ FROM [sys].[default_constraints] [d]
+ INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id]
+ WHERE ([d].[parent_object_id] = OBJECT_ID(N'[QuoteItems]') AND [c].[name] = N'Quantity');
+ IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [QuoteItems] DROP CONSTRAINT [' + @var0 + '];');
+ ALTER TABLE [QuoteItems] ALTER COLUMN [Quantity] decimal(18,2) NOT NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260317205927_FixLaborItemQuantityDecimal'
+)
+BEGIN
+ DECLARE @var1 sysname;
+ SELECT @var1 = [d].[name]
+ FROM [sys].[default_constraints] [d]
+ INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id]
+ WHERE ([d].[parent_object_id] = OBJECT_ID(N'[JobItems]') AND [c].[name] = N'Quantity');
+ IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [JobItems] DROP CONSTRAINT [' + @var1 + '];');
+ ALTER TABLE [JobItems] ALTER COLUMN [Quantity] decimal(18,2) NOT NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260317205927_FixLaborItemQuantityDecimal'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-17T20:59:24.2463737Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260317205927_FixLaborItemQuantityDecimal'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-17T20:59:24.2463746Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260317205927_FixLaborItemQuantityDecimal'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-17T20:59:24.2463748Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260317205927_FixLaborItemQuantityDecimal'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260317205927_FixLaborItemQuantityDecimal', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318124847_AddJobTimeEntries'
+)
+BEGIN
+ CREATE TABLE [JobTimeEntries] (
+ [Id] int NOT NULL IDENTITY,
+ [JobId] int NOT NULL,
+ [ShopWorkerId] int NOT NULL,
+ [WorkDate] datetime2 NOT NULL,
+ [HoursWorked] decimal(18,2) NOT NULL,
+ [Stage] nvarchar(max) NULL,
+ [Notes] nvarchar(max) NULL,
+ [CompanyId] int NOT NULL,
+ [CreatedAt] datetime2 NOT NULL,
+ [UpdatedAt] datetime2 NULL,
+ [CreatedBy] nvarchar(max) NULL,
+ [UpdatedBy] nvarchar(max) NULL,
+ [IsDeleted] bit NOT NULL,
+ [DeletedAt] datetime2 NULL,
+ [DeletedBy] nvarchar(max) NULL,
+ CONSTRAINT [PK_JobTimeEntries] PRIMARY KEY ([Id]),
+ CONSTRAINT [FK_JobTimeEntries_Jobs_JobId] FOREIGN KEY ([JobId]) REFERENCES [Jobs] ([Id]) ON DELETE CASCADE,
+ CONSTRAINT [FK_JobTimeEntries_ShopWorkers_ShopWorkerId] FOREIGN KEY ([ShopWorkerId]) REFERENCES [ShopWorkers] ([Id]) ON DELETE CASCADE
+ );
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318124847_AddJobTimeEntries'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-18T12:48:44.7462691Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318124847_AddJobTimeEntries'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-18T12:48:44.7462697Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318124847_AddJobTimeEntries'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-18T12:48:44.7462699Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318124847_AddJobTimeEntries'
+)
+BEGIN
+ CREATE INDEX [IX_JobTimeEntries_JobId] ON [JobTimeEntries] ([JobId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318124847_AddJobTimeEntries'
+)
+BEGIN
+ CREATE INDEX [IX_JobTimeEntries_ShopWorkerId] ON [JobTimeEntries] ([ShopWorkerId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318124847_AddJobTimeEntries'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260318124847_AddJobTimeEntries', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318131500_AddJobShopAccessCode'
+)
+BEGIN
+ ALTER TABLE [Jobs] ADD [ShopAccessCode] uniqueidentifier NOT NULL DEFAULT (NEWID());
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318131500_AddJobShopAccessCode'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-18T13:14:57.2203832Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318131500_AddJobShopAccessCode'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-18T13:14:57.2203838Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318131500_AddJobShopAccessCode'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-18T13:14:57.2203839Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318131500_AddJobShopAccessCode'
+)
+BEGIN
+ CREATE UNIQUE INDEX [IX_Jobs_ShopAccessCode] ON [Jobs] ([ShopAccessCode]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318131500_AddJobShopAccessCode'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260318131500_AddJobShopAccessCode', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318132857_AddShopWorkerRoleCosts'
+)
+BEGIN
+ CREATE TABLE [ShopWorkerRoleCosts] (
+ [Id] int NOT NULL IDENTITY,
+ [Role] int NOT NULL,
+ [HourlyRate] decimal(18,2) NOT NULL,
+ [CompanyId] int NOT NULL,
+ [CreatedAt] datetime2 NOT NULL,
+ [UpdatedAt] datetime2 NULL,
+ [CreatedBy] nvarchar(max) NULL,
+ [UpdatedBy] nvarchar(max) NULL,
+ [IsDeleted] bit NOT NULL,
+ [DeletedAt] datetime2 NULL,
+ [DeletedBy] nvarchar(max) NULL,
+ CONSTRAINT [PK_ShopWorkerRoleCosts] PRIMARY KEY ([Id])
+ );
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318132857_AddShopWorkerRoleCosts'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-18T13:28:54.6854802Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318132857_AddShopWorkerRoleCosts'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-18T13:28:54.6854849Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318132857_AddShopWorkerRoleCosts'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-18T13:28:54.6854851Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318132857_AddShopWorkerRoleCosts'
+)
+BEGIN
+ CREATE UNIQUE INDEX [IX_ShopWorkerRoleCosts_CompanyId_Role] ON [ShopWorkerRoleCosts] ([CompanyId], [Role]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318132857_AddShopWorkerRoleCosts'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260318132857_AddShopWorkerRoleCosts', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318134236_AddReworkTracking'
+)
+BEGIN
+ ALTER TABLE [Jobs] ADD [IsReworkJob] bit NOT NULL DEFAULT CAST(0 AS bit);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318134236_AddReworkTracking'
+)
+BEGIN
+ ALTER TABLE [Jobs] ADD [OriginalJobId] int NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318134236_AddReworkTracking'
+)
+BEGIN
+ CREATE TABLE [ReworkRecords] (
+ [Id] int NOT NULL IDENTITY,
+ [JobId] int NOT NULL,
+ [JobItemId] int NULL,
+ [ReworkJobId] int NULL,
+ [ReworkType] int NOT NULL,
+ [Reason] int NOT NULL,
+ [DefectDescription] nvarchar(max) NOT NULL,
+ [DiscoveredBy] int NOT NULL,
+ [DiscoveredDate] datetime2 NOT NULL,
+ [ReportedByName] nvarchar(max) NULL,
+ [EstimatedReworkCost] decimal(18,2) NOT NULL,
+ [ActualReworkCost] decimal(18,2) NOT NULL,
+ [IsBillableToCustomer] bit NOT NULL,
+ [BillingNotes] nvarchar(max) NULL,
+ [Status] int NOT NULL,
+ [Resolution] int NULL,
+ [ResolvedDate] datetime2 NULL,
+ [ResolutionNotes] nvarchar(max) NULL,
+ [CompanyId] int NOT NULL,
+ [CreatedAt] datetime2 NOT NULL,
+ [UpdatedAt] datetime2 NULL,
+ [CreatedBy] nvarchar(max) NULL,
+ [UpdatedBy] nvarchar(max) NULL,
+ [IsDeleted] bit NOT NULL,
+ [DeletedAt] datetime2 NULL,
+ [DeletedBy] nvarchar(max) NULL,
+ CONSTRAINT [PK_ReworkRecords] PRIMARY KEY ([Id]),
+ CONSTRAINT [FK_ReworkRecords_JobItems_JobItemId] FOREIGN KEY ([JobItemId]) REFERENCES [JobItems] ([Id]),
+ CONSTRAINT [FK_ReworkRecords_Jobs_JobId] FOREIGN KEY ([JobId]) REFERENCES [Jobs] ([Id]) ON DELETE NO ACTION,
+ CONSTRAINT [FK_ReworkRecords_Jobs_ReworkJobId] FOREIGN KEY ([ReworkJobId]) REFERENCES [Jobs] ([Id])
+ );
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318134236_AddReworkTracking'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-18T13:42:32.9092998Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318134236_AddReworkTracking'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-18T13:42:32.9093003Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318134236_AddReworkTracking'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-18T13:42:32.9093005Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318134236_AddReworkTracking'
+)
+BEGIN
+ CREATE INDEX [IX_Jobs_OriginalJobId] ON [Jobs] ([OriginalJobId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318134236_AddReworkTracking'
+)
+BEGIN
+ CREATE INDEX [IX_ReworkRecords_JobId] ON [ReworkRecords] ([JobId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318134236_AddReworkTracking'
+)
+BEGIN
+ CREATE INDEX [IX_ReworkRecords_JobItemId] ON [ReworkRecords] ([JobItemId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318134236_AddReworkTracking'
+)
+BEGIN
+ CREATE INDEX [IX_ReworkRecords_ReworkJobId] ON [ReworkRecords] ([ReworkJobId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318134236_AddReworkTracking'
+)
+BEGIN
+ ALTER TABLE [Jobs] ADD CONSTRAINT [FK_Jobs_Jobs_OriginalJobId] FOREIGN KEY ([OriginalJobId]) REFERENCES [Jobs] ([Id]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318134236_AddReworkTracking'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260318134236_AddReworkTracking', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318222648_AddRefundsAndCreditMemos'
+)
+BEGIN
+ ALTER TABLE [Invoices] ADD [CreditApplied] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318222648_AddRefundsAndCreditMemos'
+)
+BEGIN
+ ALTER TABLE [Customers] ADD [CreditBalance] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318222648_AddRefundsAndCreditMemos'
+)
+BEGIN
+ CREATE TABLE [CreditMemos] (
+ [Id] int NOT NULL IDENTITY,
+ [MemoNumber] nvarchar(450) NOT NULL,
+ [CustomerId] int NOT NULL,
+ [OriginalInvoiceId] int NULL,
+ [ReworkRecordId] int NULL,
+ [Amount] decimal(18,2) NOT NULL,
+ [AmountApplied] decimal(18,2) NOT NULL,
+ [IssueDate] datetime2 NOT NULL,
+ [ExpiryDate] datetime2 NULL,
+ [Reason] nvarchar(max) NOT NULL,
+ [Notes] nvarchar(max) NULL,
+ [Status] int NOT NULL,
+ [IssuedById] nvarchar(450) NULL,
+ [CompanyId] int NOT NULL,
+ [CreatedAt] datetime2 NOT NULL,
+ [UpdatedAt] datetime2 NULL,
+ [CreatedBy] nvarchar(max) NULL,
+ [UpdatedBy] nvarchar(max) NULL,
+ [IsDeleted] bit NOT NULL,
+ [DeletedAt] datetime2 NULL,
+ [DeletedBy] nvarchar(max) NULL,
+ CONSTRAINT [PK_CreditMemos] PRIMARY KEY ([Id]),
+ CONSTRAINT [FK_CreditMemos_AspNetUsers_IssuedById] FOREIGN KEY ([IssuedById]) REFERENCES [AspNetUsers] ([Id]),
+ CONSTRAINT [FK_CreditMemos_Customers_CustomerId] FOREIGN KEY ([CustomerId]) REFERENCES [Customers] ([Id]) ON DELETE NO ACTION,
+ CONSTRAINT [FK_CreditMemos_Invoices_OriginalInvoiceId] FOREIGN KEY ([OriginalInvoiceId]) REFERENCES [Invoices] ([Id]),
+ CONSTRAINT [FK_CreditMemos_ReworkRecords_ReworkRecordId] FOREIGN KEY ([ReworkRecordId]) REFERENCES [ReworkRecords] ([Id])
+ );
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318222648_AddRefundsAndCreditMemos'
+)
+BEGIN
+ CREATE TABLE [Refunds] (
+ [Id] int NOT NULL IDENTITY,
+ [InvoiceId] int NOT NULL,
+ [PaymentId] int NULL,
+ [Amount] decimal(18,2) NOT NULL,
+ [RefundDate] datetime2 NOT NULL,
+ [RefundMethod] int NOT NULL,
+ [Reason] nvarchar(max) NOT NULL,
+ [Reference] nvarchar(max) NULL,
+ [Notes] nvarchar(max) NULL,
+ [Status] int NOT NULL,
+ [IssuedDate] datetime2 NULL,
+ [IssuedById] nvarchar(450) NULL,
+ [CompanyId] int NOT NULL,
+ [CreatedAt] datetime2 NOT NULL,
+ [UpdatedAt] datetime2 NULL,
+ [CreatedBy] nvarchar(max) NULL,
+ [UpdatedBy] nvarchar(max) NULL,
+ [IsDeleted] bit NOT NULL,
+ [DeletedAt] datetime2 NULL,
+ [DeletedBy] nvarchar(max) NULL,
+ CONSTRAINT [PK_Refunds] PRIMARY KEY ([Id]),
+ CONSTRAINT [FK_Refunds_AspNetUsers_IssuedById] FOREIGN KEY ([IssuedById]) REFERENCES [AspNetUsers] ([Id]),
+ CONSTRAINT [FK_Refunds_Invoices_InvoiceId] FOREIGN KEY ([InvoiceId]) REFERENCES [Invoices] ([Id]) ON DELETE NO ACTION,
+ CONSTRAINT [FK_Refunds_Payments_PaymentId] FOREIGN KEY ([PaymentId]) REFERENCES [Payments] ([Id])
+ );
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318222648_AddRefundsAndCreditMemos'
+)
+BEGIN
+ CREATE TABLE [CreditMemoApplications] (
+ [Id] int NOT NULL IDENTITY,
+ [CreditMemoId] int NOT NULL,
+ [InvoiceId] int NOT NULL,
+ [AmountApplied] decimal(18,2) NOT NULL,
+ [AppliedDate] datetime2 NOT NULL,
+ [AppliedById] nvarchar(450) NULL,
+ [CompanyId] int NOT NULL,
+ [CreatedAt] datetime2 NOT NULL,
+ [UpdatedAt] datetime2 NULL,
+ [CreatedBy] nvarchar(max) NULL,
+ [UpdatedBy] nvarchar(max) NULL,
+ [IsDeleted] bit NOT NULL,
+ [DeletedAt] datetime2 NULL,
+ [DeletedBy] nvarchar(max) NULL,
+ CONSTRAINT [PK_CreditMemoApplications] PRIMARY KEY ([Id]),
+ CONSTRAINT [FK_CreditMemoApplications_AspNetUsers_AppliedById] FOREIGN KEY ([AppliedById]) REFERENCES [AspNetUsers] ([Id]),
+ CONSTRAINT [FK_CreditMemoApplications_CreditMemos_CreditMemoId] FOREIGN KEY ([CreditMemoId]) REFERENCES [CreditMemos] ([Id]) ON DELETE NO ACTION,
+ CONSTRAINT [FK_CreditMemoApplications_Invoices_InvoiceId] FOREIGN KEY ([InvoiceId]) REFERENCES [Invoices] ([Id]) ON DELETE NO ACTION
+ );
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318222648_AddRefundsAndCreditMemos'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-18T22:26:44.9349567Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318222648_AddRefundsAndCreditMemos'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-18T22:26:44.9349573Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318222648_AddRefundsAndCreditMemos'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-18T22:26:44.9349575Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318222648_AddRefundsAndCreditMemos'
+)
+BEGIN
+ CREATE INDEX [IX_CreditMemoApplications_AppliedById] ON [CreditMemoApplications] ([AppliedById]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318222648_AddRefundsAndCreditMemos'
+)
+BEGIN
+ CREATE INDEX [IX_CreditMemoApplications_CreditMemoId] ON [CreditMemoApplications] ([CreditMemoId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318222648_AddRefundsAndCreditMemos'
+)
+BEGIN
+ CREATE INDEX [IX_CreditMemoApplications_InvoiceId] ON [CreditMemoApplications] ([InvoiceId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318222648_AddRefundsAndCreditMemos'
+)
+BEGIN
+ CREATE UNIQUE INDEX [IX_CreditMemos_CompanyId_MemoNumber] ON [CreditMemos] ([CompanyId], [MemoNumber]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318222648_AddRefundsAndCreditMemos'
+)
+BEGIN
+ CREATE INDEX [IX_CreditMemos_CustomerId] ON [CreditMemos] ([CustomerId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318222648_AddRefundsAndCreditMemos'
+)
+BEGIN
+ CREATE INDEX [IX_CreditMemos_IssuedById] ON [CreditMemos] ([IssuedById]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318222648_AddRefundsAndCreditMemos'
+)
+BEGIN
+ CREATE INDEX [IX_CreditMemos_OriginalInvoiceId] ON [CreditMemos] ([OriginalInvoiceId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318222648_AddRefundsAndCreditMemos'
+)
+BEGIN
+ CREATE INDEX [IX_CreditMemos_ReworkRecordId] ON [CreditMemos] ([ReworkRecordId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318222648_AddRefundsAndCreditMemos'
+)
+BEGIN
+ CREATE INDEX [IX_Refunds_InvoiceId] ON [Refunds] ([InvoiceId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318222648_AddRefundsAndCreditMemos'
+)
+BEGIN
+ CREATE INDEX [IX_Refunds_IssuedById] ON [Refunds] ([IssuedById]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318222648_AddRefundsAndCreditMemos'
+)
+BEGIN
+ CREATE INDEX [IX_Refunds_PaymentId] ON [Refunds] ([PaymentId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260318222648_AddRefundsAndCreditMemos'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260318222648_AddRefundsAndCreditMemos', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319023827_AddJobTemplates'
+)
+BEGIN
+ CREATE TABLE [JobTemplates] (
+ [Id] int NOT NULL IDENTITY,
+ [Name] nvarchar(max) NOT NULL,
+ [Description] nvarchar(max) NULL,
+ [CustomerId] int NULL,
+ [SpecialInstructions] nvarchar(max) NULL,
+ [IsActive] bit NOT NULL,
+ [UsageCount] int NOT NULL,
+ [CompanyId] int NOT NULL,
+ [CreatedAt] datetime2 NOT NULL,
+ [UpdatedAt] datetime2 NULL,
+ [CreatedBy] nvarchar(max) NULL,
+ [UpdatedBy] nvarchar(max) NULL,
+ [IsDeleted] bit NOT NULL,
+ [DeletedAt] datetime2 NULL,
+ [DeletedBy] nvarchar(max) NULL,
+ CONSTRAINT [PK_JobTemplates] PRIMARY KEY ([Id]),
+ CONSTRAINT [FK_JobTemplates_Customers_CustomerId] FOREIGN KEY ([CustomerId]) REFERENCES [Customers] ([Id])
+ );
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319023827_AddJobTemplates'
+)
+BEGIN
+ CREATE TABLE [JobTemplateItems] (
+ [Id] int NOT NULL IDENTITY,
+ [JobTemplateId] int NOT NULL,
+ [Description] nvarchar(max) NOT NULL,
+ [Quantity] decimal(18,2) NOT NULL,
+ [SurfaceAreaSqFt] decimal(18,2) NOT NULL,
+ [CatalogItemId] int NULL,
+ [IsGenericItem] bit NOT NULL,
+ [IsLaborItem] bit NOT NULL,
+ [ManualUnitPrice] decimal(18,2) NULL,
+ [RequiresSandblasting] bit NOT NULL,
+ [RequiresMasking] bit NOT NULL,
+ [IncludePrepCost] bit NOT NULL,
+ [EstimatedMinutes] int NOT NULL,
+ [Complexity] nvarchar(max) NULL,
+ [Notes] nvarchar(max) NULL,
+ [DisplayOrder] int NOT NULL,
+ [CompanyId] int NOT NULL,
+ [CreatedAt] datetime2 NOT NULL,
+ [UpdatedAt] datetime2 NULL,
+ [CreatedBy] nvarchar(max) NULL,
+ [UpdatedBy] nvarchar(max) NULL,
+ [IsDeleted] bit NOT NULL,
+ [DeletedAt] datetime2 NULL,
+ [DeletedBy] nvarchar(max) NULL,
+ CONSTRAINT [PK_JobTemplateItems] PRIMARY KEY ([Id]),
+ CONSTRAINT [FK_JobTemplateItems_CatalogItems_CatalogItemId] FOREIGN KEY ([CatalogItemId]) REFERENCES [CatalogItems] ([Id]),
+ CONSTRAINT [FK_JobTemplateItems_JobTemplates_JobTemplateId] FOREIGN KEY ([JobTemplateId]) REFERENCES [JobTemplates] ([Id]) ON DELETE CASCADE
+ );
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319023827_AddJobTemplates'
+)
+BEGIN
+ CREATE TABLE [JobTemplateItemCoats] (
+ [Id] int NOT NULL IDENTITY,
+ [JobTemplateItemId] int NOT NULL,
+ [CoatName] nvarchar(max) NOT NULL,
+ [Sequence] int NOT NULL,
+ [InventoryItemId] int NULL,
+ [ColorName] nvarchar(max) NULL,
+ [VendorId] int NULL,
+ [ColorCode] nvarchar(max) NULL,
+ [Finish] nvarchar(max) NULL,
+ [CoverageSqFtPerLb] decimal(18,2) NOT NULL,
+ [TransferEfficiency] decimal(18,2) NOT NULL,
+ [PowderCostPerLb] decimal(18,2) NULL,
+ [Notes] nvarchar(max) NULL,
+ [CompanyId] int NOT NULL,
+ [CreatedAt] datetime2 NOT NULL,
+ [UpdatedAt] datetime2 NULL,
+ [CreatedBy] nvarchar(max) NULL,
+ [UpdatedBy] nvarchar(max) NULL,
+ [IsDeleted] bit NOT NULL,
+ [DeletedAt] datetime2 NULL,
+ [DeletedBy] nvarchar(max) NULL,
+ CONSTRAINT [PK_JobTemplateItemCoats] PRIMARY KEY ([Id]),
+ CONSTRAINT [FK_JobTemplateItemCoats_InventoryItems_InventoryItemId] FOREIGN KEY ([InventoryItemId]) REFERENCES [InventoryItems] ([Id]),
+ CONSTRAINT [FK_JobTemplateItemCoats_JobTemplateItems_JobTemplateItemId] FOREIGN KEY ([JobTemplateItemId]) REFERENCES [JobTemplateItems] ([Id]) ON DELETE CASCADE,
+ CONSTRAINT [FK_JobTemplateItemCoats_Vendors_VendorId] FOREIGN KEY ([VendorId]) REFERENCES [Vendors] ([Id])
+ );
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319023827_AddJobTemplates'
+)
+BEGIN
+ CREATE TABLE [JobTemplateItemPrepServices] (
+ [Id] int NOT NULL IDENTITY,
+ [JobTemplateItemId] int NOT NULL,
+ [PrepServiceId] int NOT NULL,
+ [EstimatedMinutes] int NOT NULL,
+ [CompanyId] int NOT NULL,
+ [CreatedAt] datetime2 NOT NULL,
+ [UpdatedAt] datetime2 NULL,
+ [CreatedBy] nvarchar(max) NULL,
+ [UpdatedBy] nvarchar(max) NULL,
+ [IsDeleted] bit NOT NULL,
+ [DeletedAt] datetime2 NULL,
+ [DeletedBy] nvarchar(max) NULL,
+ CONSTRAINT [PK_JobTemplateItemPrepServices] PRIMARY KEY ([Id]),
+ CONSTRAINT [FK_JobTemplateItemPrepServices_JobTemplateItems_JobTemplateItemId] FOREIGN KEY ([JobTemplateItemId]) REFERENCES [JobTemplateItems] ([Id]) ON DELETE CASCADE,
+ CONSTRAINT [FK_JobTemplateItemPrepServices_PrepServices_PrepServiceId] FOREIGN KEY ([PrepServiceId]) REFERENCES [PrepServices] ([Id]) ON DELETE CASCADE
+ );
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319023827_AddJobTemplates'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-19T02:38:23.4195291Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319023827_AddJobTemplates'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-19T02:38:23.4195296Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319023827_AddJobTemplates'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-19T02:38:23.4195298Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319023827_AddJobTemplates'
+)
+BEGIN
+ CREATE INDEX [IX_JobTemplateItemCoats_InventoryItemId] ON [JobTemplateItemCoats] ([InventoryItemId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319023827_AddJobTemplates'
+)
+BEGIN
+ CREATE INDEX [IX_JobTemplateItemCoats_JobTemplateItemId] ON [JobTemplateItemCoats] ([JobTemplateItemId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319023827_AddJobTemplates'
+)
+BEGIN
+ CREATE INDEX [IX_JobTemplateItemCoats_VendorId] ON [JobTemplateItemCoats] ([VendorId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319023827_AddJobTemplates'
+)
+BEGIN
+ CREATE INDEX [IX_JobTemplateItemPrepServices_JobTemplateItemId] ON [JobTemplateItemPrepServices] ([JobTemplateItemId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319023827_AddJobTemplates'
+)
+BEGIN
+ CREATE INDEX [IX_JobTemplateItemPrepServices_PrepServiceId] ON [JobTemplateItemPrepServices] ([PrepServiceId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319023827_AddJobTemplates'
+)
+BEGIN
+ CREATE INDEX [IX_JobTemplateItems_CatalogItemId] ON [JobTemplateItems] ([CatalogItemId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319023827_AddJobTemplates'
+)
+BEGIN
+ CREATE INDEX [IX_JobTemplateItems_JobTemplateId] ON [JobTemplateItems] ([JobTemplateId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319023827_AddJobTemplates'
+)
+BEGIN
+ CREATE INDEX [IX_JobTemplates_CustomerId] ON [JobTemplates] ([CustomerId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319023827_AddJobTemplates'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260319023827_AddJobTemplates', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319154506_AddGiftCertificates'
+)
+BEGIN
+ ALTER TABLE [Invoices] ADD [GiftCertificateRedeemed] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319154506_AddGiftCertificates'
+)
+BEGIN
+ CREATE TABLE [GiftCertificates] (
+ [Id] int NOT NULL IDENTITY,
+ [CertificateCode] nvarchar(max) NOT NULL,
+ [OriginalAmount] decimal(18,2) NOT NULL,
+ [RedeemedAmount] decimal(18,2) NOT NULL,
+ [RecipientCustomerId] int NULL,
+ [RecipientName] nvarchar(max) NULL,
+ [RecipientEmail] nvarchar(max) NULL,
+ [IssuedReason] int NOT NULL,
+ [PurchasePrice] decimal(18,2) NULL,
+ [PurchasingCustomerId] int NULL,
+ [Status] int NOT NULL,
+ [IssueDate] datetime2 NOT NULL,
+ [ExpiryDate] datetime2 NULL,
+ [Notes] nvarchar(max) NULL,
+ [IssuedById] nvarchar(450) NULL,
+ [CompanyId] int NOT NULL,
+ [CreatedAt] datetime2 NOT NULL,
+ [UpdatedAt] datetime2 NULL,
+ [CreatedBy] nvarchar(max) NULL,
+ [UpdatedBy] nvarchar(max) NULL,
+ [IsDeleted] bit NOT NULL,
+ [DeletedAt] datetime2 NULL,
+ [DeletedBy] nvarchar(max) NULL,
+ CONSTRAINT [PK_GiftCertificates] PRIMARY KEY ([Id]),
+ CONSTRAINT [FK_GiftCertificates_AspNetUsers_IssuedById] FOREIGN KEY ([IssuedById]) REFERENCES [AspNetUsers] ([Id]),
+ CONSTRAINT [FK_GiftCertificates_Customers_PurchasingCustomerId] FOREIGN KEY ([PurchasingCustomerId]) REFERENCES [Customers] ([Id]),
+ CONSTRAINT [FK_GiftCertificates_Customers_RecipientCustomerId] FOREIGN KEY ([RecipientCustomerId]) REFERENCES [Customers] ([Id])
+ );
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319154506_AddGiftCertificates'
+)
+BEGIN
+ CREATE TABLE [GiftCertificateRedemptions] (
+ [Id] int NOT NULL IDENTITY,
+ [GiftCertificateId] int NOT NULL,
+ [InvoiceId] int NOT NULL,
+ [AmountRedeemed] decimal(18,2) NOT NULL,
+ [RedeemedDate] datetime2 NOT NULL,
+ [RedeemedById] nvarchar(450) NULL,
+ [CompanyId] int NOT NULL,
+ [CreatedAt] datetime2 NOT NULL,
+ [UpdatedAt] datetime2 NULL,
+ [CreatedBy] nvarchar(max) NULL,
+ [UpdatedBy] nvarchar(max) NULL,
+ [IsDeleted] bit NOT NULL,
+ [DeletedAt] datetime2 NULL,
+ [DeletedBy] nvarchar(max) NULL,
+ CONSTRAINT [PK_GiftCertificateRedemptions] PRIMARY KEY ([Id]),
+ CONSTRAINT [FK_GiftCertificateRedemptions_AspNetUsers_RedeemedById] FOREIGN KEY ([RedeemedById]) REFERENCES [AspNetUsers] ([Id]),
+ CONSTRAINT [FK_GiftCertificateRedemptions_GiftCertificates_GiftCertificateId] FOREIGN KEY ([GiftCertificateId]) REFERENCES [GiftCertificates] ([Id]) ON DELETE CASCADE,
+ CONSTRAINT [FK_GiftCertificateRedemptions_Invoices_InvoiceId] FOREIGN KEY ([InvoiceId]) REFERENCES [Invoices] ([Id]) ON DELETE CASCADE
+ );
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319154506_AddGiftCertificates'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-19T15:45:03.1454465Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319154506_AddGiftCertificates'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-19T15:45:03.1454472Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319154506_AddGiftCertificates'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-19T15:45:03.1454474Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319154506_AddGiftCertificates'
+)
+BEGIN
+ CREATE INDEX [IX_GiftCertificateRedemptions_GiftCertificateId] ON [GiftCertificateRedemptions] ([GiftCertificateId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319154506_AddGiftCertificates'
+)
+BEGIN
+ CREATE INDEX [IX_GiftCertificateRedemptions_InvoiceId] ON [GiftCertificateRedemptions] ([InvoiceId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319154506_AddGiftCertificates'
+)
+BEGIN
+ CREATE INDEX [IX_GiftCertificateRedemptions_RedeemedById] ON [GiftCertificateRedemptions] ([RedeemedById]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319154506_AddGiftCertificates'
+)
+BEGIN
+ CREATE INDEX [IX_GiftCertificates_IssuedById] ON [GiftCertificates] ([IssuedById]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319154506_AddGiftCertificates'
+)
+BEGIN
+ CREATE INDEX [IX_GiftCertificates_PurchasingCustomerId] ON [GiftCertificates] ([PurchasingCustomerId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319154506_AddGiftCertificates'
+)
+BEGIN
+ CREATE INDEX [IX_GiftCertificates_RecipientCustomerId] ON [GiftCertificates] ([RecipientCustomerId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260319154506_AddGiftCertificates'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260319154506_AddGiftCertificates', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320002450_AddRefundStoreCreditLink'
+)
+BEGIN
+ ALTER TABLE [Refunds] ADD [CreditMemoId] int NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320002450_AddRefundStoreCreditLink'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-20T00:24:47.3611509Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320002450_AddRefundStoreCreditLink'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-20T00:24:47.3611518Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320002450_AddRefundStoreCreditLink'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-20T00:24:47.3611521Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320002450_AddRefundStoreCreditLink'
+)
+BEGIN
+ CREATE INDEX [IX_Refunds_CreditMemoId] ON [Refunds] ([CreditMemoId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320002450_AddRefundStoreCreditLink'
+)
+BEGIN
+ ALTER TABLE [Refunds] ADD CONSTRAINT [FK_Refunds_CreditMemos_CreditMemoId] FOREIGN KEY ([CreditMemoId]) REFERENCES [CreditMemos] ([Id]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320002450_AddRefundStoreCreditLink'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260320002450_AddRefundStoreCreditLink', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320005106_AddQuoteItemIsAiItem'
+)
+BEGIN
+ ALTER TABLE [QuoteItems] ADD [IsAiItem] bit NOT NULL DEFAULT CAST(0 AS bit);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320005106_AddQuoteItemIsAiItem'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-20T00:51:03.2423766Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320005106_AddQuoteItemIsAiItem'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-20T00:51:03.2423772Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320005106_AddQuoteItemIsAiItem'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-20T00:51:03.2423774Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320005106_AddQuoteItemIsAiItem'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260320005106_AddQuoteItemIsAiItem', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320011057_AddQuotePricingSnapshot'
+)
+BEGIN
+ ALTER TABLE [Quotes] ADD [ItemsSubtotal] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320011057_AddQuotePricingSnapshot'
+)
+BEGIN
+ ALTER TABLE [Quotes] ADD [OvenBatchCost] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320011057_AddQuotePricingSnapshot'
+)
+BEGIN
+ ALTER TABLE [Quotes] ADD [OverheadAmount] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320011057_AddQuotePricingSnapshot'
+)
+BEGIN
+ ALTER TABLE [Quotes] ADD [OverheadPercent] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320011057_AddQuotePricingSnapshot'
+)
+BEGIN
+ ALTER TABLE [Quotes] ADD [ProfitMargin] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320011057_AddQuotePricingSnapshot'
+)
+BEGIN
+ ALTER TABLE [Quotes] ADD [ProfitPercent] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320011057_AddQuotePricingSnapshot'
+)
+BEGIN
+ ALTER TABLE [Quotes] ADD [ShopSuppliesAmount] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320011057_AddQuotePricingSnapshot'
+)
+BEGIN
+ ALTER TABLE [Quotes] ADD [ShopSuppliesPercent] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320011057_AddQuotePricingSnapshot'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-20T01:10:54.1468159Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320011057_AddQuotePricingSnapshot'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-20T01:10:54.1468166Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320011057_AddQuotePricingSnapshot'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-20T01:10:54.1468176Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320011057_AddQuotePricingSnapshot'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260320011057_AddQuotePricingSnapshot', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320231509_AddStripeConnectAndOnlinePayments'
+)
+BEGIN
+ ALTER TABLE [SubscriptionPlanConfigs] ADD [AllowOnlinePayments] bit NOT NULL DEFAULT CAST(0 AS bit);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320231509_AddStripeConnectAndOnlinePayments'
+)
+BEGIN
+ ALTER TABLE [Quotes] ADD [DepositPercent] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320231509_AddStripeConnectAndOnlinePayments'
+)
+BEGIN
+ ALTER TABLE [Quotes] ADD [RequiresDeposit] bit NOT NULL DEFAULT CAST(0 AS bit);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320231509_AddStripeConnectAndOnlinePayments'
+)
+BEGIN
+ ALTER TABLE [Invoices] ADD [OnlineAmountPaid] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320231509_AddStripeConnectAndOnlinePayments'
+)
+BEGIN
+ ALTER TABLE [Invoices] ADD [OnlinePaymentStatus] int NOT NULL DEFAULT 0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320231509_AddStripeConnectAndOnlinePayments'
+)
+BEGIN
+ ALTER TABLE [Invoices] ADD [OnlineSurchargeCollected] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320231509_AddStripeConnectAndOnlinePayments'
+)
+BEGIN
+ ALTER TABLE [Invoices] ADD [PaymentLinkExpiresAt] datetime2 NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320231509_AddStripeConnectAndOnlinePayments'
+)
+BEGIN
+ ALTER TABLE [Invoices] ADD [PaymentLinkToken] nvarchar(max) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320231509_AddStripeConnectAndOnlinePayments'
+)
+BEGIN
+ ALTER TABLE [Invoices] ADD [StripePaymentIntentId] nvarchar(max) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320231509_AddStripeConnectAndOnlinePayments'
+)
+BEGIN
+ ALTER TABLE [Companies] ADD [OnlinePaymentSurchargeType] int NOT NULL DEFAULT 0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320231509_AddStripeConnectAndOnlinePayments'
+)
+BEGIN
+ ALTER TABLE [Companies] ADD [OnlinePaymentSurchargeValue] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320231509_AddStripeConnectAndOnlinePayments'
+)
+BEGIN
+ ALTER TABLE [Companies] ADD [OnlineSurchargeAcknowledged] bit NOT NULL DEFAULT CAST(0 AS bit);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320231509_AddStripeConnectAndOnlinePayments'
+)
+BEGIN
+ ALTER TABLE [Companies] ADD [StripeAccountId] nvarchar(max) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320231509_AddStripeConnectAndOnlinePayments'
+)
+BEGIN
+ ALTER TABLE [Companies] ADD [StripeConnectStatus] int NOT NULL DEFAULT 0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320231509_AddStripeConnectAndOnlinePayments'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-20T23:15:05.6886302Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320231509_AddStripeConnectAndOnlinePayments'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-20T23:15:05.6886308Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320231509_AddStripeConnectAndOnlinePayments'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-20T23:15:05.6886310Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260320231509_AddStripeConnectAndOnlinePayments'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260320231509_AddStripeConnectAndOnlinePayments', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260326230438_AddQuotePhotoSubscriptionLimits'
+)
+BEGIN
+ ALTER TABLE [SubscriptionPlanConfigs] ADD [MaxQuotePhotos] int NOT NULL DEFAULT 0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260326230438_AddQuotePhotoSubscriptionLimits'
+)
+BEGIN
+ ALTER TABLE [Companies] ADD [MaxQuotePhotosOverride] int NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260326230438_AddQuotePhotoSubscriptionLimits'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-26T23:04:35.1353265Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260326230438_AddQuotePhotoSubscriptionLimits'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-26T23:04:35.1353273Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260326230438_AddQuotePhotoSubscriptionLimits'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-26T23:04:35.1353275Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260326230438_AddQuotePhotoSubscriptionLimits'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260326230438_AddQuotePhotoSubscriptionLimits', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260328133627_AddJobPhotoIsAiAnalysisPhoto'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-28T13:36:24.1548411Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260328133627_AddJobPhotoIsAiAnalysisPhoto'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-28T13:36:24.1548419Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260328133627_AddJobPhotoIsAiAnalysisPhoto'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-28T13:36:24.1548421Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260328133627_AddJobPhotoIsAiAnalysisPhoto'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260328133627_AddJobPhotoIsAiAnalysisPhoto', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329003300_AddJobDiscountRushFields'
+)
+BEGIN
+ ALTER TABLE [Jobs] ADD [DiscountReason] nvarchar(max) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329003300_AddJobDiscountRushFields'
+)
+BEGIN
+ ALTER TABLE [Jobs] ADD [DiscountType] int NOT NULL DEFAULT 0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329003300_AddJobDiscountRushFields'
+)
+BEGIN
+ ALTER TABLE [Jobs] ADD [DiscountValue] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329003300_AddJobDiscountRushFields'
+)
+BEGIN
+ ALTER TABLE [Jobs] ADD [IsRushJob] bit NOT NULL DEFAULT CAST(0 AS bit);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329003300_AddJobDiscountRushFields'
+)
+BEGIN
+ ALTER TABLE [JobPhotos] ADD [IsAiAnalysisPhoto] bit NOT NULL DEFAULT CAST(0 AS bit);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329003300_AddJobDiscountRushFields'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-29T00:32:56.7368710Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329003300_AddJobDiscountRushFields'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-29T00:32:56.7368717Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329003300_AddJobDiscountRushFields'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-29T00:32:56.7368718Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329003300_AddJobDiscountRushFields'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260329003300_AddJobDiscountRushFields', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329005838_AddDeposits'
+)
+BEGIN
+ CREATE TABLE [Deposits] (
+ [Id] int NOT NULL IDENTITY,
+ [ReceiptNumber] nvarchar(max) NOT NULL,
+ [CustomerId] int NOT NULL,
+ [JobId] int NULL,
+ [QuoteId] int NULL,
+ [Amount] decimal(18,2) NOT NULL,
+ [PaymentMethod] int NOT NULL,
+ [ReceivedDate] datetime2 NOT NULL,
+ [Reference] nvarchar(max) NULL,
+ [Notes] nvarchar(max) NULL,
+ [RecordedById] nvarchar(450) NULL,
+ [AppliedToInvoiceId] int NULL,
+ [AppliedDate] datetime2 NULL,
+ [CompanyId] int NOT NULL,
+ [CreatedAt] datetime2 NOT NULL,
+ [UpdatedAt] datetime2 NULL,
+ [CreatedBy] nvarchar(max) NULL,
+ [UpdatedBy] nvarchar(max) NULL,
+ [IsDeleted] bit NOT NULL,
+ [DeletedAt] datetime2 NULL,
+ [DeletedBy] nvarchar(max) NULL,
+ CONSTRAINT [PK_Deposits] PRIMARY KEY ([Id]),
+ CONSTRAINT [FK_Deposits_AspNetUsers_RecordedById] FOREIGN KEY ([RecordedById]) REFERENCES [AspNetUsers] ([Id]),
+ CONSTRAINT [FK_Deposits_Customers_CustomerId] FOREIGN KEY ([CustomerId]) REFERENCES [Customers] ([Id]) ON DELETE CASCADE,
+ CONSTRAINT [FK_Deposits_Invoices_AppliedToInvoiceId] FOREIGN KEY ([AppliedToInvoiceId]) REFERENCES [Invoices] ([Id]) ON DELETE SET NULL,
+ CONSTRAINT [FK_Deposits_Jobs_JobId] FOREIGN KEY ([JobId]) REFERENCES [Jobs] ([Id]),
+ CONSTRAINT [FK_Deposits_Quotes_QuoteId] FOREIGN KEY ([QuoteId]) REFERENCES [Quotes] ([Id])
+ );
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329005838_AddDeposits'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-29T00:58:35.7576949Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329005838_AddDeposits'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-29T00:58:35.7576955Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329005838_AddDeposits'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-29T00:58:35.7576957Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329005838_AddDeposits'
+)
+BEGIN
+ CREATE INDEX [IX_Deposits_AppliedToInvoiceId] ON [Deposits] ([AppliedToInvoiceId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329005838_AddDeposits'
+)
+BEGIN
+ CREATE INDEX [IX_Deposits_CustomerId] ON [Deposits] ([CustomerId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329005838_AddDeposits'
+)
+BEGIN
+ CREATE INDEX [IX_Deposits_JobId] ON [Deposits] ([JobId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329005838_AddDeposits'
+)
+BEGIN
+ CREATE INDEX [IX_Deposits_QuoteId] ON [Deposits] ([QuoteId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329005838_AddDeposits'
+)
+BEGIN
+ CREATE INDEX [IX_Deposits_RecordedById] ON [Deposits] ([RecordedById]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329005838_AddDeposits'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260329005838_AddDeposits', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329134753_AddMerchandise'
+)
+BEGIN
+ DROP INDEX [IX_Invoices_CompanyId_JobId] ON [Invoices];
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329134753_AddMerchandise'
+)
+BEGIN
+ DROP INDEX [IX_Invoices_JobId] ON [Invoices];
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329134753_AddMerchandise'
+)
+BEGIN
+ DECLARE @var2 sysname;
+ SELECT @var2 = [d].[name]
+ FROM [sys].[default_constraints] [d]
+ INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id]
+ WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Invoices]') AND [c].[name] = N'JobId');
+ IF @var2 IS NOT NULL EXEC(N'ALTER TABLE [Invoices] DROP CONSTRAINT [' + @var2 + '];');
+ ALTER TABLE [Invoices] ALTER COLUMN [JobId] int NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329134753_AddMerchandise'
+)
+BEGIN
+ ALTER TABLE [InvoiceItems] ADD [CatalogItemId] int NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329134753_AddMerchandise'
+)
+BEGIN
+ ALTER TABLE [CatalogItems] ADD [InventoryItemId] int NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329134753_AddMerchandise'
+)
+BEGIN
+ ALTER TABLE [CatalogItems] ADD [IsMerchandise] bit NOT NULL DEFAULT CAST(0 AS bit);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329134753_AddMerchandise'
+)
+BEGIN
+ ALTER TABLE [CatalogCategories] ADD [IsMerchandise] bit NOT NULL DEFAULT CAST(0 AS bit);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329134753_AddMerchandise'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-29T13:47:49.4176542Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329134753_AddMerchandise'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-29T13:47:49.4176549Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329134753_AddMerchandise'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-29T13:47:49.4176551Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329134753_AddMerchandise'
+)
+BEGIN
+ EXEC(N'CREATE UNIQUE INDEX [IX_Invoices_CompanyId_JobId] ON [Invoices] ([CompanyId], [JobId]) WHERE [JobId] IS NOT NULL');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329134753_AddMerchandise'
+)
+BEGIN
+ EXEC(N'CREATE UNIQUE INDEX [IX_Invoices_JobId] ON [Invoices] ([JobId]) WHERE [JobId] IS NOT NULL');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329134753_AddMerchandise'
+)
+BEGIN
+ CREATE INDEX [IX_InvoiceItems_CatalogItemId] ON [InvoiceItems] ([CatalogItemId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329134753_AddMerchandise'
+)
+BEGIN
+ CREATE INDEX [IX_CatalogItems_InventoryItemId] ON [CatalogItems] ([InventoryItemId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329134753_AddMerchandise'
+)
+BEGIN
+ ALTER TABLE [CatalogItems] ADD CONSTRAINT [FK_CatalogItems_InventoryItems_InventoryItemId] FOREIGN KEY ([InventoryItemId]) REFERENCES [InventoryItems] ([Id]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329134753_AddMerchandise'
+)
+BEGIN
+ ALTER TABLE [InvoiceItems] ADD CONSTRAINT [FK_InvoiceItems_CatalogItems_CatalogItemId] FOREIGN KEY ([CatalogItemId]) REFERENCES [CatalogItems] ([Id]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329134753_AddMerchandise'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260329134753_AddMerchandise', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329141137_AddGiftCertificateInvoiceItems'
+)
+BEGIN
+ ALTER TABLE [InvoiceItems] ADD [GcExpiryDate] datetime2 NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329141137_AddGiftCertificateInvoiceItems'
+)
+BEGIN
+ ALTER TABLE [InvoiceItems] ADD [GcRecipientEmail] nvarchar(max) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329141137_AddGiftCertificateInvoiceItems'
+)
+BEGIN
+ ALTER TABLE [InvoiceItems] ADD [GcRecipientName] nvarchar(max) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329141137_AddGiftCertificateInvoiceItems'
+)
+BEGIN
+ ALTER TABLE [InvoiceItems] ADD [GeneratedGiftCertificateId] int NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329141137_AddGiftCertificateInvoiceItems'
+)
+BEGIN
+ ALTER TABLE [InvoiceItems] ADD [IsGiftCertificate] bit NOT NULL DEFAULT CAST(0 AS bit);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329141137_AddGiftCertificateInvoiceItems'
+)
+BEGIN
+ ALTER TABLE [GiftCertificates] ADD [SourceInvoiceItemId] int NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329141137_AddGiftCertificateInvoiceItems'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-29T14:11:34.2305437Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329141137_AddGiftCertificateInvoiceItems'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-29T14:11:34.2305443Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329141137_AddGiftCertificateInvoiceItems'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-29T14:11:34.2305445Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329141137_AddGiftCertificateInvoiceItems'
+)
+BEGIN
+ CREATE INDEX [IX_InvoiceItems_GeneratedGiftCertificateId] ON [InvoiceItems] ([GeneratedGiftCertificateId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329141137_AddGiftCertificateInvoiceItems'
+)
+BEGIN
+ ALTER TABLE [InvoiceItems] ADD CONSTRAINT [FK_InvoiceItems_GiftCertificates_GeneratedGiftCertificateId] FOREIGN KEY ([GeneratedGiftCertificateId]) REFERENCES [GiftCertificates] ([Id]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260329141137_AddGiftCertificateInvoiceItems'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260329141137_AddGiftCertificateInvoiceItems', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260330234034_AddSalesItemFields'
+)
+BEGIN
+ ALTER TABLE [QuoteItems] ADD [IsSalesItem] bit NOT NULL DEFAULT CAST(0 AS bit);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260330234034_AddSalesItemFields'
+)
+BEGIN
+ ALTER TABLE [QuoteItems] ADD [Sku] nvarchar(max) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260330234034_AddSalesItemFields'
+)
+BEGIN
+ ALTER TABLE [JobItems] ADD [IsSalesItem] bit NOT NULL DEFAULT CAST(0 AS bit);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260330234034_AddSalesItemFields'
+)
+BEGIN
+ ALTER TABLE [JobItems] ADD [Sku] nvarchar(max) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260330234034_AddSalesItemFields'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-30T23:40:30.1483162Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260330234034_AddSalesItemFields'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-30T23:40:30.1483168Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260330234034_AddSalesItemFields'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-03-30T23:40:30.1483170Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260330234034_AddSalesItemFields'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260330234034_AddSalesItemFields', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260401125630_AddQuoteDepositPaymentFields'
+)
+BEGIN
+ ALTER TABLE [Quotes] ADD [DepositAmountPaid] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260401125630_AddQuoteDepositPaymentFields'
+)
+BEGIN
+ ALTER TABLE [Quotes] ADD [DepositPaymentIntentId] nvarchar(max) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260401125630_AddQuoteDepositPaymentFields'
+)
+BEGIN
+ ALTER TABLE [Quotes] ADD [DepositPaymentLinkExpiresAt] datetime2 NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260401125630_AddQuoteDepositPaymentFields'
+)
+BEGIN
+ ALTER TABLE [Quotes] ADD [DepositPaymentLinkToken] nvarchar(max) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260401125630_AddQuoteDepositPaymentFields'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-01T12:56:27.1808248Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260401125630_AddQuoteDepositPaymentFields'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-01T12:56:27.1808254Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260401125630_AddQuoteDepositPaymentFields'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-01T12:56:27.1808255Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260401125630_AddQuoteDepositPaymentFields'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260401125630_AddQuoteDepositPaymentFields', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260401131724_AddUniqueDocumentNumberConstraints'
+)
+BEGIN
+ DECLARE @var3 sysname;
+ SELECT @var3 = [d].[name]
+ FROM [sys].[default_constraints] [d]
+ INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id]
+ WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Bills]') AND [c].[name] = N'BalanceDue');
+ IF @var3 IS NOT NULL EXEC(N'ALTER TABLE [Bills] DROP CONSTRAINT [' + @var3 + '];');
+ ALTER TABLE [Bills] DROP COLUMN [BalanceDue];
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260401131724_AddUniqueDocumentNumberConstraints'
+)
+BEGIN
+ DECLARE @var4 sysname;
+ SELECT @var4 = [d].[name]
+ FROM [sys].[default_constraints] [d]
+ INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id]
+ WHERE ([d].[parent_object_id] = OBJECT_ID(N'[GiftCertificates]') AND [c].[name] = N'CertificateCode');
+ IF @var4 IS NOT NULL EXEC(N'ALTER TABLE [GiftCertificates] DROP CONSTRAINT [' + @var4 + '];');
+ ALTER TABLE [GiftCertificates] ALTER COLUMN [CertificateCode] nvarchar(450) NOT NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260401131724_AddUniqueDocumentNumberConstraints'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-01T13:17:21.8121883Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260401131724_AddUniqueDocumentNumberConstraints'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-01T13:17:21.8121891Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260401131724_AddUniqueDocumentNumberConstraints'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-01T13:17:21.8121893Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260401131724_AddUniqueDocumentNumberConstraints'
+)
+BEGIN
+ CREATE UNIQUE INDEX [IX_GiftCertificates_CertificateCode] ON [GiftCertificates] ([CertificateCode]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260401131724_AddUniqueDocumentNumberConstraints'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260401131724_AddUniqueDocumentNumberConstraints', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260401141653_FixGiftCertificateUniqueIndexPerCompany'
+)
+BEGIN
+ DROP INDEX [IX_GiftCertificates_CertificateCode] ON [GiftCertificates];
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260401141653_FixGiftCertificateUniqueIndexPerCompany'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-01T14:16:49.2887180Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260401141653_FixGiftCertificateUniqueIndexPerCompany'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-01T14:16:49.2887185Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260401141653_FixGiftCertificateUniqueIndexPerCompany'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-01T14:16:49.2887186Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260401141653_FixGiftCertificateUniqueIndexPerCompany'
+)
+BEGIN
+ CREATE UNIQUE INDEX [IX_GiftCertificates_CompanyId_CertificateCode] ON [GiftCertificates] ([CompanyId], [CertificateCode]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260401141653_FixGiftCertificateUniqueIndexPerCompany'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260401141653_FixGiftCertificateUniqueIndexPerCompany', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402015422_AddInvoiceExternalReference'
+)
+BEGIN
+ ALTER TABLE [Invoices] ADD [ExternalReference] nvarchar(450) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402015422_AddInvoiceExternalReference'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-02T01:54:18.8649199Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402015422_AddInvoiceExternalReference'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-02T01:54:18.8649205Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402015422_AddInvoiceExternalReference'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-02T01:54:18.8649206Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402015422_AddInvoiceExternalReference'
+)
+BEGIN
+ CREATE INDEX [IX_Invoices_CompanyId_ExternalReference] ON [Invoices] ([CompanyId], [ExternalReference]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402015422_AddInvoiceExternalReference'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260402015422_AddInvoiceExternalReference', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402032156_AddMigratingFromQuickBooks'
+)
+BEGIN
+ ALTER TABLE [CompanyPreferences] ADD [MigratingFromQuickBooks] bit NOT NULL DEFAULT CAST(0 AS bit);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402032156_AddMigratingFromQuickBooks'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-02T03:21:53.0005398Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402032156_AddMigratingFromQuickBooks'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-02T03:21:53.0005405Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402032156_AddMigratingFromQuickBooks'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-02T03:21:53.0005406Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402032156_AddMigratingFromQuickBooks'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260402032156_AddMigratingFromQuickBooks', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402165758_AddQbMigrationStateJson'
+)
+BEGIN
+ ALTER TABLE [CompanyPreferences] ADD [QbMigrationStateJson] nvarchar(max) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402165758_AddQbMigrationStateJson'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-02T16:57:55.0246999Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402165758_AddQbMigrationStateJson'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-02T16:57:55.0247004Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402165758_AddQbMigrationStateJson'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-02T16:57:55.0247006Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402165758_AddQbMigrationStateJson'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260402165758_AddQbMigrationStateJson', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402184721_FixInventorySkuUniqueIndex'
+)
+BEGIN
+ DROP INDEX [IX_InventoryItems_SKU] ON [InventoryItems];
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402184721_FixInventorySkuUniqueIndex'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-02T18:47:18.8788284Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402184721_FixInventorySkuUniqueIndex'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-02T18:47:18.8788291Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402184721_FixInventorySkuUniqueIndex'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-02T18:47:18.8788292Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402184721_FixInventorySkuUniqueIndex'
+)
+BEGIN
+ CREATE UNIQUE INDEX [IX_InventoryItems_CompanyId_SKU] ON [InventoryItems] ([CompanyId], [SKU]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402184721_FixInventorySkuUniqueIndex'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260402184721_FixInventorySkuUniqueIndex', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402185216_FixJobShopAccessCodeUniqueIndex'
+)
+BEGIN
+ DROP INDEX [IX_Jobs_ShopAccessCode] ON [Jobs];
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402185216_FixJobShopAccessCodeUniqueIndex'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-02T18:52:13.7857008Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402185216_FixJobShopAccessCodeUniqueIndex'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-02T18:52:13.7857015Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402185216_FixJobShopAccessCodeUniqueIndex'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-02T18:52:13.7857016Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402185216_FixJobShopAccessCodeUniqueIndex'
+)
+BEGIN
+ CREATE UNIQUE INDEX [IX_Jobs_CompanyId_ShopAccessCode] ON [Jobs] ([CompanyId], [ShopAccessCode]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402185216_FixJobShopAccessCodeUniqueIndex'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260402185216_FixJobShopAccessCodeUniqueIndex', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402224949_AddDashboardTips'
+)
+BEGIN
+ CREATE TABLE [DashboardTips] (
+ [Id] int NOT NULL IDENTITY,
+ [TipText] nvarchar(max) NOT NULL,
+ [IsActive] bit NOT NULL,
+ [CreatedAt] datetime2 NOT NULL,
+ CONSTRAINT [PK_DashboardTips] PRIMARY KEY ([Id])
+ );
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402224949_AddDashboardTips'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-02T22:49:46.0354841Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402224949_AddDashboardTips'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-02T22:49:46.0354847Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402224949_AddDashboardTips'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-02T22:49:46.0354849Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260402224949_AddDashboardTips'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260402224949_AddDashboardTips', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260403000650_AddStripeWebhookEvents'
+)
+BEGIN
+ CREATE TABLE [StripeWebhookEvents] (
+ [Id] bigint NOT NULL IDENTITY,
+ [EventId] nvarchar(max) NOT NULL,
+ [EventType] nvarchar(max) NOT NULL,
+ [CompanyId] int NULL,
+ [RawJson] nvarchar(max) NOT NULL,
+ [Status] int NOT NULL,
+ [ErrorMessage] nvarchar(max) NULL,
+ [ReceivedAt] datetime2 NOT NULL,
+ [ProcessedAt] datetime2 NULL,
+ CONSTRAINT [PK_StripeWebhookEvents] PRIMARY KEY ([Id])
+ );
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260403000650_AddStripeWebhookEvents'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-03T00:06:46.7783905Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260403000650_AddStripeWebhookEvents'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-03T00:06:46.7783912Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260403000650_AddStripeWebhookEvents'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-03T00:06:46.7783913Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260403000650_AddStripeWebhookEvents'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260403000650_AddStripeWebhookEvents', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260404151636_AddAllowAccountingToPlan'
+)
+BEGIN
+ ALTER TABLE [SubscriptionPlanConfigs] ADD [AllowAccounting] bit NOT NULL DEFAULT CAST(0 AS bit);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260404151636_AddAllowAccountingToPlan'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-04T15:16:32.2541952Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260404151636_AddAllowAccountingToPlan'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-04T15:16:32.2541958Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260404151636_AddAllowAccountingToPlan'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-04T15:16:32.2541968Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260404151636_AddAllowAccountingToPlan'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260404151636_AddAllowAccountingToPlan', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260404194126_AddBillReceiptFilePath'
+)
+BEGIN
+ ALTER TABLE [Bills] ADD [ReceiptFilePath] nvarchar(max) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260404194126_AddBillReceiptFilePath'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-04T19:41:22.8540290Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260404194126_AddBillReceiptFilePath'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-04T19:41:22.8540296Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260404194126_AddBillReceiptFilePath'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-04T19:41:22.8540297Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260404194126_AddBillReceiptFilePath'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260404194126_AddBillReceiptFilePath', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405003350_AddPerformanceIndexes'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-05T00:33:47.2862744Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405003350_AddPerformanceIndexes'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-05T00:33:47.2862750Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405003350_AddPerformanceIndexes'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-05T00:33:47.2862752Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405003350_AddPerformanceIndexes'
+)
+BEGIN
+ CREATE INDEX [IX_InventoryTransactions_TransactionType_TransactionDate] ON [InventoryTransactions] ([TransactionType], [TransactionDate]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405003350_AddPerformanceIndexes'
+)
+BEGIN
+ CREATE INDEX [IX_InventoryItems_CompanyId_IsActive] ON [InventoryItems] ([CompanyId], [IsActive]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405003350_AddPerformanceIndexes'
+)
+BEGIN
+ CREATE INDEX [IX_InventoryItems_IsActive] ON [InventoryItems] ([IsActive]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405003350_AddPerformanceIndexes'
+)
+BEGIN
+ CREATE INDEX [IX_Bills_CompanyId_Status] ON [Bills] ([CompanyId], [Status]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405003350_AddPerformanceIndexes'
+)
+BEGIN
+ CREATE INDEX [IX_Bills_DueDate] ON [Bills] ([DueDate]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405003350_AddPerformanceIndexes'
+)
+BEGIN
+ CREATE INDEX [IX_Bills_Status] ON [Bills] ([Status]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405003350_AddPerformanceIndexes'
+)
+BEGIN
+ CREATE INDEX [IX_Appointments_ScheduledStartTime] ON [Appointments] ([ScheduledStartTime]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405003350_AddPerformanceIndexes'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260405003350_AddPerformanceIndexes', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405155653_AddPlatformSettings'
+)
+BEGIN
+ CREATE TABLE [PlatformSettings] (
+ [Id] int NOT NULL IDENTITY,
+ [Key] nvarchar(200) NOT NULL,
+ [Value] nvarchar(max) NULL,
+ [Label] nvarchar(max) NULL,
+ [Description] nvarchar(max) NULL,
+ [GroupName] nvarchar(max) NULL,
+ [UpdatedAt] datetime2 NULL,
+ [UpdatedBy] nvarchar(max) NULL,
+ CONSTRAINT [PK_PlatformSettings] PRIMARY KEY ([Id])
+ );
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405155653_AddPlatformSettings'
+)
+BEGIN
+ CREATE UNIQUE INDEX [IX_PlatformSettings_Key] ON [PlatformSettings] ([Key]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405155653_AddPlatformSettings'
+)
+BEGIN
+ IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'Id', N'Key', N'Value', N'Label', N'Description', N'GroupName') AND [object_id] = OBJECT_ID(N'[PlatformSettings]'))
+ SET IDENTITY_INSERT [PlatformSettings] ON;
+ EXEC(N'INSERT INTO [PlatformSettings] ([Id], [Key], [Value], [Label], [Description], [GroupName])
+ VALUES (1, N''AdminNotificationEmail'', NULL, N''Admin Notification Email'', N''Email address that receives platform event notifications (new signups, bug reports, subscription events). Leave blank to disable.'', N''Notifications'')');
+ IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'Id', N'Key', N'Value', N'Label', N'Description', N'GroupName') AND [object_id] = OBJECT_ID(N'[PlatformSettings]'))
+ SET IDENTITY_INSERT [PlatformSettings] OFF;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405155653_AddPlatformSettings'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-05T15:56:49.8180443Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405155653_AddPlatformSettings'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-05T15:56:49.8180449Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405155653_AddPlatformSettings'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-05T15:56:49.8180450Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405155653_AddPlatformSettings'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260405155653_AddPlatformSettings', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405161241_AddPlatformSettingsV2'
+)
+BEGIN
+ DECLARE @var5 sysname;
+ SELECT @var5 = [d].[name]
+ FROM [sys].[default_constraints] [d]
+ INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id]
+ WHERE ([d].[parent_object_id] = OBJECT_ID(N'[PlatformSettings]') AND [c].[name] = N'Key');
+ IF @var5 IS NOT NULL EXEC(N'ALTER TABLE [PlatformSettings] DROP CONSTRAINT [' + @var5 + '];');
+ ALTER TABLE [PlatformSettings] ALTER COLUMN [Key] nvarchar(200) NOT NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405161241_AddPlatformSettingsV2'
+)
+BEGIN
+ IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'Id', N'Key', N'Value', N'Label', N'Description', N'GroupName') AND [object_id] = OBJECT_ID(N'[PlatformSettings]'))
+ SET IDENTITY_INSERT [PlatformSettings] ON;
+ EXEC(N'INSERT INTO [PlatformSettings] ([Id], [Key], [Value], [Label], [Description], [GroupName])
+ VALUES (2, N''BaseUrl'', NULL, N''Base URL'', N''Public URL of this application (e.g. https://app.powdercoatinglogix.com). Used in email links. Falls back to the current request URL if blank.'', N''General''),
+ (3, N''TrialPeriodDays'', N''7'', N''Trial Period (days)'', N''Number of days a new company gets on the free trial before their subscription expires.'', N''Subscriptions''),
+ (4, N''QuoteApprovalTokenDays'', N''30'', N''Quote Approval Token Validity (days)'', N''How many days a customer quote-approval link remains valid before expiring.'', N''Quotes''),
+ (5, N''AuditLogRetentionDays'', N''365'', N''Audit Log Retention (days)'', N''Audit log entries older than this many days are automatically purged by the nightly job.'', N''Data Retention''),
+ (6, N''StripeWebhookRetentionDays'', N''90'', N''Stripe Webhook Retention (days)'', N''Processed Stripe webhook events older than this many days are automatically purged.'', N''Data Retention'')');
+ IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'Id', N'Key', N'Value', N'Label', N'Description', N'GroupName') AND [object_id] = OBJECT_ID(N'[PlatformSettings]'))
+ SET IDENTITY_INSERT [PlatformSettings] OFF;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405161241_AddPlatformSettingsV2'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-05T16:12:38.5900904Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405161241_AddPlatformSettingsV2'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-05T16:12:38.5900913Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405161241_AddPlatformSettingsV2'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-05T16:12:38.5900914Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405161241_AddPlatformSettingsV2'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260405161241_AddPlatformSettingsV2', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405162137_UpdateAdminEmailDescription'
+)
+BEGIN
+ EXEC(N'UPDATE [PlatformSettings] SET [Description] = N''Email address(es) that receive platform event notifications (new signups, bug reports, subscription events). Separate multiple addresses with commas. Leave blank to disable.''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405162137_UpdateAdminEmailDescription'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-05T16:21:34.4700837Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405162137_UpdateAdminEmailDescription'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-05T16:21:34.4700844Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405162137_UpdateAdminEmailDescription'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-05T16:21:34.4700846Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260405162137_UpdateAdminEmailDescription'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260405162137_UpdateAdminEmailDescription', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260406191501_MakeBillLineItemAccountIdNullable'
+)
+BEGIN
+ DECLARE @var6 sysname;
+ SELECT @var6 = [d].[name]
+ FROM [sys].[default_constraints] [d]
+ INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id]
+ WHERE ([d].[parent_object_id] = OBJECT_ID(N'[BillLineItems]') AND [c].[name] = N'AccountId');
+ IF @var6 IS NOT NULL EXEC(N'ALTER TABLE [BillLineItems] DROP CONSTRAINT [' + @var6 + '];');
+ ALTER TABLE [BillLineItems] ALTER COLUMN [AccountId] int NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260406191501_MakeBillLineItemAccountIdNullable'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-06T19:14:56.7157942Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260406191501_MakeBillLineItemAccountIdNullable'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-06T19:14:56.7157953Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260406191501_MakeBillLineItemAccountIdNullable'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-06T19:14:56.7157955Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260406191501_MakeBillLineItemAccountIdNullable'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260406191501_MakeBillLineItemAccountIdNullable', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260408205345_AddJobIntakeFields'
+)
+BEGIN
+ ALTER TABLE [Jobs] ADD [IntakeCheckedByUserId] nvarchar(450) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260408205345_AddJobIntakeFields'
+)
+BEGIN
+ ALTER TABLE [Jobs] ADD [IntakeConditionNotes] nvarchar(max) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260408205345_AddJobIntakeFields'
+)
+BEGIN
+ ALTER TABLE [Jobs] ADD [IntakeDate] datetime2 NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260408205345_AddJobIntakeFields'
+)
+BEGIN
+ ALTER TABLE [Jobs] ADD [IntakePartCount] int NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260408205345_AddJobIntakeFields'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-08T20:53:42.2947842Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260408205345_AddJobIntakeFields'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-08T20:53:42.2947847Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260408205345_AddJobIntakeFields'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-08T20:53:42.2947849Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260408205345_AddJobIntakeFields'
+)
+BEGIN
+ CREATE INDEX [IX_Jobs_IntakeCheckedByUserId] ON [Jobs] ([IntakeCheckedByUserId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260408205345_AddJobIntakeFields'
+)
+BEGIN
+ ALTER TABLE [Jobs] ADD CONSTRAINT [FK_Jobs_AspNetUsers_IntakeCheckedByUserId] FOREIGN KEY ([IntakeCheckedByUserId]) REFERENCES [AspNetUsers] ([Id]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260408205345_AddJobIntakeFields'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260408205345_AddJobIntakeFields', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260409013822_AddInAppNotifications'
+)
+BEGIN
+ CREATE TABLE [InAppNotifications] (
+ [Id] int NOT NULL IDENTITY,
+ [Title] nvarchar(max) NOT NULL,
+ [Message] nvarchar(max) NOT NULL,
+ [Link] nvarchar(max) NULL,
+ [NotificationType] nvarchar(max) NOT NULL,
+ [IsRead] bit NOT NULL,
+ [ReadAt] datetime2 NULL,
+ [QuoteId] int NULL,
+ [InvoiceId] int NULL,
+ [CustomerId] int NULL,
+ [CompanyId] int NOT NULL,
+ [CreatedAt] datetime2 NOT NULL,
+ [UpdatedAt] datetime2 NULL,
+ [CreatedBy] nvarchar(max) NULL,
+ [UpdatedBy] nvarchar(max) NULL,
+ [IsDeleted] bit NOT NULL,
+ [DeletedAt] datetime2 NULL,
+ [DeletedBy] nvarchar(max) NULL,
+ CONSTRAINT [PK_InAppNotifications] PRIMARY KEY ([Id]),
+ CONSTRAINT [FK_InAppNotifications_Customers_CustomerId] FOREIGN KEY ([CustomerId]) REFERENCES [Customers] ([Id]),
+ CONSTRAINT [FK_InAppNotifications_Invoices_InvoiceId] FOREIGN KEY ([InvoiceId]) REFERENCES [Invoices] ([Id]),
+ CONSTRAINT [FK_InAppNotifications_Quotes_QuoteId] FOREIGN KEY ([QuoteId]) REFERENCES [Quotes] ([Id])
+ );
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260409013822_AddInAppNotifications'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-09T01:38:18.3630787Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260409013822_AddInAppNotifications'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-09T01:38:18.3630794Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260409013822_AddInAppNotifications'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-09T01:38:18.3630795Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260409013822_AddInAppNotifications'
+)
+BEGIN
+ CREATE INDEX [IX_InAppNotifications_CustomerId] ON [InAppNotifications] ([CustomerId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260409013822_AddInAppNotifications'
+)
+BEGIN
+ CREATE INDEX [IX_InAppNotifications_InvoiceId] ON [InAppNotifications] ([InvoiceId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260409013822_AddInAppNotifications'
+)
+BEGIN
+ CREATE INDEX [IX_InAppNotifications_QuoteId] ON [InAppNotifications] ([QuoteId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260409013822_AddInAppNotifications'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260409013822_AddInAppNotifications', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260410021934_AddLegalCompliance'
+)
+BEGIN
+ ALTER TABLE [Companies] ADD [MarketingEmailOptOut] bit NOT NULL DEFAULT CAST(0 AS bit);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260410021934_AddLegalCompliance'
+)
+BEGIN
+ ALTER TABLE [Companies] ADD [MarketingUnsubscribeToken] nvarchar(max) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260410021934_AddLegalCompliance'
+)
+BEGIN
+
+ UPDATE Companies
+ SET MarketingUnsubscribeToken = LOWER(REPLACE(NEWID(), '-', ''))
+ WHERE MarketingUnsubscribeToken IS NULL
+
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260410021934_AddLegalCompliance'
+)
+BEGIN
+ DECLARE @var7 sysname;
+ SELECT @var7 = [d].[name]
+ FROM [sys].[default_constraints] [d]
+ INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id]
+ WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Companies]') AND [c].[name] = N'MarketingUnsubscribeToken');
+ IF @var7 IS NOT NULL EXEC(N'ALTER TABLE [Companies] DROP CONSTRAINT [' + @var7 + '];');
+ ALTER TABLE [Companies] ALTER COLUMN [MarketingUnsubscribeToken] nvarchar(max) NOT NULL;
+ ALTER TABLE [Companies] ADD DEFAULT N'' FOR [MarketingUnsubscribeToken];
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260410021934_AddLegalCompliance'
+)
+BEGIN
+ CREATE TABLE [TermsAcceptances] (
+ [Id] int NOT NULL IDENTITY,
+ [UserId] nvarchar(max) NOT NULL,
+ [CompanyId] int NOT NULL,
+ [TosVersion] nvarchar(max) NOT NULL,
+ [AcceptedAt] datetime2 NOT NULL,
+ [IpAddress] nvarchar(max) NULL,
+ [UserAgent] nvarchar(max) NULL,
+ CONSTRAINT [PK_TermsAcceptances] PRIMARY KEY ([Id])
+ );
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260410021934_AddLegalCompliance'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-10T02:19:30.4105127Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260410021934_AddLegalCompliance'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-10T02:19:30.4105133Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260410021934_AddLegalCompliance'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-10T02:19:30.4105135Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260410021934_AddLegalCompliance'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260410021934_AddLegalCompliance', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260410025353_AddAiFeaturesToPlanConfig'
+)
+BEGIN
+ ALTER TABLE [SubscriptionPlanConfigs] ADD [AllowAiInventoryAssist] bit NOT NULL DEFAULT CAST(0 AS bit);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260410025353_AddAiFeaturesToPlanConfig'
+)
+BEGIN
+ ALTER TABLE [SubscriptionPlanConfigs] ADD [AllowAiPhotoQuotes] bit NOT NULL DEFAULT CAST(0 AS bit);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260410025353_AddAiFeaturesToPlanConfig'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-10T02:53:49.5828243Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260410025353_AddAiFeaturesToPlanConfig'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-10T02:53:49.5828250Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260410025353_AddAiFeaturesToPlanConfig'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-10T02:53:49.5828252Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260410025353_AddAiFeaturesToPlanConfig'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260410025353_AddAiFeaturesToPlanConfig', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260410032027_AddTrialsEnabledSetting'
+)
+BEGIN
+ IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'Id', N'Key', N'Value', N'Label', N'Description', N'GroupName') AND [object_id] = OBJECT_ID(N'[PlatformSettings]'))
+ SET IDENTITY_INSERT [PlatformSettings] ON;
+ EXEC(N'INSERT INTO [PlatformSettings] ([Id], [Key], [Value], [Label], [Description], [GroupName])
+ VALUES (7, N''TrialsEnabled'', N''true'', N''Free Trials Enabled'', N''When true (default), new signups start with a free trial period. When false, a credit card is required at signup — registrants are sent through Stripe Checkout before their account is created.'', N''Subscriptions'')');
+ IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'Id', N'Key', N'Value', N'Label', N'Description', N'GroupName') AND [object_id] = OBJECT_ID(N'[PlatformSettings]'))
+ SET IDENTITY_INSERT [PlatformSettings] OFF;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260410032027_AddTrialsEnabledSetting'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-10T03:20:23.1587184Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260410032027_AddTrialsEnabledSetting'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-10T03:20:23.1587190Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260410032027_AddTrialsEnabledSetting'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-10T03:20:23.1587191Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260410032027_AddTrialsEnabledSetting'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260410032027_AddTrialsEnabledSetting', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260412005228_AddMaxTenantsSetting'
+)
+BEGIN
+ IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'Id', N'Key', N'Value', N'Label', N'Description', N'GroupName') AND [object_id] = OBJECT_ID(N'[PlatformSettings]'))
+ SET IDENTITY_INSERT [PlatformSettings] ON;
+ EXEC(N'INSERT INTO [PlatformSettings] ([Id], [Key], [Value], [Label], [Description], [GroupName])
+ VALUES (8, N''MaxTenants'', N'''', N''Max Tenants'', N''Maximum number of tenant companies allowed to self-register. Leave blank or 0 for unlimited. Once the limit is reached, the signup page and login signup link are hidden.'', N''Access Control'')');
+ IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'Id', N'Key', N'Value', N'Label', N'Description', N'GroupName') AND [object_id] = OBJECT_ID(N'[PlatformSettings]'))
+ SET IDENTITY_INSERT [PlatformSettings] OFF;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260412005228_AddMaxTenantsSetting'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-12T00:52:25.3071531Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260412005228_AddMaxTenantsSetting'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-12T00:52:25.3071537Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260412005228_AddMaxTenantsSetting'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-12T00:52:25.3071538Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260412005228_AddMaxTenantsSetting'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260412005228_AddMaxTenantsSetting', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260412174157_AddCompanyFeatureOverrides'
+)
+BEGIN
+ ALTER TABLE [Companies] ADD [AccountingOverride] bit NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260412174157_AddCompanyFeatureOverrides'
+)
+BEGIN
+ ALTER TABLE [Companies] ADD [OnlinePaymentsOverride] bit NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260412174157_AddCompanyFeatureOverrides'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-12T17:41:53.0142151Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260412174157_AddCompanyFeatureOverrides'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-12T17:41:53.0142159Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260412174157_AddCompanyFeatureOverrides'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-12T17:41:53.0142161Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260412174157_AddCompanyFeatureOverrides'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260412174157_AddCompanyFeatureOverrides', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260412183411_AddIsAnnualBilling'
+)
+BEGIN
+ ALTER TABLE [Companies] ADD [IsAnnualBilling] bit NOT NULL DEFAULT CAST(0 AS bit);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260412183411_AddIsAnnualBilling'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-12T18:34:08.9093047Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260412183411_AddIsAnnualBilling'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-12T18:34:08.9093054Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260412183411_AddIsAnnualBilling'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-12T18:34:08.9093055Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260412183411_AddIsAnnualBilling'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260412183411_AddIsAnnualBilling', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260414135810_AddPendingRegistrationSession'
+)
+BEGIN
+ CREATE TABLE [PendingRegistrationSessions] (
+ [Id] int NOT NULL IDENTITY,
+ [Token] nvarchar(max) NOT NULL,
+ [CompanyName] nvarchar(max) NOT NULL,
+ [CompanyPhone] nvarchar(max) NULL,
+ [FirstName] nvarchar(max) NOT NULL,
+ [LastName] nvarchar(max) NOT NULL,
+ [Email] nvarchar(max) NOT NULL,
+ [Plan] int NOT NULL,
+ [IsAnnual] bit NOT NULL,
+ [CreatedAt] datetime2 NOT NULL,
+ [IsCompleted] bit NOT NULL,
+ CONSTRAINT [PK_PendingRegistrationSessions] PRIMARY KEY ([Id])
+ );
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260414135810_AddPendingRegistrationSession'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-14T13:58:07.0916607Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260414135810_AddPendingRegistrationSession'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-14T13:58:07.0916613Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260414135810_AddPendingRegistrationSession'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-14T13:58:07.0916614Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260414135810_AddPendingRegistrationSession'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260414135810_AddPendingRegistrationSession', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260415010203_AddSetupWizardCompletionTracking'
+)
+BEGIN
+ ALTER TABLE [CompanyPreferences] ADD [SetupWizardCompletedAt] datetime2 NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260415010203_AddSetupWizardCompletionTracking'
+)
+BEGIN
+ ALTER TABLE [CompanyPreferences] ADD [SetupWizardCompletedByName] nvarchar(max) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260415010203_AddSetupWizardCompletionTracking'
+)
+BEGIN
+ ALTER TABLE [CompanyPreferences] ADD [SetupWizardCompletedByUserId] nvarchar(max) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260415010203_AddSetupWizardCompletionTracking'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-15T01:02:00.3083161Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260415010203_AddSetupWizardCompletionTracking'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-15T01:02:00.3083167Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260415010203_AddSetupWizardCompletionTracking'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-15T01:02:00.3083169Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260415010203_AddSetupWizardCompletionTracking'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260415010203_AddSetupWizardCompletionTracking', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260415120000_AddAuditLogTable'
+)
+BEGIN
+ CREATE TABLE [AuditLogs] (
+ [Id] bigint NOT NULL IDENTITY,
+ [UserId] nvarchar(max) NULL,
+ [UserName] nvarchar(max) NOT NULL,
+ [CompanyId] int NULL,
+ [CompanyName] nvarchar(max) NULL,
+ [Action] nvarchar(max) NOT NULL,
+ [EntityType] nvarchar(450) NOT NULL,
+ [EntityId] nvarchar(450) NULL,
+ [EntityDescription] nvarchar(max) NULL,
+ [OldValues] nvarchar(max) NULL,
+ [NewValues] nvarchar(max) NULL,
+ [IpAddress] nvarchar(max) NULL,
+ [Timestamp] datetime2 NOT NULL,
+ CONSTRAINT [PK_AuditLogs] PRIMARY KEY ([Id])
+ );
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260415120000_AddAuditLogTable'
+)
+BEGIN
+ CREATE INDEX [IX_AuditLogs_CompanyId_Timestamp] ON [AuditLogs] ([CompanyId], [Timestamp]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260415120000_AddAuditLogTable'
+)
+BEGIN
+ CREATE INDEX [IX_AuditLogs_EntityType_EntityId] ON [AuditLogs] ([EntityType], [EntityId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260415120000_AddAuditLogTable'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260415120000_AddAuditLogTable', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260417044255_AddInventoryTransactionJobId'
+)
+BEGIN
+ ALTER TABLE [InventoryTransactions] ADD [JobId] int NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260417044255_AddInventoryTransactionJobId'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-17T04:42:51.1510259Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260417044255_AddInventoryTransactionJobId'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-17T04:42:51.1510266Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260417044255_AddInventoryTransactionJobId'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-17T04:42:51.1510268Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260417044255_AddInventoryTransactionJobId'
+)
+BEGIN
+ CREATE INDEX [IX_InventoryTransactions_JobId] ON [InventoryTransactions] ([JobId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260417044255_AddInventoryTransactionJobId'
+)
+BEGIN
+ ALTER TABLE [InventoryTransactions] ADD CONSTRAINT [FK_InventoryTransactions_Jobs_JobId] FOREIGN KEY ([JobId]) REFERENCES [Jobs] ([Id]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260417044255_AddInventoryTransactionJobId'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260417044255_AddInventoryTransactionJobId', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260417160645_AddSamplePanel'
+)
+BEGIN
+ ALTER TABLE [InventoryItems] ADD [HasSamplePanel] bit NOT NULL DEFAULT CAST(0 AS bit);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260417160645_AddSamplePanel'
+)
+BEGIN
+ ALTER TABLE [InventoryItems] ADD [IsCoating] bit NOT NULL DEFAULT CAST(0 AS bit);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260417160645_AddSamplePanel'
+)
+BEGIN
+ ALTER TABLE [InventoryItems] ADD [SamplePanelNotes] nvarchar(max) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260417160645_AddSamplePanel'
+)
+BEGIN
+
+ UPDATE ii
+ SET ii.IsCoating = 1
+ FROM InventoryItems ii
+ INNER JOIN InventoryCategoryLookups icl ON icl.Id = ii.InventoryCategoryId
+ WHERE icl.IsCoating = 1 AND icl.IsDeleted = 0
+
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260417160645_AddSamplePanel'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-17T16:06:41.3326769Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260417160645_AddSamplePanel'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-17T16:06:41.3326775Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260417160645_AddSamplePanel'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-17T16:06:41.3326776Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260417160645_AddSamplePanel'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260417160645_AddSamplePanel', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260417170543_DropItemIsCoatingColumn'
+)
+BEGIN
+ DECLARE @var8 sysname;
+ SELECT @var8 = [d].[name]
+ FROM [sys].[default_constraints] [d]
+ INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id]
+ WHERE ([d].[parent_object_id] = OBJECT_ID(N'[InventoryItems]') AND [c].[name] = N'IsCoating');
+ IF @var8 IS NOT NULL EXEC(N'ALTER TABLE [InventoryItems] DROP CONSTRAINT [' + @var8 + '];');
+ ALTER TABLE [InventoryItems] DROP COLUMN [IsCoating];
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260417170543_DropItemIsCoatingColumn'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-17T17:05:40.0377587Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260417170543_DropItemIsCoatingColumn'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-17T17:05:40.0377592Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260417170543_DropItemIsCoatingColumn'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-17T17:05:40.0377594Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260417170543_DropItemIsCoatingColumn'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260417170543_DropItemIsCoatingColumn', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260418220837_AddWorkOrderTemplate'
+)
+BEGIN
+ DECLARE @var9 sysname;
+ SELECT @var9 = [d].[name]
+ FROM [sys].[default_constraints] [d]
+ INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id]
+ WHERE ([d].[parent_object_id] = OBJECT_ID(N'[InventoryItems]') AND [c].[name] = N'SamplePanelNotes');
+ IF @var9 IS NOT NULL EXEC(N'ALTER TABLE [InventoryItems] DROP CONSTRAINT [' + @var9 + '];');
+ ALTER TABLE [InventoryItems] DROP COLUMN [SamplePanelNotes];
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260418220837_AddWorkOrderTemplate'
+)
+BEGIN
+ ALTER TABLE [CompanyPreferences] ADD [WoAccentColor] nvarchar(max) NOT NULL DEFAULT N'';
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260418220837_AddWorkOrderTemplate'
+)
+BEGIN
+ ALTER TABLE [CompanyPreferences] ADD [WoTerms] nvarchar(max) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260418220837_AddWorkOrderTemplate'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-18T22:08:33.1580643Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260418220837_AddWorkOrderTemplate'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-18T22:08:33.1580650Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260418220837_AddWorkOrderTemplate'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-18T22:08:33.1580651Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260418220837_AddWorkOrderTemplate'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260418220837_AddWorkOrderTemplate', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260419201818_AddInvoiceNumberPrefix'
+)
+BEGIN
+ ALTER TABLE [CompanyPreferences] ADD [InvoiceNumberPrefix] nvarchar(max) NOT NULL DEFAULT N'';
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260419201818_AddInvoiceNumberPrefix'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-19T20:18:14.2123100Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260419201818_AddInvoiceNumberPrefix'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-19T20:18:14.2123106Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260419201818_AddInvoiceNumberPrefix'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-19T20:18:14.2123107Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260419201818_AddInvoiceNumberPrefix'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260419201818_AddInvoiceNumberPrefix', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260419215302_AddContactSubmissions'
+)
+BEGIN
+ CREATE TABLE [ContactSubmissions] (
+ [Id] int NOT NULL IDENTITY,
+ [SenderName] nvarchar(max) NOT NULL,
+ [SenderEmail] nvarchar(max) NOT NULL,
+ [CompanyName] nvarchar(max) NOT NULL,
+ [Category] nvarchar(max) NOT NULL,
+ [Subject] nvarchar(max) NOT NULL,
+ [Message] nvarchar(max) NOT NULL,
+ [IsRead] bit NOT NULL,
+ [ReadAt] datetime2 NULL,
+ [ReadByUserId] nvarchar(max) NULL,
+ [ReadByUserName] nvarchar(max) NULL,
+ [AdminNotes] nvarchar(max) NULL,
+ [CompanyId] int NOT NULL,
+ [CreatedAt] datetime2 NOT NULL,
+ [UpdatedAt] datetime2 NULL,
+ [CreatedBy] nvarchar(max) NULL,
+ [UpdatedBy] nvarchar(max) NULL,
+ [IsDeleted] bit NOT NULL,
+ [DeletedAt] datetime2 NULL,
+ [DeletedBy] nvarchar(max) NULL,
+ CONSTRAINT [PK_ContactSubmissions] PRIMARY KEY ([Id])
+ );
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260419215302_AddContactSubmissions'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-19T21:52:59.4160772Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260419215302_AddContactSubmissions'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-19T21:52:59.4160778Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260419215302_AddContactSubmissions'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-19T21:52:59.4160779Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260419215302_AddContactSubmissions'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260419215302_AddContactSubmissions', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260420233610_AddShopCapabilityProfile'
+)
+BEGIN
+ ALTER TABLE [CompanyOperatingCosts] ADD [BlastNozzleSize] int NOT NULL DEFAULT 0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260420233610_AddShopCapabilityProfile'
+)
+BEGIN
+ ALTER TABLE [CompanyOperatingCosts] ADD [BlastRateSqFtPerHourOverride] decimal(18,2) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260420233610_AddShopCapabilityProfile'
+)
+BEGIN
+ ALTER TABLE [CompanyOperatingCosts] ADD [BlastSetupType] int NOT NULL DEFAULT 0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260420233610_AddShopCapabilityProfile'
+)
+BEGIN
+ ALTER TABLE [CompanyOperatingCosts] ADD [CoatingGunType] int NOT NULL DEFAULT 0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260420233610_AddShopCapabilityProfile'
+)
+BEGIN
+ ALTER TABLE [CompanyOperatingCosts] ADD [CoatingRateSqFtPerHourOverride] decimal(18,2) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260420233610_AddShopCapabilityProfile'
+)
+BEGIN
+ ALTER TABLE [CompanyOperatingCosts] ADD [CompressorCfm] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260420233610_AddShopCapabilityProfile'
+)
+BEGIN
+ ALTER TABLE [CompanyOperatingCosts] ADD [PrimaryBlastSubstrate] int NOT NULL DEFAULT 0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260420233610_AddShopCapabilityProfile'
+)
+BEGIN
+ ALTER TABLE [CompanyOperatingCosts] ADD [ShopCapabilityTier] int NOT NULL DEFAULT 0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260420233610_AddShopCapabilityProfile'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-20T23:36:06.0440591Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260420233610_AddShopCapabilityProfile'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-20T23:36:06.0440597Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260420233610_AddShopCapabilityProfile'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-20T23:36:06.0440599Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260420233610_AddShopCapabilityProfile'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260420233610_AddShopCapabilityProfile', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421003346_AddCompanyBlastSetups'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-21T00:33:43.0886131Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421003346_AddCompanyBlastSetups'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-21T00:33:43.0886138Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421003346_AddCompanyBlastSetups'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-21T00:33:43.0886139Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421003346_AddCompanyBlastSetups'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260421003346_AddCompanyBlastSetups', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421012409_AddCompanyBlastSetupsTable'
+)
+BEGIN
+ ALTER TABLE [QuoteItemPrepServices] ADD [BlastSetupId] int NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421012409_AddCompanyBlastSetupsTable'
+)
+BEGIN
+ ALTER TABLE [PrepServices] ADD [RequiresBlastSetup] bit NOT NULL DEFAULT CAST(0 AS bit);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421012409_AddCompanyBlastSetupsTable'
+)
+BEGIN
+ ALTER TABLE [JobItemPrepServices] ADD [BlastSetupId] int NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421012409_AddCompanyBlastSetupsTable'
+)
+BEGIN
+ CREATE TABLE [CompanyBlastSetups] (
+ [Id] int NOT NULL IDENTITY,
+ [Name] nvarchar(100) NOT NULL,
+ [SetupType] int NOT NULL,
+ [CompressorCfm] decimal(18,2) NOT NULL,
+ [BlastNozzleSize] int NOT NULL,
+ [PrimarySubstrate] int NOT NULL,
+ [BlastRateSqFtPerHourOverride] decimal(18,2) NULL,
+ [IsDefault] bit NOT NULL,
+ [IsActive] bit NOT NULL,
+ [DisplayOrder] int NOT NULL,
+ [CompanyId] int NOT NULL,
+ [CreatedAt] datetime2 NOT NULL,
+ [UpdatedAt] datetime2 NULL,
+ [CreatedBy] nvarchar(max) NULL,
+ [UpdatedBy] nvarchar(max) NULL,
+ [IsDeleted] bit NOT NULL,
+ [DeletedAt] datetime2 NULL,
+ [DeletedBy] nvarchar(max) NULL,
+ CONSTRAINT [PK_CompanyBlastSetups] PRIMARY KEY ([Id]),
+ CONSTRAINT [FK_CompanyBlastSetups_Companies_CompanyId] FOREIGN KEY ([CompanyId]) REFERENCES [Companies] ([Id]) ON DELETE NO ACTION
+ );
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421012409_AddCompanyBlastSetupsTable'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-21T01:24:05.9835208Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421012409_AddCompanyBlastSetupsTable'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-21T01:24:05.9835215Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421012409_AddCompanyBlastSetupsTable'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-21T01:24:05.9835220Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421012409_AddCompanyBlastSetupsTable'
+)
+BEGIN
+ CREATE INDEX [IX_QuoteItemPrepServices_BlastSetupId] ON [QuoteItemPrepServices] ([BlastSetupId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421012409_AddCompanyBlastSetupsTable'
+)
+BEGIN
+ CREATE INDEX [IX_JobItemPrepServices_BlastSetupId] ON [JobItemPrepServices] ([BlastSetupId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421012409_AddCompanyBlastSetupsTable'
+)
+BEGIN
+ CREATE INDEX [IX_CompanyBlastSetups_CompanyId] ON [CompanyBlastSetups] ([CompanyId]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421012409_AddCompanyBlastSetupsTable'
+)
+BEGIN
+ ALTER TABLE [JobItemPrepServices] ADD CONSTRAINT [FK_JobItemPrepServices_CompanyBlastSetups_BlastSetupId] FOREIGN KEY ([BlastSetupId]) REFERENCES [CompanyBlastSetups] ([Id]) ON DELETE SET NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421012409_AddCompanyBlastSetupsTable'
+)
+BEGIN
+ ALTER TABLE [QuoteItemPrepServices] ADD CONSTRAINT [FK_QuoteItemPrepServices_CompanyBlastSetups_BlastSetupId] FOREIGN KEY ([BlastSetupId]) REFERENCES [CompanyBlastSetups] ([Id]) ON DELETE SET NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421012409_AddCompanyBlastSetupsTable'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260421012409_AddCompanyBlastSetupsTable', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421125956_AddQuoteCostBreakdownColumns2'
+)
+BEGIN
+ ALTER TABLE [Quotes] ADD [EquipmentCosts] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421125956_AddQuoteCostBreakdownColumns2'
+)
+BEGIN
+ ALTER TABLE [Quotes] ADD [LaborCosts] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421125956_AddQuoteCostBreakdownColumns2'
+)
+BEGIN
+ ALTER TABLE [Quotes] ADD [MaterialCosts] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421125956_AddQuoteCostBreakdownColumns2'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-21T12:59:53.4982640Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421125956_AddQuoteCostBreakdownColumns2'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-21T12:59:53.4982651Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421125956_AddQuoteCostBreakdownColumns2'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-21T12:59:53.4982653Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421125956_AddQuoteCostBreakdownColumns2'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260421125956_AddQuoteCostBreakdownColumns2', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421132123_AddQuoteItemCostSnapshot'
+)
+BEGIN
+ ALTER TABLE [QuoteItems] ADD [ItemEquipmentCost] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421132123_AddQuoteItemCostSnapshot'
+)
+BEGIN
+ ALTER TABLE [QuoteItems] ADD [ItemLaborCost] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421132123_AddQuoteItemCostSnapshot'
+)
+BEGIN
+ ALTER TABLE [QuoteItems] ADD [ItemMaterialCost] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421132123_AddQuoteItemCostSnapshot'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-21T13:21:19.6983052Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421132123_AddQuoteItemCostSnapshot'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-21T13:21:19.6983058Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421132123_AddQuoteItemCostSnapshot'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-21T13:21:19.6983060Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421132123_AddQuoteItemCostSnapshot'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260421132123_AddQuoteItemCostSnapshot', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421135923_AddPricingModeAndHideDiscount'
+)
+BEGIN
+ ALTER TABLE [Quotes] ADD [HideDiscountFromCustomer] bit NOT NULL DEFAULT CAST(0 AS bit);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421135923_AddPricingModeAndHideDiscount'
+)
+BEGIN
+ ALTER TABLE [CompanyOperatingCosts] ADD [PricingMode] int NOT NULL DEFAULT 0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421135923_AddPricingModeAndHideDiscount'
+)
+BEGIN
+ ALTER TABLE [CompanyOperatingCosts] ADD [TargetMarginPercent] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421135923_AddPricingModeAndHideDiscount'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-21T13:59:19.8113639Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421135923_AddPricingModeAndHideDiscount'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-21T13:59:19.8113645Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421135923_AddPricingModeAndHideDiscount'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-21T13:59:19.8113646Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260421135923_AddPricingModeAndHideDiscount'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260421135923_AddPricingModeAndHideDiscount', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260422040844_AddUserBan'
+)
+BEGIN
+ ALTER TABLE [AspNetUsers] ADD [IsBanned] bit NOT NULL DEFAULT CAST(0 AS bit);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260422040844_AddUserBan'
+)
+BEGIN
+ ALTER TABLE [AspNetUsers] ADD [BannedAt] datetime2 NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260422040844_AddUserBan'
+)
+BEGIN
+ ALTER TABLE [AspNetUsers] ADD [BanReason] nvarchar(max) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260422040844_AddUserBan'
+)
+BEGIN
+ ALTER TABLE [AspNetUsers] ADD [BannedByUserId] nvarchar(450) NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260422040844_AddUserBan'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-22T04:08:40.9182111Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260422040844_AddUserBan'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-22T04:08:40.9182118Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260422040844_AddUserBan'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-22T04:08:40.9182119Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260422040844_AddUserBan'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260422040844_AddUserBan', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260422042129_AddBannedIps'
+)
+BEGIN
+ CREATE TABLE [BannedIps] (
+ [Id] int NOT NULL IDENTITY,
+ [IpAddress] nvarchar(45) NOT NULL,
+ [Reason] nvarchar(500) NULL,
+ [BannedByUserId] nvarchar(450) NULL,
+ [BannedAt] datetime2 NOT NULL,
+ [ExpiresAt] datetime2 NULL,
+ [IsActive] bit NOT NULL,
+ CONSTRAINT [PK_BannedIps] PRIMARY KEY ([Id])
+ );
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260422042129_AddBannedIps'
+)
+BEGIN
+ CREATE INDEX [IX_BannedIps_IpAddress_IsActive] ON [BannedIps] ([IpAddress], [IsActive]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260422042129_AddBannedIps'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-22T04:21:26.9627092Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260422042129_AddBannedIps'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-22T04:21:26.9627100Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260422042129_AddBannedIps'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-22T04:21:26.9627102Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260422042129_AddBannedIps'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260422042129_AddBannedIps', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260423011936_AddAiUsageLog'
+)
+BEGIN
+ CREATE TABLE [AiUsageLogs] (
+ [Id] bigint NOT NULL IDENTITY,
+ [CompanyId] int NOT NULL,
+ [UserId] nvarchar(max) NOT NULL,
+ [Feature] nvarchar(max) NOT NULL,
+ [Success] bit NOT NULL,
+ [InputLength] int NOT NULL,
+ [CalledAt] datetime2 NOT NULL,
+ CONSTRAINT [PK_AiUsageLogs] PRIMARY KEY ([Id]),
+ CONSTRAINT [FK_AiUsageLogs_Companies_CompanyId] FOREIGN KEY ([CompanyId]) REFERENCES [Companies] ([Id])
+ );
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260423011936_AddAiUsageLog'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-23T01:19:33.1714669Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260423011936_AddAiUsageLog'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-23T01:19:33.1714674Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260423011936_AddAiUsageLog'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-23T01:19:33.1714676Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260423011936_AddAiUsageLog'
+)
+BEGIN
+ CREATE INDEX [IX_AiUsageLogs_CompanyId_CalledAt] ON [AiUsageLogs] ([CompanyId], [CalledAt]);
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260423011936_AddAiUsageLog'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260423011936_AddAiUsageLog', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260423015446_AddSmsOptedOutAt'
+)
+BEGIN
+ ALTER TABLE [Customers] ADD [SmsOptedOutAt] datetime2 NULL;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260423015446_AddSmsOptedOutAt'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-23T01:54:43.1815272Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260423015446_AddSmsOptedOutAt'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-23T01:54:43.1815281Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260423015446_AddSmsOptedOutAt'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-23T01:54:43.1815283Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260423015446_AddSmsOptedOutAt'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260423015446_AddSmsOptedOutAt', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
+BEGIN TRANSACTION;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260424232825_AddFacilityOverheadFields'
+)
+BEGIN
+ ALTER TABLE [CompanyOperatingCosts] ADD [MonthlyBillableHours] int NOT NULL DEFAULT 160;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260424232825_AddFacilityOverheadFields'
+)
+BEGIN
+ ALTER TABLE [CompanyOperatingCosts] ADD [MonthlyRent] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260424232825_AddFacilityOverheadFields'
+)
+BEGIN
+ ALTER TABLE [CompanyOperatingCosts] ADD [MonthlyUtilities] decimal(18,2) NOT NULL DEFAULT 0.0;
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260424232825_AddFacilityOverheadFields'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-24T23:28:22.1047155Z''
+ WHERE [Id] = 1;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260424232825_AddFacilityOverheadFields'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-24T23:28:22.1047162Z''
+ WHERE [Id] = 2;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260424232825_AddFacilityOverheadFields'
+)
+BEGIN
+ EXEC(N'UPDATE [PricingTiers] SET [CreatedAt] = ''2026-04-24T23:28:22.1047164Z''
+ WHERE [Id] = 3;
+ SELECT @@ROWCOUNT');
+END;
+GO
+
+IF NOT EXISTS (
+ SELECT * FROM [__EFMigrationsHistory]
+ WHERE [MigrationId] = N'20260424232825_AddFacilityOverheadFields'
+)
+BEGIN
+ INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
+ VALUES (N'20260424232825_AddFacilityOverheadFields', N'8.0.11');
+END;
+GO
+
+COMMIT;
+GO
+
diff --git a/src/PowderCoating.Core/Entities/UserPasskey.cs b/src/PowderCoating.Core/Entities/UserPasskey.cs
new file mode 100644
index 0000000..ae97587
--- /dev/null
+++ b/src/PowderCoating.Core/Entities/UserPasskey.cs
@@ -0,0 +1,39 @@
+namespace PowderCoating.Core.Entities;
+
+///
+/// Stores a WebAuthn public-key credential (passkey) registered by an application user.
+/// One row per device per user. Does not inherit BaseEntity — passkeys are identity
+/// credentials, not business-domain records, and require no soft-delete or company-scoped
+/// global query filter (the Login flow queries across tenants by credentialId before auth).
+///
+public class UserPasskey
+{
+ public int Id { get; set; }
+
+ /// FK to AspNetUsers.Id (GUID string).
+ public string UserId { get; set; } = default!;
+
+ /// Stored for display/management queries. NOT used as a query filter.
+ public int CompanyId { get; set; }
+
+ /// WebAuthn credential ID — unique identifier for this passkey.
+ public byte[] CredentialId { get; set; } = default!;
+
+ /// COSE-encoded public key from the authenticator.
+ public byte[] PublicKey { get; set; } = default!;
+
+ /// Opaque user handle sent by the authenticator during login.
+ public byte[] UserHandle { get; set; } = default!;
+
+ ///
+ /// Monotonically increasing counter used to detect cloned authenticators.
+ /// Stored as long to avoid SQL Server uint mapping issues; Fido2NetLib uses uint.
+ ///
+ public long SignCount { get; set; }
+
+ /// User-supplied or browser-provided friendly name, e.g. "Scott's iPhone".
+ public string? DeviceFriendlyName { get; set; }
+
+ public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
+ public DateTime? LastUsedAt { get; set; }
+}
diff --git a/src/PowderCoating.Infrastructure/Data/ApplicationDbContext.cs b/src/PowderCoating.Infrastructure/Data/ApplicationDbContext.cs
index 433f3ef..37c9493 100644
--- a/src/PowderCoating.Infrastructure/Data/ApplicationDbContext.cs
+++ b/src/PowderCoating.Infrastructure/Data/ApplicationDbContext.cs
@@ -385,6 +385,13 @@ public class ApplicationDbContext : IdentityDbContext
///
public DbSet PendingRegistrationSessions { get; set; }
+ ///
+ /// WebAuthn passkey credentials registered by users for biometric login (Face ID, fingerprint).
+ /// No global query filter — the login flow queries by credentialId before authentication,
+ /// requiring cross-tenant lookup. Per-user isolation is enforced in the controller.
+ ///
+ public DbSet UserPasskeys { get; set; }
+
///
/// Configures the EF Core model: applies entity type configurations from the assembly,
/// registers global query filters, defines relationships, adds performance indexes, and seeds
@@ -792,9 +799,14 @@ public class ApplicationDbContext : IdentityDbContext
property.SetColumnType("decimal(18,2)");
}
+ // UserPasskey: unique index on CredentialId (WebAuthn requires global uniqueness)
+ modelBuilder.Entity()
+ .HasIndex(p => p.CredentialId)
+ .IsUnique();
+
// Configure relationships
ConfigureRelationships(modelBuilder);
-
+
// Seed initial data
SeedInitialData(modelBuilder);
}
diff --git a/src/PowderCoating.Infrastructure/Migrations/20260425182712_AddUserPasskeys.Designer.cs b/src/PowderCoating.Infrastructure/Migrations/20260425182712_AddUserPasskeys.Designer.cs
new file mode 100644
index 0000000..8ab5f77
--- /dev/null
+++ b/src/PowderCoating.Infrastructure/Migrations/20260425182712_AddUserPasskeys.Designer.cs
@@ -0,0 +1,9244 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using PowderCoating.Infrastructure.Data;
+
+#nullable disable
+
+namespace PowderCoating.Infrastructure.Migrations
+{
+ [DbContext(typeof(ApplicationDbContext))]
+ [Migration("20260425182712_AddUserPasskeys")]
+ partial class AddUserPasskeys
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "8.0.11")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Name")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("NormalizedName")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName")
+ .IsUnique()
+ .HasDatabaseName("RoleNameIndex")
+ .HasFilter("[NormalizedName] IS NOT NULL");
+
+ b.ToTable("AspNetRoles", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("ClaimType")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ClaimValue")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("RoleId")
+ .IsRequired()
+ .HasColumnType("nvarchar(450)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetRoleClaims", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("ClaimType")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ClaimValue")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UserId")
+ .IsRequired()
+ .HasColumnType("nvarchar(450)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserClaims", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
+ {
+ b.Property("LoginProvider")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("ProviderKey")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("ProviderDisplayName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UserId")
+ .IsRequired()
+ .HasColumnType("nvarchar(450)");
+
+ b.HasKey("LoginProvider", "ProviderKey");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserLogins", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("RoleId")
+ .HasColumnType("nvarchar(450)");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetUserRoles", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("LoginProvider")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("Name")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("Value")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AspNetUserTokens", (string)null);
+ });
+
+ modelBuilder.Entity("PowderCoating.Core.Entities.Account", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("AccountNumber")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("AccountSubType")
+ .HasColumnType("int");
+
+ b.Property("AccountType")
+ .HasColumnType("int");
+
+ b.Property("CompanyId")
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("CreatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CurrentBalance")
+ .HasColumnType("decimal(18,2)");
+
+ b.Property("DeletedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DeletedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Description")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("IsActive")
+ .HasColumnType("bit");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("IsSystem")
+ .HasColumnType("bit");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("OpeningBalance")
+ .HasColumnType("decimal(18,2)");
+
+ b.Property("OpeningBalanceDate")
+ .HasColumnType("datetime2");
+
+ b.Property("ParentAccountId")
+ .HasColumnType("int");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("UpdatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ParentAccountId");
+
+ b.ToTable("Accounts");
+ });
+
+ modelBuilder.Entity("PowderCoating.Core.Entities.AiItemPrediction", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("AiTags")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CompanyId")
+ .HasColumnType("int");
+
+ b.Property("Confidence")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ConversationRounds")
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("CreatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DeletedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DeletedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("PredictedComplexity")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PredictedMinutes")
+ .HasColumnType("int");
+
+ b.Property("PredictedSurfaceAreaSqFt")
+ .HasColumnType("decimal(18,2)");
+
+ b.Property("PredictedUnitPrice")
+ .HasColumnType("decimal(18,2)");
+
+ b.Property("Reasoning")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("UpdatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UserOverrodeEstimate")
+ .HasColumnType("bit");
+
+ b.HasKey("Id");
+
+ b.ToTable("AiItemPredictions");
+ });
+
+ modelBuilder.Entity("PowderCoating.Core.Entities.AiUsageLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("CalledAt")
+ .HasColumnType("datetime2");
+
+ b.Property("CompanyId")
+ .HasColumnType("int");
+
+ b.Property("Feature")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("InputLength")
+ .HasColumnType("int");
+
+ b.Property("Success")
+ .HasColumnType("bit");
+
+ b.Property("UserId")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CompanyId", "CalledAt")
+ .HasDatabaseName("IX_AiUsageLogs_CompanyId_CalledAt");
+
+ b.ToTable("AiUsageLogs");
+ });
+
+ modelBuilder.Entity("PowderCoating.Core.Entities.Announcement", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("CreatedByUserId")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreatedByUserName")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ExpiresAt")
+ .HasColumnType("datetime2");
+
+ b.Property("IsActive")
+ .HasColumnType("bit");
+
+ b.Property("IsDismissible")
+ .HasColumnType("bit");
+
+ b.Property("Message")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("StartsAt")
+ .HasColumnType("datetime2");
+
+ b.Property("Target")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("TargetCompanyId")
+ .HasColumnType("int");
+
+ b.Property("TargetPlan")
+ .HasColumnType("int");
+
+ b.Property("Title")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.HasKey("Id");
+
+ b.ToTable("Announcements");
+ });
+
+ modelBuilder.Entity("PowderCoating.Core.Entities.AnnouncementDismissal", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("AnnouncementId")
+ .HasColumnType("int");
+
+ b.Property("DismissedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("UserId")
+ .IsRequired()
+ .HasColumnType("nvarchar(450)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AnnouncementId", "UserId")
+ .IsUnique();
+
+ b.ToTable("AnnouncementDismissals");
+ });
+
+ modelBuilder.Entity("PowderCoating.Core.Entities.ApplicationUser", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("AccessFailedCount")
+ .HasColumnType("int");
+
+ b.Property("Address")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("BanReason")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("BannedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("BannedByUserId")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CanApproveQuotes")
+ .HasColumnType("bit");
+
+ b.Property("CanCreateQuotes")
+ .HasColumnType("bit");
+
+ b.Property("CanManageCalendar")
+ .HasColumnType("bit");
+
+ b.Property("CanManageCustomers")
+ .HasColumnType("bit");
+
+ b.Property("CanManageEquipment")
+ .HasColumnType("bit");
+
+ b.Property("CanManageInventory")
+ .HasColumnType("bit");
+
+ b.Property("CanManageInvoices")
+ .HasColumnType("bit");
+
+ b.Property("CanManageJobs")
+ .HasColumnType("bit");
+
+ b.Property("CanManageMaintenance")
+ .HasColumnType("bit");
+
+ b.Property("CanManageProducts")
+ .HasColumnType("bit");
+
+ b.Property("CanManageVendors")
+ .HasColumnType("bit");
+
+ b.Property("CanViewCalendar")
+ .HasColumnType("bit");
+
+ b.Property("CanViewProducts")
+ .HasColumnType("bit");
+
+ b.Property("CanViewReports")
+ .HasColumnType("bit");
+
+ b.Property("CanViewShopFloor")
+ .HasColumnType("bit");
+
+ b.Property("City")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CompanyId")
+ .HasColumnType("int");
+
+ b.Property("CompanyRole")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DashboardLayout")
+ .HasColumnType("int");
+
+ b.Property("DateFormat")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Department")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Email")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("EmailConfirmed")
+ .HasColumnType("bit");
+
+ b.Property("EmployeeNumber")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("FirstName")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("HireDate")
+ .HasColumnType("datetime2");
+
+ b.Property("IsActive")
+ .HasColumnType("bit");
+
+ b.Property("IsBanned")
+ .HasColumnType("bit");
+
+ b.Property("LastLoginDate")
+ .HasColumnType("datetime2");
+
+ b.Property("LastName")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LockoutEnabled")
+ .HasColumnType("bit");
+
+ b.Property("LockoutEnd")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("NormalizedEmail")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("NormalizedUserName")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("Notes")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PasswordHash")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PhoneNumber")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PhoneNumberConfirmed")
+ .HasColumnType("bit");
+
+ b.Property("Position")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ProfilePictureFilePath")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("SecurityStamp")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("SidebarColor")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("State")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("TerminationDate")
+ .HasColumnType("datetime2");
+
+ b.Property("Theme")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("TimeZone")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("TwoFactorEnabled")
+ .HasColumnType("bit");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("UserName")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("ZipCode")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CompanyId");
+
+ b.HasIndex("NormalizedEmail")
+ .HasDatabaseName("EmailIndex");
+
+ b.HasIndex("NormalizedUserName")
+ .IsUnique()
+ .HasDatabaseName("UserNameIndex")
+ .HasFilter("[NormalizedUserName] IS NOT NULL");
+
+ b.ToTable("AspNetUsers", (string)null);
+ });
+
+ modelBuilder.Entity("PowderCoating.Core.Entities.Appointment", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("ActualEndTime")
+ .HasColumnType("datetime2");
+
+ b.Property("ActualStartTime")
+ .HasColumnType("datetime2");
+
+ b.Property("AppointmentNumber")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("AppointmentStatusId")
+ .HasColumnType("int");
+
+ b.Property("AppointmentTypeId")
+ .HasColumnType("int");
+
+ b.Property("AssignedUserId")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("CompanyId")
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("CreatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CustomerId")
+ .HasColumnType("int");
+
+ b.Property("DeletedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DeletedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Description")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("IsAllDay")
+ .HasColumnType("bit");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("IsReminderEnabled")
+ .HasColumnType("bit");
+
+ b.Property("JobId")
+ .HasColumnType("int");
+
+ b.Property("Location")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Notes")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ReminderMinutesBefore")
+ .HasColumnType("int");
+
+ b.Property("ScheduledEndTime")
+ .HasColumnType("datetime2");
+
+ b.Property("ScheduledStartTime")
+ .HasColumnType("datetime2");
+
+ b.Property("Title")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("UpdatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AppointmentStatusId");
+
+ b.HasIndex("AppointmentTypeId");
+
+ b.HasIndex("AssignedUserId");
+
+ b.HasIndex("CustomerId");
+
+ b.HasIndex("JobId");
+
+ b.HasIndex("ScheduledStartTime");
+
+ b.HasIndex("CompanyId", "AppointmentStatusId")
+ .HasDatabaseName("IX_Appointments_CompanyId_AppointmentStatusId");
+
+ b.HasIndex("CompanyId", "ScheduledStartTime")
+ .HasDatabaseName("IX_Appointments_CompanyId_ScheduledStartTime");
+
+ b.ToTable("Appointments");
+ });
+
+ modelBuilder.Entity("PowderCoating.Core.Entities.AppointmentStatusLookup", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("ColorClass")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CompanyId")
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("CreatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DeletedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DeletedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Description")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DisplayName")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DisplayOrder")
+ .HasColumnType("int");
+
+ b.Property("IconClass")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("IsActive")
+ .HasColumnType("bit");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("IsSystemDefined")
+ .HasColumnType("bit");
+
+ b.Property("IsTerminalStatus")
+ .HasColumnType("bit");
+
+ b.Property("StatusCode")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("UpdatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("AppointmentStatusLookups");
+ });
+
+ modelBuilder.Entity("PowderCoating.Core.Entities.AppointmentTypeLookup", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("ColorClass")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CompanyId")
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("CreatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DeletedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DeletedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Description")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DisplayName")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DisplayOrder")
+ .HasColumnType("int");
+
+ b.Property("IconClass")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("IsActive")
+ .HasColumnType("bit");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("IsSystemDefined")
+ .HasColumnType("bit");
+
+ b.Property("RequiresJobLink")
+ .HasColumnType("bit");
+
+ b.Property("TypeCode")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("UpdatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("AppointmentTypeLookups");
+ });
+
+ modelBuilder.Entity("PowderCoating.Core.Entities.AuditLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Action")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CompanyId")
+ .HasColumnType("int");
+
+ b.Property("CompanyName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("EntityDescription")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("EntityId")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("EntityType")
+ .IsRequired()
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("IpAddress")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("NewValues")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("OldValues")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Timestamp")
+ .HasColumnType("datetime2");
+
+ b.Property("UserId")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UserName")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CompanyId", "Timestamp");
+
+ b.HasIndex("EntityType", "EntityId");
+
+ b.ToTable("AuditLogs");
+ });
+
+ modelBuilder.Entity("PowderCoating.Core.Entities.BannedIp", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("BannedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("BannedByUserId")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ExpiresAt")
+ .HasColumnType("datetime2");
+
+ b.Property("IpAddress")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("IsActive")
+ .HasColumnType("bit");
+
+ b.Property("Reason")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("BannedIps");
+ });
+
+ modelBuilder.Entity("PowderCoating.Core.Entities.Bill", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("APAccountId")
+ .HasColumnType("int");
+
+ b.Property("AmountPaid")
+ .HasColumnType("decimal(18,2)");
+
+ b.Property("BillDate")
+ .HasColumnType("datetime2");
+
+ b.Property