Actualización CRUD módulo facturas externas y adición de validaciones
This commit is contained in:
@ -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";
|
||||||
}
|
}
|
||||||
@ -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
|
|
||||||
);
|
|
||||||
@ -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);
|
||||||
|
|||||||
@ -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 {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//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
|
//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 &&
|
if(!invoice){
|
||||||
data.pricePerGallon
|
return null;
|
||||||
) {
|
}
|
||||||
|
|
||||||
data.totalAmount =
|
const previousMileage = data.previousMileage ?? invoice.previousMileage;
|
||||||
data.gallons *
|
|
||||||
data.pricePerGallon;
|
const currentMileage = data.currentMileage ?? invoice.currentMileage;
|
||||||
|
|
||||||
|
const gallonQuantity = data.gallonQuantity ?? invoice.gallonQuantity;
|
||||||
|
|
||||||
|
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
return await ExternalInvoiceModel
|
|
||||||
.findByIdAndUpdate(
|
data.totalAmount = gallonQuantity * pricePerGallon;
|
||||||
id,
|
|
||||||
data,
|
|
||||||
{
|
|
||||||
new: true
|
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user