diff --git a/api-v3/src/inspection-visits/field-findings.service.ts b/api-v3/src/inspection-visits/field-findings.service.ts index a96c9ad..9aa8218 100644 --- a/api-v3/src/inspection-visits/field-findings.service.ts +++ b/api-v3/src/inspection-visits/field-findings.service.ts @@ -2,7 +2,7 @@ import { BadRequestException, ConflictException, Injectable, NotFoundException } import { DataSource } from 'typeorm'; import type { AuthPrincipal, RequestWithContext } from '../common/http/request-context'; import type { CreateInspectionFindingDto } from '../inspection-findings/dto/create-inspection-finding.dto'; -import { FindingCatalogService } from '../inspection-findings/finding-catalog.service'; +import { F3FindingCatalogResolverService } from '../inspection-findings/f3-finding-catalog-resolver.service'; import { InspectionFindingsService } from '../inspection-findings/inspection-findings.service'; import { assertMobileInspector } from '../inspection-operations/mobile-inspector-policy'; import type { CreateFieldFindingDto } from './dto/create-field-finding.dto'; @@ -32,7 +32,7 @@ interface FieldFindingGate { export class FieldFindingsService { constructor( private readonly dataSource: DataSource, - private readonly catalog: FindingCatalogService, + private readonly catalog: F3FindingCatalogResolverService, private readonly findings: InspectionFindingsService, ) {} @@ -112,6 +112,8 @@ export class FieldFindingsService { company.code AS "companyCode", company.name AS "companyName", asset.id AS "assetId", + asset_type.code AS "assetTypeCode", + asset.inventory_family_id AS "inventoryFamilyId", asset.operational_area_id AS "assetAreaId", asset.operator_company_id AS "assetCompanyId", EXISTS ( @@ -158,6 +160,7 @@ export class FieldFindingsService { LEFT JOIN assets company ON company.id = visit.operator_company_id LEFT JOIN assets asset ON asset.id = $2::uuid AND asset.information_status <> 'INACTIVE' + LEFT JOIN asset_types asset_type ON asset_type.id=asset.asset_type_id WHERE visit.id = $1::uuid `, [visitId, assetId, principal.userId]) as Array<{ visitId: string; @@ -170,6 +173,8 @@ export class FieldFindingsService { companyCode: string | null; companyName: string | null; assetId: string | null; + assetTypeCode: string | null; + inventoryFamilyId: string | null; assetAreaId: string | null; assetCompanyId: string | null; assigned: boolean; @@ -186,7 +191,7 @@ export class FieldFindingsService { if (row.visitStatus !== 'IN_PROGRESS') { throw new ConflictException({ code: 'FIELD_FINDING_VISIT_NOT_IN_PROGRESS', - message: 'Los hallazgos sólo pueden registrarse cuando la inspección está en curso', + message: 'Los Hallazgos sólo pueden registrarse cuando la inspección está en curso', }); } if (!row.assigned) { @@ -207,6 +212,18 @@ export class FieldFindingsService { message: 'Registro de Inventario no encontrado', }); } + if (!['instalacion', 'subinstalacion'].includes(String(row.assetTypeCode).toLowerCase())) { + throw new BadRequestException({ + code: 'FIELD_FINDING_TECHNICAL_LEVEL_REQUIRED', + message: 'Los Hallazgos se registran sobre una Instalación o Subinstalación, no sobre Área/Yacimiento', + }); + } + if (!row.inventoryFamilyId) { + throw new ConflictException({ + code: 'FIELD_FINDING_FAMILY_REQUIRED', + message: 'La Instalación/Subinstalación debe tener una familia técnica u Otro antes de registrar Hallazgos', + }); + } if (row.assetAreaId !== row.areaId || row.assetCompanyId !== row.companyId) { throw new BadRequestException({ code: 'FIELD_FINDING_INVENTORY_OUTSIDE_CONTEXT', @@ -216,7 +233,7 @@ export class FieldFindingsService { if (!row.selected) { throw new ConflictException({ code: 'FIELD_FINDING_INVENTORY_NOT_SELECTED', - message: 'Seleccioná el Inventario dentro de la inspección antes de registrar un hallazgo', + message: 'Seleccioná el Inventario dentro de la inspección antes de registrar un Hallazgo', }); } @@ -230,7 +247,7 @@ export class FieldFindingsService { if (!readyForFinding) { throw new ConflictException({ code: 'FIELD_FINDING_CAPTURE_REQUIRED', - message: 'Antes del hallazgo, el Inventario creado en campo debe tener GPS y al menos una foto', + message: 'Antes del Hallazgo, el Inventario creado en campo debe tener GPS y al menos una foto', capture: { captureRequired, hasGeometry, creationGpsCaptured, fieldPhotoCount }, }); } @@ -264,7 +281,7 @@ export class FieldFindingsService { if (rows.length === 0) { throw new ConflictException({ code: 'FIELD_FINDING_DRAFT_ACT_REQUIRED', - message: 'La inspección no tiene un Acta borrador abierta para registrar hallazgos', + message: 'La inspección no tiene un Acta borrador abierta para registrar Hallazgos', }); } if (rows.length > 1) {