From 432e89110c3197d8b4d423fad3a42deac3ec6f8d Mon Sep 17 00:00:00 2001 From: karol Date: Sat, 4 Jul 2026 14:40:16 +0000 Subject: [PATCH] =?UTF-8?q?Modificaci=C3=B3n=20CRUD=20m=C3=B3dulo=20aproba?= =?UTF-8?q?ciones?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/approvals/approval.controller.ts | 144 +++------ .../modules/approvals/approval.interface.ts | 11 +- .../src/modules/approvals/approval.model.ts | 5 +- .../src/modules/approvals/approval.service.ts | 287 +++++++----------- .../pump-reading/pumpReading.interface.ts | 27 +- backend/src/utils/requestNumber.ts | 6 +- 6 files changed, 193 insertions(+), 287 deletions(-) diff --git a/backend/src/modules/approvals/approval.controller.ts b/backend/src/modules/approvals/approval.controller.ts index e4fd41d..0cd3310 100644 --- a/backend/src/modules/approvals/approval.controller.ts +++ b/backend/src/modules/approvals/approval.controller.ts @@ -6,9 +6,8 @@ const service = new ApprovalService(); export class ApprovalController { - /** - * Obtener todas las aprobaciones - */ + //Obtener todas las aprobaciones + async getAll( req: Request, res: Response @@ -36,9 +35,8 @@ export class ApprovalController { } - /** - * Obtener aprobación por ID - */ + //Obtener aprobación por ID + async getById( req: Request, res: Response @@ -54,34 +52,26 @@ export class ApprovalController { if (!approval) { return res.status(404).json({ - message: - "Aprobación no encontrada" + message:"Aprobación no encontrada" }); } - res.json( - approval - ); + res.json(approval); - } - catch (error:any) { + } catch(error){ - console.error(error); - - res.status(500).json({ - message: "Error al aprobar solicitud", - error: error.message, - stack: error.stack - }); + res.status(500).json({ + message: "Error al obtener solicitud", + error + }); } } - /** - * Crear aprobación - */ + //Crear aprobación + async create( req: Request, res: Response @@ -89,8 +79,7 @@ export class ApprovalController { try { - const approval = - await service.create( + const approval = await service.create( req.body ); @@ -98,12 +87,9 @@ export class ApprovalController { approval ); - } - catch (error) { - + } catch (error) { res.status(500).json({ - message: - "Error al crear aprobación", + message:"Error al crear aprobación", error }); @@ -111,9 +97,8 @@ export class ApprovalController { } - /** - * Aprobar solicitud - */ + //Aprobar solicitud + async approve( req: Request, res: Response @@ -121,27 +106,20 @@ export class ApprovalController { try { - const approval = - await service.approve( + const approval = await service.approve( req.params.id as string, - req.body.approvedBy, - req.body.comments ); - res.json( - approval - ); + res.json(approval); - } - catch (error) { + } catch (error) { res.status(500).json({ - message: - "Error al aprobar solicitud", + message:"Error al aprobar solicitud", error }); @@ -149,9 +127,8 @@ export class ApprovalController { } - /** - * Rechazar solicitud - */ + //Rechazar solicitud + async reject( req: Request, res: Response @@ -159,27 +136,18 @@ export class ApprovalController { try { - const approval = - await service.reject( - + const approval = await service.reject( req.params.id as string, - req.body.approvedBy, - req.body.comments - ); - res.json( - approval - ); + res.json(approval); - } - catch (error) { + }catch (error) { res.status(500).json({ - message: - "Error al rechazar solicitud", + message:"Error al rechazar solicitud", error }); @@ -187,9 +155,8 @@ export class ApprovalController { } - /** - * Buscar por estado - */ + //Buscar por estado + async getByStatus( req: Request, res: Response @@ -197,21 +164,16 @@ export class ApprovalController { try { - const approvals = - await service.getByStatus( + const approvals = await service.getByStatus( req.params.status as string ); - res.json( - approvals - ); + res.json(approvals); - } - catch (error) { + } catch (error) { res.status(500).json({ - message: - "Error al buscar aprobaciones", + message:"Error al buscar aprobaciones", error }); @@ -219,9 +181,8 @@ export class ApprovalController { } - /** - * Buscar por tipo de referencia - */ + //Buscar por tipo de referencia + async getByReferenceType( req: Request, res: Response @@ -229,21 +190,16 @@ export class ApprovalController { try { - const approvals = - await service.getByReferenceType( + const approvals = await service.getByReferenceType( req.params.referenceType as string ); - res.json( - approvals - ); + res.json(approvals); - } - catch (error) { + } catch (error) { res.status(500).json({ - message: - "Error al buscar aprobaciones", + message:"Error al buscar aprobaciones", error }); @@ -251,9 +207,8 @@ export class ApprovalController { } - /** - * Eliminar aprobación - */ + // Eliminar aprobación + async delete( req: Request, res: Response @@ -261,31 +216,26 @@ export class ApprovalController { try { - const approval = - await service.delete( + const approval = await service.delete( req.params.id as string ); if (!approval) { return res.status(404).json({ - message: - "Aprobación no encontrada" + message:"Aprobación no encontrada" }); } res.json({ - message: - "Aprobación eliminada correctamente" + message: "Aprobación eliminada correctamente" }); - } - catch (error) { + } catch (error) { res.status(500).json({ - message: - "Error al eliminar aprobación", + message:"Error al eliminar aprobación", error }); diff --git a/backend/src/modules/approvals/approval.interface.ts b/backend/src/modules/approvals/approval.interface.ts index 33744b6..78cd457 100644 --- a/backend/src/modules/approvals/approval.interface.ts +++ b/backend/src/modules/approvals/approval.interface.ts @@ -1,16 +1,19 @@ -import { ObjectId } from "mongoose"; +import { Types } from "mongoose"; export interface IApproval { referenceType:string; - referenceId:ObjectId; + referenceId:Types.ObjectId; - approvedBy?:ObjectId; + approvedBy?:Types.ObjectId; approvedDate?:Date; - status:string; + status: + | "PENDIENTE" + | "APROBADO" + | "RECHAZADO"; comments?:string; diff --git a/backend/src/modules/approvals/approval.model.ts b/backend/src/modules/approvals/approval.model.ts index 7f843d0..2adcc07 100644 --- a/backend/src/modules/approvals/approval.model.ts +++ b/backend/src/modules/approvals/approval.model.ts @@ -40,7 +40,4 @@ new mongoose.Schema({ timestamps:true }); -export default mongoose.model( - "Approval", - approvalSchema -); \ No newline at end of file +export default mongoose.model("Approval", approvalSchema); \ No newline at end of file diff --git a/backend/src/modules/approvals/approval.service.ts b/backend/src/modules/approvals/approval.service.ts index 4b81427..044e567 100644 --- a/backend/src/modules/approvals/approval.service.ts +++ b/backend/src/modules/approvals/approval.service.ts @@ -1,11 +1,7 @@ import ApprovalModel from "./approval.model"; - import FuelRequestModel from "../fuel-requests/fuelRequest.model"; - import externalInvoiceModel from "../external-invoices/externalInvoice.model"; - import lpgModel from "../lpg/lpg.model"; - import { IApproval } from "./approval.interface"; @@ -16,9 +12,9 @@ export class ApprovalService { async getAll() { return await ApprovalModel - .find() - .populate("approvedBy") - .sort({ + .find() + .populate("approvedBy") + .sort({ createdAt: -1 }); @@ -31,8 +27,8 @@ export class ApprovalService { ) { return await ApprovalModel - .findById(id) - .populate("approvedBy"); + .findById(id) + .populate("approvedBy"); } @@ -42,8 +38,18 @@ export class ApprovalService { data: IApproval ) { - const approval = - new ApprovalModel(data); + const exists = await ApprovalModel.findOne({ + referenceType: data.referenceType, + referenceId: data.referenceId + }); + + if (exists) { + throw new Error( + "La solicitud ya tiene una aprobación registrada." + ); + } + + const approval = new ApprovalModel(data); return await approval.save(); @@ -51,220 +57,153 @@ export class ApprovalService { // async approve( - approvalId: string, - approvedBy: string, - comments?: string + approvalId: string, + approvedBy: string, + comments?: string ) { // Buscar aprobación - const approval = - await ApprovalModel.findById( - approvalId - ); + const approval = await ApprovalModel.findById( + approvalId + ); if (!approval) { - throw new Error( "Aprobación no encontrada" ); - } - // Actualizar aprobación - approval.status = - "APROBADO"; + // Validar que aún esté pendiente + if (approval.status !== "PENDIENTE") { + throw new Error("Esta solicitud ya fue procesada."); + } - approval.approvedBy = - approvedBy as any; + // Actualizar datos de la aprobación + approval.status = "APROBADO"; - approval.approvedDate = - new Date(); + approval.approvedBy = approvedBy as any; - approval.comments = - comments || ""; + approval.approvedDate = new Date(); + + approval.comments = comments || ""; await approval.save(); - if ( - approval.referenceType === - "FuelRequest" - ) { + // Actualizar el documento relacionado + if (approval.referenceType === "FuelRequest") { - await FuelRequestModel - .findByIdAndUpdate( + await FuelRequestModel.findByIdAndUpdate( + approval.referenceId, + { + status: "APROBADO" + }, + { + new: true + } + ); - approval.referenceId, + } else if (approval.referenceType === "ExternalInvoice") { - { - status: - "APROBADO" - }, + await externalInvoiceModel.findByIdAndUpdate( + approval.referenceId, + { + status: "APROBADO" + }, + { + new: true + } + ); - { - new: true - } + } else if (approval.referenceType === "LPG") { - ); + await lpgModel.findByIdAndUpdate( + approval.referenceId, + { + status: "APROBADO" + }, + { + new: true + } + ); } - if ( - approval.referenceType === - "ExternalInvoice" - ) { - - await externalInvoiceModel - .findByIdAndUpdate( - - approval.referenceId, - - { - status: - "APROBADO" - }, - - { - new: true - } - - ); - - } - - if ( - approval.referenceType === - "LPG" - ) { - - await lpgModel - .findByIdAndUpdate( - - approval.referenceId, - - { - status: - "APROBADO" - }, - - { - new: true - } - - ); - } - - return approval; - } //Rechazar solicitud async reject( - approvalId: string, - approvedBy: string, - comments?: string + approvalId: string, + approvedBy: string, + comments?: string ) { // Buscar aprobación - const approval = - await ApprovalModel.findById( - approvalId - ); + const approval = await ApprovalModel.findById( + approvalId + ); if (!approval) { - - throw new Error( - "Aprobación no encontrada" - ); - + throw new Error("Aprobación no encontrada"); } - // Actualizar aprobación - approval.status = - "RECHAZADO"; + // Validar que aún esté pendiente + if (approval.status !== "PENDIENTE") { + throw new Error("Esta solicitud ya fue procesada."); + } - approval.approvedBy = - approvedBy as any; + // Actualizar datos de la aprobación + approval.status = "RECHAZADO"; - approval.approvedDate = - new Date(); + approval.approvedBy = approvedBy as any; - approval.comments = - comments || ""; + approval.approvedDate = new Date(); + + approval.comments = comments || ""; await approval.save(); - if ( - approval.referenceType === - "FuelRequest" - ) { + // Actualizar el documento relacionado + if (approval.referenceType === "FuelRequest") { - await FuelRequestModel - .findByIdAndUpdate( + await FuelRequestModel.findByIdAndUpdate( + approval.referenceId, + { + status: "RECHAZADO" + }, + { + new: true + } + ); - approval.referenceId, + } else if (approval.referenceType === "ExternalInvoice") { - { - status: - "RECHAZADO" - }, + await externalInvoiceModel.findByIdAndUpdate( + approval.referenceId, + { + status: "RECHAZADO" + }, + { + new: true + } + ); - { - new: true - } + } else if (approval.referenceType === "LPG") { - ); + await lpgModel.findByIdAndUpdate( + approval.referenceId, + { + status: "RECHAZADO" + }, + { + new: true + } + ); } - if ( - approval.referenceType === - "ExternalInvoice" - ) { - - await externalInvoiceModel - .findByIdAndUpdate( - - approval.referenceId, - - { - status: - "RECHAZADO" - }, - - { - new: true - } - - ); - - } - - if ( - approval.referenceType === - "LPG" - ) { - - await lpgModel - .findByIdAndUpdate( - - approval.referenceId, - - { - status: - "RECHAZADO" - }, - - { - new: true - } - - ); - } - return approval; - } //Obtener aprobaciones por estado @@ -298,7 +237,7 @@ export class ApprovalService { ) { return await ApprovalModel - .findByIdAndDelete(id); + .findByIdAndDelete(id); } diff --git a/backend/src/modules/pump-reading/pumpReading.interface.ts b/backend/src/modules/pump-reading/pumpReading.interface.ts index 340d46a..8014e30 100644 --- a/backend/src/modules/pump-reading/pumpReading.interface.ts +++ b/backend/src/modules/pump-reading/pumpReading.interface.ts @@ -1,17 +1,30 @@ -import {ObjectId} from 'mongoose'; +import {Types} from 'mongoose'; export interface IPumpReading { - readingNumber:string; - fuelPumpId:ObjectId; - fuelTypeId:ObjectId; + readingNumber?:string; + + fuelPumpId:Types.ObjectId; + + fuelTypeId:Types.ObjectId; readingDate:Date; + initialReading:number; + finalReading:number; + gallonsDispensed?:number; + systemDispensed?:number; - difference:number; - createdBy:ObjectId; - status:string; + + difference?:number; + + createdBy:Types.ObjectId; + + status?: + | "ABIERTA" + | "CUADRADA" + | "CON_DIFERENCIA"; + comments?:string; } diff --git a/backend/src/utils/requestNumber.ts b/backend/src/utils/requestNumber.ts index 33ba4c3..e6917fe 100644 --- a/backend/src/utils/requestNumber.ts +++ b/backend/src/utils/requestNumber.ts @@ -4,4 +4,8 @@ export const generateRequestNumber = ():string =>{ export const generateRequestLPGNumber =():string =>{ return `LPG-${Date.now()}`; -} \ No newline at end of file +} + +export const generatePumpReadingNumber = (): string => { + return `PR-${Date.now()}`; +}; \ No newline at end of file