// application/customer-application-service.ts import type { Criteria } from "@repo/rdx-criteria/server"; import type { UniqueID } from "@repo/rdx-ddd"; import { type Collection, Result } from "@repo/rdx-utils"; import type { Transaction } from "sequelize"; import { Customer, type CustomerPatchProps, type ICustomerCreateProps, type ICustomerRepository, } from "../domain"; import type { CustomerListDTO } from "../infrastructure"; export class CustomerApplicationService { constructor(private readonly repository: ICustomerRepository) {} /** * Construye un nuevo agregado CustomerInvoice a partir de props validadas. * * @param companyId - Identificador UUID de la empresa a la que pertenece el cliente. * @param props - Las propiedades ya validadas para crear el cliente. * @param customerId - Identificador UUID del cliente (opcional). * @returns Result - El agregado construido o un error si falla la creación. */ buildCustomerInCompany( companyId: UniqueID, props: Omit, customerId?: UniqueID ): Result { return Customer.create({ ...props, companyId }, customerId); } /** * Guarda un nuevo cliente y devuelve el cliente guardado. * * @param companyId - Identificador UUID de la empresa a la que pertenece el cliente. * @param customer - El cliente a guardar. * @param transaction - Transacción activa para la operación. * @returns Result - El cliente guardado o un error si falla la operación. */ async createCustomerInCompany( companyId: UniqueID, customer: Customer, transaction?: Transaction ): Promise> { const result = await this.repository.create(customer, transaction); if (result.isFailure) return Result.fail(result.error); return this.getCustomerByIdInCompany(companyId, customer.id, transaction); } /** * Actualiza un cliente existente y devuelve el cliente actualizado. * * @param companyId - Identificador UUID de la empresa a la que pertenece el cliente. * @param customer - El cliente a guardar. * @param transaction - Transacción activa para la operación. * @returns Result - El cliente guardado o un error si falla la operación. */ async updateCustomerInCompany( companyId: UniqueID, customer: Customer, transaction?: Transaction ): Promise> { const result = await this.repository.update(customer, transaction); if (result.isFailure) return Result.fail(result.error); return this.getCustomerByIdInCompany(companyId, customer.id, transaction); } /** * Actualiza parcialmente un cliente existente con nuevos datos. * Solo en memoria. No lo guarda en el repositorio. * * @param companyId - Identificador de la empresa a la que pertenece el cliente. * @param customerId - Identificador del cliente a actualizar. * @param changes - Subconjunto de props válidas para aplicar. * @param transaction - Transacción activa para la operación. * @returns Result - Cliente actualizado o error. */ async patchCustomerByIdInCompany( companyId: UniqueID, customerId: UniqueID, changes: CustomerPatchProps, transaction?: Transaction ): Promise> { const customerResult = await this.getCustomerByIdInCompany(companyId, customerId, transaction); if (customerResult.isFailure) { return Result.fail(customerResult.error); } const updated = customerResult.data.update(changes); if (updated.isFailure) { return Result.fail(updated.error); } return Result.ok(updated.data); } /** * Elimina (o marca como eliminado) un cliente según su ID. * * @param companyId - Identificador de la empresa a la que pertenece el cliente. * @param customerId - Identificador UUID del cliente. * @param transaction - Transacción activa para la operación. * @returns Result - Resultado de la operación. */ async deleteCustomerByIdInCompany( companyId: UniqueID, customerId: UniqueID, transaction?: Transaction ): Promise> { return this.repository.deleteByIdInCompany(companyId, customerId, transaction); } /** * * Comprueba si existe o no en persistencia un cliente con el ID proporcionado * * @param companyId - Identificador UUID de la empresa a la que pertenece el cliente. * @param customerId - Identificador UUID del cliente * @param transaction - Transacción activa para la operación. * @returns Result - Existe el cliente o no. */ async existsByIdInCompany( companyId: UniqueID, customerId: UniqueID, transaction?: Transaction ): Promise> { return this.repository.existsByIdInCompany(companyId, customerId, transaction); } /** * Recupera un cliente por su identificador único. * * @param companyId - Identificador UUID de la empresa a la que pertenece el cliente. * @param customerId - Identificador UUID del cliente. * @param transaction - Transacción activa para la operación. * @returns Result - Cliente encontrado o error. */ async getCustomerByIdInCompany( companyId: UniqueID, customerId: UniqueID, transaction?: Transaction ): Promise> { return this.repository.getByIdInCompany(companyId, customerId, transaction); } /** * Obtiene una colección de clientes 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 clientes o error. */ async findCustomerByCriteriaInCompany( companyId: UniqueID, criteria: Criteria, transaction?: Transaction ): Promise, Error>> { return this.repository.findByCriteriaInCompany(companyId, criteria, transaction); } }