bmc_hub/migrations/178_customer_vendor_links.sql

82 lines
3.1 KiB
MySQL
Raw Normal View History

-- Migration 178: Link customers and vendors (many-to-many)
-- Created: 2026-04-13
CREATE TABLE IF NOT EXISTS customer_vendor_links (
id SERIAL PRIMARY KEY,
customer_id INTEGER NOT NULL REFERENCES customers(id) ON DELETE CASCADE,
vendor_id INTEGER NOT NULL REFERENCES vendors(id) ON DELETE CASCADE,
relationship_type VARCHAR(50) NOT NULL DEFAULT 'supplier',
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE (customer_id, vendor_id)
);
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1
FROM pg_constraint
WHERE conname = 'chk_customer_vendor_links_relationship_type'
) THEN
ALTER TABLE customer_vendor_links
ADD CONSTRAINT chk_customer_vendor_links_relationship_type
CHECK (relationship_type IN ('supplier', 'reseller', 'partner'));
END IF;
END $$;
CREATE INDEX IF NOT EXISTS idx_customer_vendor_links_customer_id
ON customer_vendor_links(customer_id);
CREATE INDEX IF NOT EXISTS idx_customer_vendor_links_vendor_id
ON customer_vendor_links(vendor_id);
CREATE INDEX IF NOT EXISTS idx_customer_vendor_links_relationship_type
ON customer_vendor_links(relationship_type);
CREATE OR REPLACE FUNCTION update_customer_vendor_links_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS trg_customer_vendor_links_updated_at ON customer_vendor_links;
CREATE TRIGGER trg_customer_vendor_links_updated_at
BEFORE UPDATE ON customer_vendor_links
FOR EACH ROW
EXECUTE FUNCTION update_customer_vendor_links_updated_at();
-- Backfill links by CVR first (most reliable)
INSERT INTO customer_vendor_links (customer_id, vendor_id, relationship_type)
SELECT c.id, v.id, 'supplier'
FROM customers c
JOIN vendors v
ON regexp_replace(COALESCE(c.cvr_number, ''), '\\D', '', 'g') <> ''
AND regexp_replace(COALESCE(v.cvr_number, ''), '\\D', '', 'g') <> ''
AND regexp_replace(COALESCE(c.cvr_number, ''), '\\D', '', 'g') = regexp_replace(COALESCE(v.cvr_number, ''), '\\D', '', 'g')
ON CONFLICT (customer_id, vendor_id) DO NOTHING;
-- Backfill by exact email match
INSERT INTO customer_vendor_links (customer_id, vendor_id, relationship_type)
SELECT c.id, v.id, 'supplier'
FROM customers c
JOIN vendors v
ON LOWER(TRIM(COALESCE(c.email, ''))) <> ''
AND LOWER(TRIM(COALESCE(v.email, ''))) <> ''
AND LOWER(TRIM(COALESCE(c.email, ''))) = LOWER(TRIM(COALESCE(v.email, '')))
ON CONFLICT (customer_id, vendor_id) DO NOTHING;
-- Backfill by exact normalized name match
INSERT INTO customer_vendor_links (customer_id, vendor_id, relationship_type)
SELECT c.id, v.id, 'supplier'
FROM customers c
JOIN vendors v
ON LOWER(TRIM(COALESCE(c.name, ''))) <> ''
AND LOWER(TRIM(COALESCE(v.name, ''))) <> ''
AND LOWER(TRIM(COALESCE(c.name, ''))) = LOWER(TRIM(COALESCE(v.name, '')))
ON CONFLICT (customer_id, vendor_id) DO NOTHING;
COMMENT ON TABLE customer_vendor_links IS 'Links customers to vendors to support entities that are both customer and supplier';
COMMENT ON COLUMN customer_vendor_links.relationship_type IS 'supplier, reseller, or partner';