CRUD lecturas de bomba

This commit is contained in:
2026-06-29 23:22:53 +00:00
parent 8482ee608d
commit 1aaee34a83
4 changed files with 507 additions and 0 deletions

View File

@ -0,0 +1,119 @@
import {Request, Response } from "express";
import { PumpReadingService } from "./pumpReading.service";
const service = new PumpReadingService();
export class PumpReadingController {
async create(
req:Request,
res:Response
){
try {
const reading = await service.create(
req.body
)
res.status(201).json(reading);
}catch (error){
res.status(500).json({
message:"Error al crear la lectura",
error
});
}
}
async getAll(
req:Request,
res:Response
){
try{
const readings = await service.getAll();
res.json(readings);
}catch(error){
res.status(500).json({
message:"Error al obtener las lecturas",
error
});
}
}
async getById(
req:Request,
res:Response
){
try{
const reading = await service.getById(
req.params.id as string
)
if(!reading){
return res.status(404).json({
message:"Lectura no encontrada"
});
}
res.json(reading);
}catch(error){
res.status(500).json({
message:"Error al obtener la lectura",
error
});
}
}
async update(
req:Request,
res:Response
){
try{
const reading = await service.update(
req.params.id as string,
req.body
);
if(!reading){
return res.status(404).json({
message:"Lectura no encontrada"
});
}
res.json(reading);
}catch(error){
res.status(500).json({
message:"Error al actualizar lectura",
error
});
}
}
async delete(
req:Request,
res:Response
){
try{
const reading = await service.delete(
req.params.id as string
);
if(!reading){
return res.status(404).json({
message:"Lectura no encontrada"
});
}
res.json({
message:"Lectura eliminada"
});
}catch (error){
res.status(500).json({
message:"Error al eliminiar lectura"
});
}
}
}

View File

@ -0,0 +1,17 @@
import {ObjectId} from 'mongoose';
export interface IPumpReading {
readingNumber:string;
fuelPumpId:ObjectId;
fuelTypeId:ObjectId;
readingDate:Date;
initialReading:number;
finalReading:number;
gallonsDispensed?:number;
systemDispensed?:number;
difference:number;
createdBy:ObjectId;
status:string;
comments?:string;
}

View File

@ -0,0 +1,89 @@
import mongoose from "mongoose";
const pumpReadingSchema = new mongoose.Schema({
readingNumber:{
type:String,
required:true,
unique:true
},
fuelPumpId:{
type:mongoose.Schema.Types.ObjectId,
ref:"FuelPump",
required:true
},
fuelTypeId:{
type:mongoose.Schema.Types.ObjectId,
ref:"FuelType",
required:true
},
readingDate:{
type:Date,
required:true
},
initialReading:{
type:Number,
required:true,
min:0
},
finalReading:{
type:Number,
required:true,
min:0
},
gallonsDispensed:{
type:Number,
default:0
},
systemDispensed:{
type:Number,
default:0
},
difference:{
type:Number,
default:0
},
createdBy:{
type:mongoose.Schema.Types.ObjectId,
ref:"User",
required:true
},
status:{
type:String,
enum:["ABIERTA",
"CUADRADA",
"CON_DIFERENCIA"
],
default:"ABIERTA"
},
comments:{
type:String
}
},
{
timestamps:true,
versionKey:false
}
);
pumpReadingSchema.pre("save",
function(){
this.gallonsDispensed = this.finalReading-this.initialReading;
}
);
export default mongoose.model("PumpReading",pumpReadingSchema);

View File

@ -0,0 +1,282 @@
import pumpReadingModel from "./pumpReading.model";
import { IPumpReading } from "./pumpReading.interface";
import fuelRequestModel from "../fuel-requests/fuelRequest.model";
import anomalyModel from "../anomalies/anomaly.model";
export class PumpReadingService{
//Crear nueva lectura de bomba
async create(
data:IPumpReading
){
data.gallonsDispensed=
data.finalReading-
data.initialReading;
const pumpReading = new pumpReadingModel(data);
return await pumpReading.save();
}
//Obtener todas las lecturas
async getAll(){
return await pumpReadingModel
.find()
.populate("fuelPumpId")
.populate("fuelTypeId")
.populate("createdBy")
.sort({
readingDate:-1
});
}
async getById(
id:string
){
return await pumpReadingModel
.findById(id)
.populate("fuelPumpId")
.populate("fuelTypeId")
.populate("createdBy")
}
async update (
id:string,
data:Partial<IPumpReading>
){
if(
data.initialReading !== undefined&&
data.finalReading !== undefined
){
data.gallonsDispensed =
data.finalReading -
data.initialReading;
}
return await pumpReadingModel.findByIdAndUpdate(
id,
data,
{
new:true
}
);
}
async delete (
id:string
){
return await pumpReadingModel
.findByIdAndDelete
}
//Calcular galones despachados
async calculateDispensedGallons(
id:string
){
const reading =
await pumpReadingModel.findById(id);
if(!reading){
throw new Error(
"Lectura no encontrado"
);
}
reading.gallonsDispensed =
reading.finalReading -
reading.initialReading;
await reading.save();
return reading.gallonsDispensed;
}
//Calcular galones registrados
async calculateSystemDispensed(
id:string
){
const reading =
await pumpReadingModel.findById(id);
if(!reading){
throw new Error (
"Lectura no encontrada"
);
}
const requests = await fuelRequestModel.find({
fuelPumpId:reading.fuelPumpId,
createdAt:{
$gte:reading.readingDate,
$lte:new Date()
}
});
const total = requests.reduce(
(sum, request) =>
sum + request.gallonQuantity,
0
);
reading.systemDispensed = total;
await reading.save();
return total;
}
//Calcular diferencia
async calculateDifference(
id:string
){
const reading = await pumpReadingModel.findById(id);
if (!reading) {
throw new Error(
"Lectura no encontrada"
);
}
reading.difference =
reading.gallonsDispensed -
reading.systemDispensed;
await reading.save();
return reading.difference;
}
//Actualizar estado
async updateSatatus(
id:string
){
const reading = await pumpReadingModel.findById(id);
if (!reading) {
throw new Error(
"Lectura no encontrada"
);
}
if(
reading.difference === 0
){
reading.status = "CUADRADA";
}
else{
reading.status = "CON_DIFERENCIA"
}
await reading.save();
return reading.status;
}
async updateFuelRequests(
id:string
){
const reading = await pumpReadingModel.findById(id);
if(!reading){
throw new Error(
"Lectura no encontrada"
);
}
const requests = await fuelRequestModel.find ({
fuelPumpId:reading.fuelPumpId,
createdAt:{
$gte:reading.readingDate,
$lte:new Date()
}
});
for (const request of requests) {
request.pumpReading =
reading._id as any;
request.pumpDifference =
reading.difference;
await request.save();
}
return requests;
}
//Crear anomalía por diferencencia
async creataDifferenfeAnomaly(
id:string
){
const reading = await pumpReadingModel.findById(id);
if(!reading){
throw new Error (
"Lectura no encontrada"
);
}
if (reading.difference ===0){
return null;
}
const anomaly = new anomalyModel({
vehicleId:0,
anomalyType:
"DIFERENCIA EN BOMBA",
description:
`La bomba presenta una diferencia de ${reading.difference} galones`,
detectedBy: "SISTEMA",
status: "ABIERTA",
comments: "Generada automáticamente por el sistema"
});
return await anomaly.save();
}
async closeReading(
id:string
){
const reading = await pumpReadingModel.findById(id);
if (!reading){
throw new Error (
"Lectura no encontrada"
);
}
await this.calculateDispensedGallons(id);
await this.calculateSystemDispensed(id);
const difference = await this.calculateDifference(id);
await this.updateSatatus(id);
await this.updateFuelRequests(id);
//Crear anomalía
if(difference !== 0){
await this.creataDifferenfeAnomaly(id);
}
return await pumpReadingModel
.findById(id)
.populate("fuelPumpId")
.populate("fuelTypeId")
.populate("createdBy")
}
}