Mejorado VO Tax
This commit is contained in:
parent
54e47fee1b
commit
b9bfdc02aa
@ -77,8 +77,17 @@ export class Tax extends ValueObject<TaxProps> {
|
||||
*/
|
||||
static createFromCode(code: string, provider: TaxCatalogProvider): Result<Tax, Error> {
|
||||
const normalized = (code ?? "").trim().toLowerCase();
|
||||
if (!normalized || !Tax.CODE_REGEX.test(normalized)) {
|
||||
return Result.fail(new Error(`Código de impuesto inválido: "${code}"`));
|
||||
|
||||
const schema = z
|
||||
.string()
|
||||
.min(1, "El código del impuesto es obligatorio.")
|
||||
.max(40, "El código del impuesto no puede exceder 40 caracteres.")
|
||||
.regex(Tax.CODE_REGEX, "El código contiene caracteres no permitidos.");
|
||||
|
||||
const validationResult = schema.safeParse(normalized);
|
||||
|
||||
if (!validationResult.success) {
|
||||
return Result.fail(new Error(validationResult.error.issues.map((e) => e.message).join(", ")));
|
||||
}
|
||||
|
||||
const maybeItem = provider.findByCode(normalized);
|
||||
|
||||
@ -24,9 +24,16 @@ export abstract class SequelizeDomainMapper<TModel extends Model, TModelAttribut
|
||||
return Result.ok(new Collection([], totalCount));
|
||||
}
|
||||
|
||||
const items = _source.map(
|
||||
(value, index) => this.mapToDomain(value as TModel, { index, ...params }).data
|
||||
);
|
||||
const items: TEntity[] = [];
|
||||
for (let index = 0; index < _source.length; index++) {
|
||||
const value = _source[index];
|
||||
const result = this.mapToDomain(value as TModel, { index, ...params });
|
||||
if (result.isFailure) {
|
||||
return Result.fail(result.error);
|
||||
}
|
||||
items.push(result.data);
|
||||
}
|
||||
|
||||
return Result.ok(new Collection(items, totalCount));
|
||||
} catch (error) {
|
||||
return Result.fail(error as Error);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@erp/customer-invoices",
|
||||
"version": "0.0.4",
|
||||
"version": "0.0.5",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { RequestWithAuth, enforceTenant, enforceUser, mockUser } from "@erp/auth/api";
|
||||
import { enforceTenant, enforceUser, mockUser, RequestWithAuth } from "@erp/auth/api";
|
||||
import { ModuleParams, validateRequest } from "@erp/core/api";
|
||||
import { ILogger } from "@repo/rdx-logger";
|
||||
import { Application, NextFunction, Request, Response, Router } from "express";
|
||||
@ -31,9 +31,8 @@ export const customerInvoicesRouter = (params: ModuleParams) => {
|
||||
const deps = buildCustomerInvoiceDependencies(params);
|
||||
|
||||
const router: Router = Router({ mergeParams: true });
|
||||
|
||||
// 🔐 Autenticación + Tenancy para TODO el router
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "production") {
|
||||
// 🔐 Autenticación + Tenancy para TODO el router
|
||||
router.use(
|
||||
(req: Request, res: Response, next: NextFunction) =>
|
||||
mockUser(req as RequestWithAuth, res, next) // Debe ir antes de las rutas protegidas
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { ISequelizeDomainMapper, MapperParamsType, SequelizeDomainMapper } from "@erp/core/api";
|
||||
import {
|
||||
UniqueID,
|
||||
ValidationErrorCollection,
|
||||
ValidationErrorDetail,
|
||||
extractOrPushError,
|
||||
maybeFromNullableVO,
|
||||
toNullable,
|
||||
UniqueID,
|
||||
ValidationErrorCollection,
|
||||
ValidationErrorDetail,
|
||||
} from "@repo/rdx-ddd";
|
||||
import { Result } from "@repo/rdx-utils";
|
||||
import {
|
||||
@ -74,7 +74,7 @@ export class CustomerInvoiceItemDomainMapper
|
||||
|
||||
const unitAmount = extractOrPushError(
|
||||
maybeFromNullableVO(source.unit_amount_value, (value) =>
|
||||
ItemAmount.create({ value, currency_code: attributes.currencyCode!.code })
|
||||
ItemAmount.create({ value, currency_code: attributes.currencyCode?.code })
|
||||
),
|
||||
`items[${index}].unit_amount`,
|
||||
errors
|
||||
@ -130,6 +130,13 @@ export class CustomerInvoiceItemDomainMapper
|
||||
});
|
||||
}
|
||||
|
||||
// Si hubo errores de mapeo, devolvemos colección de validación
|
||||
if (errors.length > 0) {
|
||||
return Result.fail(
|
||||
new ValidationErrorCollection("Customer invoice item mapping failed [mapToDomain]", errors)
|
||||
);
|
||||
}
|
||||
|
||||
const taxes = ItemTaxes.create(taxesResults.data.getAll());
|
||||
|
||||
// 3) Construcción del elemento de dominio
|
||||
|
||||
@ -226,7 +226,7 @@ export class CustomerInvoiceDomainMapper
|
||||
if (itemsResults.isFailure) {
|
||||
errors.push({
|
||||
path: "items",
|
||||
message: recipientResult.error.message,
|
||||
message: itemsResults.error.message,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { JsonTaxCatalogProvider } from "@erp/core";
|
||||
import {
|
||||
ISequelizeDomainMapper,
|
||||
MapperParamsType,
|
||||
@ -5,13 +6,11 @@ import {
|
||||
Tax,
|
||||
} from "@erp/core/api";
|
||||
|
||||
import { JsonTaxCatalogProvider } from "@erp/core";
|
||||
|
||||
import {
|
||||
extractOrPushError,
|
||||
UniqueID,
|
||||
ValidationErrorCollection,
|
||||
ValidationErrorDetail,
|
||||
extractOrPushError,
|
||||
} from "@repo/rdx-ddd";
|
||||
import { Result } from "@repo/rdx-utils";
|
||||
import { CustomerInvoiceItem } from "../../../domain";
|
||||
@ -65,6 +64,13 @@ export class ItemTaxesDomainMapper
|
||||
errors
|
||||
);
|
||||
|
||||
// Si hubo errores de mapeo, devolvemos colección de validación
|
||||
if (errors.length > 0) {
|
||||
return Result.fail(
|
||||
new ValidationErrorCollection("Invoice item tax mapping failed [mapToDomain]", errors)
|
||||
);
|
||||
}
|
||||
|
||||
// Creación del objeto de dominio
|
||||
const createResult = Tax.create(tax!);
|
||||
if (createResult.isFailure) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user