import { Criteria } from "@repo/rdx-criteria/server"; import { UniqueID } from "@repo/rdx-ddd"; import { Collection, Result } from "@repo/rdx-utils"; import { Customer, CustomerPatchProps, CustomerProps } from "../aggregates"; import { ICustomerRepository } from "../repositories"; export class CustomerService { constructor(private readonly repository: ICustomerRepository) {} /** * Construye un nuevo agregado Customer 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 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 una instancia de Customer en persistencia. * * @param customer - El agregado a guardar (con el companyId ya asignado) * @param transaction - Transacción activa para la operación. * @returns Result - El agregado guardado o un error si falla la operación. */ async saveCustomer(customer: Customer, transaction: any): Promise> { return this.repository.save(customer, 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. */ existsByIdInCompany( companyId: UniqueID, customerId: UniqueID, transaction?: any ): Promise> { return this.repository.existsByIdInCompany(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?: any ): Promise, Error>> { return this.repository.findByCriteriaInCompany(companyId, criteria, 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 encontradoF o error. */ async getCustomerByIdInCompany( companyId: UniqueID, customerId: UniqueID, transaction?: any ): Promise> { return this.repository.getByIdInCompany(companyId, customerId, transaction); } /** * Actualiza parcialmente un cliente existente con nuevos datos. * 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 partial - Subconjunto de props válidas para aplicar. * @param transaction - Transacción activa para la operación. * @returns Result - Cliente actualizado o error. */ async updateCustomerByIdInCompany( companyId: UniqueID, customerId: UniqueID, partial: CustomerPatchProps, transaction?: any ): Promise> { const customerResult = await this.getCustomerByIdInCompany(companyId, customerId, transaction); if (customerResult.isFailure) { return Result.fail(customerResult.error); } const customer = customerResult.data; const updatedCustomer = customer.update(partial); if (updatedCustomer.isFailure) { return Result.fail(updatedCustomer.error); } return Result.ok(updatedCustomer.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?: any ): Promise> { return this.repository.deleteByIdInCompany(companyId, customerId, transaction); } }