-- ============================================================ -- Lookup Table Migration Verification Script -- ============================================================ -- This script verifies that the enum-to-lookup migration was successful -- and that all data integrity has been preserved. -- -- Run this against the PowderCoatingDb database -- ============================================================ PRINT '========================================'; PRINT 'LOOKUP TABLE MIGRATION VERIFICATION'; PRINT '========================================'; PRINT ''; -- ============================================================ -- SECTION 1: Verify Lookup Tables Exist -- ============================================================ PRINT '1. CHECKING LOOKUP TABLES EXIST...'; PRINT ''; IF EXISTS (SELECT * FROM sys.tables WHERE name = 'JobStatusLookups') PRINT ' ✓ JobStatusLookups table exists' ELSE PRINT ' ✗ ERROR: JobStatusLookups table NOT found!'; IF EXISTS (SELECT * FROM sys.tables WHERE name = 'JobPriorityLookups') PRINT ' ✓ JobPriorityLookups table exists' ELSE PRINT ' ✗ ERROR: JobPriorityLookups table NOT found!'; IF EXISTS (SELECT * FROM sys.tables WHERE name = 'QuoteStatusLookups') PRINT ' ✓ QuoteStatusLookups table exists' ELSE PRINT ' ✗ ERROR: QuoteStatusLookups table NOT found!'; PRINT ''; -- ============================================================ -- SECTION 2: Verify Lookup Data Counts -- ============================================================ PRINT '2. CHECKING LOOKUP DATA COUNTS...'; PRINT ''; DECLARE @JobStatusCount INT; DECLARE @JobPriorityCount INT; DECLARE @QuoteStatusCount INT; DECLARE @CompanyCount INT; SELECT @CompanyCount = COUNT(*) FROM Companies WHERE IsDeleted = 0; SELECT @JobStatusCount = COUNT(*) FROM JobStatusLookups WHERE IsDeleted = 0; SELECT @JobPriorityCount = COUNT(*) FROM JobPriorityLookups WHERE IsDeleted = 0; SELECT @QuoteStatusCount = COUNT(*) FROM QuoteStatusLookups WHERE IsDeleted = 0; PRINT ' Companies: ' + CAST(@CompanyCount AS VARCHAR(10)); PRINT ' Job Statuses: ' + CAST(@JobStatusCount AS VARCHAR(10)) + ' (Expected: ' + CAST(@CompanyCount * 16 AS VARCHAR(10)) + ')'; PRINT ' Job Priorities: ' + CAST(@JobPriorityCount AS VARCHAR(10)) + ' (Expected: ' + CAST(@CompanyCount * 5 AS VARCHAR(10)) + ')'; PRINT ' Quote Statuses: ' + CAST(@QuoteStatusCount AS VARCHAR(10)) + ' (Expected: ' + CAST(@CompanyCount * 7 AS VARCHAR(10)) + ')'; IF @JobStatusCount = @CompanyCount * 16 PRINT ' ✓ Job Status count correct' ELSE PRINT ' ⚠ Job Status count mismatch (may be normal if custom statuses added)'; IF @JobPriorityCount = @CompanyCount * 5 PRINT ' ✓ Job Priority count correct' ELSE PRINT ' ⚠ Job Priority count mismatch (may be normal if custom priorities added)'; IF @QuoteStatusCount = @CompanyCount * 7 PRINT ' ✓ Quote Status count correct' ELSE PRINT ' ⚠ Quote Status count mismatch (may be normal if custom statuses added)'; PRINT ''; -- ============================================================ -- SECTION 3: Verify Foreign Key Relationships -- ============================================================ PRINT '3. CHECKING FOREIGN KEY RELATIONSHIPS...'; PRINT ''; -- Check Jobs table has FK to JobStatusLookup IF EXISTS (SELECT * FROM sys.foreign_keys WHERE name = 'FK_Jobs_JobStatusLookups_JobStatusId') PRINT ' ✓ Jobs.JobStatusId FK exists' ELSE PRINT ' ✗ ERROR: Jobs.JobStatusId FK NOT found!'; -- Check Jobs table has FK to JobPriorityLookup IF EXISTS (SELECT * FROM sys.foreign_keys WHERE name = 'FK_Jobs_JobPriorityLookups_JobPriorityId') PRINT ' ✓ Jobs.JobPriorityId FK exists' ELSE PRINT ' ✗ ERROR: Jobs.JobPriorityId FK NOT found!'; -- Check Quotes table has FK to QuoteStatusLookup IF EXISTS (SELECT * FROM sys.foreign_keys WHERE name = 'FK_Quotes_QuoteStatusLookups_QuoteStatusId') PRINT ' ✓ Quotes.QuoteStatusId FK exists' ELSE PRINT ' ✗ ERROR: Quotes.QuoteStatusId FK NOT found!'; PRINT ''; -- ============================================================ -- SECTION 4: Verify Data Integrity - No Orphaned Records -- ============================================================ PRINT '4. CHECKING DATA INTEGRITY...'; PRINT ''; -- Check for jobs with NULL status DECLARE @JobsWithNullStatus INT; SELECT @JobsWithNullStatus = COUNT(*) FROM Jobs WHERE JobStatusId IS NULL; IF @JobsWithNullStatus = 0 PRINT ' ✓ All Jobs have valid JobStatusId' ELSE PRINT ' ✗ ERROR: ' + CAST(@JobsWithNullStatus AS VARCHAR(10)) + ' Jobs have NULL JobStatusId!'; -- Check for jobs with NULL priority DECLARE @JobsWithNullPriority INT; SELECT @JobsWithNullPriority = COUNT(*) FROM Jobs WHERE JobPriorityId IS NULL; IF @JobsWithNullPriority = 0 PRINT ' ✓ All Jobs have valid JobPriorityId' ELSE PRINT ' ✗ ERROR: ' + CAST(@JobsWithNullPriority AS VARCHAR(10)) + ' Jobs have NULL JobPriorityId!'; -- Check for quotes with NULL status DECLARE @QuotesWithNullStatus INT; SELECT @QuotesWithNullStatus = COUNT(*) FROM Quotes WHERE QuoteStatusId IS NULL; IF @QuotesWithNullStatus = 0 PRINT ' ✓ All Quotes have valid QuoteStatusId' ELSE PRINT ' ✗ ERROR: ' + CAST(@QuotesWithNullStatus AS VARCHAR(10)) + ' Quotes have NULL QuoteStatusId!'; -- Check for orphaned job status references DECLARE @OrphanedJobStatuses INT; SELECT @OrphanedJobStatuses = COUNT(*) FROM Jobs j LEFT JOIN JobStatusLookups s ON j.JobStatusId = s.Id WHERE j.JobStatusId IS NOT NULL AND s.Id IS NULL; IF @OrphanedJobStatuses = 0 PRINT ' ✓ No orphaned JobStatus references' ELSE PRINT ' ✗ ERROR: ' + CAST(@OrphanedJobStatuses AS VARCHAR(10)) + ' Jobs reference non-existent statuses!'; PRINT ''; -- ============================================================ -- SECTION 5: Verify Unique Constraints -- ============================================================ PRINT '5. CHECKING UNIQUE CONSTRAINTS...'; PRINT ''; -- Check for duplicate status codes per company DECLARE @DuplicateJobStatuses INT; SELECT @DuplicateJobStatuses = COUNT(*) FROM ( SELECT CompanyId, StatusCode, COUNT(*) as cnt FROM JobStatusLookups WHERE IsDeleted = 0 GROUP BY CompanyId, StatusCode HAVING COUNT(*) > 1 ) AS dupes; IF @DuplicateJobStatuses = 0 PRINT ' ✓ No duplicate JobStatus codes per company' ELSE PRINT ' ✗ ERROR: ' + CAST(@DuplicateJobStatuses AS VARCHAR(10)) + ' duplicate JobStatus codes found!'; -- Check for duplicate priority codes per company DECLARE @DuplicateJobPriorities INT; SELECT @DuplicateJobPriorities = COUNT(*) FROM ( SELECT CompanyId, PriorityCode, COUNT(*) as cnt FROM JobPriorityLookups WHERE IsDeleted = 0 GROUP BY CompanyId, PriorityCode HAVING COUNT(*) > 1 ) AS dupes; IF @DuplicateJobPriorities = 0 PRINT ' ✓ No duplicate JobPriority codes per company' ELSE PRINT ' ✗ ERROR: ' + CAST(@DuplicateJobPriorities AS VARCHAR(10)) + ' duplicate JobPriority codes found!'; PRINT ''; -- ============================================================ -- SECTION 6: Verify Business Logic Flags -- ============================================================ PRINT '6. CHECKING BUSINESS LOGIC FLAGS...'; PRINT ''; -- Check that each company has exactly one "Approved" quote status DECLARE @CompaniesWithMultipleApproved INT; SELECT @CompaniesWithMultipleApproved = COUNT(*) FROM ( SELECT CompanyId, COUNT(*) as cnt FROM QuoteStatusLookups WHERE IsApprovedStatus = 1 AND IsDeleted = 0 GROUP BY CompanyId HAVING COUNT(*) > 1 ) AS dupes; IF @CompaniesWithMultipleApproved = 0 PRINT ' ✓ Each company has exactly one Approved quote status' ELSE PRINT ' ⚠ WARNING: ' + CAST(@CompaniesWithMultipleApproved AS VARCHAR(10)) + ' companies have multiple Approved statuses!'; -- Check that system-defined statuses exist DECLARE @SystemJobStatuses INT; SELECT @SystemJobStatuses = COUNT(DISTINCT StatusCode) FROM JobStatusLookups WHERE IsSystemDefined = 1 AND StatusCode IN ('PENDING', 'COMPLETED', 'CANCELLED'); IF @SystemJobStatuses = 3 PRINT ' ✓ System-defined job statuses exist (PENDING, COMPLETED, CANCELLED)' ELSE PRINT ' ⚠ WARNING: Missing system-defined job statuses'; PRINT ''; -- ============================================================ -- SECTION 7: Sample Data Display -- ============================================================ PRINT '7. SAMPLE LOOKUP DATA (First Company)...'; PRINT ''; -- Get first company ID DECLARE @FirstCompanyId INT; SELECT TOP 1 @FirstCompanyId = Id FROM Companies WHERE IsDeleted = 0 ORDER BY Id; PRINT ' Job Statuses for Company ' + CAST(@FirstCompanyId AS VARCHAR(10)) + ':'; SELECT ' ' + CAST(DisplayOrder AS VARCHAR(3)) + '. ' + DisplayName + ' (' + StatusCode + ') - ' + ColorClass + CASE WHEN IsSystemDefined = 1 THEN ' [SYSTEM]' ELSE '' END AS StatusInfo FROM JobStatusLookups WHERE CompanyId = @FirstCompanyId AND IsDeleted = 0 ORDER BY DisplayOrder; PRINT ''; PRINT ' Job Priorities for Company ' + CAST(@FirstCompanyId AS VARCHAR(10)) + ':'; SELECT ' ' + CAST(DisplayOrder AS VARCHAR(3)) + '. ' + DisplayName + ' (' + PriorityCode + ') - ' + ColorClass AS PriorityInfo FROM JobPriorityLookups WHERE CompanyId = @FirstCompanyId AND IsDeleted = 0 ORDER BY DisplayOrder; PRINT ''; PRINT ' Quote Statuses for Company ' + CAST(@FirstCompanyId AS VARCHAR(10)) + ':'; SELECT ' ' + CAST(DisplayOrder AS VARCHAR(3)) + '. ' + DisplayName + ' (' + StatusCode + ') - ' + ColorClass + CASE WHEN IsApprovedStatus = 1 THEN ' [APPROVED]' ELSE '' END + CASE WHEN IsConvertedStatus = 1 THEN ' [CONVERTED]' ELSE '' END AS StatusInfo FROM QuoteStatusLookups WHERE CompanyId = @FirstCompanyId AND IsDeleted = 0 ORDER BY DisplayOrder; PRINT ''; PRINT '========================================'; PRINT 'VERIFICATION COMPLETE'; PRINT '========================================';