149 lines
5.9 KiB
PL/PgSQL
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;
|