F6.1 hotfix · jerarquía de Inspecciones y scope Yacimiento (#37)
Corrige creación de Inspección, separa Departamento→Área→Yacimiento, elimina el UPDATE oculto de checklist en lectura, integra Preparación para campo como etapa de Inspección, limita operaciones Android al Yacimiento, preserva scope en edición, auto-incluye Inventarios accionables, valida Operadora a plannedStartAt y recompila Android 0.15.2/vc24 con el ícono exacto de presentación.
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
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 };
|
||||
}
|
||||
|
||||
async operatorsForArea(
|
||||
areaId: string,
|
||||
at?: string,
|
||||
): Promise<{ data: InspectionPlanningHierarchyItem[] }> {
|
||||
await this.requireType(areaId, 'area', 'El Área seleccionada no es válida');
|
||||
const effectiveAt = at ? new Date(at) : new Date();
|
||||
if (!Number.isFinite(effectiveAt.getTime())) {
|
||||
throw new BadRequestException({
|
||||
code: 'INSPECTION_PLANNING_DATE_INVALID',
|
||||
message: 'La fecha de planificación no es válida',
|
||||
});
|
||||
}
|
||||
const data = await this.dataSource.query(`
|
||||
SELECT DISTINCT company.id, company.code, company.name
|
||||
FROM area_company_relations relation
|
||||
INNER JOIN assets company ON company.id=relation.company_id
|
||||
INNER JOIN asset_types type ON type.id=company.asset_type_id
|
||||
WHERE relation.area_id=$1::uuid
|
||||
AND relation.relation_role='OPERATOR'
|
||||
AND relation.valid_from <= $2::timestamptz
|
||||
AND (relation.valid_until IS NULL OR relation.valid_until > $2::timestamptz)
|
||||
AND type.operational_role='COMPANY'
|
||||
AND type.is_active=true
|
||||
AND company.information_status<>'INACTIVE'
|
||||
ORDER BY company.name, company.code
|
||||
`, [areaId, effectiveAt]) as InspectionPlanningHierarchyItem[];
|
||||
return { data };
|
||||
}
|
||||
|
||||
private async requireType(id: string, typeCode: string, message: string): Promise<void> {
|
||||
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 });
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user