From 998708fd2e7c17c7c099e6af730f0743affbcd43 Mon Sep 17 00:00:00 2001 From: karol Date: Fri, 19 Jun 2026 22:30:35 +0000 Subject: [PATCH] CRUD modulo Requisicion de combustible --- backend/src/app.ts | 2 + .../fuel-requests/fuelRequest.controller.ts | 140 ++++++++++++++++++ .../fuel-requests/fuelRequest.interface.ts | 25 ++++ .../fuel-requests/fuelRequest.model.ts | 115 ++++++++++++++ .../fuel-requests/fuelRequest.routes.ts | 49 ++++++ .../fuel-requests/fuelRequest.service.ts | 101 +++++++++++++ backend/src/utils/requestNumber.ts | 3 + 7 files changed, 435 insertions(+) create mode 100644 backend/src/modules/fuel-requests/fuelRequest.controller.ts create mode 100644 backend/src/modules/fuel-requests/fuelRequest.interface.ts create mode 100644 backend/src/modules/fuel-requests/fuelRequest.model.ts create mode 100644 backend/src/modules/fuel-requests/fuelRequest.routes.ts create mode 100644 backend/src/modules/fuel-requests/fuelRequest.service.ts create mode 100644 backend/src/utils/requestNumber.ts diff --git a/backend/src/app.ts b/backend/src/app.ts index ff5326c..e3aa06d 100644 --- a/backend/src/app.ts +++ b/backend/src/app.ts @@ -9,6 +9,7 @@ import fuelPriceRoute from "./modules/fuel_prices/fuelPrices.routes"; import fuelPumpRouter from "./modules/fuel_pumps/fuelPump.routes"; import vehicleConfigRouter from "./modules/vehicles-config/vehiclesConfigs.routes"; import vAssigRouter from "./modules/vehicle-assignments/vehicleassig.routes"; +import fuelRequestRouter from "./modules/fuel-requests/fuelRequest.routes"; @@ -25,6 +26,7 @@ app.use("/api/fuelprice", fuelPriceRoute); app.use("/api/pump", fuelPumpRouter); app.use("/api/vconfig", vehicleConfigRouter); app.use("/api/vAssig", vAssigRouter); +app.use("/api/fuelRequest", fuelRequestRouter); app.use(express.urlencoded({ diff --git a/backend/src/modules/fuel-requests/fuelRequest.controller.ts b/backend/src/modules/fuel-requests/fuelRequest.controller.ts new file mode 100644 index 0000000..8c001c8 --- /dev/null +++ b/backend/src/modules/fuel-requests/fuelRequest.controller.ts @@ -0,0 +1,140 @@ +import { Request, Response } from "express"; +import { FuelRequestService } from "./fuelRequest.service"; + +const service = new FuelRequestService(); + +export class FuelRequestController { + //Obtener todas las requisiciones + + async getAll( + req:Request, + res:Response + ){ + + try{ + const requests = await service.getAll(); + res.json(requests); + } catch (error){ + + res.status(500).json({ + message:"Error al obtener requisiciones", + error + }); + } + + } + + //Obtener requisición por ID + + async getById( + req:Request, + res:Response + ){ + try { + const request = + await service.getById( + req.params.id as string + ); + + if(!request) { + return res.status(404).json({ + message: + "Requisición no encontrada" + }); + } + + res.json(request); + } + + catch (error) { + res.status(500).json({ + message:"Error al obtener requisicion", + error + }); + } + } + + + //Crear requisición + + async create( + req:Request, + res:Response + ){ + try { + const request = + await service.create( + req.body + ); + + res.status(201).json( + request + ); + + } + catch (error) { + res.status(500).json({ + message:"Error al crear requisición", + error + }); + } + } + + + async update( + req:Request, + res:Response + ){ + try { + + const request = await service.update( + req.params.id as string, + req.body + ); + + if (!request) { + return res.status(404).json({ + message: + "Requisición no encontrada" + }); + } + + res.json(request); + }catch(error) { + res.status(500).json({ + message:"Error al actualizar requisición", + error + }); + } + } + + //Eliminar requisición + + async delete( + req:Request, + res:Response + ){ + try{ + const request = + await service.delete( + req.params.id as string + ); + + if(!request){ + return res.status(404).json({ + message: + "Requisición no encontrada" + }); + } + res.json({ + message:"Requisición eliminada correctamente" + }); + } + catch (error) { + res.status(500).json({ + message: "Error al eliminar requisición", + error + }); + } + } +} \ No newline at end of file diff --git a/backend/src/modules/fuel-requests/fuelRequest.interface.ts b/backend/src/modules/fuel-requests/fuelRequest.interface.ts new file mode 100644 index 0000000..438b633 --- /dev/null +++ b/backend/src/modules/fuel-requests/fuelRequest.interface.ts @@ -0,0 +1,25 @@ +import {ObjectId} from "mongoose"; + +export interface IFuelRequest { + + requestNumber:string; + employeeId:number; + department:number; + vehicleId:number; + routeId:number; + fuelPumpId?:ObjectId; + fuelTypeId:ObjectId; + createdBy:ObjectId; + authorizedBy?:ObjectId; + gallonQuantity:number; + pricePerGallon:number; + totalAmount?:number; + previousMileage:number; + currentMileage:number; + distanceTraveled?:number; + pumpReadingId?:ObjectId; + pumpDifference?:number; + comments?:string; + odometerWorkin:boolean; + status:string; +} \ No newline at end of file diff --git a/backend/src/modules/fuel-requests/fuelRequest.model.ts b/backend/src/modules/fuel-requests/fuelRequest.model.ts new file mode 100644 index 0000000..2b5fa3b --- /dev/null +++ b/backend/src/modules/fuel-requests/fuelRequest.model.ts @@ -0,0 +1,115 @@ +import mongoose from "mongoose"; + +const fuelRequestSchema = new mongoose.Schema({ + + requestNumber:{ + type:Number, + required:true, + unique:true + }, + + employeeId:{ + type:Number, + required:true + }, + + departmentId:{ + type:Number, + required:true + }, + + routeId:{ + type:Number, + required:true + }, + + fuelPumpId:{ + type:mongoose.Schema.Types.ObjectId, + ref:"FuelPump" + }, + + fuelTypeId:{ + type:mongoose.Schema.Types.ObjectId, + ref:"FuelType" + }, + + createdBy:{ + type:mongoose.Schema.Types.ObjectId, + ref:"User", + required:true + }, + + authorizedBy:{ + type:mongoose.Schema.Types.ObjectId, + ref:"User" + }, + + gallonQuantity:{ + type:Number, + required:true + }, + + pricePerGallon:{ + type:Number, + default:0 + }, + + totalAmount:{ + type:Number, + default:0 + }, + + previousMileage:{ + type:Number, + required:true, + }, + + currentMileage:{ + type:Number, + required:true + }, + + distanceTraveled:{ + type:Number, + default:0 + }, + + pumpReading:{ + type:mongoose.Schema.Types.ObjectId, + ref:"PumpReading", + }, + + pumpDifference:{ + type:Number, + default:0 + }, + + comments:{ + type:String + }, + + odometerWorking:{ + type:Boolean, + default:true + + }, + + status:{ + type:String, + enum:[ + "PENDIENTE", + "APROBADO", + "RECHAZADO", + ], + + default:"PENDIENTE" + } +}, + +{ + timestamps:true +} + +); + +export default mongoose.model("FuelRequest", fuelRequestSchema); \ No newline at end of file diff --git a/backend/src/modules/fuel-requests/fuelRequest.routes.ts b/backend/src/modules/fuel-requests/fuelRequest.routes.ts new file mode 100644 index 0000000..549f918 --- /dev/null +++ b/backend/src/modules/fuel-requests/fuelRequest.routes.ts @@ -0,0 +1,49 @@ +import { Router } from "express"; +import { FuelRequestController } from "./fuelRequest.controller"; +import { authMiddleware } from "../auth/auth.middleware"; + +const fuelRequestRouter = Router(); + +const controller = new FuelRequestController(); + + +//Obtener todas las requisiciones +fuelRequestRouter.get( + "/", + authMiddleware, + controller.getAll +); + + +//Obtener requisición por ID + +fuelRequestRouter.get( + "/:id", + authMiddleware, + controller.getById +); + + +//Crear requisición +fuelRequestRouter.post( + "/", + authMiddleware, + controller.create +); + + +//Actualizar requisición +fuelRequestRouter.put( + "/:id", + authMiddleware, + controller.update +); + +//Eliminar requisició +fuelRequestRouter.delete( + "/:id", + authMiddleware, + controller.delete +); + +export default fuelRequestRouter; \ No newline at end of file diff --git a/backend/src/modules/fuel-requests/fuelRequest.service.ts b/backend/src/modules/fuel-requests/fuelRequest.service.ts new file mode 100644 index 0000000..0820054 --- /dev/null +++ b/backend/src/modules/fuel-requests/fuelRequest.service.ts @@ -0,0 +1,101 @@ +import fuelRequestModel from "./fuelRequest.model"; +import { IFuelRequest } from "./fuelRequest.interface"; + +import { generateRequestNumber } from "../../utils/requestNumber"; + +export class FuelRequestService { + //Obtener todas las requisiciones + + async getAll() { + return await fuelRequestModel + .find() + .populate("fuelPumpId") + .populate("fuelTypeId") + .populate("createdBy") + .populate("authorizedBy") + .sort({ createdAt: -1 }); + } + + //Obtener reauisición por ID + + async getById( + id:string + ) { + + return await fuelRequestModel + .findById(id) + .populate("fuelPumpId") + .populate("fuelTypeId") + .populate("createdBy") + .populate("authorizedBy"); + + } + + //Crear una nueva requisición + + async create ( + data:IFuelRequest + ){ + //Generar número automático + data.requestNumber = generateRequestNumber(); + + //Calcular distancia recorrida + data.distanceTraveled = data.currentMileage - data.previousMileage; + + //Calcular monto total + data.totalAmount = data.gallonQuantity * data.pricePerGallon; + + //Estado inicial + data.status = "PENDIENTE"; + + //Crear documento + const request = new fuelRequestModel(data); + + //Guardar en DB + return await request.save(); + + } + + async update( + id:string, + data:Partial + ){ + //Recalcular distancia + if(data.currentMileage !== undefined && + data.previousMileage !== undefined + ){ + data.distanceTraveled = + data.currentMileage - + data.previousMileage; + } + + //Recalcular monto + if( + data.gallonQuantity !== undefined && + data.pricePerGallon !== undefined + ){ + data.totalAmount = + data.gallonQuantity * + data.pricePerGallon; + } + + return await fuelRequestModel + .findByIdAndUpdate( + id, + data, + { + new:true + } + ); + } + + //Eliminar requisición + + async delete( + id:string + ){ + + return await fuelRequestModel + .findByIdAndDelete(id); + } +} \ No newline at end of file diff --git a/backend/src/utils/requestNumber.ts b/backend/src/utils/requestNumber.ts new file mode 100644 index 0000000..2cf8baa --- /dev/null +++ b/backend/src/utils/requestNumber.ts @@ -0,0 +1,3 @@ +export const generateRequestNumber = ():string =>{ + return `REQ-${Date.now()}`; +} \ No newline at end of file