import { Document, Model, Schema, model, FilterQuery } from "mongoose"; import { CreateCashFlowParams, FindCashFlowParams, ICashFlow, ICashFlowAdapter, PaginateCashFlowParams, PaginateCashFlowResults, } from "./CashFlow.Interface"; import { PAYMENT_PROCCESS_DATE } from "../Payments/Payments.Interface"; import AppointmentList from "../Appointments/Appointments"; export interface ICashFlowDocument extends Omit, Document {} export class CashFlowAdapterMongoose implements ICashFlowAdapter { schema: Schema; movementList: Model; constructor() { this.schema = new Schema({ companyId: { type: Schema.Types.ObjectId, required: true, ref: "Company", }, clientId: { type: Schema.Types.ObjectId, required: false, ref: "Client", }, clientAccountMovementId: { type: Schema.Types.ObjectId, required: false, ref: "ClientAccountMovement", }, paymentId: { type: Schema.Types.ObjectId, required: false, ref: "Payment", }, appointmentId: { type: Schema.Types.ObjectId, required: false, ref: "Appointment", }, employeeId: { type: Schema.Types.ObjectId, required: false, ref: "Employee", }, amount: { type: Number, required: true, default: 0 }, description: { type: String, required: false, default: "" }, year: { type: Number, required: true, default: 0 }, month: { type: Number, required: true, default: 0 }, type: { type: String, required: true, default: 0 }, reference: { type: String, required: false, default: "" }, paymentMethod: { type: String, required: false }, createdAt: { type: Date, required: true, default: Date.now }, }); this.movementList = model("CashFlow", this.schema); } public async create(data: CreateCashFlowParams): Promise { let creationDate = new Date(); if (data.proccessDate == PAYMENT_PROCCESS_DATE.NOW) { creationDate = new Date(); } else if (data.proccessDate == PAYMENT_PROCCESS_DATE.APPOINTMENT) { const appointment = await AppointmentList.Appointments.AppointmentList.findOne({ _id: data.appointmentId, }); if (!appointment) { throw new Error("No se encontrĂ³ la reserva"); } creationDate = new Date(appointment.start); } return await this.movementList.create({ ...data, createdAt: creationDate }); } public async delete(id: string): Promise { await this.movementList.deleteOne({ _id: id }); } private buildSearchCriteria( filters: Omit ): FilterQuery { const searchCriteria: FilterQuery = {}; if (filters.startDate) { searchCriteria.createdAt = { $gte: filters.startDate, $lte: filters.endDate, }; } if (filters.year) { searchCriteria.year = filters.year; } if (filters.month) { searchCriteria.month = filters.month; } if (filters.type) { searchCriteria.type = filters.type; } if (filters.reference) { searchCriteria.reference = filters.reference; } if (filters.clientId) { searchCriteria.clientId = filters.clientId; } if (filters.clientAccountMovementId) { searchCriteria.clientAccountMovementId = filters.clientAccountMovementId; } if (filters.companyId) { searchCriteria.companyId = filters.companyId; } if (filters.paymentId) { searchCriteria.paymentId = filters.paymentId; } if (filters.appointmentId) { searchCriteria.appointmentId = filters.appointmentId; } if (filters.employeeId) { searchCriteria.employeeId = filters.employeeId; } if (filters.paymentMethod) { searchCriteria.paymentMethod = filters.paymentMethod; } return searchCriteria; } public async paginate(filters: PaginateCashFlowParams): Promise { const searchCriteria = this.buildSearchCriteria(filters); const count = await this.movementList.countDocuments(searchCriteria).exec(); const skip = (filters.page - 1) * filters.limit; const results = await this.movementList .find(searchCriteria) .skip(skip) .limit(filters.limit) .sort({ createdAt: -1 }) .exec(); return { data: results, balance: 0, page: filters.page, pages: Math.ceil(count / filters.limit), }; } public async find(filters: Omit): Promise { const searchCriteria = this.buildSearchCriteria(filters); return this.movementList.find(searchCriteria).exec(); } public async findOne( filters: Omit ): Promise { return this.movementList.findOne(filters).exec(); } }