0b839d0746
- Company Settings: switch save button from type=submit to type=button to bypass HTML5 form validation blocking the submit event; replace AutoMapper Map() with explicit property assignment so EF change tracking reliably detects mutations; fix showButtonSuccess() never re-enabling the button after a successful save - Invoice PDF: move PAID stamp into the header row as a centered middle column so it sits between the company and invoice blocks without adding height to the document - Purge script: use business-date fields instead of CreatedAt so imported records (which all share today's CreatedAt) are correctly filtered by actual transaction dates Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
432 lines
18 KiB
Transact-SQL
432 lines
18 KiB
Transact-SQL
-- =============================================================================
|
|
-- Company Data Purge Script
|
|
-- Removes financial, job, and quote data dated before a cutoff date.
|
|
-- Customers and Vendors are always preserved.
|
|
--
|
|
-- 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
|
|
-- • Vendors
|
|
-- • Inventory items and inventory transactions
|
|
-- • Equipment, catalog items, pricing tiers
|
|
-- • Company settings and configuration
|
|
-- • Any record whose business date >= @CutoffDate
|
|
--
|
|
-- INSTRUCTIONS:
|
|
-- 1. Set @CompanyId — find it with: SELECT Id, Name FROM Companies
|
|
-- 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 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
|
|
|
|
-- =============================================================================
|
|
SET NOCOUNT ON;
|
|
|
|
IF @CompanyId = 0
|
|
BEGIN
|
|
RAISERROR('ERROR: Set @CompanyId before running this script. Run: SELECT Id, Name FROM Companies', 16, 1);
|
|
RETURN;
|
|
END
|
|
|
|
PRINT '============================================================';
|
|
PRINT 'Purge run at: ' + CONVERT(NVARCHAR, GETDATE(), 120);
|
|
PRINT 'Company ID : ' + CAST(@CompanyId AS NVARCHAR);
|
|
PRINT 'Cutoff date : ' + CAST(@CutoffDate AS NVARCHAR) + ' (records BEFORE this date)';
|
|
PRINT 'Dry run : ' + CASE @DryRun WHEN 1 THEN 'YES — no changes will be made' ELSE 'NO — deletes will be applied' END;
|
|
PRINT '============================================================';
|
|
|
|
BEGIN TRANSACTION;
|
|
|
|
-- ===========================================================================
|
|
-- SECTION 1 — JOURNAL ENTRIES & GL
|
|
-- Uses EntryDate (JournalEntries) and StatementDate (BankReconciliations)
|
|
-- ===========================================================================
|
|
PRINT '';
|
|
PRINT '--- Section 1: Journal Entries & GL ---';
|
|
|
|
-- Null the self-referential ReversalOfId FK before deleting
|
|
UPDATE JournalEntries
|
|
SET ReversalOfId = NULL
|
|
WHERE CompanyId = @CompanyId
|
|
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 CAST(EntryDate AS DATE) < @CutoffDate);
|
|
PRINT 'JournalEntryLines deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR);
|
|
|
|
DELETE FROM JournalEntries
|
|
WHERE CompanyId = @CompanyId AND CAST(EntryDate AS DATE) < @CutoffDate;
|
|
PRINT 'JournalEntries deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR);
|
|
|
|
DELETE FROM BankReconciliations
|
|
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 ---';
|
|
|
|
-- Vendor credits (must come before Bills because VendorCreditApplications references both)
|
|
DELETE FROM VendorCreditApplications
|
|
WHERE VendorCreditId IN (
|
|
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 CAST(CreditDate AS DATE) < @CutoffDate);
|
|
PRINT 'VendorCreditLineItems deleted: ' + CAST(@@ROWCOUNT AS NVARCHAR);
|
|
|
|
DELETE FROM VendorCredits
|
|
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 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 CAST(BillDate AS DATE) < @CutoffDate);
|
|
PRINT 'BillLineItems deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR);
|
|
|
|
DELETE FROM Bills
|
|
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 CAST(OrderDate AS DATE) < @CutoffDate);
|
|
PRINT 'PurchaseOrderItems deleted: ' + CAST(@@ROWCOUNT AS NVARCHAR);
|
|
|
|
DELETE FROM PurchaseOrders
|
|
WHERE CompanyId = @CompanyId AND CAST(OrderDate AS DATE) < @CutoffDate;
|
|
PRINT 'PurchaseOrders deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR);
|
|
|
|
-- Expenses (Date column)
|
|
DELETE FROM Expenses
|
|
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 ---';
|
|
|
|
-- CreditMemos: NULL the OriginalInvoiceId FK before deleting the invoice it points to
|
|
UPDATE CreditMemos
|
|
SET OriginalInvoiceId = NULL
|
|
WHERE CompanyId = @CompanyId
|
|
AND OriginalInvoiceId IN (
|
|
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 CAST(InvoiceDate AS DATE) < @CutoffDate)
|
|
OR CreditMemoId IN (
|
|
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 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 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 CAST(InvoiceDate AS DATE) < @CutoffDate);
|
|
PRINT 'GiftCertificateRedemptions deleted: ' + CAST(@@ROWCOUNT AS NVARCHAR);
|
|
|
|
-- Payments (PaymentDate)
|
|
DELETE FROM Payments
|
|
WHERE InvoiceId IN (
|
|
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)
|
|
UPDATE InvoiceItems
|
|
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 CAST(COALESCE(j.IntakeDate, j.CreatedAt) AS DATE) < @CutoffDate);
|
|
|
|
DELETE FROM InvoiceItems
|
|
WHERE InvoiceId IN (
|
|
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
|
|
UPDATE Deposits
|
|
SET AppliedToInvoiceId = NULL,
|
|
AppliedDate = NULL
|
|
WHERE CompanyId = @CompanyId
|
|
AND AppliedToInvoiceId IN (
|
|
SELECT Id FROM Invoices WHERE CompanyId = @CompanyId AND CAST(InvoiceDate AS DATE) < @CutoffDate);
|
|
|
|
-- Now delete deposits that fall within the cutoff (ReceivedDate)
|
|
DELETE FROM Deposits
|
|
WHERE CompanyId = @CompanyId AND CAST(ReceivedDate AS DATE) < @CutoffDate;
|
|
PRINT 'Deposits deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR);
|
|
|
|
-- Notification logs referencing deleted invoices
|
|
UPDATE NotificationLogs
|
|
SET InvoiceId = NULL
|
|
WHERE CompanyId = @CompanyId
|
|
AND InvoiceId IN (
|
|
SELECT Id FROM Invoices WHERE CompanyId = @CompanyId AND CAST(InvoiceDate AS DATE) < @CutoffDate);
|
|
|
|
DELETE FROM Invoices
|
|
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 ---';
|
|
|
|
-- NULL FKs in other tables that point to jobs/job-items being deleted --
|
|
|
|
-- BillLineItems.JobId (bill survived but referenced a deleted job)
|
|
UPDATE BillLineItems
|
|
SET JobId = NULL
|
|
WHERE JobId IN (
|
|
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 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 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 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 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 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 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 CAST(COALESCE(IntakeDate, CreatedAt) AS DATE) < @CutoffDate)
|
|
OR ReworkJobId IN (
|
|
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 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 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 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 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 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 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 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 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 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 CAST(COALESCE(IntakeDate, CreatedAt) AS DATE) < @CutoffDate);
|
|
PRINT 'PowderUsageLogs deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR);
|
|
|
|
DELETE FROM AiItemPredictions
|
|
WHERE CompanyId = @CompanyId AND CAST(CreatedAt AS DATE) < @CutoffDate;
|
|
PRINT 'AiItemPredictions deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR);
|
|
|
|
DELETE FROM Jobs
|
|
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 ---';
|
|
|
|
-- NULL FKs that point to quotes being deleted
|
|
UPDATE Deposits
|
|
SET QuoteId = NULL
|
|
WHERE CompanyId = @CompanyId
|
|
AND QuoteId IN (
|
|
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 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 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 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 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 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 CAST(QuoteDate AS DATE) < @CutoffDate);
|
|
PRINT 'QuotePhotos deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR);
|
|
|
|
DELETE FROM QuotePrepServices
|
|
WHERE QuoteId IN (
|
|
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 CAST(QuoteDate AS DATE) < @CutoffDate;
|
|
PRINT 'Quotes deleted : ' + CAST(@@ROWCOUNT AS NVARCHAR);
|
|
|
|
-- ===========================================================================
|
|
-- SUMMARY & COMMIT / ROLLBACK
|
|
-- ===========================================================================
|
|
PRINT '';
|
|
PRINT '============================================================';
|
|
|
|
IF @DryRun = 1
|
|
BEGIN
|
|
PRINT 'DRY RUN complete — rolling back. No data was changed.';
|
|
PRINT 'Set @DryRun = 0 and run again to apply the deletes.';
|
|
ROLLBACK TRANSACTION;
|
|
END
|
|
ELSE
|
|
BEGIN
|
|
PRINT 'Purge complete — committing.';
|
|
COMMIT TRANSACTION;
|
|
END
|