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); res.status(201).json(anomaly);
}catch (error){ }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( const anomaly = await service.changeStatus(
req.params.id as string, req.params.id as string,
req.body req.body.status
); );
if(!anomaly) { if(!anomaly) {
@ -130,9 +132,12 @@ export class AnomalyController{
){ ){
try{ try{
// Usuario autenticado
const user = (req as any).user;
const anomaly = await service.close( const anomaly = await service.close(
req.params.id as string, req.params.id as string,
req.body.resolvedBy, user.id,
req.body.comments req.body.comments
); );
@ -143,6 +148,7 @@ export class AnomalyController{
}); });
} }
res.json(anomaly);
}catch (error) { }catch (error) {
res.status(500).json({ res.status(500).json({
@ -261,6 +267,4 @@ export class AnomalyController{
} }
} }
} }

View File

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

View File

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

View File

@ -8,13 +8,15 @@ const controller = new AnomalyController();
anomalyRouter.get("/", authMiddleware, controller.getAll); anomalyRouter.get("/", authMiddleware, controller.getAll);
anomalyRouter.get("/:id", authMiddleware, controller.getById);
anomalyRouter.get("/status/:status", authMiddleware, controller.getByStatus); 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); anomalyRouter.post("/", authMiddleware, controller.create);

View File

@ -1,24 +1,22 @@
import mongoose from "mongoose";
import anomalyModel from "./anomaly.model"; import anomalyModel from "./anomaly.model";
import { IAnomaly } from "./anomaly.interface"; import { IAnomaly } from "./anomaly.interface";
export class AnomalyService{ export class AnomalyService{
//Crear anomalía
async create(
data:IAnomaly
){
const anomaly = new anomalyModel(data);
return await anomaly.save();
}
//Obtener anomalía //Obtener anomalía
async getAll() { async getAll() {
return await anomalyModel return await anomalyModel
.find() .find()
.populate("reportedBy") .populate(
.populate("resolvedBy") "reportedBy",
"userName"
)
.populate(
"resolvedBy",
"userName"
)
.sort({ .sort({
createdAt:-1 createdAt:-1
}); });
@ -30,15 +28,68 @@ export class AnomalyService{
){ ){
return await anomalyModel return await anomalyModel
.findById(id) .findById(id)
.populate("reportedBy") .populate(
.populate("resolvedBy") "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 //Actualizar
async update( async update(
id:string, id:string,
data:Partial<IAnomaly> 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( return await anomalyModel.findByIdAndUpdate(
id, id,
data, data,
@ -51,18 +102,51 @@ export class AnomalyService{
//Cambiar estado //Cambiar estado
async changeStatus( async changeStatus(
id:string, id: string,
status:string status: string
){ ) {
return await anomalyModel.findByIdAndUpdate(
id, // Buscar la anomalía
{ const anomaly = await anomalyModel.findById(id);
status
}, if (!anomaly) {
{ return null;
new:true }
}
); // 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 //Cerrar anomalía
@ -70,20 +154,33 @@ export class AnomalyService{
async close( async close(
id:string, id:string,
resolvedBy:string, resolvedBy:string,
comments?:String comments?:string
){ ){
return await anomalyModel.findByIdAndUpdate( const anomaly = await anomalyModel.findById(id);
id,
{ if(!anomaly){
status:"CERRADA", return null;
resolvedBy, }
resolvedDate: new Date(),
comments if(anomaly.status === "CERRADA"){
}, throw new Error(
{ "La anomalía ya está cerrada."
new:true );
} }
);
// 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( async getByStatus(
@ -123,5 +220,4 @@ export class AnomalyService{
){ ){
return await anomalyModel.findByIdAndDelete(id); return await anomalyModel.findByIdAndDelete(id);
} }
} }