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 { ICustomerInvoiceService, CustomerInvoice } from "../domain"; export class CreateCustomerInvoiceUseCase { constructor( private readonly customerCustomerInvoiceService: ICustomerInvoiceService, private readonly transactionManager: ITransactionManager ) {} public execute( customerCustomerInvoiceID: 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 customerCustomerInvoice with dto return await this.customerCustomerInvoiceService.updateCustomerInvoiceById(customerCustomerInvoiceID, 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 customerCustomerInvoice let customerCustomerInvoice_status = CustomerInvoiceStatus.create(customerCustomerInvoiceDTO.status).object; if (customerCustomerInvoice_status.isEmpty()) { customerCustomerInvoice_status = CustomerInvoiceStatus.createDraft(); } let customerCustomerInvoice_series = CustomerInvoiceSeries.create(customerCustomerInvoiceDTO.customerCustomerInvoice_series).object; if (customerCustomerInvoice_series.isEmpty()) { customerCustomerInvoice_series = CustomerInvoiceSeries.create(customerCustomerInvoiceDTO.customerCustomerInvoice_series).object; } let issue_date = CustomerInvoiceDate.create(customerCustomerInvoiceDTO.issue_date).object; if (issue_date.isEmpty()) { issue_date = CustomerInvoiceDate.createCurrentDate().object; } let operation_date = CustomerInvoiceDate.create(customerCustomerInvoiceDTO.operation_date).object; if (operation_date.isEmpty()) { operation_date = CustomerInvoiceDate.createCurrentDate().object; } let customerCustomerInvoiceCurrency = Currency.createFromCode(customerCustomerInvoiceDTO.currency).object; if (customerCustomerInvoiceCurrency.isEmpty()) { customerCustomerInvoiceCurrency = Currency.createDefaultCode().object; } let customerCustomerInvoiceLanguage = Language.createFromCode(customerCustomerInvoiceDTO.language_code).object; if (customerCustomerInvoiceLanguage.isEmpty()) { customerCustomerInvoiceLanguage = Language.createDefaultCode().object; } const items = new Collection( customerCustomerInvoiceDTO.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 (!customerCustomerInvoice_status.isDraft()) { throw Error("Error al crear una factura que no es borrador"); } return DraftCustomerInvoice.create( { customerCustomerInvoiceSeries: customerCustomerInvoice_series, issueDate: issue_date, operationDate: operation_date, customerCustomerInvoiceCurrency, language: customerCustomerInvoiceLanguage, customerCustomerInvoiceNumber: CustomerInvoiceNumber.create(undefined).object, //notes: Note.create(customerCustomerInvoiceDTO.notes).object, //senderId: UniqueID.create(null).object, recipient, items, }, customerCustomerInvoiceId ); } */ } /* 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: customerCustomerInvoiceDTO } = request; // Validaciones const customerCustomerInvoiceDTOOrError = ensureUpdateCustomerInvoice_DTOIsValid(customerCustomerInvoiceDTO); if (customerCustomerInvoiceDTOOrError.isFailure) { return this.handleValidationFailure(customerCustomerInvoiceDTOOrError.error); } const transaction = this._adapter.startTransaction(); const customerCustomerInvoiceRepoBuilder = this.getRepository("CustomerInvoice"); let customerCustomerInvoice: CustomerInvoice | null = null; try { await transaction.complete(async (t) => { customerCustomerInvoice = await customerCustomerInvoiceRepoBuilder({ transaction: t }).getById(id); }); if (customerCustomerInvoice === null) { return Result.fail( UseCaseError.create(UseCaseError.NOT_FOUND_ERROR, `CustomerInvoice not found`, { id: request.id.toString(), entity: "customerCustomerInvoice", }) ); } return Result.ok(customerCustomerInvoice); } catch (error: unknown) { const _error = error as Error; if (customerCustomerInvoiceRepoBuilder().isRepositoryError(_error)) { return this.handleRepositoryError(error as BaseError, customerCustomerInvoiceRepoBuilder()); } else { return this.handleUnexceptedError(error); } } // Recipient validations const recipientIdOrError = ensureParticipantIdIsValid( customerCustomerInvoiceDTO?.recipient?.id, ); if (recipientIdOrError.isFailure) { return this.handleValidationFailure( recipientIdOrError.error, "Recipient ID not valid", ); } const recipientId = recipientIdOrError.object; const recipientBillingIdOrError = ensureParticipantAddressIdIsValid( customerCustomerInvoiceDTO?.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( customerCustomerInvoiceDTO?.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 customerCustomerInvoice const customerCustomerInvoiceOrError = await this.tryUpdateCustomerInvoiceInstance( customerCustomerInvoiceDTO, customerCustomerInvoiceIdOrError.object, //senderId, //senderBillingId, //senderShippingId, recipientContact, ); if (customerCustomerInvoiceOrError.isFailure) { const { error: domainError } = customerCustomerInvoiceOrError; 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(customerCustomerInvoiceOrError.object); } private async tryUpdateCustomerInvoiceInstance(customerCustomerInvoiceDTO, customerCustomerInvoiceId, recipient) { // Create customerCustomerInvoice let customerCustomerInvoice_status = CustomerInvoiceStatus.create(customerCustomerInvoiceDTO.status).object; if (customerCustomerInvoice_status.isEmpty()) { customerCustomerInvoice_status = CustomerInvoiceStatus.createDraft(); } let customerCustomerInvoice_series = CustomerInvoiceSeries.create(customerCustomerInvoiceDTO.customerCustomerInvoice_series).object; if (customerCustomerInvoice_series.isEmpty()) { customerCustomerInvoice_series = CustomerInvoiceSeries.create(customerCustomerInvoiceDTO.customerCustomerInvoice_series).object; } let issue_date = CustomerInvoiceDate.create(customerCustomerInvoiceDTO.issue_date).object; if (issue_date.isEmpty()) { issue_date = CustomerInvoiceDate.createCurrentDate().object; } let operation_date = CustomerInvoiceDate.create(customerCustomerInvoiceDTO.operation_date).object; if (operation_date.isEmpty()) { operation_date = CustomerInvoiceDate.createCurrentDate().object; } let customerCustomerInvoiceCurrency = Currency.createFromCode(customerCustomerInvoiceDTO.currency).object; if (customerCustomerInvoiceCurrency.isEmpty()) { customerCustomerInvoiceCurrency = Currency.createDefaultCode().object; } let customerCustomerInvoiceLanguage = Language.createFromCode(customerCustomerInvoiceDTO.language_code).object; if (customerCustomerInvoiceLanguage.isEmpty()) { customerCustomerInvoiceLanguage = Language.createDefaultCode().object; } const items = new Collection( customerCustomerInvoiceDTO.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 (!customerCustomerInvoice_status.isDraft()) { throw Error("Error al crear una factura que no es borrador"); } return DraftCustomerInvoice.create( { customerCustomerInvoiceSeries: customerCustomerInvoice_series, issueDate: issue_date, operationDate: operation_date, customerCustomerInvoiceCurrency, language: customerCustomerInvoiceLanguage, customerCustomerInvoiceNumber: CustomerInvoiceNumber.create(undefined).object, //notes: Note.create(customerCustomerInvoiceDTO.notes).object, //senderId: UniqueID.create(null).object, recipient, items, }, customerCustomerInvoiceId ); } 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(customerCustomerInvoice: DraftCustomerInvoice) { const transaction = this._adapter.startTransaction(); const customerCustomerInvoiceRepoBuilder = this.getRepository("CustomerInvoice"); try { await transaction.complete(async (t) => { const customerCustomerInvoiceRepo = customerCustomerInvoiceRepoBuilder({ transaction: t }); await customerCustomerInvoiceRepo.save(customerCustomerInvoice); }); return Result.ok(customerCustomerInvoice); } catch (error: unknown) { const _error = error as Error; if (customerCustomerInvoiceRepoBuilder().isRepositoryError(_error)) { return this.handleRepositoryError(error as BaseError, customerCustomerInvoiceRepoBuilder()); } 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) ); } } */