erp_be/scripts/patch-locations-merge.sql

149 lines
5.9 KiB
PL/PgSQL

-- Merge plants + warehouses into locations (type: plant | warehouse)
BEGIN;
CREATE TABLE IF NOT EXISTS locations (
id BIGSERIAL PRIMARY KEY,
type VARCHAR(20) NOT NULL CHECK (type IN ('plant', 'warehouse')),
code VARCHAR(30) NOT NULL,
name VARCHAR(150) NOT NULL,
parent_id BIGINT REFERENCES locations(id),
gstin VARCHAR(15),
address TEXT,
city VARCHAR(100),
state VARCHAR(100),
pincode VARCHAR(10),
phone VARCHAR(15),
location VARCHAR(200),
is_active BOOLEAN NOT NULL DEFAULT true,
created_by BIGINT,
updated_by BIGINT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
deleted_at TIMESTAMPTZ
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_locations_code_active
ON locations (code)
WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_locations_type ON locations (type);
CREATE INDEX IF NOT EXISTS idx_locations_parent_id ON locations (parent_id);
-- Migrate plants (preserve ids) when legacy table exists
DO $$
BEGIN
IF EXISTS (
SELECT 1 FROM information_schema.tables
WHERE table_schema = 'public' AND table_name = 'plants'
) THEN
INSERT INTO locations (
id, type, code, name, gstin, address, city, state, pincode, phone,
is_active, created_by, updated_by, created_at, updated_at, deleted_at
)
OVERRIDING SYSTEM VALUE
SELECT
id, 'plant', code, name, gstin, address, city, state, pincode, phone,
is_active, created_by, updated_by, created_at, updated_at, deleted_at
FROM plants
ON CONFLICT (id) DO NOTHING;
END IF;
END $$;
-- Migrate warehouses (preserve ids; plant_id -> parent_id)
DO $$
BEGIN
IF EXISTS (
SELECT 1 FROM information_schema.tables
WHERE table_schema = 'public' AND table_name = 'warehouses'
) THEN
INSERT INTO locations (
id, type, code, name, parent_id, location,
is_active, created_by, updated_by, created_at, updated_at, deleted_at
)
OVERRIDING SYSTEM VALUE
SELECT
id, 'warehouse', code, name, plant_id, location,
is_active, created_by, updated_by, created_at, updated_at, deleted_at
FROM warehouses
ON CONFLICT (id) DO NOTHING;
END IF;
END $$;
SELECT setval(
pg_get_serial_sequence('locations', 'id'),
GREATEST(COALESCE((SELECT MAX(id) FROM locations), 1), 1)
);
-- Drop FKs referencing plants / warehouses
DO $$
DECLARE r RECORD;
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'plants') THEN
FOR r IN
SELECT c.conname, c.conrelid::regclass AS tbl
FROM pg_constraint c
WHERE c.contype = 'f' AND c.confrelid = 'public.plants'::regclass
LOOP
EXECUTE format('ALTER TABLE %s DROP CONSTRAINT IF EXISTS %I', r.tbl, r.conname);
END LOOP;
END IF;
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'warehouses') THEN
FOR r IN
SELECT c.conname, c.conrelid::regclass AS tbl
FROM pg_constraint c
WHERE c.contype = 'f' AND c.confrelid = 'public.warehouses'::regclass
LOOP
EXECUTE format('ALTER TABLE %s DROP CONSTRAINT IF EXISTS %I', r.tbl, r.conname);
END LOOP;
END IF;
END $$;
-- Point existing FK columns to locations (idempotent)
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'users_plant_id_fkey') THEN
ALTER TABLE users ADD CONSTRAINT users_plant_id_fkey FOREIGN KEY (plant_id) REFERENCES locations(id);
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'assets_plant_id_fkey') THEN
ALTER TABLE assets ADD CONSTRAINT assets_plant_id_fkey FOREIGN KEY (plant_id) REFERENCES locations(id);
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'assets_warehouse_id_fkey') THEN
ALTER TABLE assets ADD CONSTRAINT assets_warehouse_id_fkey FOREIGN KEY (warehouse_id) REFERENCES locations(id);
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'purchase_orders_plant_id_fkey') THEN
ALTER TABLE purchase_orders ADD CONSTRAINT purchase_orders_plant_id_fkey FOREIGN KEY (plant_id) REFERENCES locations(id);
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'purchase_orders_warehouse_id_fkey') THEN
ALTER TABLE purchase_orders ADD CONSTRAINT purchase_orders_warehouse_id_fkey FOREIGN KEY (warehouse_id) REFERENCES locations(id);
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'grn_warehouse_id_fkey') THEN
ALTER TABLE grn ADD CONSTRAINT grn_warehouse_id_fkey FOREIGN KEY (warehouse_id) REFERENCES locations(id);
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'asset_transfers_from_plant_id_fkey') THEN
ALTER TABLE asset_transfers ADD CONSTRAINT asset_transfers_from_plant_id_fkey FOREIGN KEY (from_plant_id) REFERENCES locations(id);
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'asset_transfers_to_plant_id_fkey') THEN
ALTER TABLE asset_transfers ADD CONSTRAINT asset_transfers_to_plant_id_fkey FOREIGN KEY (to_plant_id) REFERENCES locations(id);
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'asset_transfers_from_warehouse_id_fkey') THEN
ALTER TABLE asset_transfers ADD CONSTRAINT asset_transfers_from_warehouse_id_fkey FOREIGN KEY (from_warehouse_id) REFERENCES locations(id);
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'asset_transfers_to_warehouse_id_fkey') THEN
ALTER TABLE asset_transfers ADD CONSTRAINT asset_transfers_to_warehouse_id_fkey FOREIGN KEY (to_warehouse_id) REFERENCES locations(id);
END IF;
END $$;
-- Drop views that depend on plants/warehouses, then drop legacy tables
DROP VIEW IF EXISTS v_purchase_orders CASCADE;
DROP VIEW IF EXISTS v_grn CASCADE;
DROP VIEW IF EXISTS v_assets CASCADE;
DROP VIEW IF EXISTS v_asset_expiry_alerts CASCADE;
DROP VIEW IF EXISTS v_asset_next_service CASCADE;
DROP TABLE IF EXISTS warehouses;
DROP TABLE IF EXISTS plants;
COMMIT;