import { createHash } from 'node:crypto'; import { MigrationInterface, QueryRunner } from 'typeorm'; import { F31_INSTALLATION_FAMILIES, F31_UNIVERSAL_FINDINGS, } from '../../reference-data/f3-1-inventory-excel'; const INSTALLATION_OTHER_CODE = 'F31-INST-OTRO'; function subOtherCode(parentCode: string): string { return `F31-SUB-OTRO-${createHash('sha1').update(parentCode).digest('hex').slice(0, 12).toUpperCase()}`; } export class PhaseF31OtherInventoryFamilies1789844800000 implements MigrationInterface { name = 'PhaseF31OtherInventoryFamilies1789844800000'; public async up(queryRunner: QueryRunner): Promise { await queryRunner.query(` INSERT INTO inventory_families( code,name,level,legacy_type_code,information_labels,source_reference,is_active ) VALUES ($1::varchar,'Otro / no catalogado','INSTALLATION',NULL,'[]'::jsonb, 'SYSTEM:F3.1:OTHER',true) ON CONFLICT (code) DO UPDATE SET name=EXCLUDED.name,is_active=true,updated_at=CURRENT_TIMESTAMP `, [INSTALLATION_OTHER_CODE]); for (const parent of F31_INSTALLATION_FAMILIES) { const code = subOtherCode(parent.code); await queryRunner.query(` INSERT INTO inventory_families( code,name,level,legacy_type_code,information_labels,source_reference,is_active ) VALUES ($1::varchar,'Otro / no catalogado','SUBINSTALLATION',NULL,'[]'::jsonb, $2::varchar,true) ON CONFLICT (code) DO UPDATE SET name=EXCLUDED.name,is_active=true,updated_at=CURRENT_TIMESTAMP `, [code, `SYSTEM:F3.1:OTHER:${parent.code}`]); await queryRunner.query(` INSERT INTO inventory_family_parent_rules(child_family_id,parent_family_id) SELECT child.id,parent.id FROM inventory_families child JOIN inventory_families parent ON parent.code=$2::varchar WHERE child.code=$1::varchar ON CONFLICT (child_family_id) DO UPDATE SET parent_family_id=EXCLUDED.parent_family_id `, [code, parent.code]); } // Si la Instalación misma es "Otro", también necesita una opción "Otro" hija. const rootSubOther = subOtherCode(INSTALLATION_OTHER_CODE); await queryRunner.query(` INSERT INTO inventory_families( code,name,level,legacy_type_code,information_labels,source_reference,is_active ) VALUES ($1::varchar,'Otro / no catalogado','SUBINSTALLATION',NULL,'[]'::jsonb, 'SYSTEM:F3.1:OTHER:F31-INST-OTRO',true) ON CONFLICT (code) DO UPDATE SET name=EXCLUDED.name,is_active=true,updated_at=CURRENT_TIMESTAMP `, [rootSubOther]); await queryRunner.query(` INSERT INTO inventory_family_parent_rules(child_family_id,parent_family_id) SELECT child.id,parent.id FROM inventory_families child JOIN inventory_families parent ON parent.code=$2::varchar WHERE child.code=$1::varchar ON CONFLICT (child_family_id) DO UPDATE SET parent_family_id=EXCLUDED.parent_family_id `, [rootSubOther, INSTALLATION_OTHER_CODE]); const otherCodes = [ INSTALLATION_OTHER_CODE, ...F31_INSTALLATION_FAMILIES.map((parent) => subOtherCode(parent.code)), rootSubOther, ]; for (const familyCode of otherCodes) { for (const title of F31_UNIVERSAL_FINDINGS) { await queryRunner.query(` INSERT INTO finding_catalog_item_inventory_families(catalog_item_id,inventory_family_id) SELECT item.id,family.id FROM finding_catalog_items item JOIN finding_categories category ON category.id=item.category_id CROSS JOIN inventory_families family WHERE lower(category.code)='app26r2' AND lower(btrim(item.title))=lower(btrim($2::text)) AND family.code=$1::varchar ON CONFLICT (catalog_item_id,inventory_family_id) DO NOTHING `, [familyCode, title]); } } } public async down(queryRunner: QueryRunner): Promise { const codes = [ INSTALLATION_OTHER_CODE, ...F31_INSTALLATION_FAMILIES.map((parent) => subOtherCode(parent.code)), subOtherCode(INSTALLATION_OTHER_CODE), ]; await queryRunner.query(` DELETE FROM inventory_families WHERE code=ANY($1::varchar[]) AND NOT EXISTS (SELECT 1 FROM assets asset WHERE asset.inventory_family_id=inventory_families.id) `, [codes]); } }