78 lines
2.5 KiB
TypeScript
78 lines
2.5 KiB
TypeScript
import { Injectable, NotFoundException } from '@nestjs/common';
|
|
import { DataSource } from 'typeorm';
|
|
|
|
export interface InspectionPreventiveCandidate {
|
|
id: string;
|
|
code: string;
|
|
name: string;
|
|
typeName: string;
|
|
}
|
|
|
|
@Injectable()
|
|
export class InspectionPreventiveCandidatesService {
|
|
constructor(private readonly dataSource: DataSource) {}
|
|
|
|
async list(visitId: string, search?: string): Promise<{ data: InspectionPreventiveCandidate[] }> {
|
|
const [context] = (await this.dataSource.query(`
|
|
SELECT
|
|
visit.operational_area_id AS "operationalAreaId",
|
|
COALESCE(visit.scope_asset_id, visit.operational_area_id) AS "scopeAssetId"
|
|
FROM inspection_visits visit
|
|
WHERE visit.id = $1::uuid
|
|
`, [visitId])) as Array<{
|
|
operationalAreaId: string | null;
|
|
scopeAssetId: string | null;
|
|
}>;
|
|
|
|
if (!context) {
|
|
throw new NotFoundException({
|
|
code: 'INSPECTION_VISIT_NOT_FOUND',
|
|
message: 'Visita de inspección no encontrada',
|
|
});
|
|
}
|
|
|
|
if (!context.operationalAreaId || !context.scopeAssetId) return { data: [] };
|
|
|
|
const term = search?.trim().slice(0, 200) ?? '';
|
|
const rows = (await this.dataSource.query(`
|
|
WITH RECURSIVE scope_tree AS (
|
|
SELECT root.id
|
|
FROM assets root
|
|
WHERE root.id = $2::uuid
|
|
UNION ALL
|
|
SELECT child.id
|
|
FROM assets child
|
|
INNER JOIN scope_tree parent_scope ON parent_scope.id = child.parent_id
|
|
)
|
|
SELECT
|
|
asset.id,
|
|
asset.code,
|
|
asset.name,
|
|
asset_type.name AS "typeName"
|
|
FROM scope_tree
|
|
INNER JOIN assets asset ON asset.id = scope_tree.id
|
|
INNER JOIN asset_types asset_type ON asset_type.id = asset.asset_type_id
|
|
WHERE asset.id <> $2::uuid
|
|
AND asset.operational_area_id = $3::uuid
|
|
AND asset.information_status <> 'INACTIVE'
|
|
AND lower(asset_type.code) IN ('instalacion', 'subinstalacion')
|
|
AND NOT EXISTS (
|
|
SELECT 1
|
|
FROM inspection_visit_assets linked
|
|
WHERE linked.visit_id = $1::uuid
|
|
AND linked.asset_id = asset.id
|
|
)
|
|
AND (
|
|
$4::text = ''
|
|
OR asset.code ILIKE '%' || $4::text || '%'
|
|
OR asset.name ILIKE '%' || $4::text || '%'
|
|
OR COALESCE(asset.common_name, '') ILIKE '%' || $4::text || '%'
|
|
)
|
|
ORDER BY asset_type.name, asset.name, asset.code
|
|
LIMIT 100
|
|
`, [visitId, context.scopeAssetId, context.operationalAreaId, term])) as InspectionPreventiveCandidate[];
|
|
|
|
return { data: rows };
|
|
}
|
|
}
|