import { UniqueID } from "@/core/common/domain"; import { ITransactionManager } from "@/core/common/infrastructure/database"; import { Result } from "@repo/rdx-utils"; import { IUpdateCustomerInvoiceRequestDTO } from "../../common/dto"; import { CustomerInvoice, ICustomerInvoiceService } from "../domain"; export class CreateCustomerInvoiceUseCase { constructor( private readonly customerInvoiceService: ICustomerInvoiceService, private readonly transactionManager: ITransactionManager ) {} public execute( customerInvoiceID: UniqueID, dto: Partial ): Promise> { return this.transactionManager.complete(async (transaction) => { return Result.fail(new Error("No implementado")); /* try { const validOrErrors = this.validateCustomerInvoiceData(dto); if (validOrErrors.isFailure) { return Result.fail(validOrErrors.error); } const data = validOrErrors.data; // Update customerInvoice with dto return await this.customerInvoiceService.updateCustomerInvoiceById(customerInvoiceID, data, transaction); } catch (error: unknown) { logger.error(error as Error); return Result.fail(error as Error); } */ }); } /* private validateCustomerInvoiceData( dto: Partial ): Result, Error> { const errors: Error[] = []; const validatedData: Partial = {}; // Create customerInvoice let customerInvoice_status = CustomerInvoiceStatus.create(customerInvoiceDTO.status).object; if (customerInvoice_status.isEmpty()) { customerInvoice_status = CustomerInvoiceStatus.createDraft(); } let customerInvoice_series = CustomerInvoiceSeries.create(customerInvoiceDTO.customerInvoice_series).object; if (customerInvoice_series.isEmpty()) { customerInvoice_series = CustomerInvoiceSeries.create(customerInvoiceDTO.customerInvoice_series).object; } let invoice_date = CustomerInvoiceDate.create(customerInvoiceDTO.invoice_date).object; if (invoice_date.isEmpty()) { invoice_date = CustomerInvoiceDate.createCurrentDate().object; } let operation_date = CustomerInvoiceDate.create(customerInvoiceDTO.operation_date).object; if (operation_date.isEmpty()) { operation_date = CustomerInvoiceDate.createCurrentDate().object; } let customerInvoiceCurrency = Currency.createFromCode(customerInvoiceDTO.currency).object; if (customerInvoiceCurrency.isEmpty()) { customerInvoiceCurrency = Currency.createDefaultCode().object; } let customerInvoiceLanguage = Language.createFromCode(customerInvoiceDTO.language_code).object; if (customerInvoiceLanguage.isEmpty()) { customerInvoiceLanguage = Language.createDefaultCode().object; } const items = new Collection( customerInvoiceDTO.items?.map( (item) => CustomerInvoiceSimpleItem.create({ description: Description.create(item.description).object, quantity: Quantity.create(item.quantity).object, unitPrice: UnitPrice.create({ amount: item.unit_price.amount, currencyCode: item.unit_price.currency, precision: item.unit_price.precision, }).object, }).object ) ); if (!customerInvoice_status.isDraft()) { throw Error("Error al crear una factura que no es borrador"); } return DraftCustomerInvoice.create( { customerInvoiceSeries: customerInvoice_series, invoiceDate: invoice_date, operationDate: operation_date, customerInvoiceCurrency, language: customerInvoiceLanguage, customerInvoiceNumber: CustomerInvoiceNumber.create(undefined).object, //notes: Note.create(customerInvoiceDTO.notes).object, //senderId: UniqueID.create(null).object, recipient, items, }, customerInvoiceId ); } */ } /* export type UpdateCustomerInvoiceResponseOrError = | Result // Misc errors (value objects) | Result; // Success! export class UpdateCustomerInvoiceUseCase2 implements IUseCase<{ id: UniqueID; data: IUpdateCustomerInvoice_DTO }, Promise> { private _context: IInvoicingContext; private _adapter: ISequelizeAdapter; private _repositoryManager: IRepositoryManager; constructor(context: IInvoicingContext) { this._context = context; this._adapter = context.adapter; this._repositoryManager = context.repositoryManager; } private getRepository(name: string) { return this._repositoryManager.getRepository(name); } private handleValidationFailure( validationError: Error, message?: string ): Result { return Result.fail( UseCaseError.create( UseCaseError.INVALID_INPUT_DATA, message ? message : validationError.message, validationError ) ); } async execute(request: { id: UniqueID; data: IUpdateCustomerInvoice_DTO; }): Promise { const { id, data: customerInvoiceDTO } = request; // Validaciones const customerInvoiceDTOOrError = ensureUpdateCustomerInvoice_DTOIsValid(customerInvoiceDTO); if (customerInvoiceDTOOrError.isFailure) { return this.handleValidationFailure(customerInvoiceDTOOrError.error); } const transaction = this._adapter.startTransaction(); const customerInvoiceRepoBuilder = this.getRepository("CustomerInvoice"); let customerInvoice: CustomerInvoice | null = null; try { await transaction.complete(async (t) => { customerInvoice = await customerInvoiceRepoBuilder({ transaction: t }).getById(id); }); if (customerInvoice === null) { return Result.fail( UseCaseError.create(UseCaseError.NOT_FOUND_ERROR, `CustomerInvoice not found`, { id: request.id.toString(), entity: "customerInvoice", }) ); } return Result.ok(customerInvoice); } catch (error: unknown) { const _error = error as Error; if (customerInvoiceRepoBuilder().isRepositoryError(_error)) { return this.handleRepositoryError(error as BaseError, customerInvoiceRepoBuilder()); } else { return this.handleUnexceptedError(error); } } // Recipient validations const recipientIdOrError = ensureParticipantIdIsValid( customerInvoiceDTO?.recipient?.id, ); if (recipientIdOrError.isFailure) { return this.handleValidationFailure( recipientIdOrError.error, "Recipient ID not valid", ); } const recipientId = recipientIdOrError.object; const recipientBillingIdOrError = ensureParticipantAddressIdIsValid( customerInvoiceDTO?.recipient?.billing_address_id, ); if (recipientBillingIdOrError.isFailure) { return this.handleValidationFailure( recipientBillingIdOrError.error, "Recipient billing address ID not valid", ); } const recipientBillingId = recipientBillingIdOrError.object; const recipientShippingIdOrError = ensureParticipantAddressIdIsValid( customerInvoiceDTO?.recipient?.shipping_address_id, ); if (recipientShippingIdOrError.isFailure) { return this.handleValidationFailure( recipientShippingIdOrError.error, "Recipient shipping address ID not valid", ); } const recipientShippingId = recipientShippingIdOrError.object; const recipientContact = await this.findContact( recipientId, recipientBillingId, recipientShippingId, ); if (!recipientContact) { return this.handleValidationFailure( new Error(`Recipient with ID ${recipientId.toString()} does not exist`), ); } // Crear customerInvoice const customerInvoiceOrError = await this.tryUpdateCustomerInvoiceInstance( customerInvoiceDTO, customerInvoiceIdOrError.object, //senderId, //senderBillingId, //senderShippingId, recipientContact, ); if (customerInvoiceOrError.isFailure) { const { error: domainError } = customerInvoiceOrError; let errorCode = ""; let message = ""; switch (domainError.code) { case CustomerInvoice.ERROR_CUSTOMER_WITHOUT_NAME: errorCode = UseCaseError.INVALID_INPUT_DATA; message = "El cliente debe ser una compañía o tener nombre y apellidos."; break; default: errorCode = UseCaseError.UNEXCEPTED_ERROR; message = ""; break; } return Result.fail( UseCaseError.create(errorCode, message, domainError), ); } return this.saveCustomerInvoice(customerInvoiceOrError.object); } private async tryUpdateCustomerInvoiceInstance(customerInvoiceDTO, customerInvoiceId, recipient) { // Create customerInvoice let customerInvoice_status = CustomerInvoiceStatus.create(customerInvoiceDTO.status).object; if (customerInvoice_status.isEmpty()) { customerInvoice_status = CustomerInvoiceStatus.createDraft(); } let customerInvoice_series = CustomerInvoiceSeries.create(customerInvoiceDTO.customerInvoice_series).object; if (customerInvoice_series.isEmpty()) { customerInvoice_series = CustomerInvoiceSeries.create(customerInvoiceDTO.customerInvoice_series).object; } let invoice_date = CustomerInvoiceDate.create(customerInvoiceDTO.invoice_date).object; if (invoice_date.isEmpty()) { invoice_date = CustomerInvoiceDate.createCurrentDate().object; } let operation_date = CustomerInvoiceDate.create(customerInvoiceDTO.operation_date).object; if (operation_date.isEmpty()) { operation_date = CustomerInvoiceDate.createCurrentDate().object; } let customerInvoiceCurrency = Currency.createFromCode(customerInvoiceDTO.currency).object; if (customerInvoiceCurrency.isEmpty()) { customerInvoiceCurrency = Currency.createDefaultCode().object; } let customerInvoiceLanguage = Language.createFromCode(customerInvoiceDTO.language_code).object; if (customerInvoiceLanguage.isEmpty()) { customerInvoiceLanguage = Language.createDefaultCode().object; } const items = new Collection( customerInvoiceDTO.items?.map( (item) => CustomerInvoiceSimpleItem.create({ description: Description.create(item.description).object, quantity: Quantity.create(item.quantity).object, unitPrice: UnitPrice.create({ amount: item.unit_price.amount, currencyCode: item.unit_price.currency, precision: item.unit_price.precision, }).object, }).object ) ); if (!customerInvoice_status.isDraft()) { throw Error("Error al crear una factura que no es borrador"); } return DraftCustomerInvoice.create( { customerInvoiceSeries: customerInvoice_series, invoiceDate: invoice_date, operationDate: operation_date, customerInvoiceCurrency, language: customerInvoiceLanguage, customerInvoiceNumber: CustomerInvoiceNumber.create(undefined).object, //notes: Note.create(customerInvoiceDTO.notes).object, //senderId: UniqueID.create(null).object, recipient, items, }, customerInvoiceId ); } private async findContact( contactId: UniqueID, billingAddressId: UniqueID, shippingAddressId: UniqueID ) { const contactRepoBuilder = this.getRepository("Contact"); const contact = await contactRepoBuilder().getById2( contactId, billingAddressId, shippingAddressId ); return contact; } private async saveCustomerInvoice(customerInvoice: DraftCustomerInvoice) { const transaction = this._adapter.startTransaction(); const customerInvoiceRepoBuilder = this.getRepository("CustomerInvoice"); try { await transaction.complete(async (t) => { const customerInvoiceRepo = customerInvoiceRepoBuilder({ transaction: t }); await customerInvoiceRepo.save(customerInvoice); }); return Result.ok(customerInvoice); } catch (error: unknown) { const _error = error as Error; if (customerInvoiceRepoBuilder().isRepositoryError(_error)) { return this.handleRepositoryError(error as BaseError, customerInvoiceRepoBuilder()); } else { return this.handleUnexceptedError(error); } } } private handleUnexceptedError(error): Result { return Result.fail( UseCaseError.create(UseCaseError.UNEXCEPTED_ERROR, error.message, error) ); } private handleRepositoryError( error: BaseError, repository: ICustomerInvoiceRepository ): Result { const { message, details } = repository.handleRepositoryError(error); return Result.fail( UseCaseError.create(UseCaseError.REPOSITORY_ERROR, message, details) ); } } */