.
This commit is contained in:
parent
330240deaa
commit
108bbea5fc
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "0.6.0",
|
||||
"version": "0.6.1",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "WEB: Vite (Chrome)",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
"compilerOptions": {
|
||||
"resolveJsonModule": true,
|
||||
"esModuleInterop": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@erp/auth",
|
||||
"version": "0.6.0",
|
||||
"version": "0.6.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@erp/core",
|
||||
"version": "0.6.0",
|
||||
"version": "0.6.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
"paths": {
|
||||
"@erp/core/*": ["./src/*"]
|
||||
},
|
||||
|
||||
"baseUrl": ".",
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
"target": "ES2022",
|
||||
"useDefineForClassFields": true,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@erp/customer-invoices",
|
||||
"version": "0.6.0",
|
||||
"version": "0.6.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -22,6 +22,12 @@ export interface IProformaRepository {
|
||||
transaction: unknown
|
||||
): Promise<Result<Proforma, Error>>;
|
||||
|
||||
getByFactuGESIdInCompany(
|
||||
companyId: UniqueID,
|
||||
factugesId: string,
|
||||
transaction: unknown
|
||||
): Promise<Result<Proforma, Error>>;
|
||||
|
||||
findByCriteriaInCompany(
|
||||
companyId: UniqueID,
|
||||
criteria: Criteria,
|
||||
|
||||
@ -13,6 +13,12 @@ export interface IProformaFinder {
|
||||
transaction?: unknown
|
||||
): Promise<Result<Proforma, Error>>;
|
||||
|
||||
findProformaByFactuGESId(
|
||||
companyId: UniqueID,
|
||||
factugesId: string,
|
||||
transaction?: unknown
|
||||
): Promise<Result<Proforma, Error>>;
|
||||
|
||||
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<Result<Proforma, Error>> {
|
||||
return this.repository.getByFactuGESIdInCompany(companyId, factugesId, transaction);
|
||||
}
|
||||
|
||||
async proformaExists(
|
||||
companyId: UniqueID,
|
||||
proformaId: UniqueID,
|
||||
|
||||
@ -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<Result<Proforma, Error>>;
|
||||
|
||||
getProformaByFactuGESId: (
|
||||
factugesId: string,
|
||||
context: IProformaServicesContext
|
||||
) => Promise<Result<Proforma, Error>>;
|
||||
|
||||
getProformaSnapshotById: (
|
||||
id: UniqueID,
|
||||
context: IProformaServicesContext
|
||||
|
||||
@ -10,6 +10,8 @@ import {
|
||||
proformasRouter,
|
||||
} from "./infrastructure";
|
||||
|
||||
export type { IProformaPublicServices } from "./application";
|
||||
|
||||
export const customerInvoicesAPIModule: IModuleServer = {
|
||||
name: "customer-invoices",
|
||||
version: "1.0.0",
|
||||
|
||||
@ -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
|
||||
);
|
||||
|
||||
@ -28,6 +28,11 @@ export type ProformaPublicServices = {
|
||||
context: ProformaServicesContext
|
||||
) => Promise<Result<Proforma, Error>>;
|
||||
|
||||
getProformaByFactuGESId: (
|
||||
factugesId: string,
|
||||
context: ProformaServicesContext
|
||||
) => Promise<Result<Proforma, Error>>;
|
||||
|
||||
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);
|
||||
|
||||
@ -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<ProformaCreateProps>;
|
||||
parent: Partial<IProformaCreateProps>;
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
@ -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<CustomerInvoice, Error>
|
||||
*/
|
||||
async getByFactuGESIdInCompany(
|
||||
companyId: UniqueID,
|
||||
factugesId: string,
|
||||
transaction: Transaction,
|
||||
options: FindOptions<InferAttributes<CustomerInvoiceModel>> = {}
|
||||
): Promise<Result<Proforma, Error>> {
|
||||
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<InferAttributes<CustomerInvoiceModel>> = {
|
||||
...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).
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
"paths": {
|
||||
"@erp/customer-invoices/*": ["./src/*"]
|
||||
},
|
||||
|
||||
"baseUrl": ".",
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
"target": "ES2022",
|
||||
"useDefineForClassFields": true,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@erp/customers",
|
||||
"description": "Customers",
|
||||
"version": "0.6.0",
|
||||
"version": "0.6.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -11,7 +11,7 @@ export interface ICustomerCreator {
|
||||
companyId: UniqueID;
|
||||
id: UniqueID;
|
||||
props: ICustomerCreateProps;
|
||||
unknown: unknown;
|
||||
transaction?: unknown;
|
||||
}): Promise<Result<Customer, Error>>;
|
||||
}
|
||||
|
||||
@ -30,12 +30,16 @@ export class CustomerCreator implements ICustomerCreator {
|
||||
companyId: UniqueID;
|
||||
id: UniqueID;
|
||||
props: ICustomerCreateProps;
|
||||
unknown: unknown;
|
||||
transaction?: unknown;
|
||||
}): Promise<Result<Customer, Error>> {
|
||||
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);
|
||||
|
||||
@ -10,25 +10,25 @@ export interface ICustomerFinder {
|
||||
findCustomerById(
|
||||
companyId: UniqueID,
|
||||
customerId: UniqueID,
|
||||
unknown?: unknown
|
||||
transaction?: unknown
|
||||
): Promise<Result<Customer, Error>>;
|
||||
|
||||
findCustomerByTIN(
|
||||
companyId: UniqueID,
|
||||
tin: TINNumber,
|
||||
unknown?: unknown
|
||||
transaction?: unknown
|
||||
): Promise<Result<Customer, Error>>;
|
||||
|
||||
customerExists(
|
||||
companyId: UniqueID,
|
||||
invoiceId: UniqueID,
|
||||
unknown?: unknown
|
||||
transaction?: unknown
|
||||
): Promise<Result<boolean, Error>>;
|
||||
|
||||
findCustomersByCriteria(
|
||||
companyId: UniqueID,
|
||||
criteria: Criteria,
|
||||
unknown?: unknown
|
||||
transaction?: unknown
|
||||
): Promise<Result<Collection<CustomerSummary>, Error>>;
|
||||
}
|
||||
|
||||
@ -38,32 +38,32 @@ export class CustomerFinder implements ICustomerFinder {
|
||||
async findCustomerById(
|
||||
companyId: UniqueID,
|
||||
customerId: UniqueID,
|
||||
unknown?: unknown
|
||||
transaction?: unknown
|
||||
): Promise<Result<Customer, Error>> {
|
||||
return this.repository.getByIdInCompany(companyId, customerId, unknown);
|
||||
return this.repository.getByIdInCompany(companyId, customerId, transaction);
|
||||
}
|
||||
|
||||
findCustomerByTIN(
|
||||
companyId: UniqueID,
|
||||
tin: TINNumber,
|
||||
unknown?: unknown
|
||||
transaction?: unknown
|
||||
): Promise<Result<Customer, Error>> {
|
||||
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<Result<boolean, Error>> {
|
||||
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<Result<Collection<CustomerSummary>, Error>> {
|
||||
return this.repository.findByCriteriaInCompany(companyId, criteria, unknown);
|
||||
return this.repository.findByCriteriaInCompany(companyId, criteria, transaction);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 = {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
"paths": {
|
||||
"@erp/customers/*": ["./src/*"]
|
||||
},
|
||||
|
||||
"baseUrl": ".",
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
"target": "ES2022",
|
||||
"useDefineForClassFields": true,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@erp/factuges",
|
||||
"version": "0.6.0",
|
||||
"version": "0.6.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -83,6 +83,7 @@ export type ProformaDraftItem = {
|
||||
};
|
||||
|
||||
export type ProformaDraft = {
|
||||
factugesID: string;
|
||||
series: Maybe<InvoiceSerie>;
|
||||
invoiceDate: UtcDate;
|
||||
operationDate: Maybe<UtcDate>;
|
||||
@ -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!,
|
||||
|
||||
@ -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<ProformaPublicServices["createProforma"]>["1"];
|
||||
type CreateProformaProps = Parameters<IProformaPublicServices["createProforma"]>["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);
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
"paths": {
|
||||
"@erp/factuges/*": ["./src/*"]
|
||||
},
|
||||
|
||||
"baseUrl": ".",
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
"target": "ES2022",
|
||||
"useDefineForClassFields": true,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
"paths": {
|
||||
"@erp/supplier-invoices/*": ["./src/*"]
|
||||
},
|
||||
|
||||
"baseUrl": ".",
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
"target": "ES2022",
|
||||
"useDefineForClassFields": true,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@erp/suppliers",
|
||||
"description": "Suppliers",
|
||||
"version": "0.6.0",
|
||||
"version": "0.6.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -11,7 +11,7 @@ export interface ISupplierCreator {
|
||||
companyId: UniqueID;
|
||||
id: UniqueID;
|
||||
props: ISupplierCreateProps;
|
||||
unknown: unknown;
|
||||
transaction?: unknown;
|
||||
}): Promise<Result<Supplier, Error>>;
|
||||
}
|
||||
|
||||
@ -30,12 +30,16 @@ export class SupplierCreator implements ISupplierCreator {
|
||||
companyId: UniqueID;
|
||||
id: UniqueID;
|
||||
props: ISupplierCreateProps;
|
||||
unknown: unknown;
|
||||
transaction?: unknown;
|
||||
}): Promise<Result<Supplier, Error>> {
|
||||
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);
|
||||
|
||||
@ -10,25 +10,25 @@ export interface ISupplierFinder {
|
||||
findSupplierById(
|
||||
companyId: UniqueID,
|
||||
supplierId: UniqueID,
|
||||
unknown?: unknown
|
||||
transaction?: unknown
|
||||
): Promise<Result<Supplier, Error>>;
|
||||
|
||||
findSupplierByTIN(
|
||||
companyId: UniqueID,
|
||||
tin: TINNumber,
|
||||
unknown?: unknown
|
||||
transaction?: unknown
|
||||
): Promise<Result<Supplier, Error>>;
|
||||
|
||||
supplierExists(
|
||||
companyId: UniqueID,
|
||||
invoiceId: UniqueID,
|
||||
unknown?: unknown
|
||||
transaction?: unknown
|
||||
): Promise<Result<boolean, Error>>;
|
||||
|
||||
findSuppliersByCriteria(
|
||||
companyId: UniqueID,
|
||||
criteria: Criteria,
|
||||
unknown?: unknown
|
||||
transaction?: unknown
|
||||
): Promise<Result<Collection<SupplierSummary>, Error>>;
|
||||
}
|
||||
|
||||
@ -38,32 +38,32 @@ export class SupplierFinder implements ISupplierFinder {
|
||||
async findSupplierById(
|
||||
companyId: UniqueID,
|
||||
supplierId: UniqueID,
|
||||
unknown?: unknown
|
||||
transaction?: unknown
|
||||
): Promise<Result<Supplier, Error>> {
|
||||
return this.repository.getByIdInCompany(companyId, supplierId, unknown);
|
||||
return this.repository.getByIdInCompany(companyId, supplierId, transaction);
|
||||
}
|
||||
|
||||
findSupplierByTIN(
|
||||
companyId: UniqueID,
|
||||
tin: TINNumber,
|
||||
unknown?: unknown
|
||||
transaction?: unknown
|
||||
): Promise<Result<Supplier, Error>> {
|
||||
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<Result<boolean, Error>> {
|
||||
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<Result<Collection<SupplierSummary>, Error>> {
|
||||
return this.repository.findByCriteriaInCompany(companyId, criteria, unknown);
|
||||
return this.repository.findByCriteriaInCompany(companyId, criteria, transaction);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
"paths": {
|
||||
"@erp/suppliers/*": ["./src/*"]
|
||||
},
|
||||
|
||||
"baseUrl": ".",
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
"target": "ES2022",
|
||||
"useDefineForClassFields": true,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@repo/rdx-criteria",
|
||||
"version": "0.6.0",
|
||||
"version": "0.6.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@repo/rdx-ddd",
|
||||
"version": "0.6.0",
|
||||
"version": "0.6.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@repo/rdx-logger",
|
||||
"version": "0.6.0",
|
||||
"version": "0.6.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
{
|
||||
"extends": "@repo/typescript-config/react-library.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@repo/rdx-ui/*": ["./src/*"]
|
||||
},
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@repo/rdx-utils",
|
||||
"version": "0.6.0",
|
||||
"version": "0.6.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user