diff --git a/api-v3/src/inspection-visits/inspection-planning-hierarchy.service.ts b/api-v3/src/inspection-visits/inspection-planning-hierarchy.service.ts new file mode 100644 index 0000000..53651be --- /dev/null +++ b/api-v3/src/inspection-visits/inspection-planning-hierarchy.service.ts @@ -0,0 +1,80 @@ +import { BadRequestException, Injectable } from '@nestjs/common'; +import { DataSource } from 'typeorm'; + +export interface InspectionPlanningHierarchyItem { + id: string; + code: string; + name: string; +} + +@Injectable() +export class InspectionPlanningHierarchyService { + constructor(private readonly dataSource: DataSource) {} + + async departments(): Promise<{ data: InspectionPlanningHierarchyItem[] }> { + const data = await this.dataSource.query(` + SELECT department.id, department.code, department.name + FROM assets department + INNER JOIN asset_types type ON type.id=department.asset_type_id + WHERE lower(type.code)='departamento' + AND type.is_active=true + AND department.information_status<>'INACTIVE' + AND EXISTS ( + SELECT 1 + FROM assets area + INNER JOIN asset_types area_type ON area_type.id=area.asset_type_id + WHERE area.parent_id=department.id + AND lower(area_type.code)='area' + AND area.information_status<>'INACTIVE' + ) + ORDER BY department.name, department.code + `) as InspectionPlanningHierarchyItem[]; + return { data }; + } + + async areasForDepartment(departmentId: string): Promise<{ data: InspectionPlanningHierarchyItem[] }> { + await this.requireType(departmentId, 'departamento', 'El Departamento seleccionado no es válido'); + const data = await this.dataSource.query(` + SELECT area.id, area.code, area.name + FROM assets area + INNER JOIN asset_types type ON type.id=area.asset_type_id + WHERE area.parent_id=$1::uuid + AND lower(type.code)='area' + AND type.is_active=true + AND area.information_status<>'INACTIVE' + ORDER BY area.name, area.code + `, [departmentId]) as InspectionPlanningHierarchyItem[]; + return { data }; + } + + async yacimientosForArea(areaId: string): Promise<{ data: InspectionPlanningHierarchyItem[] }> { + await this.requireType(areaId, 'area', 'El Área seleccionada no es válida'); + const data = await this.dataSource.query(` + SELECT yacimiento.id, yacimiento.code, yacimiento.name + FROM assets yacimiento + INNER JOIN asset_types type ON type.id=yacimiento.asset_type_id + WHERE yacimiento.parent_id=$1::uuid + AND lower(type.code)='yacimiento' + AND type.is_active=true + AND yacimiento.information_status<>'INACTIVE' + ORDER BY yacimiento.name, yacimiento.code + `, [areaId]) as InspectionPlanningHierarchyItem[]; + return { data }; + } + + private async requireType(id: string, typeCode: string, message: string): Promise { + const [row] = await this.dataSource.query(` + SELECT 1 + FROM assets asset + INNER JOIN asset_types type ON type.id=asset.asset_type_id + WHERE asset.id=$1::uuid + AND lower(type.code)=lower($2) + AND type.is_active=true + AND asset.information_status<>'INACTIVE' + LIMIT 1 + `, [id, typeCode]) as Array<{ '?column?': number }>; + if (!row) { + throw new BadRequestException({ code: 'INSPECTION_PLANNING_HIERARCHY_INVALID', message }); + } + } +}