Actualización CRUD módulo facturas externas y adición de validaciones

This commit is contained in:
2026-07-03 16:48:09 +00:00
parent d638e00701
commit 4c34f20705
4 changed files with 122 additions and 78 deletions

View File

@ -1,4 +1,4 @@
import { ObjectId } from "mongoose"; import { Types } from "mongoose";
export interface IExternalInvoice { export interface IExternalInvoice {
@ -14,22 +14,32 @@ export interface IExternalInvoice {
departmentId:number; departmentId:number;
fuelTypeId:ObjectId; fuelTypeId:Types.ObjectId;
invoiceDate:Date; invoiceDate:Date;
gallons:number; gallonQuantity: number;
pricePerGallon:number; pricePerGallon:number;
totalAmount?:number; totalAmount?:number;
createdBy:ObjectId; previousMileage: number;
approvedBy?:ObjectId; currentMileage: number;
distanceTraveled?: number;
createdBy:Types.ObjectId;
approvedBy?:Types.ObjectId;
comments?:string; comments?:string;
status:string; odometerWorking: boolean;
status:
| "PENDIENTE"
| "APROBADO"
| "RECHAZADO";
} }

View File

@ -43,7 +43,7 @@ const externalInvoiceSchema = new mongoose.Schema({
required:true required:true
}, },
gallons:{ gallonQuantity:{
type:Number, type:Number,
required:true required:true
}, },
@ -58,6 +58,21 @@ const externalInvoiceSchema = new mongoose.Schema({
default:0 default:0
}, },
previousMileage:{
type:Number,
required:true,
},
currentMileage:{
type:Number,
required:true
},
distanceTraveled:{
type:Number,
default:0
},
createdBy:{ createdBy:{
type:mongoose.Schema.Types.ObjectId, type:mongoose.Schema.Types.ObjectId,
ref:"User", ref:"User",
@ -73,6 +88,12 @@ const externalInvoiceSchema = new mongoose.Schema({
type:String type:String
}, },
odometerWorking:{
type:Boolean,
default:true
},
status:{ status:{
type:String, type:String,
enum:[ enum:[
@ -89,20 +110,5 @@ const externalInvoiceSchema = new mongoose.Schema({
versionKey:false versionKey:false
}); });
//Calcular total antes de guardar
externalInvoiceSchema.pre( export default mongoose.model( "ExternalInvoice", externalInvoiceSchema);
"save",
async function () {
this.totalAmount =
this.gallons *
this.pricePerGallon;
}
);
export default mongoose.model(
"ExternalInvoice",
externalInvoiceSchema
);

View File

@ -12,6 +12,14 @@ const controller = new ExternalInvoiceController();
invoicerouter.get("/", authMiddleware, controller.getAll); invoicerouter.get("/", authMiddleware, controller.getAll);
//Buscar por estado
invoicerouter.get("/status/:status", authMiddleware, controller.getByStatus);
//Buscar por zona
invoicerouter.get("/zone/:zone", authMiddleware, controller.getByZone);
//Obtener factura por ID //Obtener factura por ID
invoicerouter.get("/:id", authMiddleware, controller.getById); invoicerouter.get("/:id", authMiddleware, controller.getById);
@ -24,14 +32,6 @@ invoicerouter.post("/", authMiddleware, controller.create);
invoicerouter.put("/:id", authMiddleware, controller.update); invoicerouter.put("/:id", authMiddleware, controller.update);
//Buscar por estado
invoicerouter.get("/status/:status", authMiddleware, controller.getByStatus);
//Buscar por zona
invoicerouter.get("/zone/:zone", authMiddleware, controller.getByZone);
//Eliminar factura //Eliminar factura
invoicerouter.delete("/:id", authMiddleware, controller.delete); invoicerouter.delete("/:id", authMiddleware, controller.delete);

View File

@ -1,31 +1,15 @@
import ExternalInvoiceModel from "./externalInvoice.model"; import externalInvoiceModel from "./externalInvoice.model";
import { IExternalInvoice } from "./externalInvoice.interface"; import { IExternalInvoice } from "./externalInvoice.interface";
export class ExternalInvoiceService { export class ExternalInvoiceService {
//Crear factura externa
async create(
data: IExternalInvoice
) {
// Calcular monto total
data.totalAmount =
data.gallons *
data.pricePerGallon;
const invoice =
new ExternalInvoiceModel(data);
return await invoice.save();
}
//Obtener todas las facturas //Obtener todas las facturas
async getAll() { async getAll() {
return await ExternalInvoiceModel return await externalInvoiceModel
.find() .find()
.populate("fuelTypeId") .populate("fuelTypeId")
.populate("createdBy") .populate("createdBy")
@ -36,13 +20,13 @@ export class ExternalInvoiceService {
} }
// Obtener factura por ID
// Obtener factura por ID
async getById( async getById(
id: string id: string
) { ) {
return await ExternalInvoiceModel return await externalInvoiceModel
.findById(id) .findById(id)
.populate("fuelTypeId") .populate("fuelTypeId")
.populate("createdBy") .populate("createdBy")
@ -50,69 +34,113 @@ export class ExternalInvoiceService {
} }
//Actualizar factura
//Crear factura externa
async create(
data: IExternalInvoice
) {
if(data.currentMileage < data.previousMileage) {
throw new Error ("El kilometraje no puede ser menor que el anterior");
}
//Validar que los galones sean mayor a 0
if(data.gallonQuantity <= 0){
throw new Error ("La cantidad de galones debe ser mayor que 0");
}
// Calcular monto total
data.totalAmount = data.gallonQuantity * data.pricePerGallon;
//Calcular distancia recorrida
data.distanceTraveled = data.currentMileage - data.previousMileage;
const invoice = new externalInvoiceModel(data);
return await invoice.save();
}
//Actualizar factura
async update( async update(
id: string, id: string,
data: Partial<IExternalInvoice> data: Partial<IExternalInvoice>
) { ) {
// Recalcular total si cambian datos const invoice = await externalInvoiceModel.findById(id);
if (
data.gallons &&
data.pricePerGallon
) {
data.totalAmount =
data.gallons *
data.pricePerGallon;
if(!invoice){
return null;
} }
return await ExternalInvoiceModel const previousMileage = data.previousMileage ?? invoice.previousMileage;
.findByIdAndUpdate(
id, const currentMileage = data.currentMileage ?? invoice.currentMileage;
data,
{ const gallonQuantity = data.gallonQuantity ?? invoice.gallonQuantity;
new: true
} const pricePerGallon = data.pricePerGallon ?? invoice.pricePerGallon;
);
//Recalcular distancia recorrida
data.distanceTraveled = currentMileage - previousMileage;
//Validar kilometraje
if(data.distanceTraveled < 0){
throw new Error("El kilometraje actual no puede ser menor que el anterior");
}
data.totalAmount = gallonQuantity * pricePerGallon;
const updateInvoice = await externalInvoiceModel.findByIdAndUpdate(
id,
data,
{
new:true
}
);
return updateInvoice;
} }
// Buscar por estado
// Buscar por estado
async getByStatus( async getByStatus(
status: string status: string
) { ) {
return await ExternalInvoiceModel return await externalInvoiceModel
.find({ .find({
status status
} as any); } as any);
} }
// Buscar por zona
// Buscar por zona
async getByZone( async getByZone(
zone: string zone: string
) { ) {
return await ExternalInvoiceModel return await externalInvoiceModel
.find({ .find({
zone zone
} as any); } as any);
} }
//Eliminar factura
//Eliminar factura
async delete( async delete(
id: string id: string
) { ) {
return await ExternalInvoiceModel return await externalInvoiceModel
.findByIdAndDelete(id); .findByIdAndDelete(id);
} }