import { DuplicateEntityError, ITransactionManager } from "@erp/core/api"; import { CreateCustomerCommandDTO } from "@erp/customers/common/dto"; import { Result } from "@repo/rdx-utils"; import { Transaction } from "sequelize"; import { ICustomerService } from "../../domain"; import { mapDTOToCustomerProps } from "../helpers"; import { CreateCustomersAssembler } from "./assembler"; export class CreateCustomerUseCase { constructor( private readonly service: ICustomerService, private readonly transactionManager: ITransactionManager, private readonly assembler: CreateCustomersAssembler ) {} public execute(dto: CreateCustomerCommandDTO) { const customerPropsOrError = mapDTOToCustomerProps(dto); if (customerPropsOrError.isFailure) { return Result.fail(customerPropsOrError.error); } const { props, id } = customerPropsOrError.data; const customerOrError = this.service.build(props, id); if (customerOrError.isFailure) { return Result.fail(customerOrError.error); } const newCustomer = customerOrError.data; return this.transactionManager.complete(async (transaction: Transaction) => { try { const duplicateCheck = await this.service.existsById(id, transaction); if (duplicateCheck.isFailure) { return Result.fail(duplicateCheck.error); } if (duplicateCheck.data) { return Result.fail(new DuplicateEntityError("Customer", id.toString())); } const result = await this.service.save(newCustomer, transaction); if (result.isFailure) { return Result.fail(result.error); } const viewDTO = this.assembler.toDTO(newCustomer); return Result.ok(viewDTO); } catch (error: unknown) { return Result.fail(error as Error); } }); } }