import { Criteria } from "@repo/rdx-criteria/server"; import { UniqueID } from "@repo/rdx-ddd"; import { Collection, Result } from "@repo/rdx-utils"; import { Transaction } from "sequelize"; import { CustomerInvoiceListDTO } from "../../infrastructure"; import { CustomerInvoice, CustomerInvoicePatchProps, CustomerInvoiceProps } from "../aggregates"; import { ICustomerInvoiceRepository } from "../repositories"; export class CustomerInvoiceService { constructor(private readonly repository: ICustomerInvoiceRepository) {} /** * Construye un nuevo agregado CustomerInvoice a partir de props validadas. * * @param companyId - Identificador de la empresa a la que pertenece el cliente. * @param props - Las propiedades ya validadas para crear la factura. * @param invoiceId - Identificador UUID de la factura (opcional). * @returns Result - El agregado construido o un error si falla la creación. */ buildInvoiceInCompany( companyId: UniqueID, props: Omit, invoiceId?: UniqueID ): Result { return CustomerInvoice.create({ ...props, companyId }, invoiceId); } /** * Guarda una nueva factura y devuelve la factura guardada. * * @param companyId - Identificador UUID de la empresa a la que pertenece el cliente. * @param invoice - El agregado a guardar. * @param transaction - Transacción activa para la operación. * @returns Result - El agregado guardado o un error si falla la operación. */ async createInvoice( companyId: UniqueID, invoice: CustomerInvoice, transaction: Transaction ): Promise> { const result = await this.repository.create(invoice, transaction); if (result.isFailure) { return Result.fail(result.error); } return this.getInvoiceByIdInCompany(companyId, invoice.id, transaction); } /** * Actualiza una nueva factura y devuelve la factura actualizada. * * @param companyId - Identificador UUID de la empresa a la que pertenece el cliente. * @param invoice - El agregado a guardar. * @param transaction - Transacción activa para la operación. * @returns Result - El agregado guardado o un error si falla la operación. */ async updateInvoice( companyId: UniqueID, invoice: CustomerInvoice, transaction: Transaction ): Promise> { const result = await this.repository.update(invoice, transaction); if (result.isFailure) { return Result.fail(result.error); } return this.getInvoiceByIdInCompany(companyId, invoice.id, transaction); } /** * * Comprueba si existe o no en persistencia una factura con el ID proporcionado * * @param companyId - Identificador UUID de la empresa a la que pertenece el cliente. * @param invoiceId - Identificador UUID de la factura. * @param transaction - Transacción activa para la operación. * @returns Result - Existe la factura o no. */ async existsByIdInCompany( companyId: UniqueID, invoiceId: UniqueID, transaction?: Transaction ): Promise> { return this.repository.existsByIdInCompany(companyId, invoiceId, transaction); } /** * Obtiene una colección de facturas que cumplen con los filtros definidos en un objeto Criteria. * * @param companyId - Identificador UUID de la empresa a la que pertenece el cliente. * @param criteria - Objeto con condiciones de filtro, paginación y orden. * @param transaction - Transacción activa para la operación. * @returns Result, Error> - Colección de facturas o error. */ async findInvoiceByCriteriaInCompany( companyId: UniqueID, criteria: Criteria, transaction?: Transaction ): Promise, Error>> { return this.repository.findByCriteriaInCompany(companyId, criteria, transaction); } /** * Recupera una factura por su identificador único. * * @param invoiceId - Identificador UUID de la factura. * @param transaction - Transacción activa para la operación. * @returns Result - Factura encontrada o error. */ async getInvoiceByIdInCompany( companyId: UniqueID, invoiceId: UniqueID, transaction?: Transaction ): Promise> { return await this.repository.getByIdInCompany(companyId, invoiceId, transaction); } /** * Actualiza parcialmente una factura existente con nuevos datos. * No lo guarda en el repositorio. * * @param companyId - Identificador de la empresa a la que pertenece el cliente. * @param invoiceId - Identificador de la factura a actualizar. * @param changes - Subconjunto de props válidas para aplicar. * @param transaction - Transacción activa para la operación. * @returns Result - Factura actualizada o error. */ async updateInvoiceByIdInCompany( companyId: UniqueID, invoiceId: UniqueID, changes: CustomerInvoicePatchProps, transaction?: Transaction ): Promise> { // Verificar si la factura existe const invoiceResult = await this.getInvoiceByIdInCompany(companyId, invoiceId, transaction); if (invoiceResult.isFailure) { return Result.fail(invoiceResult.error); } const invoice = invoiceResult.data; const updatedInvoice = invoice.update(changes); if (updatedInvoice.isFailure) { return Result.fail(updatedInvoice.error); } return Result.ok(updatedInvoice.data); } /** * Elimina (o marca como eliminada) una factura según su ID. * * @param companyId - Identificador de la empresa a la que pertenece el cliente. * @param invoiceId - Identificador UUID de la factura. * @param transaction - Transacción activa para la operación. * @returns Result - Resultado de la operación. */ async deleteInvoiceByIdInCompany( companyId: UniqueID, invoiceId: UniqueID, transaction?: Transaction ): Promise> { return this.repository.deleteByIdInCompany(companyId, invoiceId, transaction); } }