From a521d0fec7c77bdcab11e027a1bc7c7b2e575e9a Mon Sep 17 00:00:00 2001 From: enlineawork Date: Mon, 7 Sep 2026 14:42:09 -0300 Subject: [PATCH] =?UTF-8?q?F3.1:=20resolver=20Hallazgos=20por=20familia=20?= =?UTF-8?q?t=C3=A9cnica?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../f3-finding-catalog-resolver.service.ts | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 api-v3/src/inspection-findings/f3-finding-catalog-resolver.service.ts diff --git a/api-v3/src/inspection-findings/f3-finding-catalog-resolver.service.ts b/api-v3/src/inspection-findings/f3-finding-catalog-resolver.service.ts new file mode 100644 index 0000000..1826bdd --- /dev/null +++ b/api-v3/src/inspection-findings/f3-finding-catalog-resolver.service.ts @@ -0,0 +1,97 @@ +import { Injectable, NotFoundException } from '@nestjs/common'; +import { DataSource } from 'typeorm'; +import type { ListFindingCatalogQueryDto } from './dto/list-finding-catalog-query.dto'; +import { FindingCatalogService } from './finding-catalog.service'; + +@Injectable() +export class F3FindingCatalogResolverService { + constructor( + private readonly dataSource: DataSource, + private readonly legacyCatalog: FindingCatalogService, + ) {} + + async listApplicableForAsset(assetId: string, query: ListFindingCatalogQueryDto) { + const [asset] = await this.dataSource.query(` + SELECT asset.id,asset.code,asset.name, + asset.inventory_family_id AS "familyId", + family.code AS "familyCode",family.name AS "familyName",family.level AS "familyLevel" + FROM assets asset + LEFT JOIN inventory_families family ON family.id=asset.inventory_family_id + WHERE asset.id=$1::uuid + `, [assetId]) as Array<{ + id: string; + code: string; + name: string; + familyId: string | null; + familyCode: string | null; + familyName: string | null; + familyLevel: string | null; + }>; + if (!asset) { + throw new NotFoundException({ code: 'ASSET_NOT_FOUND', message: 'Registro de Inventario no encontrado' }); + } + if (!asset.familyId) return this.legacyCatalog.listApplicableForAsset(assetId, query); + + const filters = [ + 'mapping.inventory_family_id=$1::uuid', + 'item.is_active=true', + 'category.is_active=true', + 'merge_record.source_item_id IS NULL', + ]; + const params: unknown[] = [asset.familyId]; + if (query.categoryId) { + params.push(query.categoryId); + filters.push(`category.id=$${params.length}::uuid`); + } + if (query.search?.trim()) { + params.push(`%${query.search.trim()}%`); + const token = `$${params.length}`; + filters.push(`(item.title ILIKE ${token} OR COALESCE(item.legal_basis,'') ILIKE ${token} OR COALESCE(item.glossary,'') ILIKE ${token})`); + } + + const where = filters.join(' AND '); + const [categories, items] = await Promise.all([ + this.dataSource.query(` + SELECT DISTINCT category.id,category.code,category.name,category.sort_order AS "sortOrder" + FROM finding_catalog_item_inventory_families mapping + JOIN finding_catalog_items item ON item.id=mapping.catalog_item_id + JOIN finding_categories category ON category.id=item.category_id + LEFT JOIN finding_catalog_item_merges merge_record ON merge_record.source_item_id=item.id + WHERE ${where} + ORDER BY category.sort_order,category.name,category.id + `, params), + this.dataSource.query(` + SELECT item.id,item.category_id AS "categoryId",item.code, + item.source_number AS "sourceNumber",item.title,item.legal_basis AS "legalBasis", + item.glossary,item.suggested_severity AS "suggestedSeverity",item.revision, + category.name AS "categoryName" + FROM finding_catalog_item_inventory_families mapping + JOIN finding_catalog_items item ON item.id=mapping.catalog_item_id + JOIN finding_categories category ON category.id=item.category_id + LEFT JOIN finding_catalog_item_merges merge_record ON merge_record.source_item_id=item.id + WHERE ${where} + ORDER BY category.sort_order,item.source_number,item.code + `, params), + ]); + + return { + asset: { id: asset.id, code: asset.code, name: asset.name }, + inventoryFamily: { + id: asset.familyId, + code: asset.familyCode, + name: asset.familyName, + level: asset.familyLevel, + }, + typeConfigured: true, + configurationReason: `F3.1 · Catálogo del Excel asociado a ${asset.familyName ?? 'la familia técnica'}`, + categories, + items, + other: { + enabled: true, + code: 'OTHER', + label: 'OTROS', + help: 'Usalo cuando el hallazgo no exista en la familia técnica. Se enviará una propuesta a revisión de oficina.', + }, + }; + } +}