Modificación módulo aprobaciones y adición de validaciones

This commit is contained in:
2026-07-04 15:55:43 +00:00
parent 432e89110c
commit 4d6f2004ac
5 changed files with 159 additions and 58 deletions

View File

@ -61,7 +61,9 @@ export class AnomalyController{
res.status(201).json(anomaly);
}catch (error){
res
res.status(500).json({
message:"Error al crear anomalía"
});
}
}
@ -103,7 +105,7 @@ export class AnomalyController{
const anomaly = await service.changeStatus(
req.params.id as string,
req.body
req.body.status
);
if(!anomaly) {
@ -130,9 +132,12 @@ export class AnomalyController{
){
try{
// Usuario autenticado
const user = (req as any).user;
const anomaly = await service.close(
req.params.id as string,
req.body.resolvedBy,
user.id,
req.body.comments
);
@ -143,6 +148,7 @@ export class AnomalyController{
});
}
res.json(anomaly);
}catch (error) {
res.status(500).json({
@ -260,7 +266,5 @@ export class AnomalyController{
})
}
}
}
}

View File

@ -1,18 +1,18 @@
import { ObjectId } from "mongoose";
import { Types } from "mongoose";
export interface IAnomaly {
_id?: ObjectId;
_id?: Types.ObjectId;
vehicleId: number;
employeeId?: number;
fuelRequestId?: ObjectId;
fuelRequestId?: Types.ObjectId;
externalInvoiceId?: ObjectId;
externalInvoiceId?: Types.ObjectId;
lpgId?: ObjectId;
lpgId?: Types.ObjectId;
anomalyType:
| "RENDIMIENTO BAJO"
@ -30,9 +30,9 @@ export interface IAnomaly {
| "SISTEMA"
| "USUARIO";
reportedBy?: ObjectId;
reportedBy?: Types.ObjectId;
resolvedBy?: ObjectId;
resolvedBy?: Types.ObjectId;
resolvedDate?: Date;
@ -42,5 +42,4 @@ export interface IAnomaly {
| "CERRADA";
comments?: string;
}

View File

@ -21,7 +21,7 @@ const anomalySchema = new mongoose.Schema({
ref:"ExternalInvoice"
},
lpg:{
lpgId:{
type:mongoose.Schema.Types.ObjectId,
ref:"LPG"
},

View File

@ -8,13 +8,15 @@ const controller = new AnomalyController();
anomalyRouter.get("/", authMiddleware, controller.getAll);
anomalyRouter.get("/:id", authMiddleware, controller.getById);
anomalyRouter.get("/status/:status", authMiddleware, controller.getByStatus);
anomalyRouter.get("/vehicleId/:vehicleId", authMiddleware, controller.getByVehicle);
anomalyRouter.get("/vehicle/:vehicleId", authMiddleware, controller.getByVehicle);
anomalyRouter.get("/employeeId/:employeeId", authMiddleware, controller.getByEmployee);
anomalyRouter.get("/employee/:employeeId", authMiddleware, controller.getByEmployee);
anomalyRouter.get("/type/:type", authMiddleware, controller.getByType);
anomalyRouter.get("/:id", authMiddleware, controller.getById);
anomalyRouter.post("/", authMiddleware, controller.create);

View File

@ -1,24 +1,22 @@
import mongoose from "mongoose";
import anomalyModel from "./anomaly.model";
import { IAnomaly } from "./anomaly.interface";
export class AnomalyService{
//Crear anomalía
async create(
data:IAnomaly
){
const anomaly = new anomalyModel(data);
return await anomaly.save();
}
//Obtener anomalía
async getAll() {
return await anomalyModel
.find()
.populate("reportedBy")
.populate("resolvedBy")
.populate(
"reportedBy",
"userName"
)
.populate(
"resolvedBy",
"userName"
)
.sort({
createdAt:-1
});
@ -30,15 +28,68 @@ export class AnomalyService{
){
return await anomalyModel
.findById(id)
.populate("reportedBy")
.populate("resolvedBy")
.populate(
"reportedBy",
"userName"
)
.populate(
"resolvedBy",
"userName"
)
}
//Crear anomalía
async create(
data:IAnomaly
){
// Validar vehículo
if (!data.vehicleId) {
throw new Error(
"Debe indicar un vehículo."
);
}
// Validar descripción
if (!data.description?.trim()) {
throw new Error(
"La descripción es obligatoria."
);
}
// Estado inicial
data.status = "ABIERTA";
// Si no viene quién la detectó,
// se considera reportada por un usuario.
data.detectedBy = data.detectedBy ?? "USUARIO";
const anomaly = new anomalyModel(data);
return await anomaly.save();
}
//Actualizar
async update(
id:string,
data:Partial<IAnomaly>
){
const anomaly =
await anomalyModel.findById(id);
if(!anomaly){
return null;
}
if(anomaly.status==="CERRADA"){
throw new Error(
"No es posible modificar una anomalía cerrada."
);
}
return await anomalyModel.findByIdAndUpdate(
id,
data,
@ -51,18 +102,51 @@ export class AnomalyService{
//Cambiar estado
async changeStatus(
id:string,
status:string
){
return await anomalyModel.findByIdAndUpdate(
id,
{
status
},
{
new:true
}
);
id: string,
status: string
) {
// Buscar la anomalía
const anomaly = await anomalyModel.findById(id);
if (!anomaly) {
return null;
}
// Validar estados permitidos
if (
![
"ABIERTA",
"EN PROCESO",
"CERRADA"
].includes(status)
) {
throw new Error(
"Estado inválido."
);
}
// No permitir cambiar una anomalía ya cerrada
if (anomaly.status === "CERRADA") {
throw new Error(
"La anomalía ya está cerrada."
);
}
// Obligar a usar el método close()
if (status === "CERRADA") {
throw new Error(
"Para cerrar una anomalía utilice el método Close."
);
}
// Actualizar estado
anomaly.status = status as
"ABIERTA" | "EN PROCESO";
await anomaly.save();
return anomaly;
}
//Cerrar anomalía
@ -70,20 +154,33 @@ export class AnomalyService{
async close(
id:string,
resolvedBy:string,
comments?:String
comments?:string
){
return await anomalyModel.findByIdAndUpdate(
id,
{
status:"CERRADA",
resolvedBy,
resolvedDate: new Date(),
comments
},
{
new:true
}
);
const anomaly = await anomalyModel.findById(id);
if(!anomaly){
return null;
}
if(anomaly.status === "CERRADA"){
throw new Error(
"La anomalía ya está cerrada."
);
}
// Actualizar la anomalía
anomaly.status = "CERRADA";
anomaly.resolvedBy =
new mongoose.Types.ObjectId(resolvedBy);
anomaly.resolvedDate = new Date();
anomaly.comments = comments ?? "";
await anomaly.save();
return anomaly;
}
async getByStatus(
@ -123,5 +220,4 @@ export class AnomalyService{
){
return await anomalyModel.findByIdAndDelete(id);
}
}