diff --git a/scripts/purge_imported_data.sql b/scripts/purge_imported_data.sql index 3ff20df..d392839 100644 --- a/scripts/purge_imported_data.sql +++ b/scripts/purge_imported_data.sql @@ -1,14 +1,16 @@ -- ============================================================================= -- Company Data Purge Script --- Removes financial, job, and quote data created before a cutoff date. +-- Removes financial, job, and quote data dated before a cutoff date. -- Customers and Vendors are always preserved. -- --- WHAT THIS DELETES (for records where CreatedAt < @CutoffDate): --- • Journal entries & bank reconciliations --- • Bills, bill payments, purchase orders, vendor credits, expenses --- • Invoices, invoice payments, credit memos, refunds, deposits --- • Jobs and all child records (items, coats, prep, notes, photos, etc.) --- • Quotes and all child records +-- WHAT THIS DELETES (using each entity's own business date, not CreatedAt): +-- • Journal entries (EntryDate) & bank reconciliations (StatementDate) +-- • Bills (BillDate), bill payments (PaymentDate), purchase orders (OrderDate) +-- • Vendor credits (CreditDate), expenses (Date) +-- • Invoices (InvoiceDate), payments (PaymentDate), deposits (ReceivedDate) +-- • Credit memos, refunds, gift cert redemptions tied to deleted invoices +-- • Jobs (IntakeDate, falling back to CreatedAt when null) and all child records +-- • Quotes (QuoteDate) and all child records -- -- WHAT THIS KEEPS (always): -- • Customers, customer notes, customer contacts, preferred powders @@ -16,17 +18,17 @@ -- • Inventory items and inventory transactions -- • Equipment, catalog items, pricing tiers -- • Company settings and configuration --- • Any record with CreatedAt >= @CutoffDate +-- • Any record whose business date >= @CutoffDate -- -- INSTRUCTIONS: -- 1. Set @CompanyId — find it with: SELECT Id, Name FROM Companies --- 2. Set @CutoffDate — records created BEFORE this date are deleted +-- 2. Set @CutoffDate — records dated BEFORE this date are deleted -- 3. Run with @DryRun = 1 first and review the row counts printed -- 4. Back up the database before setting @DryRun = 0 -- 5. Set @DryRun = 0 and run again to apply -- ============================================================================= -DECLARE @CutoffDate DATE = '2026-01-01'; -- Delete records created BEFORE this date +DECLARE @CutoffDate DATE = '2026-01-01'; -- Delete records dated BEFORE this date DECLARE @CompanyId INT = 0; -- !! Set to your company ID before running DECLARE @DryRun BIT = 1; -- 1 = preview counts only | 0 = apply deletes @@ -50,6 +52,7 @@ BEGIN TRANSACTION; -- =========================================================================== -- SECTION 1 — JOURNAL ENTRIES & GL +-- Uses EntryDate (JournalEntries) and StatementDate (BankReconciliations) -- =========================================================================== PRINT ''; PRINT '--- Section 1: Journal Entries & GL ---'; @@ -58,23 +61,24 @@ PRINT '--- Section 1: Journal Entries & GL ---'; UPDATE JournalEntries SET ReversalOfId = NULL WHERE CompanyId = @CompanyId - AND ReversalOfId IN (SELECT Id FROM JournalEntries WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + AND ReversalOfId IN (SELECT Id FROM JournalEntries WHERE CompanyId = @CompanyId AND CAST(EntryDate AS DATE) < @CutoffDate); DELETE FROM JournalEntryLines WHERE JournalEntryId IN ( - SELECT Id FROM JournalEntries WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM JournalEntries WHERE CompanyId = @CompanyId AND CAST(EntryDate AS DATE) < @CutoffDate); PRINT 'JournalEntryLines deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); DELETE FROM JournalEntries -WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate; +WHERE CompanyId = @CompanyId AND CAST(EntryDate AS DATE) < @CutoffDate; PRINT 'JournalEntries deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); DELETE FROM BankReconciliations -WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate; +WHERE CompanyId = @CompanyId AND CAST(StatementDate AS DATE) < @CutoffDate; PRINT 'BankReconciliations deleted: ' + CAST(@@ROWCOUNT AS NVARCHAR); -- =========================================================================== -- SECTION 2 — BILLS, PURCHASE ORDERS & EXPENSES +-- Uses CreditDate (VendorCredits), BillDate (Bills), OrderDate (POs), Date (Expenses) -- =========================================================================== PRINT ''; PRINT '--- Section 2: Bills, Purchase Orders & Expenses ---'; @@ -82,50 +86,53 @@ PRINT '--- Section 2: Bills, Purchase Orders & Expenses ---'; -- Vendor credits (must come before Bills because VendorCreditApplications references both) DELETE FROM VendorCreditApplications WHERE VendorCreditId IN ( - SELECT Id FROM VendorCredits WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM VendorCredits WHERE CompanyId = @CompanyId AND CAST(CreditDate AS DATE) < @CutoffDate); PRINT 'VendorCreditApplications deleted: ' + CAST(@@ROWCOUNT AS NVARCHAR); DELETE FROM VendorCreditLineItems WHERE VendorCreditId IN ( - SELECT Id FROM VendorCredits WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM VendorCredits WHERE CompanyId = @CompanyId AND CAST(CreditDate AS DATE) < @CutoffDate); PRINT 'VendorCreditLineItems deleted: ' + CAST(@@ROWCOUNT AS NVARCHAR); DELETE FROM VendorCredits -WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate; +WHERE CompanyId = @CompanyId AND CAST(CreditDate AS DATE) < @CutoffDate; PRINT 'VendorCredits deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); -- Bills DELETE FROM BillPayments WHERE BillId IN ( - SELECT Id FROM Bills WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Bills WHERE CompanyId = @CompanyId AND CAST(BillDate AS DATE) < @CutoffDate); PRINT 'BillPayments deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); DELETE FROM BillLineItems WHERE BillId IN ( - SELECT Id FROM Bills WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Bills WHERE CompanyId = @CompanyId AND CAST(BillDate AS DATE) < @CutoffDate); PRINT 'BillLineItems deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); DELETE FROM Bills -WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate; +WHERE CompanyId = @CompanyId AND CAST(BillDate AS DATE) < @CutoffDate; PRINT 'Bills deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); -- Purchase orders DELETE FROM PurchaseOrderItems WHERE PurchaseOrderId IN ( - SELECT Id FROM PurchaseOrders WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM PurchaseOrders WHERE CompanyId = @CompanyId AND CAST(OrderDate AS DATE) < @CutoffDate); PRINT 'PurchaseOrderItems deleted: ' + CAST(@@ROWCOUNT AS NVARCHAR); DELETE FROM PurchaseOrders -WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate; +WHERE CompanyId = @CompanyId AND CAST(OrderDate AS DATE) < @CutoffDate; PRINT 'PurchaseOrders deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); --- Expenses +-- Expenses (Date column) DELETE FROM Expenses -WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate; +WHERE CompanyId = @CompanyId AND CAST([Date] AS DATE) < @CutoffDate; PRINT 'Expenses deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); -- =========================================================================== -- SECTION 3 — INVOICES, PAYMENTS & DEPOSITS +-- Uses InvoiceDate (Invoices), PaymentDate (Payments), ReceivedDate (Deposits) +-- CreditMemos/Refunds/GiftCertRedemptions have no standalone date — deleted +-- only when their parent invoice falls within the cutoff. -- =========================================================================== PRINT ''; PRINT '--- Section 3: Invoices, Payments & Deposits ---'; @@ -135,34 +142,34 @@ UPDATE CreditMemos SET OriginalInvoiceId = NULL WHERE CompanyId = @CompanyId AND OriginalInvoiceId IN ( - SELECT Id FROM Invoices WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Invoices WHERE CompanyId = @CompanyId AND CAST(InvoiceDate AS DATE) < @CutoffDate); DELETE FROM CreditMemoApplications WHERE InvoiceId IN ( - SELECT Id FROM Invoices WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate) + SELECT Id FROM Invoices WHERE CompanyId = @CompanyId AND CAST(InvoiceDate AS DATE) < @CutoffDate) OR CreditMemoId IN ( - SELECT Id FROM CreditMemos WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM CreditMemos WHERE CompanyId = @CompanyId AND CAST(CreatedAt AS DATE) < @CutoffDate); PRINT 'CreditMemoApplications deleted: ' + CAST(@@ROWCOUNT AS NVARCHAR); DELETE FROM CreditMemos -WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate; +WHERE CompanyId = @CompanyId AND CAST(CreatedAt AS DATE) < @CutoffDate; PRINT 'CreditMemos deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); -- Refunds and gift-cert redemptions tied to deleted invoices DELETE FROM Refunds WHERE InvoiceId IN ( - SELECT Id FROM Invoices WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Invoices WHERE CompanyId = @CompanyId AND CAST(InvoiceDate AS DATE) < @CutoffDate); PRINT 'Refunds deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); DELETE FROM GiftCertificateRedemptions WHERE InvoiceId IN ( - SELECT Id FROM Invoices WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Invoices WHERE CompanyId = @CompanyId AND CAST(InvoiceDate AS DATE) < @CutoffDate); PRINT 'GiftCertificateRedemptions deleted: ' + CAST(@@ROWCOUNT AS NVARCHAR); --- Payments +-- Payments (PaymentDate) DELETE FROM Payments WHERE InvoiceId IN ( - SELECT Id FROM Invoices WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Invoices WHERE CompanyId = @CompanyId AND CAST(InvoiceDate AS DATE) < @CutoffDate); PRINT 'Payments deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); -- InvoiceItems (NULL SourceJobItemId on any invoice items that survive but point at deleted jobs) @@ -171,11 +178,12 @@ SET SourceJobItemId = NULL WHERE SourceJobItemId IN ( SELECT ji.Id FROM JobItems ji INNER JOIN Jobs j ON ji.JobId = j.Id - WHERE j.CompanyId = @CompanyId AND j.CreatedAt < @CutoffDate); + WHERE j.CompanyId = @CompanyId + AND CAST(COALESCE(j.IntakeDate, j.CreatedAt) AS DATE) < @CutoffDate); DELETE FROM InvoiceItems WHERE InvoiceId IN ( - SELECT Id FROM Invoices WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Invoices WHERE CompanyId = @CompanyId AND CAST(InvoiceDate AS DATE) < @CutoffDate); PRINT 'InvoiceItems deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); -- Deposits: clear the AppliedToInvoiceId FK before deleting the invoices @@ -184,11 +192,11 @@ SET AppliedToInvoiceId = NULL, AppliedDate = NULL WHERE CompanyId = @CompanyId AND AppliedToInvoiceId IN ( - SELECT Id FROM Invoices WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Invoices WHERE CompanyId = @CompanyId AND CAST(InvoiceDate AS DATE) < @CutoffDate); --- Now delete deposits that were created before the cutoff +-- Now delete deposits that fall within the cutoff (ReceivedDate) DELETE FROM Deposits -WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate; +WHERE CompanyId = @CompanyId AND CAST(ReceivedDate AS DATE) < @CutoffDate; PRINT 'Deposits deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); -- Notification logs referencing deleted invoices @@ -196,14 +204,16 @@ UPDATE NotificationLogs SET InvoiceId = NULL WHERE CompanyId = @CompanyId AND InvoiceId IN ( - SELECT Id FROM Invoices WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Invoices WHERE CompanyId = @CompanyId AND CAST(InvoiceDate AS DATE) < @CutoffDate); DELETE FROM Invoices -WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate; +WHERE CompanyId = @CompanyId AND CAST(InvoiceDate AS DATE) < @CutoffDate; PRINT 'Invoices deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); -- =========================================================================== -- SECTION 4 — JOBS +-- Uses COALESCE(IntakeDate, CreatedAt) — IntakeDate is the business date; +-- falls back to CreatedAt when not set (e.g. jobs created before IntakeDate existed). -- =========================================================================== PRINT ''; PRINT '--- Section 4: Jobs ---'; @@ -214,121 +224,140 @@ PRINT '--- Section 4: Jobs ---'; UPDATE BillLineItems SET JobId = NULL WHERE JobId IN ( - SELECT Id FROM Jobs WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Jobs WHERE CompanyId = @CompanyId + AND CAST(COALESCE(IntakeDate, CreatedAt) AS DATE) < @CutoffDate); -- Expenses.JobId UPDATE Expenses SET JobId = NULL WHERE CompanyId = @CompanyId AND JobId IN ( - SELECT Id FROM Jobs WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Jobs WHERE CompanyId = @CompanyId + AND CAST(COALESCE(IntakeDate, CreatedAt) AS DATE) < @CutoffDate); -- Appointments.JobId UPDATE Appointments SET JobId = NULL WHERE CompanyId = @CompanyId AND JobId IN ( - SELECT Id FROM Jobs WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Jobs WHERE CompanyId = @CompanyId + AND CAST(COALESCE(IntakeDate, CreatedAt) AS DATE) < @CutoffDate); -- Deposits.JobId (NoAction FK — must NULL before deleting job) UPDATE Deposits SET JobId = NULL WHERE CompanyId = @CompanyId AND JobId IN ( - SELECT Id FROM Jobs WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Jobs WHERE CompanyId = @CompanyId + AND CAST(COALESCE(IntakeDate, CreatedAt) AS DATE) < @CutoffDate); -- NotificationLogs.JobId UPDATE NotificationLogs SET JobId = NULL WHERE CompanyId = @CompanyId AND JobId IN ( - SELECT Id FROM Jobs WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Jobs WHERE CompanyId = @CompanyId + AND CAST(COALESCE(IntakeDate, CreatedAt) AS DATE) < @CutoffDate); -- OvenBatchItems: delete before OvenBatches and before JobItems DELETE FROM OvenBatchItems WHERE JobId IN ( - SELECT Id FROM Jobs WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Jobs WHERE CompanyId = @CompanyId + AND CAST(COALESCE(IntakeDate, CreatedAt) AS DATE) < @CutoffDate); PRINT 'OvenBatchItems deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); -- Clean up now-empty OvenBatches (batches belonging to this company with no remaining items) DELETE FROM OvenBatches WHERE CompanyId = @CompanyId - AND CreatedAt < @CutoffDate AND Id NOT IN (SELECT DISTINCT OvenBatchId FROM OvenBatchItems); PRINT 'OvenBatches deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); -- ReworkRecords (JobId required FK; ReworkJobId optional) DELETE FROM ReworkRecords WHERE JobId IN ( - SELECT Id FROM Jobs WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate) + SELECT Id FROM Jobs WHERE CompanyId = @CompanyId + AND CAST(COALESCE(IntakeDate, CreatedAt) AS DATE) < @CutoffDate) OR ReworkJobId IN ( - SELECT Id FROM Jobs WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Jobs WHERE CompanyId = @CompanyId + AND CAST(COALESCE(IntakeDate, CreatedAt) AS DATE) < @CutoffDate); PRINT 'ReworkRecords deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); -- JobItem children (coats and prep services) DELETE FROM JobItemCoats WHERE JobItemId IN ( SELECT Id FROM JobItems WHERE JobId IN ( - SELECT Id FROM Jobs WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate)); + SELECT Id FROM Jobs WHERE CompanyId = @CompanyId + AND CAST(COALESCE(IntakeDate, CreatedAt) AS DATE) < @CutoffDate)); PRINT 'JobItemCoats deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); DELETE FROM JobItemPrepServices WHERE JobItemId IN ( SELECT Id FROM JobItems WHERE JobId IN ( - SELECT Id FROM Jobs WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate)); + SELECT Id FROM Jobs WHERE CompanyId = @CompanyId + AND CAST(COALESCE(IntakeDate, CreatedAt) AS DATE) < @CutoffDate)); PRINT 'JobItemPrepServices deleted: ' + CAST(@@ROWCOUNT AS NVARCHAR); DELETE FROM JobItems WHERE JobId IN ( - SELECT Id FROM Jobs WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Jobs WHERE CompanyId = @CompanyId + AND CAST(COALESCE(IntakeDate, CreatedAt) AS DATE) < @CutoffDate); PRINT 'JobItems deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); -- Job metadata tables DELETE FROM JobChangeHistories WHERE JobId IN ( - SELECT Id FROM Jobs WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Jobs WHERE CompanyId = @CompanyId + AND CAST(COALESCE(IntakeDate, CreatedAt) AS DATE) < @CutoffDate); PRINT 'JobChangeHistories deleted: ' + CAST(@@ROWCOUNT AS NVARCHAR); DELETE FROM JobTimeEntries WHERE JobId IN ( - SELECT Id FROM Jobs WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Jobs WHERE CompanyId = @CompanyId + AND CAST(COALESCE(IntakeDate, CreatedAt) AS DATE) < @CutoffDate); PRINT 'JobTimeEntries deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); DELETE FROM JobPhotos WHERE JobId IN ( - SELECT Id FROM Jobs WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Jobs WHERE CompanyId = @CompanyId + AND CAST(COALESCE(IntakeDate, CreatedAt) AS DATE) < @CutoffDate); PRINT 'JobPhotos deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); DELETE FROM JobNotes WHERE JobId IN ( - SELECT Id FROM Jobs WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Jobs WHERE CompanyId = @CompanyId + AND CAST(COALESCE(IntakeDate, CreatedAt) AS DATE) < @CutoffDate); PRINT 'JobNotes deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); DELETE FROM JobStatusHistory WHERE JobId IN ( - SELECT Id FROM Jobs WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Jobs WHERE CompanyId = @CompanyId + AND CAST(COALESCE(IntakeDate, CreatedAt) AS DATE) < @CutoffDate); PRINT 'JobStatusHistory deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); DELETE FROM JobDailyPriorities WHERE JobId IN ( - SELECT Id FROM Jobs WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Jobs WHERE CompanyId = @CompanyId + AND CAST(COALESCE(IntakeDate, CreatedAt) AS DATE) < @CutoffDate); PRINT 'JobDailyPriorities deleted: ' + CAST(@@ROWCOUNT AS NVARCHAR); DELETE FROM PowderUsageLogs WHERE JobId IN ( - SELECT Id FROM Jobs WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Jobs WHERE CompanyId = @CompanyId + AND CAST(COALESCE(IntakeDate, CreatedAt) AS DATE) < @CutoffDate); PRINT 'PowderUsageLogs deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); DELETE FROM AiItemPredictions -WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate; +WHERE CompanyId = @CompanyId AND CAST(CreatedAt AS DATE) < @CutoffDate; PRINT 'AiItemPredictions deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); DELETE FROM Jobs -WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate; +WHERE CompanyId = @CompanyId + AND CAST(COALESCE(IntakeDate, CreatedAt) AS DATE) < @CutoffDate; PRINT 'Jobs deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); -- =========================================================================== -- SECTION 5 — QUOTES +-- Uses QuoteDate -- =========================================================================== PRINT ''; PRINT '--- Section 5: Quotes ---'; @@ -338,50 +367,49 @@ UPDATE Deposits SET QuoteId = NULL WHERE CompanyId = @CompanyId AND QuoteId IN ( - SELECT Id FROM Quotes WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Quotes WHERE CompanyId = @CompanyId AND CAST(QuoteDate AS DATE) < @CutoffDate); UPDATE NotificationLogs SET QuoteId = NULL WHERE CompanyId = @CompanyId AND QuoteId IN ( - SELECT Id FROM Quotes WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Quotes WHERE CompanyId = @CompanyId AND CAST(QuoteDate AS DATE) < @CutoffDate); -- QuoteItem children DELETE FROM QuoteItemCoats WHERE QuoteItemId IN ( SELECT Id FROM QuoteItems WHERE QuoteId IN ( - SELECT Id FROM Quotes WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate)); + SELECT Id FROM Quotes WHERE CompanyId = @CompanyId AND CAST(QuoteDate AS DATE) < @CutoffDate)); PRINT 'QuoteItemCoats deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); DELETE FROM QuoteItemPrepServices WHERE QuoteItemId IN ( SELECT Id FROM QuoteItems WHERE QuoteId IN ( - SELECT Id FROM Quotes WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate)); + SELECT Id FROM Quotes WHERE CompanyId = @CompanyId AND CAST(QuoteDate AS DATE) < @CutoffDate)); PRINT 'QuoteItemPrepServices deleted: ' + CAST(@@ROWCOUNT AS NVARCHAR); DELETE FROM QuoteItems WHERE QuoteId IN ( - SELECT Id FROM Quotes WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Quotes WHERE CompanyId = @CompanyId AND CAST(QuoteDate AS DATE) < @CutoffDate); PRINT 'QuoteItems deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); DELETE FROM QuoteChangeHistories WHERE QuoteId IN ( - SELECT Id FROM Quotes WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Quotes WHERE CompanyId = @CompanyId AND CAST(QuoteDate AS DATE) < @CutoffDate); PRINT 'QuoteChangeHistories deleted: ' + CAST(@@ROWCOUNT AS NVARCHAR); DELETE FROM QuotePhotos WHERE QuoteId IN ( - SELECT Id FROM Quotes WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Quotes WHERE CompanyId = @CompanyId AND CAST(QuoteDate AS DATE) < @CutoffDate); PRINT 'QuotePhotos deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); --- QuotePrepServices are scoped to the quote's company via the quote FK, not directly DELETE FROM QuotePrepServices WHERE QuoteId IN ( - SELECT Id FROM Quotes WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate); + SELECT Id FROM Quotes WHERE CompanyId = @CompanyId AND CAST(QuoteDate AS DATE) < @CutoffDate); PRINT 'QuotePrepServices deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); DELETE FROM Quotes -WHERE CompanyId = @CompanyId AND CreatedAt < @CutoffDate; +WHERE CompanyId = @CompanyId AND CAST(QuoteDate AS DATE) < @CutoffDate; PRINT 'Quotes deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR); -- =========================================================================== diff --git a/src/PowderCoating.Application/Services/PdfService.cs b/src/PowderCoating.Application/Services/PdfService.cs index d91854f..af65c75 100644 --- a/src/PowderCoating.Application/Services/PdfService.cs +++ b/src/PowderCoating.Application/Services/PdfService.cs @@ -147,6 +147,14 @@ public class PdfService : IPdfService column.Item().Text(companyInfo.PrimaryContactEmail).FontSize(9).FontColor(Colors.Grey.Darken1); }); + if (invoice.Status == InvoiceStatus.Paid) + { + row.RelativeItem().AlignCenter().AlignMiddle() + .Border(2).BorderColor(Colors.Green.Darken1) + .PaddingVertical(6).PaddingHorizontal(16) + .Text("PAID").FontSize(20).Bold().FontColor(Colors.Green.Darken1).LetterSpacing(0.15f); + } + row.RelativeItem().AlignRight().Column(column => { column.Item().Text("INVOICE").FontSize(28).Bold().FontColor(accentColor); @@ -158,16 +166,6 @@ public class PdfService : IPdfService }); }); - if (invoice.Status == InvoiceStatus.Paid) - { - col.Item().PaddingVertical(6).AlignCenter().Column(badge => - { - badge.Item().AlignCenter().Border(2).BorderColor(Colors.Green.Darken1) - .PaddingVertical(4).PaddingHorizontal(24) - .Text("PAID").FontSize(18).Bold().FontColor(Colors.Green.Darken1).LetterSpacing(0.15f); - }); - } - col.Item().PaddingVertical(4).LineHorizontal(1).LineColor(accentColor); }); } diff --git a/src/PowderCoating.Web/Controllers/CompanySettingsController.cs b/src/PowderCoating.Web/Controllers/CompanySettingsController.cs index 3126406..7dad626 100644 --- a/src/PowderCoating.Web/Controllers/CompanySettingsController.cs +++ b/src/PowderCoating.Web/Controllers/CompanySettingsController.cs @@ -230,11 +230,19 @@ public class CompanySettingsController : Controller return Json(new { success = false, message = "Company not found." }); } - // Update company properties - _mapper.Map(dto, company); - company.UpdatedAt = DateTime.UtcNow; + // Explicit assignment avoids AutoMapper quirks with tracked EF entities + company.CompanyName = dto.CompanyName.Trim(); + company.CompanyCode = string.IsNullOrWhiteSpace(dto.CompanyCode) ? null : dto.CompanyCode.Trim(); + company.PrimaryContactName = dto.PrimaryContactName.Trim(); + company.PrimaryContactEmail = dto.PrimaryContactEmail.Trim(); + company.Phone = string.IsNullOrWhiteSpace(dto.Phone) ? null : dto.Phone.Trim(); + company.Address = string.IsNullOrWhiteSpace(dto.Address) ? null : dto.Address.Trim(); + company.City = string.IsNullOrWhiteSpace(dto.City) ? null : dto.City.Trim(); + company.State = string.IsNullOrWhiteSpace(dto.State) ? null : dto.State.Trim(); + company.ZipCode = string.IsNullOrWhiteSpace(dto.ZipCode) ? null : dto.ZipCode.Trim(); + company.TimeZone = string.IsNullOrWhiteSpace(dto.TimeZone) ? null : dto.TimeZone.Trim(); + company.AccountingMethod = dto.AccountingMethod; - await _unitOfWork.Companies.UpdateAsync(company); await _unitOfWork.CompleteAsync(); _logger.LogInformation("Company {CompanyId} settings updated by user", companyId); diff --git a/src/PowderCoating.Web/Views/CompanySettings/Index.cshtml b/src/PowderCoating.Web/Views/CompanySettings/Index.cshtml index 1151807..a9cffca 100644 --- a/src/PowderCoating.Web/Views/CompanySettings/Index.cshtml +++ b/src/PowderCoating.Web/Views/CompanySettings/Index.cshtml @@ -312,7 +312,7 @@