235 lines
7.1 KiB
PL/PgSQL
235 lines
7.1 KiB
PL/PgSQL
-- Unify asset categories onto item_categories / item_subcategories
|
|
-- Run against PostgreSQL before deploying BE that expects item_* FKs on assets.
|
|
--
|
|
-- Pre-check (optional):
|
|
-- SELECT ac.code, ac.name AS asset_cat, ic.name AS item_cat
|
|
-- FROM asset_categories ac
|
|
-- JOIN item_categories ic ON UPPER(ac.code) = UPPER(ic.code)
|
|
-- AND ac.deleted_at IS NULL AND ic.deleted_at IS NULL;
|
|
|
|
BEGIN;
|
|
|
|
-- =========================================================
|
|
-- 1) Extend item_categories with asset defaults
|
|
-- =========================================================
|
|
ALTER TABLE item_categories
|
|
ADD COLUMN IF NOT EXISTS code_prefix VARCHAR(10),
|
|
ADD COLUMN IF NOT EXISTS default_useful_life_years INT,
|
|
ADD COLUMN IF NOT EXISTS default_depreciation_method VARCHAR(20);
|
|
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (
|
|
SELECT 1 FROM pg_constraint WHERE conname = 'item_categories_code_prefix_key'
|
|
) THEN
|
|
ALTER TABLE item_categories
|
|
ADD CONSTRAINT item_categories_code_prefix_key UNIQUE (code_prefix);
|
|
END IF;
|
|
END $$;
|
|
|
|
-- =========================================================
|
|
-- 2) Mapping tables
|
|
-- =========================================================
|
|
CREATE TEMP TABLE map_asset_category (
|
|
old_asset_category_id BIGINT PRIMARY KEY,
|
|
new_item_category_id BIGINT NOT NULL
|
|
);
|
|
|
|
CREATE TEMP TABLE map_asset_subcategory (
|
|
old_asset_subcategory_id BIGINT PRIMARY KEY,
|
|
new_item_subcategory_id BIGINT NOT NULL
|
|
);
|
|
|
|
-- =========================================================
|
|
-- 3) Upsert asset_categories -> item_categories
|
|
-- =========================================================
|
|
WITH src AS (
|
|
SELECT *
|
|
FROM asset_categories
|
|
WHERE deleted_at IS NULL
|
|
),
|
|
matched AS (
|
|
SELECT s.id AS old_id, ic.id AS new_id
|
|
FROM src s
|
|
JOIN item_categories ic
|
|
ON UPPER(ic.code) = UPPER(s.code)
|
|
AND ic.deleted_at IS NULL
|
|
),
|
|
inserted AS (
|
|
INSERT INTO item_categories (
|
|
code, name, code_prefix,
|
|
default_useful_life_years, default_depreciation_method,
|
|
is_active, created_by, updated_by, created_at, updated_at
|
|
)
|
|
SELECT
|
|
s.code,
|
|
s.name,
|
|
s.code_prefix,
|
|
s.default_useful_life_years,
|
|
s.default_depreciation_method,
|
|
s.is_active,
|
|
s.created_by,
|
|
s.updated_by,
|
|
s.created_at,
|
|
s.updated_at
|
|
FROM src s
|
|
WHERE NOT EXISTS (
|
|
SELECT 1 FROM matched m WHERE m.old_id = s.id
|
|
)
|
|
RETURNING id, code
|
|
)
|
|
INSERT INTO map_asset_category (old_asset_category_id, new_item_category_id)
|
|
SELECT old_id, new_id FROM matched
|
|
UNION ALL
|
|
SELECT s.id, i.id
|
|
FROM src s
|
|
JOIN inserted i ON UPPER(i.code) = UPPER(s.code);
|
|
|
|
UPDATE item_categories ic
|
|
SET
|
|
code_prefix = COALESCE(ic.code_prefix, ac.code_prefix),
|
|
default_useful_life_years = COALESCE(ic.default_useful_life_years, ac.default_useful_life_years),
|
|
default_depreciation_method = COALESCE(ic.default_depreciation_method, ac.default_depreciation_method),
|
|
updated_at = NOW()
|
|
FROM asset_categories ac
|
|
JOIN map_asset_category m ON m.old_asset_category_id = ac.id
|
|
WHERE ic.id = m.new_item_category_id
|
|
AND ac.deleted_at IS NULL;
|
|
|
|
-- =========================================================
|
|
-- 4) Upsert asset_subcategories -> item_subcategories
|
|
-- =========================================================
|
|
WITH src AS (
|
|
SELECT asub.*, m.new_item_category_id
|
|
FROM asset_subcategories asub
|
|
JOIN map_asset_category m ON m.old_asset_category_id = asub.asset_category_id
|
|
WHERE asub.deleted_at IS NULL
|
|
),
|
|
matched AS (
|
|
SELECT s.id AS old_id, isub.id AS new_id
|
|
FROM src s
|
|
JOIN item_subcategories isub
|
|
ON UPPER(isub.code) = UPPER(s.code)
|
|
AND isub.deleted_at IS NULL
|
|
),
|
|
inserted AS (
|
|
INSERT INTO item_subcategories (
|
|
item_category_id, code, name,
|
|
is_active, created_by, updated_by, created_at, updated_at
|
|
)
|
|
SELECT
|
|
s.new_item_category_id,
|
|
s.code,
|
|
s.name,
|
|
s.is_active,
|
|
s.created_by,
|
|
s.updated_by,
|
|
s.created_at,
|
|
s.updated_at
|
|
FROM src s
|
|
WHERE NOT EXISTS (
|
|
SELECT 1 FROM matched m WHERE m.old_id = s.id
|
|
)
|
|
RETURNING id, code
|
|
)
|
|
INSERT INTO map_asset_subcategory (old_asset_subcategory_id, new_item_subcategory_id)
|
|
SELECT old_id, new_id FROM matched
|
|
UNION ALL
|
|
SELECT s.id, i.id
|
|
FROM src s
|
|
JOIN inserted i ON UPPER(i.code) = UPPER(s.code);
|
|
|
|
UPDATE item_subcategories isub
|
|
SET
|
|
item_category_id = mcat.new_item_category_id,
|
|
updated_at = NOW()
|
|
FROM map_asset_subcategory msub
|
|
JOIN asset_subcategories asub ON asub.id = msub.old_asset_subcategory_id
|
|
JOIN map_asset_category mcat ON mcat.old_asset_category_id = asub.asset_category_id
|
|
WHERE isub.id = msub.new_item_subcategory_id;
|
|
|
|
-- =========================================================
|
|
-- 5) Remap assets to item_* columns
|
|
-- =========================================================
|
|
ALTER TABLE assets
|
|
ADD COLUMN IF NOT EXISTS item_category_id BIGINT,
|
|
ADD COLUMN IF NOT EXISTS item_subcategory_id BIGINT;
|
|
|
|
UPDATE assets a
|
|
SET
|
|
item_category_id = mapped.new_item_category_id,
|
|
item_subcategory_id = mapped.new_item_subcategory_id,
|
|
updated_at = NOW()
|
|
FROM (
|
|
SELECT
|
|
a2.id AS asset_id,
|
|
mcat.new_item_category_id,
|
|
msub.new_item_subcategory_id
|
|
FROM assets a2
|
|
JOIN map_asset_category mcat
|
|
ON mcat.old_asset_category_id = a2.asset_category_id
|
|
LEFT JOIN map_asset_subcategory msub
|
|
ON msub.old_asset_subcategory_id = a2.asset_subcategory_id
|
|
) mapped
|
|
WHERE a.id = mapped.asset_id;
|
|
|
|
DO $$
|
|
DECLARE missing_count BIGINT;
|
|
BEGIN
|
|
SELECT COUNT(*) INTO missing_count
|
|
FROM assets
|
|
WHERE deleted_at IS NULL
|
|
AND item_category_id IS NULL;
|
|
|
|
IF missing_count > 0 THEN
|
|
RAISE EXCEPTION '% active assets could not be mapped to item_category_id', missing_count;
|
|
END IF;
|
|
END $$;
|
|
|
|
ALTER TABLE assets
|
|
ALTER COLUMN item_category_id SET NOT NULL;
|
|
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (
|
|
SELECT 1 FROM pg_constraint WHERE conname = 'assets_item_category_id_fkey'
|
|
) THEN
|
|
ALTER TABLE assets
|
|
ADD CONSTRAINT assets_item_category_id_fkey
|
|
FOREIGN KEY (item_category_id) REFERENCES item_categories (id);
|
|
END IF;
|
|
|
|
IF NOT EXISTS (
|
|
SELECT 1 FROM pg_constraint WHERE conname = 'assets_item_subcategory_id_fkey'
|
|
) THEN
|
|
ALTER TABLE assets
|
|
ADD CONSTRAINT assets_item_subcategory_id_fkey
|
|
FOREIGN KEY (item_subcategory_id) REFERENCES item_subcategories (id);
|
|
END IF;
|
|
END $$;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_assets_item_category_id ON assets (item_category_id);
|
|
CREATE INDEX IF NOT EXISTS idx_assets_item_subcategory_id ON assets (item_subcategory_id);
|
|
|
|
-- =========================================================
|
|
-- 6) Drop dependent views, then old asset category FKs / columns / tables
|
|
-- =========================================================
|
|
DROP VIEW IF EXISTS v_asset_expiry_alerts CASCADE;
|
|
DROP VIEW IF EXISTS v_asset_next_service CASCADE;
|
|
DROP VIEW IF EXISTS v_assets CASCADE;
|
|
|
|
ALTER TABLE assets DROP CONSTRAINT IF EXISTS assets_asset_category_id_fkey;
|
|
ALTER TABLE assets DROP CONSTRAINT IF EXISTS assets_asset_subcategory_id_fkey;
|
|
DROP INDEX IF EXISTS idx_assets_category_id;
|
|
DROP INDEX IF EXISTS idx_assets_subcategory_id;
|
|
ALTER TABLE assets DROP COLUMN IF EXISTS asset_category_id;
|
|
ALTER TABLE assets DROP COLUMN IF EXISTS asset_subcategory_id;
|
|
|
|
DROP TABLE IF EXISTS asset_subcategories;
|
|
DROP TABLE IF EXISTS asset_categories;
|
|
|
|
COMMIT;
|
|
|
|
-- Recreate reporting views after this script:
|
|
-- psql ... -f scripts/patch-assets-views.sql
|