F2.3: crear servicio de hallazgos desde Inventario
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
import { ConflictException, Injectable } from '@nestjs/common';
|
||||
import { DataSource } from 'typeorm';
|
||||
import type { AuthPrincipal, RequestWithContext } from '../common/http/request-context';
|
||||
import { FindingCatalogService } from '../inspection-findings/finding-catalog.service';
|
||||
import type { CreateInspectionFindingDto } from '../inspection-findings/dto/create-inspection-finding.dto';
|
||||
import { InspectionFindingsService } from '../inspection-findings/inspection-findings.service';
|
||||
import type { CreateFieldFindingDto } from './dto/create-field-finding.dto';
|
||||
import { FieldInventoryService } from './field-inventory.service';
|
||||
|
||||
interface DraftActRow {
|
||||
id: string;
|
||||
code: string;
|
||||
status: string;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class FieldFindingsService {
|
||||
constructor(
|
||||
private readonly dataSource: DataSource,
|
||||
private readonly fieldInventory: FieldInventoryService,
|
||||
private readonly catalog: FindingCatalogService,
|
||||
private readonly findings: InspectionFindingsService,
|
||||
) {}
|
||||
|
||||
async options(visitId: string, assetId: string, principal: AuthPrincipal) {
|
||||
const gate = await this.fieldInventory.requireReadyForFinding(visitId, assetId, principal);
|
||||
const act = await this.requireDraftAct(visitId);
|
||||
const [catalog, findings] = await Promise.all([
|
||||
this.catalog.listApplicableForAsset(assetId, {}),
|
||||
this.findings.listForAct(act.id),
|
||||
]);
|
||||
|
||||
return {
|
||||
context: gate.context,
|
||||
act,
|
||||
capture: gate.capture,
|
||||
catalog,
|
||||
findings: findings.data.filter((finding) => finding.assetId === assetId),
|
||||
canAddAnother: true,
|
||||
};
|
||||
}
|
||||
|
||||
async list(visitId: string, assetId: string, principal: AuthPrincipal) {
|
||||
const gate = await this.fieldInventory.requireReadyForFinding(visitId, assetId, principal);
|
||||
const act = await this.requireDraftAct(visitId);
|
||||
const findings = await this.findings.listForAct(act.id);
|
||||
return {
|
||||
context: gate.context,
|
||||
act,
|
||||
capture: gate.capture,
|
||||
data: findings.data.filter((finding) => finding.assetId === assetId),
|
||||
};
|
||||
}
|
||||
|
||||
async create(
|
||||
visitId: string,
|
||||
assetId: string,
|
||||
dto: CreateFieldFindingDto,
|
||||
principal: AuthPrincipal,
|
||||
request: RequestWithContext,
|
||||
) {
|
||||
const gate = await this.fieldInventory.requireReadyForFinding(visitId, assetId, principal);
|
||||
const act = await this.requireDraftAct(visitId);
|
||||
const payload: CreateInspectionFindingDto = {
|
||||
assetId,
|
||||
catalogItemId: dto.catalogItemId ?? null,
|
||||
customTitle: dto.customTitle ?? null,
|
||||
customLegalBasis: dto.customLegalBasis ?? null,
|
||||
description: dto.description,
|
||||
severity: dto.severity,
|
||||
correctionDueOn: dto.correctionDueOn ?? null,
|
||||
};
|
||||
const finding = await this.findings.create(act.id, payload, principal, request);
|
||||
return {
|
||||
context: gate.context,
|
||||
act,
|
||||
capture: gate.capture,
|
||||
finding,
|
||||
canAddAnother: true,
|
||||
};
|
||||
}
|
||||
|
||||
private async requireDraftAct(visitId: string): Promise<DraftActRow> {
|
||||
const rows = await this.dataSource.query(`
|
||||
SELECT id, code, status
|
||||
FROM inspection_acts
|
||||
WHERE visit_id = $1::uuid
|
||||
AND status = 'DRAFT'
|
||||
ORDER BY created_at DESC, id DESC
|
||||
LIMIT 2
|
||||
`, [visitId]) as DraftActRow[];
|
||||
|
||||
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',
|
||||
});
|
||||
}
|
||||
if (rows.length > 1) {
|
||||
throw new ConflictException({
|
||||
code: 'FIELD_FINDING_MULTIPLE_DRAFT_ACTS',
|
||||
message: 'La inspección tiene más de un Acta borrador. Debe resolverse antes de continuar',
|
||||
});
|
||||
}
|
||||
return rows[0];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user