import { MigrationInterface, QueryRunner } from 'typeorm'; export class PhaseF4DocumentNumbering1790046000000 implements MigrationInterface { name = 'PhaseF4DocumentNumbering1790046000000'; public async up(queryRunner: QueryRunner): Promise { await queryRunner.query(` DO $$ BEGIN IF EXISTS (SELECT 1 FROM inspection_acts WHERE act_number > 99999) THEN RAISE EXCEPTION 'F4 numbering requires inspection act numbers <= 99999'; END IF; IF EXISTS ( SELECT 1 FROM inspection_visits WHERE code ~ '^INS-[0-9]{4}-[0-9]{6}$' AND RIGHT(code, 6)::integer > 99999 ) THEN RAISE EXCEPTION 'F4 numbering requires inspection visit numbers <= 99999'; END IF; END $$ `); await queryRunner.query(` UPDATE inspection_visits SET code = 'INSP-' || LPAD(RIGHT(code, 6)::integer::text, 5, '0') || '-' || TO_CHAR( COALESCE(planned_start_at, created_at) AT TIME ZONE 'America/Argentina/Mendoza', 'DD-MM-YY' ), title = CASE WHEN title = inspection_visits.code THEN 'INSP-' || LPAD(RIGHT(inspection_visits.code, 6)::integer::text, 5, '0') || '-' || TO_CHAR( COALESCE(planned_start_at, created_at) AT TIME ZONE 'America/Argentina/Mendoza', 'DD-MM-YY' ) ELSE title END WHERE code ~ '^INS-[0-9]{4}-[0-9]{6}$' `); await queryRunner.query(` UPDATE inspection_acts SET code = 'ACT-' || LPAD(act_number::text, 5, '0') || '-' || TO_CHAR(occurred_at AT TIME ZONE 'America/Argentina/Mendoza', 'DD-MM-YY') `); await queryRunner.query(`DROP INDEX IF EXISTS uq_inspection_reports_year_number`); await queryRunner.query(` UPDATE inspection_reports report SET report_year = act.act_year, report_number = act.act_number, code = 'INF-' || LPAD(act.act_number::text, 5, '0') || '-' || TO_CHAR(act.occurred_at AT TIME ZONE 'America/Argentina/Mendoza', 'DD-MM-YY') FROM inspection_acts act WHERE act.id = report.act_id `); await queryRunner.query(` CREATE UNIQUE INDEX uq_inspection_reports_year_number ON inspection_reports(report_year, report_number) `); await queryRunner.query(` CREATE OR REPLACE FUNCTION dhv2_f4_set_act_code() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN IF NEW.act_number > 99999 THEN RAISE EXCEPTION 'Inspection Act sequence exhausted for F4 institutional format'; END IF; NEW.code := 'ACT-' || LPAD(NEW.act_number::text, 5, '0') || '-' || TO_CHAR(NEW.occurred_at AT TIME ZONE 'America/Argentina/Mendoza', 'DD-MM-YY'); RETURN NEW; END; $$ `); await queryRunner.query(` DROP TRIGGER IF EXISTS trg_dhv2_f4_set_act_code ON inspection_acts `); await queryRunner.query(` CREATE TRIGGER trg_dhv2_f4_set_act_code BEFORE INSERT OR UPDATE OF act_number, occurred_at ON inspection_acts FOR EACH ROW EXECUTE FUNCTION dhv2_f4_set_act_code() `); await queryRunner.query(` CREATE OR REPLACE FUNCTION dhv2_f4_set_report_code() RETURNS trigger LANGUAGE plpgsql AS $$ DECLARE source_act inspection_acts%ROWTYPE; BEGIN SELECT * INTO source_act FROM inspection_acts WHERE id = NEW.act_id; IF NOT FOUND THEN RAISE EXCEPTION 'Inspection Act not found for report %', NEW.act_id; END IF; IF source_act.act_number > 99999 THEN RAISE EXCEPTION 'Inspection Report sequence exhausted for F4 institutional format'; END IF; NEW.report_year := source_act.act_year; NEW.report_number := source_act.act_number; NEW.code := 'INF-' || LPAD(source_act.act_number::text, 5, '0') || '-' || TO_CHAR(source_act.occurred_at AT TIME ZONE 'America/Argentina/Mendoza', 'DD-MM-YY'); RETURN NEW; END; $$ `); await queryRunner.query(` DROP TRIGGER IF EXISTS trg_dhv2_f4_set_report_code ON inspection_reports `); await queryRunner.query(` CREATE TRIGGER trg_dhv2_f4_set_report_code BEFORE INSERT OR UPDATE OF act_id ON inspection_reports FOR EACH ROW EXECUTE FUNCTION dhv2_f4_set_report_code() `); } public async down(queryRunner: QueryRunner): Promise { await queryRunner.query(`DROP TRIGGER IF EXISTS trg_dhv2_f4_set_report_code ON inspection_reports`); await queryRunner.query(`DROP FUNCTION IF EXISTS dhv2_f4_set_report_code()`); await queryRunner.query(`DROP TRIGGER IF EXISTS trg_dhv2_f4_set_act_code ON inspection_acts`); await queryRunner.query(`DROP FUNCTION IF EXISTS dhv2_f4_set_act_code()`); } }