590 lines
27 KiB
PL/PgSQL
590 lines
27 KiB
PL/PgSQL
-- ============================================================
|
|
-- CRM Backend Refactor Migration
|
|
-- - UUID conversion for all IDs
|
|
-- - Multi-tenant branch support (alla, onvalla)
|
|
-- - Dual customer codes (CRM + ERP)
|
|
-- - Contact visibility and sharing
|
|
-- - Multi-currency quotations with revisions
|
|
-- ============================================================
|
|
|
|
BEGIN;
|
|
|
|
-- ============================================================
|
|
-- PHASE 1: Create Branches Table
|
|
-- ============================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS ms_branches (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
code TEXT NOT NULL UNIQUE,
|
|
name TEXT NOT NULL,
|
|
is_active BOOLEAN DEFAULT TRUE,
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
|
);
|
|
|
|
-- Insert initial branches
|
|
INSERT INTO ms_branches (code, name, is_active) VALUES
|
|
('alla', 'Alla Branch', TRUE),
|
|
('onvalla', 'Onvalla Branch', TRUE)
|
|
ON CONFLICT (code) DO NOTHING;
|
|
|
|
-- Create indexes
|
|
CREATE INDEX IF NOT EXISTS idx_branches_code ON ms_branches(code);
|
|
CREATE INDEX IF NOT EXISTS idx_branches_is_active ON ms_branches(is_active);
|
|
|
|
-- ============================================================
|
|
-- PHASE 2: Prepare Customers Table for UUID and Branch
|
|
-- ============================================================
|
|
|
|
-- Add new UUID column (will become primary key)
|
|
ALTER TABLE ms_customers ADD COLUMN IF NOT EXISTS new_id UUID DEFAULT gen_random_uuid();
|
|
|
|
-- Add branch ID column (nullable initially)
|
|
ALTER TABLE ms_customers ADD COLUMN IF NOT EXISTS branch_id UUID REFERENCES ms_branches(id);
|
|
|
|
-- Add dual customer code columns
|
|
ALTER TABLE ms_customers ADD COLUMN IF NOT EXISTS crm_customer_code TEXT;
|
|
ALTER TABLE ms_customers ADD COLUMN IF NOT EXISTS erp_customer_code TEXT;
|
|
|
|
-- Update credit limit to numeric if it's currently text
|
|
DO $$
|
|
BEGIN
|
|
IF EXISTS (
|
|
SELECT 1 FROM information_schema.columns
|
|
WHERE table_name = 'ms_customers'
|
|
AND column_name = 'credit_limit'
|
|
AND data_type = 'text'
|
|
) THEN
|
|
ALTER TABLE ms_customers ALTER COLUMN credit_limit TYPE NUMERIC(15,2) USING credit_limit::NUMERIC(15,2);
|
|
END IF;
|
|
END $$;
|
|
|
|
-- Update user references to UUID
|
|
ALTER TABLE ms_customers ADD COLUMN IF NOT EXISTS created_by_new UUID REFERENCES users(id);
|
|
ALTER TABLE ms_customers ADD COLUMN IF NOT EXISTS updated_by_new UUID REFERENCES users(id);
|
|
|
|
-- ============================================================
|
|
-- PHASE 3: Prepare Customer Contacts Table
|
|
-- ============================================================
|
|
|
|
-- Add new UUID column
|
|
ALTER TABLE ms_customer_contacts ADD COLUMN IF NOT EXISTS new_id UUID DEFAULT gen_random_uuid();
|
|
|
|
-- Add branch ID
|
|
ALTER TABLE ms_customer_contacts ADD COLUMN IF NOT EXISTS branch_id UUID REFERENCES ms_branches(id);
|
|
|
|
-- Update customer reference to UUID
|
|
ALTER TABLE ms_customer_contacts ADD COLUMN IF NOT EXISTS customer_id_new UUID REFERENCES ms_customers(id);
|
|
|
|
-- Add visibility fields
|
|
ALTER TABLE ms_customer_contacts ADD COLUMN IF NOT EXISTS is_public BOOLEAN DEFAULT FALSE;
|
|
|
|
-- Update user references to UUID
|
|
ALTER TABLE ms_customer_contacts ADD COLUMN IF NOT EXISTS created_by_new UUID REFERENCES users(id);
|
|
ALTER TABLE ms_customer_contacts ADD COLUMN IF NOT EXISTS updated_by_new UUID REFERENCES users(id);
|
|
|
|
-- ============================================================
|
|
-- PHASE 4: Create Contact Shares Table
|
|
-- ============================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS ms_customer_contact_shares (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
contact_id UUID NOT NULL REFERENCES ms_customer_contacts(id) ON DELETE CASCADE,
|
|
shared_with_user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
shared_by UUID NOT NULL REFERENCES users(id),
|
|
shared_at TIMESTAMP DEFAULT NOW(),
|
|
notes TEXT,
|
|
UNIQUE(contact_id, shared_with_user_id)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_contact_shares_contact ON ms_customer_contact_shares(contact_id);
|
|
CREATE INDEX IF NOT EXISTS idx_contact_shares_user ON ms_customer_contact_shares(shared_with_user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_contact_shares_shared_by ON ms_customer_contact_shares(shared_by);
|
|
|
|
-- ============================================================
|
|
-- PHASE 5: Prepare Quotations Table
|
|
-- ============================================================
|
|
|
|
-- Add new UUID column
|
|
ALTER TABLE tr_quotations ADD COLUMN IF NOT EXISTS new_id UUID DEFAULT gen_random_uuid();
|
|
|
|
-- Add branch ID
|
|
ALTER TABLE tr_quotations ADD COLUMN IF NOT EXISTS branch_id UUID REFERENCES ms_branches(id);
|
|
|
|
-- Add revision fields
|
|
ALTER TABLE tr_quotations ADD COLUMN IF NOT EXISTS revision_no INTEGER DEFAULT 1 NOT NULL;
|
|
ALTER TABLE tr_quotations ADD COLUMN IF NOT EXISTS parent_quotation_id_new UUID REFERENCES tr_quotations(id);
|
|
|
|
-- Add multi-currency fields
|
|
ALTER TABLE tr_quotations ADD COLUMN IF NOT EXISTS currency_code TEXT NOT NULL DEFAULT 'THB';
|
|
ALTER TABLE tr_quotations ADD COLUMN IF NOT EXISTS exchange_rate NUMERIC(12,6) NOT NULL DEFAULT 1.0;
|
|
ALTER TABLE tr_quotations ADD COLUMN IF NOT EXISTS base_currency_amount NUMERIC(15,2);
|
|
|
|
-- Update user references to UUID
|
|
ALTER TABLE tr_quotations ADD COLUMN IF NOT EXISTS salesman_id_new UUID REFERENCES users(id);
|
|
ALTER TABLE tr_quotations ADD COLUMN IF NOT EXISTS sale_admin_id_new UUID REFERENCES users(id);
|
|
ALTER TABLE tr_quotations ADD COLUMN IF NOT EXISTS created_by_new UUID REFERENCES users(id);
|
|
ALTER TABLE tr_quotations ADD COLUMN IF NOT EXISTS updated_by_new UUID REFERENCES users(id);
|
|
|
|
-- ============================================================
|
|
-- PHASE 6: Prepare Quotation Items Table
|
|
-- ============================================================
|
|
|
|
-- Add new UUID column
|
|
ALTER TABLE tr_quotations_items ADD COLUMN IF NOT EXISTS new_id UUID DEFAULT gen_random_uuid();
|
|
|
|
-- Update quotation reference to UUID
|
|
ALTER TABLE tr_quotations_items ADD COLUMN IF NOT EXISTS quotation_id_new UUID REFERENCES tr_quotations(id);
|
|
|
|
-- ============================================================
|
|
-- PHASE 7: Prepare Quotation Customers Table
|
|
-- ============================================================
|
|
|
|
-- Add new UUID column
|
|
ALTER TABLE tr_quotations_customers ADD COLUMN IF NOT EXISTS new_id UUID DEFAULT gen_random_uuid();
|
|
|
|
-- Update references to UUID
|
|
ALTER TABLE tr_quotations_customers ADD COLUMN IF NOT EXISTS quotation_id_new UUID REFERENCES tr_quotations(id);
|
|
ALTER TABLE tr_quotations_customers ADD COLUMN IF NOT EXISTS customer_id_new UUID REFERENCES ms_customers(id);
|
|
|
|
-- ============================================================
|
|
-- PHASE 8: Prepare Additional Quotation Tables for UUID
|
|
-- ============================================================
|
|
|
|
-- Quotation Followups
|
|
ALTER TABLE tr_quotations_followups ADD COLUMN IF NOT EXISTS new_id UUID DEFAULT gen_random_uuid();
|
|
ALTER TABLE tr_quotations_followups ADD COLUMN IF NOT EXISTS quotation_id_new UUID REFERENCES tr_quotations(id);
|
|
|
|
-- Quotation Attachments
|
|
ALTER TABLE tr_quotations_attachments ADD COLUMN IF NOT EXISTS new_id UUID DEFAULT gen_random_uuid();
|
|
ALTER TABLE tr_quotations_attachments ADD COLUMN IF NOT EXISTS quotation_id_new UUID REFERENCES tr_quotations(id);
|
|
|
|
-- Quotation Topics
|
|
ALTER TABLE tr_quotations_topics ADD COLUMN IF NOT EXISTS new_id UUID DEFAULT gen_random_uuid();
|
|
ALTER TABLE tr_quotations_topics ADD COLUMN IF NOT EXISTS quotation_id_new UUID REFERENCES tr_quotations(id);
|
|
|
|
-- Quotation Topic Items
|
|
ALTER TABLE tr_quotations_topic_items ADD COLUMN IF NOT EXISTS new_id UUID DEFAULT gen_random_uuid();
|
|
ALTER TABLE tr_quotations_topic_items ADD COLUMN IF NOT EXISTS topic_id_new UUID REFERENCES tr_quotations_topics(id);
|
|
|
|
-- Quotation Template Versions
|
|
ALTER TABLE ms_quotations_template_versions ADD COLUMN IF NOT EXISTS new_id UUID DEFAULT gen_random_uuid();
|
|
ALTER TABLE ms_quotations_template_versions ADD COLUMN IF NOT EXISTS template_id_new UUID REFERENCES ms_quotations_templates(id);
|
|
|
|
-- Quotation Template Mappings
|
|
ALTER TABLE ms_quotations_template_mappings ADD COLUMN IF NOT EXISTS new_id UUID DEFAULT gen_random_uuid();
|
|
ALTER TABLE ms_quotations_template_mappings ADD COLUMN IF NOT EXISTS template_version_id_new UUID REFERENCES ms_quotations_template_versions(id);
|
|
|
|
-- Quotation Template Table Columns
|
|
ALTER TABLE ms_quotations_template_table_columns ADD COLUMN IF NOT EXISTS new_id UUID DEFAULT gen_random_uuid();
|
|
ALTER TABLE ms_quotations_template_table_columns ADD COLUMN IF NOT EXISTS mapping_id_new UUID REFERENCES ms_quotations_template_mappings(id);
|
|
|
|
-- ============================================================
|
|
-- PHASE 9: Backfill Data
|
|
-- ============================================================
|
|
|
|
-- Get alla branch ID (will be used as default)
|
|
DO $$
|
|
DECLARE
|
|
alla_branch_id UUID;
|
|
BEGIN
|
|
SELECT id INTO alla_branch_id FROM ms_branches WHERE code = 'alla' LIMIT 1;
|
|
|
|
IF alla_branch_id IS NOT NULL THEN
|
|
-- Backfill customers branch_id (default to alla)
|
|
UPDATE ms_customers
|
|
SET branch_id = alla_branch_id
|
|
WHERE branch_id IS NULL;
|
|
|
|
-- Generate CRM customer codes from existing codes
|
|
UPDATE ms_customers
|
|
SET crm_customer_code = code
|
|
WHERE crm_customer_code IS NULL AND code IS NOT NULL;
|
|
|
|
-- Backfill customer_contacts branch_id and customer_id
|
|
UPDATE ms_customer_contacts cc
|
|
SET
|
|
branch_id = c.branch_id,
|
|
customer_id_new = c.new_id
|
|
FROM ms_customers c
|
|
WHERE cc.customer_id = c.id::INTEGER;
|
|
|
|
-- Backfill quotations branch_id
|
|
UPDATE tr_quotations q
|
|
SET branch_id = alla_branch_id
|
|
WHERE branch_id IS NULL;
|
|
|
|
-- Backfill quotation_items quotation_id
|
|
UPDATE tr_quotations_items qi
|
|
SET quotation_id_new = q.new_id
|
|
FROM tr_quotations q
|
|
WHERE qi.quotation_id = q.id::INTEGER;
|
|
|
|
-- Backfill quotation_customers references
|
|
UPDATE tr_quotations_customers qc
|
|
SET
|
|
quotation_id_new = q.new_id,
|
|
customer_id_new = c.new_id
|
|
FROM tr_quotations q
|
|
JOIN tr_quotations_customers qcc ON qcc.quotation_id = q.id::INTEGER
|
|
JOIN ms_customers c ON c.id::INTEGER = qcc.customer_id
|
|
WHERE qc.id = qcc.id;
|
|
|
|
-- Backfill quotation_followups
|
|
UPDATE tr_quotations_followups qf
|
|
SET quotation_id_new = q.new_id
|
|
FROM tr_quotations q
|
|
WHERE qf.quotation_id = q.id::INTEGER;
|
|
|
|
-- Backfill quotation_attachments
|
|
UPDATE tr_quotations_attachments qa
|
|
SET quotation_id_new = q.new_id
|
|
FROM tr_quotations q
|
|
WHERE qa.quotation_id = q.id::INTEGER;
|
|
|
|
-- Backfill quotation_topics
|
|
UPDATE tr_quotations_topics qt
|
|
SET quotation_id_new = q.new_id
|
|
FROM tr_quotations q
|
|
WHERE qt.quotation_id = q.id::INTEGER;
|
|
|
|
-- Backfill quotation_topic_items
|
|
UPDATE tr_quotations_topic_items qti
|
|
SET topic_id_new = qt.new_id
|
|
FROM tr_quotations_topics qt
|
|
WHERE qti.topic_id = qt.id::INTEGER;
|
|
|
|
-- Backfill quotation_template_versions
|
|
UPDATE ms_quotations_template_versions qtv
|
|
SET template_id_new = qt.id::UUID
|
|
FROM ms_quotations_templates qt
|
|
WHERE qtv.template_id = qt.id::INTEGER;
|
|
|
|
-- Backfill quotation_template_mappings
|
|
UPDATE ms_quotations_template_mappings qtm
|
|
SET template_version_id_new = qtv.new_id
|
|
FROM ms_quotations_template_versions qtv
|
|
WHERE qtm.template_version_id = qtv.id::INTEGER;
|
|
|
|
-- Backfill quotation_template_table_columns
|
|
UPDATE ms_quotations_template_table_columns qttc
|
|
SET mapping_id_new = qtm.new_id
|
|
FROM ms_quotations_template_mappings qtm
|
|
WHERE qttc.mapping_id = qtm.id::INTEGER;
|
|
END IF;
|
|
END $$;
|
|
|
|
-- ============================================================
|
|
-- PHASE 10: Swap Columns - Customers
|
|
-- ============================================================
|
|
|
|
-- Drop old constraints
|
|
ALTER TABLE ms_customers DROP CONSTRAINT IF EXISTS ms_customers_pkey;
|
|
ALTER TABLE ms_customers DROP CONSTRAINT IF EXISTS ms_customers_code_key;
|
|
|
|
-- Drop old columns
|
|
ALTER TABLE ms_customers DROP COLUMN IF EXISTS id CASCADE;
|
|
ALTER TABLE ms_customers DROP COLUMN IF EXISTS code CASCADE;
|
|
|
|
-- Rename new columns
|
|
ALTER TABLE ms_customers RENAME COLUMN new_id TO id;
|
|
ALTER TABLE ms_customers RENAME COLUMN crm_customer_code TO code;
|
|
|
|
-- Make new columns NOT NULL
|
|
ALTER TABLE ms_customers ALTER COLUMN id SET NOT NULL;
|
|
ALTER TABLE ms_customers ALTER COLUMN code SET NOT NULL;
|
|
ALTER TABLE ms_customers ALTER COLUMN branch_id SET NOT NULL;
|
|
|
|
-- Set default for UUID
|
|
ALTER TABLE ms_customers ALTER COLUMN id SET DEFAULT gen_random_uuid();
|
|
|
|
-- Add back constraints
|
|
ALTER TABLE ms_customers ADD PRIMARY KEY (id);
|
|
ALTER TABLE ms_customers ADD UNIQUE (code);
|
|
ALTER TABLE ms_customers ADD UNIQUE (erp_customer_code);
|
|
|
|
-- Drop old user reference columns
|
|
ALTER TABLE ms_customers DROP COLUMN IF EXISTS created_by CASCADE;
|
|
ALTER TABLE ms_customers DROP COLUMN IF EXISTS updated_by CASCADE;
|
|
|
|
-- Rename new user reference columns
|
|
ALTER TABLE ms_customers RENAME COLUMN created_by_new TO created_by;
|
|
ALTER TABLE ms_customers RENAME COLUMN updated_by_new TO updated_by;
|
|
|
|
-- ============================================================
|
|
-- PHASE 11: Swap Columns - Customer Contacts
|
|
-- ============================================================
|
|
|
|
-- Drop old constraints
|
|
ALTER TABLE ms_customer_contacts DROP CONSTRAINT IF EXISTS ms_customer_contacts_pkey;
|
|
ALTER TABLE ms_customer_contacts DROP CONSTRAINT IF EXISTS ms_customer_contacts_customer_id_fkey;
|
|
|
|
-- Drop old columns
|
|
ALTER TABLE ms_customer_contacts DROP COLUMN IF EXISTS id CASCADE;
|
|
ALTER TABLE ms_customer_contacts DROP COLUMN IF EXISTS customer_id CASCADE;
|
|
ALTER TABLE ms_customer_contacts DROP COLUMN IF EXISTS created_by CASCADE;
|
|
ALTER TABLE ms_customer_contacts DROP COLUMN IF EXISTS updated_by CASCADE;
|
|
|
|
-- Rename new columns
|
|
ALTER TABLE ms_customer_contacts RENAME COLUMN new_id TO id;
|
|
ALTER TABLE ms_customer_contacts RENAME COLUMN customer_id_new TO customer_id;
|
|
ALTER TABLE ms_customer_contacts RENAME COLUMN created_by_new TO created_by;
|
|
ALTER TABLE ms_customer_contacts RENAME COLUMN updated_by_new TO updated_by;
|
|
|
|
-- Make new columns NOT NULL
|
|
ALTER TABLE ms_customer_contacts ALTER COLUMN id SET NOT NULL;
|
|
ALTER TABLE ms_customer_contacts ALTER COLUMN customer_id SET NOT NULL;
|
|
ALTER TABLE ms_customer_contacts ALTER COLUMN created_by SET NOT NULL;
|
|
ALTER TABLE ms_customer_contacts ALTER COLUMN branch_id SET NOT NULL;
|
|
|
|
-- Set default for UUID
|
|
ALTER TABLE ms_customer_contacts ALTER COLUMN id SET DEFAULT gen_random_uuid();
|
|
|
|
-- Add back constraints
|
|
ALTER TABLE ms_customer_contacts ADD PRIMARY KEY (id);
|
|
|
|
-- ============================================================
|
|
-- PHASE 12: Swap Columns - Quotations
|
|
-- ============================================================
|
|
|
|
-- Drop old constraints
|
|
ALTER TABLE tr_quotations DROP CONSTRAINT IF EXISTS tr_quotations_pkey;
|
|
ALTER TABLE tr_quotations DROP CONSTRAINT IF EXISTS tr_quotations_code_key;
|
|
|
|
-- Drop old columns
|
|
ALTER TABLE tr_quotations DROP COLUMN IF EXISTS id CASCADE;
|
|
ALTER TABLE tr_quotations DROP COLUMN IF EXISTS code CASCADE;
|
|
ALTER TABLE tr_quotations DROP COLUMN IF EXISTS parent_quotation_id CASCADE;
|
|
ALTER TABLE tr_quotations DROP COLUMN IF EXISTS salesman_id CASCADE;
|
|
ALTER TABLE tr_quotations DROP COLUMN IF EXISTS sale_admin_id CASCADE;
|
|
ALTER TABLE tr_quotations DROP COLUMN IF EXISTS created_by CASCADE;
|
|
ALTER TABLE tr_quotations DROP COLUMN IF EXISTS updated_by CASCADE;
|
|
|
|
-- Rename new columns
|
|
ALTER TABLE tr_quotations RENAME COLUMN new_id TO id;
|
|
ALTER TABLE tr_quotations RENAME COLUMN parent_quotation_id_new TO parent_quotation_id;
|
|
ALTER TABLE tr_quotations RENAME COLUMN salesman_id_new TO salesman_id;
|
|
ALTER TABLE tr_quotations RENAME COLUMN sale_admin_id_new TO sale_admin_id;
|
|
ALTER TABLE tr_quotations RENAME COLUMN created_by_new TO created_by;
|
|
ALTER TABLE tr_quotations RENAME COLUMN updated_by_new TO updated_by;
|
|
|
|
-- Make new columns NOT NULL
|
|
ALTER TABLE tr_quotations ALTER COLUMN id SET NOT NULL;
|
|
ALTER TABLE tr_quotations ALTER COLUMN code SET NOT NULL;
|
|
ALTER TABLE tr_quotations ALTER COLUMN branch_id SET NOT NULL;
|
|
|
|
-- Set default for UUID
|
|
ALTER TABLE tr_quotations ALTER COLUMN id SET DEFAULT gen_random_uuid();
|
|
|
|
-- Add back constraints
|
|
ALTER TABLE tr_quotations ADD PRIMARY KEY (id);
|
|
-- Note: code is NO LONGER unique (multi-currency support)
|
|
|
|
-- ============================================================
|
|
-- PHASE 13: Swap Columns - Quotation Items
|
|
-- ============================================================
|
|
|
|
-- Drop old constraints
|
|
ALTER TABLE tr_quotations_items DROP CONSTRAINT IF EXISTS tr_quotations_items_pkey;
|
|
ALTER TABLE tr_quotations_items DROP CONSTRAINT IF EXISTS tr_quotations_items_quotation_id_fkey;
|
|
|
|
-- Drop old columns
|
|
ALTER TABLE tr_quotations_items DROP COLUMN IF EXISTS id CASCADE;
|
|
ALTER TABLE tr_quotations_items DROP COLUMN IF EXISTS quotation_id CASCADE;
|
|
|
|
-- Rename new columns
|
|
ALTER TABLE tr_quotations_items RENAME COLUMN new_id TO id;
|
|
ALTER TABLE tr_quotations_items RENAME COLUMN quotation_id_new TO quotation_id;
|
|
|
|
-- Make new columns NOT NULL
|
|
ALTER TABLE tr_quotations_items ALTER COLUMN id SET NOT NULL;
|
|
ALTER TABLE tr_quotations_items ALTER COLUMN quotation_id SET NOT NULL;
|
|
|
|
-- Set default for UUID
|
|
ALTER TABLE tr_quotations_items ALTER COLUMN id SET DEFAULT gen_random_uuid();
|
|
|
|
-- Add back constraints
|
|
ALTER TABLE tr_quotations_items ADD PRIMARY KEY (id);
|
|
|
|
-- ============================================================
|
|
-- PHASE 14: Swap Columns - Quotation Customers
|
|
-- ============================================================
|
|
|
|
-- Drop old constraints
|
|
ALTER TABLE tr_quotations_customers DROP CONSTRAINT IF EXISTS tr_quotations_customers_pkey;
|
|
ALTER TABLE tr_quotations_customers DROP CONSTRAINT IF EXISTS tr_quotations_customers_quotation_id_fkey;
|
|
ALTER TABLE tr_quotations_customers DROP CONSTRAINT IF EXISTS tr_quotations_customers_customer_id_fkey;
|
|
|
|
-- Drop old columns
|
|
ALTER TABLE tr_quotations_customers DROP COLUMN IF EXISTS id CASCADE;
|
|
ALTER TABLE tr_quotations_customers DROP COLUMN IF EXISTS quotation_id CASCADE;
|
|
ALTER TABLE tr_quotations_customers DROP COLUMN IF EXISTS customer_id CASCADE;
|
|
|
|
-- Rename new columns
|
|
ALTER TABLE tr_quotations_customers RENAME COLUMN new_id TO id;
|
|
ALTER TABLE tr_quotations_customers RENAME COLUMN quotation_id_new TO quotation_id;
|
|
ALTER TABLE tr_quotations_customers RENAME COLUMN customer_id_new TO customer_id;
|
|
|
|
-- Make new columns NOT NULL
|
|
ALTER TABLE tr_quotations_customers ALTER COLUMN id SET NOT NULL;
|
|
ALTER TABLE tr_quotations_customers ALTER COLUMN quotation_id SET NOT NULL;
|
|
ALTER TABLE tr_quotations_customers ALTER COLUMN customer_id SET NOT NULL;
|
|
|
|
-- Set default for UUID
|
|
ALTER TABLE tr_quotations_customers ALTER COLUMN id SET DEFAULT gen_random_uuid();
|
|
|
|
-- Add back constraints
|
|
ALTER TABLE tr_quotations_customers ADD PRIMARY KEY (id);
|
|
ALTER TABLE tr_quotations_customers ADD UNIQUE (quotation_id, customer_id, role);
|
|
|
|
-- ============================================================
|
|
-- PHASE 15: Swap Columns - Additional Tables
|
|
-- ============================================================
|
|
|
|
-- Quotation Followups
|
|
ALTER TABLE tr_quotations_followups DROP CONSTRAINT IF EXISTS tr_quotations_followups_pkey;
|
|
ALTER TABLE tr_quotations_followups DROP CONSTRAINT IF EXISTS tr_quotations_followups_quotation_id_fkey;
|
|
ALTER TABLE tr_quotations_followups DROP COLUMN IF EXISTS id CASCADE;
|
|
ALTER TABLE tr_quotations_followups DROP COLUMN IF EXISTS quotation_id CASCADE;
|
|
ALTER TABLE tr_quotations_followups RENAME COLUMN new_id TO id;
|
|
ALTER TABLE tr_quotations_followups RENAME COLUMN quotation_id_new TO quotation_id;
|
|
ALTER TABLE tr_quotations_followups ALTER COLUMN id SET NOT NULL;
|
|
ALTER TABLE tr_quotations_followups ALTER COLUMN quotation_id SET NOT NULL;
|
|
ALTER TABLE tr_quotations_followups ALTER COLUMN id SET DEFAULT gen_random_uuid();
|
|
ALTER TABLE tr_quotations_followups ADD PRIMARY KEY (id);
|
|
|
|
-- Quotation Attachments
|
|
ALTER TABLE tr_quotations_attachments DROP CONSTRAINT IF EXISTS tr_quotations_attachments_pkey;
|
|
ALTER TABLE tr_quotations_attachments DROP CONSTRAINT IF EXISTS tr_quotations_attachments_quotation_id_fkey;
|
|
ALTER TABLE tr_quotations_attachments DROP COLUMN IF EXISTS id CASCADE;
|
|
ALTER TABLE tr_quotations_attachments DROP COLUMN IF EXISTS quotation_id CASCADE;
|
|
ALTER TABLE tr_quotations_attachments RENAME COLUMN new_id TO id;
|
|
ALTER TABLE tr_quotations_attachments RENAME COLUMN quotation_id_new TO quotation_id;
|
|
ALTER TABLE tr_quotations_attachments ALTER COLUMN id SET NOT NULL;
|
|
ALTER TABLE tr_quotations_attachments ALTER COLUMN quotation_id SET NOT NULL;
|
|
ALTER TABLE tr_quotations_attachments ALTER COLUMN id SET DEFAULT gen_random_uuid();
|
|
ALTER TABLE tr_quotations_attachments ADD PRIMARY KEY (id);
|
|
|
|
-- Quotation Topics
|
|
ALTER TABLE tr_quotations_topics DROP CONSTRAINT IF EXISTS tr_quotations_topics_pkey;
|
|
ALTER TABLE tr_quotations_topics DROP CONSTRAINT IF EXISTS tr_quotations_topics_quotation_id_fkey;
|
|
ALTER TABLE tr_quotations_topics DROP COLUMN IF EXISTS id CASCADE;
|
|
ALTER TABLE tr_quotations_topics DROP COLUMN IF EXISTS quotation_id CASCADE;
|
|
ALTER TABLE tr_quotations_topics RENAME COLUMN new_id TO id;
|
|
ALTER TABLE tr_quotations_topics RENAME COLUMN quotation_id_new TO quotation_id;
|
|
ALTER TABLE tr_quotations_topics ALTER COLUMN id SET NOT NULL;
|
|
ALTER TABLE tr_quotations_topics ALTER COLUMN quotation_id SET NOT NULL;
|
|
ALTER TABLE tr_quotations_topics ALTER COLUMN id SET DEFAULT gen_random_uuid();
|
|
ALTER TABLE tr_quotations_topics ADD PRIMARY KEY (id);
|
|
|
|
-- Quotation Topic Items
|
|
ALTER TABLE tr_quotations_topic_items DROP CONSTRAINT IF EXISTS tr_quotations_topic_items_pkey;
|
|
ALTER TABLE tr_quotations_topic_items DROP CONSTRAINT IF EXISTS tr_quotations_topic_items_topic_id_fkey;
|
|
ALTER TABLE tr_quotations_topic_items DROP COLUMN IF EXISTS id CASCADE;
|
|
ALTER TABLE tr_quotations_topic_items DROP COLUMN IF EXISTS topic_id CASCADE;
|
|
ALTER TABLE tr_quotations_topic_items RENAME COLUMN new_id TO id;
|
|
ALTER TABLE tr_quotations_topic_items RENAME COLUMN topic_id_new TO topic_id;
|
|
ALTER TABLE tr_quotations_topic_items ALTER COLUMN id SET NOT NULL;
|
|
ALTER TABLE tr_quotations_topic_items ALTER COLUMN topic_id SET NOT NULL;
|
|
ALTER TABLE tr_quotations_topic_items ALTER COLUMN id SET DEFAULT gen_random_uuid();
|
|
ALTER TABLE tr_quotations_topic_items ADD PRIMARY KEY (id);
|
|
|
|
-- Quotation Template Versions
|
|
ALTER TABLE ms_quotations_template_versions DROP CONSTRAINT IF EXISTS ms_quotations_template_versions_pkey;
|
|
ALTER TABLE ms_quotations_template_versions DROP CONSTRAINT IF EXISTS ms_quotations_template_versions_template_id_fkey;
|
|
ALTER TABLE ms_quotations_template_versions DROP CONSTRAINT IF EXISTS id CASCADE;
|
|
ALTER TABLE ms_quotations_template_versions DROP CONSTRAINT IF EXISTS template_id CASCADE;
|
|
ALTER TABLE ms_quotations_template_versions RENAME COLUMN new_id TO id;
|
|
ALTER TABLE ms_quotations_template_versions RENAME COLUMN template_id_new TO template_id;
|
|
ALTER TABLE ms_quotations_template_versions ALTER COLUMN id SET NOT NULL;
|
|
ALTER TABLE ms_quotations_template_versions ALTER COLUMN template_id SET NOT NULL;
|
|
ALTER TABLE ms_quotations_template_versions ALTER COLUMN id SET DEFAULT gen_random_uuid();
|
|
ALTER TABLE ms_quotations_template_versions ADD PRIMARY KEY (id);
|
|
ALTER TABLE ms_quotations_template_versions ADD UNIQUE (template_id, version);
|
|
|
|
-- Quotation Template Mappings
|
|
ALTER TABLE ms_quotations_template_mappings DROP CONSTRAINT IF EXISTS ms_quotations_template_mappings_pkey;
|
|
ALTER TABLE ms_quotations_template_mappings DROP CONSTRAINT IF EXISTS ms_quotations_template_mappings_template_version_id_fkey;
|
|
ALTER TABLE ms_quotations_template_mappings DROP COLUMN IF EXISTS id CASCADE;
|
|
ALTER TABLE ms_quotations_template_mappings DROP COLUMN IF EXISTS template_version_id CASCADE;
|
|
ALTER TABLE ms_quotations_template_mappings RENAME COLUMN new_id TO id;
|
|
ALTER TABLE ms_quotations_template_mappings RENAME COLUMN template_version_id_new TO template_version_id;
|
|
ALTER TABLE ms_quotations_template_mappings ALTER COLUMN id SET NOT NULL;
|
|
ALTER TABLE ms_quotations_template_mappings ALTER COLUMN template_version_id SET NOT NULL;
|
|
ALTER TABLE ms_quotations_template_mappings ALTER COLUMN id SET DEFAULT gen_random_uuid();
|
|
ALTER TABLE ms_quotations_template_mappings ADD PRIMARY KEY (id);
|
|
|
|
-- Quotation Template Table Columns
|
|
ALTER TABLE ms_quotations_template_table_columns DROP CONSTRAINT IF EXISTS ms_quotations_template_table_columns_pkey;
|
|
ALTER TABLE ms_quotations_template_table_columns DROP CONSTRAINT IF EXISTS ms_quotations_template_table_columns_mapping_id_fkey;
|
|
ALTER TABLE ms_quotations_template_table_columns DROP COLUMN IF EXISTS id CASCADE;
|
|
ALTER TABLE ms_quotations_template_table_columns DROP COLUMN IF EXISTS mapping_id CASCADE;
|
|
ALTER TABLE ms_quotations_template_table_columns RENAME COLUMN new_id TO id;
|
|
ALTER TABLE ms_quotations_template_table_columns RENAME COLUMN mapping_id_new TO mapping_id;
|
|
ALTER TABLE ms_quotations_template_table_columns ALTER COLUMN id SET NOT NULL;
|
|
ALTER TABLE ms_quotations_template_table_columns ALTER COLUMN mapping_id SET NOT NULL;
|
|
ALTER TABLE ms_quotations_template_table_columns ALTER COLUMN id SET DEFAULT gen_random_uuid();
|
|
ALTER TABLE ms_quotations_template_table_columns ADD PRIMARY KEY (id);
|
|
|
|
-- ============================================================
|
|
-- PHASE 16: Create Quotation Contacts Snapshot Table
|
|
-- ============================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS tr_quotation_contacts (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
quotation_id UUID NOT NULL REFERENCES tr_quotations(id) ON DELETE CASCADE,
|
|
contact_id UUID REFERENCES ms_customer_contacts(id),
|
|
snapshot_name TEXT NOT NULL,
|
|
snapshot_email TEXT,
|
|
snapshot_phone TEXT,
|
|
snapshot_mobile TEXT,
|
|
snapshot_position TEXT,
|
|
snapshot_department TEXT,
|
|
created_at TIMESTAMP DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_quotation_contact ON tr_quotation_contacts(quotation_id);
|
|
CREATE INDEX IF NOT EXISTS idx_quotation_contact_contact ON tr_quotation_contacts(contact_id);
|
|
|
|
-- ============================================================
|
|
-- PHASE 17: Create Performance Indexes
|
|
-- ============================================================
|
|
|
|
-- Customers indexes
|
|
CREATE INDEX IF NOT EXISTS idx_customers_branch ON ms_customers(branch_id);
|
|
CREATE INDEX IF NOT EXISTS idx_customers_status ON ms_customers(customer_status);
|
|
CREATE INDEX IF NOT EXISTS idx_customers_crm_code ON ms_customers(code);
|
|
CREATE INDEX IF NOT EXISTS idx_customers_erp_code ON ms_customers(erp_customer_code);
|
|
|
|
-- Customer contacts indexes
|
|
CREATE INDEX IF NOT EXISTS idx_contacts_customer ON ms_customer_contacts(customer_id);
|
|
CREATE INDEX IF NOT EXISTS idx_contacts_branch ON ms_customer_contacts(branch_id);
|
|
CREATE INDEX IF NOT EXISTS idx_contacts_created_by ON ms_customer_contacts(created_by);
|
|
CREATE INDEX IF NOT EXISTS idx_contacts_visibility ON ms_customer_contacts(customer_id, created_by);
|
|
|
|
-- Quotations indexes
|
|
CREATE INDEX IF NOT EXISTS idx_quotations_branch ON tr_quotations(branch_id);
|
|
CREATE INDEX IF NOT EXISTS idx_quotations_code ON tr_quotations(code);
|
|
CREATE INDEX IF NOT EXISTS idx_quotation_status ON tr_quotations(status);
|
|
CREATE INDEX IF NOT EXISTS idx_quotation_date ON tr_quotations(quotation_date);
|
|
CREATE INDEX IF NOT EXISTS idx_quotations_branch_status ON tr_quotations(branch_id, status);
|
|
CREATE INDEX IF NOT EXISTS idx_quotations_revision ON tr_quotations(parent_quotation_id);
|
|
|
|
-- Quotation items indexes
|
|
CREATE INDEX IF NOT EXISTS idx_qitem_quotation_id ON tr_quotations_items(quotation_id);
|
|
|
|
-- Quotation customers indexes
|
|
CREATE INDEX IF NOT EXISTS idx_qcust_quotation_id ON tr_quotations_customers(quotation_id);
|
|
CREATE INDEX IF NOT EXISTS idx_qcust_customer_id ON tr_quotations_customers(customer_id);
|
|
|
|
COMMIT;
|
|
|
|
-- ============================================================
|
|
-- MIGRATION COMPLETE
|
|
-- ============================================================
|
|
|
|
-- Verify migration
|
|
-- SELECT COUNT(*) FROM ms_branches;
|
|
-- SELECT COUNT(*) FROM ms_customers WHERE branch_id IS NULL;
|
|
-- SELECT COUNT(*) FROM tr_quotations WHERE branch_id IS NULL;
|
|
-- SELECT COUNT(*) FROM ms_customer_contacts WHERE branch_id IS NULL; |