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 invoicePropsOrError = mapDTOToCustomerProps(dto); if (invoicePropsOrError.isFailure) { return Result.fail(invoicePropsOrError.error); } const { props, id } = invoicePropsOrError.data; const invoiceOrError = this.service.build(props, id); if (invoiceOrError.isFailure) { return Result.fail(invoiceOrError.error); } const newInvoice = invoiceOrError.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(newInvoice, transaction); if (result.isFailure) { return Result.fail(result.error); } const viewDTO = this.assembler.toDTO(newInvoice); return Result.ok(viewDTO); } catch (error: unknown) { return Result.fail(error as Error); } }); } }