diff --git a/.vscode/launch.json b/.vscode/launch.json index 16595628..44cf75e1 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,5 +1,5 @@ { - "version": "0.6.0", + "version": "0.6.1", "configurations": [ { "name": "WEB: Vite (Chrome)", diff --git a/apps/server/package.json b/apps/server/package.json index 10677686..e330c8db 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -1,6 +1,6 @@ { "name": "@erp/factuges-server", - "version": "0.6.0", + "version": "0.6.1", "private": true, "scripts": { "build": "tsup src/index.ts --config tsup.config.ts", @@ -37,6 +37,7 @@ "@erp/core": "workspace:*", "@erp/customer-invoices": "workspace:*", "@erp/customers": "workspace:*", + "@erp/factuges": "workspace:*", "@repo/rdx-logger": "workspace:*", "@repo/rdx-utils": "workspace:*", "bcrypt": "^6.0.0", diff --git a/apps/server/src/register-modules.ts b/apps/server/src/register-modules.ts index 8c899c52..c9d75daf 100644 --- a/apps/server/src/register-modules.ts +++ b/apps/server/src/register-modules.ts @@ -1,5 +1,6 @@ import customerInvoicesAPIModule from "@erp/customer-invoices/api"; import customersAPIModule from "@erp/customers/api"; +import factuGESAPIModule from "@erp/factuges/api"; //import suppliersAPIModule from "@erp/suppliers/api"; @@ -9,5 +10,6 @@ export const registerModules = () => { //registerModule(authAPIModule); registerModule(customersAPIModule); registerModule(customerInvoicesAPIModule); + registerModule(factuGESAPIModule); //registerModule(suppliersAPIModule); }; diff --git a/apps/web/package.json b/apps/web/package.json index e04675ec..ead05efd 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,7 +1,7 @@ { "name": "@erp/factuges-web", "private": true, - "version": "0.6.0", + "version": "0.6.1", "type": "module", "scripts": { "dev": "vite --host --clearScreen false", diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json index 19c9df7a..3acc7c41 100644 --- a/apps/web/tsconfig.json +++ b/apps/web/tsconfig.json @@ -4,6 +4,7 @@ "compilerOptions": { "resolveJsonModule": true, "esModuleInterop": true, + "baseUrl": ".", "paths": { "@/*": ["./src/*"] } diff --git a/modules/auth/package.json b/modules/auth/package.json index 6032b898..17d4b930 100644 --- a/modules/auth/package.json +++ b/modules/auth/package.json @@ -1,6 +1,6 @@ { "name": "@erp/auth", - "version": "0.6.0", + "version": "0.6.1", "private": true, "type": "module", "sideEffects": false, diff --git a/modules/core/package.json b/modules/core/package.json index 626b13f0..2fb74325 100644 --- a/modules/core/package.json +++ b/modules/core/package.json @@ -1,6 +1,6 @@ { "name": "@erp/core", - "version": "0.6.0", + "version": "0.6.1", "private": true, "type": "module", "sideEffects": false, diff --git a/modules/core/src/api/infrastructure/persistence/sequelize/sequelize-transaction-manager.ts b/modules/core/src/api/infrastructure/persistence/sequelize/sequelize-transaction-manager.ts index 46cb68b6..43805760 100644 --- a/modules/core/src/api/infrastructure/persistence/sequelize/sequelize-transaction-manager.ts +++ b/modules/core/src/api/infrastructure/persistence/sequelize/sequelize-transaction-manager.ts @@ -64,7 +64,7 @@ export class SequelizeTransactionManager extends TransactionManager { } try { - // Usa la forma gestionada: si `work` resuelve => commit, si lanza => rollback. + // Usa la forma gestionada: si `work` resuelve => commit, si lanza excepción => rollback. const result = await this._database.transaction(async (t) => { const workResult = await work(t); if (workResult instanceof Result && workResult.isFailure) { diff --git a/modules/core/tsconfig.json b/modules/core/tsconfig.json index 0c4ef2ea..317a401d 100644 --- a/modules/core/tsconfig.json +++ b/modules/core/tsconfig.json @@ -4,7 +4,7 @@ "paths": { "@erp/core/*": ["./src/*"] }, - + "baseUrl": ".", "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "target": "ES2022", "useDefineForClassFields": true, diff --git a/modules/customer-invoices/package.json b/modules/customer-invoices/package.json index aa94c4fd..f483ac05 100644 --- a/modules/customer-invoices/package.json +++ b/modules/customer-invoices/package.json @@ -1,6 +1,6 @@ { "name": "@erp/customer-invoices", - "version": "0.6.0", + "version": "0.6.1", "private": true, "type": "module", "sideEffects": false, diff --git a/modules/customer-invoices/src/api/application/proformas/repositories/proforma-repository.interface.ts b/modules/customer-invoices/src/api/application/proformas/repositories/proforma-repository.interface.ts index 56cef017..2de26706 100644 --- a/modules/customer-invoices/src/api/application/proformas/repositories/proforma-repository.interface.ts +++ b/modules/customer-invoices/src/api/application/proformas/repositories/proforma-repository.interface.ts @@ -22,6 +22,12 @@ export interface IProformaRepository { transaction: unknown ): Promise>; + getByFactuGESIdInCompany( + companyId: UniqueID, + factugesId: string, + transaction: unknown + ): Promise>; + findByCriteriaInCompany( companyId: UniqueID, criteria: Criteria, diff --git a/modules/customer-invoices/src/api/application/proformas/services/proforma-finder.ts b/modules/customer-invoices/src/api/application/proformas/services/proforma-finder.ts index 3bbe2aae..39a3e048 100644 --- a/modules/customer-invoices/src/api/application/proformas/services/proforma-finder.ts +++ b/modules/customer-invoices/src/api/application/proformas/services/proforma-finder.ts @@ -13,6 +13,12 @@ export interface IProformaFinder { transaction?: unknown ): Promise>; + findProformaByFactuGESId( + companyId: UniqueID, + factugesId: string, + transaction?: unknown + ): Promise>; + proformaExists( companyId: UniqueID, invoiceId: UniqueID, @@ -37,6 +43,14 @@ export class ProformaFinder implements IProformaFinder { return this.repository.getByIdInCompany(companyId, proformaId, transaction); } + async findProformaByFactuGESId( + companyId: UniqueID, + factugesId: string, + transaction?: unknown + ): Promise> { + return this.repository.getByFactuGESIdInCompany(companyId, factugesId, transaction); + } + async proformaExists( companyId: UniqueID, proformaId: UniqueID, diff --git a/modules/customer-invoices/src/api/application/proformas/services/proforma-public-services.interface.ts b/modules/customer-invoices/src/api/application/proformas/services/proforma-public-services.interface.ts index 54ae989a..abe1a25f 100644 --- a/modules/customer-invoices/src/api/application/proformas/services/proforma-public-services.interface.ts +++ b/modules/customer-invoices/src/api/application/proformas/services/proforma-public-services.interface.ts @@ -11,6 +11,8 @@ export interface IProformaServicesContext { companyId: UniqueID; } +// TODO: Eliminar para pasar a usar el tipo ProformaPublicServices + export interface IProformaPublicServices { createProforma: ( id: UniqueID, @@ -25,6 +27,11 @@ export interface IProformaPublicServices { context: IProformaServicesContext ) => Promise>; + getProformaByFactuGESId: ( + factugesId: string, + context: IProformaServicesContext + ) => Promise>; + getProformaSnapshotById: ( id: UniqueID, context: IProformaServicesContext diff --git a/modules/customer-invoices/src/api/index.ts b/modules/customer-invoices/src/api/index.ts index 6cd031a9..ffeb92b1 100644 --- a/modules/customer-invoices/src/api/index.ts +++ b/modules/customer-invoices/src/api/index.ts @@ -10,6 +10,8 @@ import { proformasRouter, } from "./infrastructure"; +export type { IProformaPublicServices } from "./application"; + export const customerInvoicesAPIModule: IModuleServer = { name: "customer-invoices", version: "1.0.0", diff --git a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-domain.mapper.ts b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-domain.mapper.ts index b75c4705..15613c14 100644 --- a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-domain.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-domain.mapper.ts @@ -64,7 +64,7 @@ export class SequelizeIssuedInvoiceDomainMapper extends SequelizeDomainMapper< const customerId = extractOrPushError(UniqueID.create(raw.customer_id), "customer_id", errors); const linkedProformaId = extractOrPushError( - UniqueID.create(String(raw.proforma_id)), + maybeFromNullableResult(raw.proforma_id, (v) => UniqueID.create(String(v))), "proforma_id", errors ); diff --git a/modules/customer-invoices/src/api/infrastructure/proformas/di/proforma-public-services.ts b/modules/customer-invoices/src/api/infrastructure/proformas/di/proforma-public-services.ts index e12fc321..8de5d95f 100644 --- a/modules/customer-invoices/src/api/infrastructure/proformas/di/proforma-public-services.ts +++ b/modules/customer-invoices/src/api/infrastructure/proformas/di/proforma-public-services.ts @@ -28,6 +28,11 @@ export type ProformaPublicServices = { context: ProformaServicesContext ) => Promise>; + getProformaByFactuGESId: ( + factugesId: string, + context: ProformaServicesContext + ) => Promise>; + getProformaSnapshotById: ( id: UniqueID, context: ProformaServicesContext @@ -88,6 +93,22 @@ export function buildProformaPublicServices( return Result.ok(proformaResult.data); }, + getProformaByFactuGESId: async (factugesId: string, context: ProformaServicesContext) => { + const { transaction, companyId } = context; + const proformaResult = await finder.findProformaByFactuGESId( + companyId, + factugesId, + transaction + ); + + if (proformaResult.isFailure) { + console.error("Error fetching proforma by FactuGES ID:", proformaResult.error); + return Result.fail(proformaResult.error); + } + + return Result.ok(proformaResult.data); + }, + getProformaSnapshotById: async (id: UniqueID, context: ProformaServicesContext) => { const { transaction, companyId } = context; const proformaResult = await finder.findProformaById(companyId, id, transaction); diff --git a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-recipient-domain.mapper.ts b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-recipient-domain.mapper.ts index 508c96f2..a71da7e6 100644 --- a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-recipient-domain.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-recipient-domain.mapper.ts @@ -14,7 +14,7 @@ import { } from "@repo/rdx-ddd"; import { Maybe, Result } from "@repo/rdx-utils"; -import { InvoiceRecipient, type ProformaCreateProps } from "../../../../../../domain"; +import { type IProformaCreateProps, InvoiceRecipient } from "../../../../../../domain"; import type { CustomerInvoiceModel } from "../../../../../common"; export class SequelizeProformaRecipientDomainMapper { @@ -28,17 +28,17 @@ export class SequelizeProformaRecipientDomainMapper { const { errors, parent } = params as { errors: ValidationErrorDetail[]; - parent: Partial; + parent: Partial; }; - const _name = source.current_customer.name; - const _tin = source.current_customer.tin; - const _street = source.current_customer.street; - const _street2 = source.current_customer.street2; - const _city = source.current_customer.city; - const _postal_code = source.current_customer.postal_code; - const _province = source.current_customer.province; - const _country = source.current_customer.country; + const _name = source.current_customer?.name; + const _tin = source.current_customer?.tin; + const _street = source.current_customer?.street; + const _street2 = source.current_customer?.street2; + const _city = source.current_customer?.city; + const _postal_code = source.current_customer?.postal_code; + const _province = source.current_customer?.province; + const _country = source.current_customer?.country; // Customer (snapshot) const customerName = extractOrPushError(Name.create(_name!), "customer_name", errors); diff --git a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/repositories/proforma.repository.ts b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/repositories/proforma.repository.ts index 735d6ec5..7cd749cd 100644 --- a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/repositories/proforma.repository.ts +++ b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/repositories/proforma.repository.ts @@ -326,6 +326,93 @@ export class ProformaRepository } } + /** + * + * Busca una factura por su identificador único de FactuGES. + * + * @param companyId - Identificador UUID de la empresa a la que pertenece la factura. + * @param factugesId - ID de la factura en FactuGES. + * @param transaction - Transacción activa para la operación. + * @param options - Opciones adicionales para la consulta (Sequelize FindOptions) + * @returns Result + */ + async getByFactuGESIdInCompany( + companyId: UniqueID, + factugesId: string, + transaction: Transaction, + options: FindOptions> = {} + ): Promise> { + const { CustomerModel } = this.database.models; + + try { + // Normalización defensiva de order/include + const normalizedOrder = Array.isArray(options.order) + ? options.order + : options.order + ? [options.order] + : []; + + const normalizedInclude = Array.isArray(options.include) + ? options.include + : options.include + ? [options.include] + : []; + + const mergedOptions: FindOptions> = { + ...options, + where: { + ...(options.where ?? {}), + factuges_id: factugesId, + is_proforma: true, + company_id: companyId.toString(), + }, + order: [ + ...normalizedOrder, + [{ model: CustomerInvoiceItemModel, as: "items" }, "position", "ASC"], + ], + include: [ + ...normalizedInclude, + + { + model: CustomerModel, + as: "current_customer", + required: false, + }, + { + model: CustomerInvoiceItemModel, + as: "items", + required: false, + }, + { + model: CustomerInvoiceTaxModel, + as: "taxes", + required: false, + }, + { + model: CustomerInvoiceModel, + as: "linked_invoice", + required: false, + attributes: ["id"], + }, + ], + transaction, + }; + + const row = await CustomerInvoiceModel.findOne(mergedOptions); + + if (!row) { + return Result.fail( + new EntityNotFoundError("CustomerInvoice", "factuges_id", factugesId.toString()) + ); + } + + const invoice = this.domainMapper.mapToDomain(row); + return invoice; + } catch (err: unknown) { + return Result.fail(translateSequelizeError(err)); + } + } + /** * * Consulta facturas usando un objeto Criteria (filtros, orden, paginación). diff --git a/modules/customer-invoices/tsconfig.json b/modules/customer-invoices/tsconfig.json index 65a9250e..1e908d07 100644 --- a/modules/customer-invoices/tsconfig.json +++ b/modules/customer-invoices/tsconfig.json @@ -4,7 +4,7 @@ "paths": { "@erp/customer-invoices/*": ["./src/*"] }, - + "baseUrl": ".", "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "target": "ES2022", "useDefineForClassFields": true, diff --git a/modules/customers/package.json b/modules/customers/package.json index ba8117e8..0169409d 100644 --- a/modules/customers/package.json +++ b/modules/customers/package.json @@ -1,7 +1,7 @@ { "name": "@erp/customers", "description": "Customers", - "version": "0.6.0", + "version": "0.6.1", "private": true, "type": "module", "sideEffects": false, diff --git a/modules/customers/src/api/application/services/customer-creator.ts b/modules/customers/src/api/application/services/customer-creator.ts index 67b40708..f1ced91b 100644 --- a/modules/customers/src/api/application/services/customer-creator.ts +++ b/modules/customers/src/api/application/services/customer-creator.ts @@ -11,7 +11,7 @@ export interface ICustomerCreator { companyId: UniqueID; id: UniqueID; props: ICustomerCreateProps; - unknown: unknown; + transaction?: unknown; }): Promise>; } @@ -30,12 +30,16 @@ export class CustomerCreator implements ICustomerCreator { companyId: UniqueID; id: UniqueID; props: ICustomerCreateProps; - unknown: unknown; + transaction?: unknown; }): Promise> { - const { companyId, id, props, unknown } = params; + const { companyId, id, props, transaction } = params; // 1. Verificar unicidad - const spec = new CustomerNotExistsInCompanySpecification(this.repository, companyId, unknown); + const spec = new CustomerNotExistsInCompanySpecification( + this.repository, + companyId, + transaction + ); const isNew = await spec.isSatisfiedBy(id); @@ -59,7 +63,7 @@ export class CustomerCreator implements ICustomerCreator { const newCustomer = createResult.data; // 3. Persistir agregado - const saveResult = await this.repository.create(newCustomer, unknown); + const saveResult = await this.repository.create(newCustomer, transaction); if (saveResult.isFailure) { return Result.fail(saveResult.error); diff --git a/modules/customers/src/api/application/services/customer-finder.ts b/modules/customers/src/api/application/services/customer-finder.ts index f8d9d334..492363d2 100644 --- a/modules/customers/src/api/application/services/customer-finder.ts +++ b/modules/customers/src/api/application/services/customer-finder.ts @@ -10,25 +10,25 @@ export interface ICustomerFinder { findCustomerById( companyId: UniqueID, customerId: UniqueID, - unknown?: unknown + transaction?: unknown ): Promise>; findCustomerByTIN( companyId: UniqueID, tin: TINNumber, - unknown?: unknown + transaction?: unknown ): Promise>; customerExists( companyId: UniqueID, invoiceId: UniqueID, - unknown?: unknown + transaction?: unknown ): Promise>; findCustomersByCriteria( companyId: UniqueID, criteria: Criteria, - unknown?: unknown + transaction?: unknown ): Promise, Error>>; } @@ -38,32 +38,32 @@ export class CustomerFinder implements ICustomerFinder { async findCustomerById( companyId: UniqueID, customerId: UniqueID, - unknown?: unknown + transaction?: unknown ): Promise> { - return this.repository.getByIdInCompany(companyId, customerId, unknown); + return this.repository.getByIdInCompany(companyId, customerId, transaction); } findCustomerByTIN( companyId: UniqueID, tin: TINNumber, - unknown?: unknown + transaction?: unknown ): Promise> { - return this.repository.getByTINInCompany(companyId, tin, unknown); + return this.repository.getByTINInCompany(companyId, tin, transaction); } async customerExists( companyId: UniqueID, customerId: UniqueID, - unknown?: unknown + transaction?: unknown ): Promise> { - return this.repository.existsByIdInCompany(companyId, customerId, unknown); + return this.repository.existsByIdInCompany(companyId, customerId, transaction); } async findCustomersByCriteria( companyId: UniqueID, criteria: Criteria, - unknown?: unknown + transaction?: unknown ): Promise, Error>> { - return this.repository.findByCriteriaInCompany(companyId, criteria, unknown); + return this.repository.findByCriteriaInCompany(companyId, criteria, transaction); } } diff --git a/modules/customers/src/api/index.ts b/modules/customers/src/api/index.ts index 181bec0e..041a3d40 100644 --- a/modules/customers/src/api/index.ts +++ b/modules/customers/src/api/index.ts @@ -4,6 +4,7 @@ import type { ICustomerPublicServices } from "./application"; import { customersRouter, models } from "./infrastructure"; import { buildCustomerPublicServices, buildCustomersDependencies } from "./infrastructure/di"; +export type { ICustomerPublicServices } from "./application"; export * from "./infrastructure/persistence/sequelize"; export const customersAPIModule: IModuleServer = { diff --git a/modules/customers/tsconfig.json b/modules/customers/tsconfig.json index dcaa2f64..124e8e30 100644 --- a/modules/customers/tsconfig.json +++ b/modules/customers/tsconfig.json @@ -4,7 +4,7 @@ "paths": { "@erp/customers/*": ["./src/*"] }, - + "baseUrl": ".", "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "target": "ES2022", "useDefineForClassFields": true, diff --git a/modules/factuges/package.json b/modules/factuges/package.json index 592e3428..2dae8293 100644 --- a/modules/factuges/package.json +++ b/modules/factuges/package.json @@ -1,6 +1,6 @@ { "name": "@erp/factuges", - "version": "0.6.0", + "version": "0.6.1", "private": true, "type": "module", "sideEffects": false, diff --git a/modules/factuges/src/api/application/mappers/create-proforma-from-factuges-input.mapper.ts b/modules/factuges/src/api/application/mappers/create-proforma-from-factuges-input.mapper.ts index 5ffd1b3a..105e6b71 100644 --- a/modules/factuges/src/api/application/mappers/create-proforma-from-factuges-input.mapper.ts +++ b/modules/factuges/src/api/application/mappers/create-proforma-from-factuges-input.mapper.ts @@ -83,6 +83,7 @@ export type ProformaDraftItem = { }; export type ProformaDraft = { + factugesID: string; series: Maybe; invoiceDate: UtcDate; operationDate: Maybe; @@ -222,7 +223,7 @@ export class CreateProformaFromFactugesInputMapper errors );*/ - //const factugesID = String(dto.factuges_id); + const factugesID = String(dto.factuges_id); const reference = extractOrPushError( maybeFromNullableResult(dto.reference, (value) => Result.ok(String(value))), @@ -327,6 +328,7 @@ export class CreateProformaFromFactugesInputMapper //status: defaultStatus, //invoiceNumber: proformaNumber!, + factugesID: factugesID, series: series!, invoiceDate: invoiceDate!, diff --git a/modules/factuges/src/api/application/use-cases/create-proforma-from-factuges.use-case.ts b/modules/factuges/src/api/application/use-cases/create-proforma-from-factuges.use-case.ts index 21a3f4df..227ae812 100644 --- a/modules/factuges/src/api/application/use-cases/create-proforma-from-factuges.use-case.ts +++ b/modules/factuges/src/api/application/use-cases/create-proforma-from-factuges.use-case.ts @@ -1,6 +1,6 @@ import type { JsonTaxCatalogProvider } from "@erp/core"; import { type ITransactionManager, isEntityNotFoundError } from "@erp/core/api"; -import type { ProformaPublicServices } from "@erp/customer-invoices/api"; +import type { IProformaPublicServices } from "@erp/customer-invoices/api"; import { type InvoiceAmount, InvoicePaymentMethod, @@ -9,7 +9,7 @@ import { type ItemAmount, type Proforma, } from "@erp/customer-invoices/api/domain"; -import type { CustomerPublicServices } from "@erp/customers/api"; +import type { ICustomerPublicServices } from "@erp/customers/api"; import { type Customer, CustomerStatus, @@ -44,19 +44,19 @@ type CreateProformaFromFactugesUseCaseInput = { }; type CreateProformaFromFactugesUseCaseDeps = { - customerServices: CustomerPublicServices; - proformaServices: ProformaPublicServices; + customerServices: ICustomerPublicServices; + proformaServices: IProformaPublicServices; dtoMapper: ICreateProformaFromFactugesInputMapper; taxCatalog: JsonTaxCatalogProvider; transactionManager: ITransactionManager; }; -type CreateProformaProps = Parameters["1"]; +type CreateProformaProps = Parameters["1"]; export class CreateProformaFromFactugesUseCase { private readonly dtoMapper: ICreateProformaFromFactugesInputMapper; - private readonly customerServices: CustomerPublicServices; - private readonly proformaServices: ProformaPublicServices; + private readonly customerServices: ICustomerPublicServices; + private readonly proformaServices: IProformaPublicServices; private readonly taxCatalog: JsonTaxCatalogProvider; private readonly transactionManager: ITransactionManager; @@ -80,6 +80,22 @@ export class CreateProformaFromFactugesUseCase { const { customerLookup, paymentLookup, customerDraft, proformaDraft, paymentDraft } = mappedPropsResult.data; + // 2) Comprobar si la proforma ya existe (idempotencia) + const existingProformaResult = await this.proformaServices.getProformaByFactuGESId( + proformaDraft.factugesID, + { companyId, transaction: null } + ); + + if (existingProformaResult.isSuccess) { + const existingProforma = existingProformaResult.data; + + return Result.ok({ + customer_id: existingProforma.customerId.toString(), + proforma_id: existingProforma.id.toString(), + }); + } + + // 3) Si no existe la proforma, la creamos dentro de una transacción. return this.transactionManager.complete(async (transaction: Transaction) => { try { const customerResult = await this.resolveCustomer(customerLookup, customerDraft, { @@ -132,6 +148,8 @@ export class CreateProformaFromFactugesUseCase { return Result.fail(createResult.error); } + console.log(createResult.data); + // Valida que los datos de entrada coincidan con el snapshot const proforma = createResult.data; const validationResult = this.validateDraftAgainstProforma(proformaDraft, proforma); diff --git a/modules/factuges/tsconfig.json b/modules/factuges/tsconfig.json index 76415a29..70ef7142 100644 --- a/modules/factuges/tsconfig.json +++ b/modules/factuges/tsconfig.json @@ -4,7 +4,7 @@ "paths": { "@erp/factuges/*": ["./src/*"] }, - + "baseUrl": ".", "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "target": "ES2022", "useDefineForClassFields": true, diff --git a/modules/supplier-invoices/package.json b/modules/supplier-invoices/package.json index baaafad8..9d78a427 100644 --- a/modules/supplier-invoices/package.json +++ b/modules/supplier-invoices/package.json @@ -1,7 +1,7 @@ { "name": "@erp/supplier-invoices", "description": "Supplier invoices", - "version": "0.6.0", + "version": "0.6.1", "private": true, "type": "module", "sideEffects": false, diff --git a/modules/supplier-invoices/tsconfig.json b/modules/supplier-invoices/tsconfig.json index 271c02d4..717814f1 100644 --- a/modules/supplier-invoices/tsconfig.json +++ b/modules/supplier-invoices/tsconfig.json @@ -4,7 +4,7 @@ "paths": { "@erp/supplier-invoices/*": ["./src/*"] }, - + "baseUrl": ".", "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "target": "ES2022", "useDefineForClassFields": true, diff --git a/modules/supplier/package.json b/modules/supplier/package.json index 8c835141..2f7e1775 100644 --- a/modules/supplier/package.json +++ b/modules/supplier/package.json @@ -1,7 +1,7 @@ { "name": "@erp/suppliers", "description": "Suppliers", - "version": "0.6.0", + "version": "0.6.1", "private": true, "type": "module", "sideEffects": false, diff --git a/modules/supplier/src/api/application/services/supplier-creator.service.ts b/modules/supplier/src/api/application/services/supplier-creator.service.ts index 0f214f1c..2ea53756 100644 --- a/modules/supplier/src/api/application/services/supplier-creator.service.ts +++ b/modules/supplier/src/api/application/services/supplier-creator.service.ts @@ -11,7 +11,7 @@ export interface ISupplierCreator { companyId: UniqueID; id: UniqueID; props: ISupplierCreateProps; - unknown: unknown; + transaction?: unknown; }): Promise>; } @@ -30,12 +30,16 @@ export class SupplierCreator implements ISupplierCreator { companyId: UniqueID; id: UniqueID; props: ISupplierCreateProps; - unknown: unknown; + transaction?: unknown; }): Promise> { - const { companyId, id, props, unknown } = params; + const { companyId, id, props, transaction } = params; // 1. Verificar unicidad - const spec = new SupplierNotExistsInCompanySpecification(this.repository, companyId, unknown); + const spec = new SupplierNotExistsInCompanySpecification( + this.repository, + companyId, + transaction + ); const isNew = await spec.isSatisfiedBy(id); @@ -59,7 +63,7 @@ export class SupplierCreator implements ISupplierCreator { const newSupplier = createResult.data; // 3. Persistir agregado - const saveResult = await this.repository.create(newSupplier, unknown); + const saveResult = await this.repository.create(newSupplier, transaction); if (saveResult.isFailure) { return Result.fail(saveResult.error); diff --git a/modules/supplier/src/api/application/services/supplier-finder.service.ts b/modules/supplier/src/api/application/services/supplier-finder.service.ts index 5996eeb9..5a338d10 100644 --- a/modules/supplier/src/api/application/services/supplier-finder.service.ts +++ b/modules/supplier/src/api/application/services/supplier-finder.service.ts @@ -10,25 +10,25 @@ export interface ISupplierFinder { findSupplierById( companyId: UniqueID, supplierId: UniqueID, - unknown?: unknown + transaction?: unknown ): Promise>; findSupplierByTIN( companyId: UniqueID, tin: TINNumber, - unknown?: unknown + transaction?: unknown ): Promise>; supplierExists( companyId: UniqueID, invoiceId: UniqueID, - unknown?: unknown + transaction?: unknown ): Promise>; findSuppliersByCriteria( companyId: UniqueID, criteria: Criteria, - unknown?: unknown + transaction?: unknown ): Promise, Error>>; } @@ -38,32 +38,32 @@ export class SupplierFinder implements ISupplierFinder { async findSupplierById( companyId: UniqueID, supplierId: UniqueID, - unknown?: unknown + transaction?: unknown ): Promise> { - return this.repository.getByIdInCompany(companyId, supplierId, unknown); + return this.repository.getByIdInCompany(companyId, supplierId, transaction); } findSupplierByTIN( companyId: UniqueID, tin: TINNumber, - unknown?: unknown + transaction?: unknown ): Promise> { - return this.repository.getByTINInCompany(companyId, tin, unknown); + return this.repository.getByTINInCompany(companyId, tin, transaction); } async supplierExists( companyId: UniqueID, supplierId: UniqueID, - unknown?: unknown + transaction?: unknown ): Promise> { - return this.repository.existsByIdInCompany(companyId, supplierId, unknown); + return this.repository.existsByIdInCompany(companyId, supplierId, transaction); } async findSuppliersByCriteria( companyId: UniqueID, criteria: Criteria, - unknown?: unknown + transaction?: unknown ): Promise, Error>> { - return this.repository.findByCriteriaInCompany(companyId, criteria, unknown); + return this.repository.findByCriteriaInCompany(companyId, criteria, transaction); } } diff --git a/modules/supplier/tsconfig.json b/modules/supplier/tsconfig.json index a055379d..7e27fb6a 100644 --- a/modules/supplier/tsconfig.json +++ b/modules/supplier/tsconfig.json @@ -4,7 +4,7 @@ "paths": { "@erp/suppliers/*": ["./src/*"] }, - + "baseUrl": ".", "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "target": "ES2022", "useDefineForClassFields": true, diff --git a/packages/rdx-criteria/package.json b/packages/rdx-criteria/package.json index 695fab4f..35b66261 100644 --- a/packages/rdx-criteria/package.json +++ b/packages/rdx-criteria/package.json @@ -1,6 +1,6 @@ { "name": "@repo/rdx-criteria", - "version": "0.6.0", + "version": "0.6.1", "private": true, "type": "module", "sideEffects": false, diff --git a/packages/rdx-ddd/package.json b/packages/rdx-ddd/package.json index c93f34de..9cc41cb8 100644 --- a/packages/rdx-ddd/package.json +++ b/packages/rdx-ddd/package.json @@ -1,6 +1,6 @@ { "name": "@repo/rdx-ddd", - "version": "0.6.0", + "version": "0.6.1", "private": true, "type": "module", "sideEffects": false, diff --git a/packages/rdx-logger/package.json b/packages/rdx-logger/package.json index 33bcc913..cd3bccad 100644 --- a/packages/rdx-logger/package.json +++ b/packages/rdx-logger/package.json @@ -1,6 +1,6 @@ { "name": "@repo/rdx-logger", - "version": "0.6.0", + "version": "0.6.1", "private": true, "type": "module", "sideEffects": false, diff --git a/packages/rdx-ui/tsconfig.json b/packages/rdx-ui/tsconfig.json index 466f5d9a..bd86d0df 100644 --- a/packages/rdx-ui/tsconfig.json +++ b/packages/rdx-ui/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "@repo/typescript-config/react-library.json", "compilerOptions": { + "baseUrl": ".", "paths": { "@repo/rdx-ui/*": ["./src/*"] }, diff --git a/packages/rdx-utils/package.json b/packages/rdx-utils/package.json index c78ab353..0aeb287a 100644 --- a/packages/rdx-utils/package.json +++ b/packages/rdx-utils/package.json @@ -1,6 +1,6 @@ { "name": "@repo/rdx-utils", - "version": "0.6.0", + "version": "0.6.1", "private": true, "type": "module", "sideEffects": false, diff --git a/packages/typescript-config/root.json b/packages/typescript-config/root.json index 0035a314..b5c368af 100644 --- a/packages/typescript-config/root.json +++ b/packages/typescript-config/root.json @@ -2,6 +2,7 @@ "$schema": "https://json.schemastore.org/tsconfig", "display": "Root", "compilerOptions": { + "baseUrl": ".", "paths": { "@erp/core/*": [ "modules/core/src/*" @@ -14,6 +15,9 @@ ], "@erp/customer-invoices/*": [ "modules/customer-invoices/src/*" + ], + "@erp/factuges/*": [ + "modules/factuges/src/*" ] }, "target": "ES2021", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7c414ea6..820a052d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -65,6 +65,9 @@ importers: '@erp/customers': specifier: workspace:* version: link:../../modules/customers + '@erp/factuges': + specifier: workspace:* + version: link:../../modules/factuges '@repo/rdx-logger': specifier: workspace:* version: link:../../packages/rdx-logger