Uecko_ERP/modules/customer-invoices/src/api/infrastructure/mappers/domain/invoice-recipient.mapper.ts
2025-10-18 21:57:52 +02:00

118 lines
3.6 KiB
TypeScript

import {
City,
Country,
Name,
PostalCode,
Province,
Street,
TINNumber,
ValidationErrorCollection,
ValidationErrorDetail,
extractOrPushError,
maybeFromNullableVO,
} from "@repo/rdx-ddd";
import { MapperParamsType } from "@erp/core/api";
import { Maybe, Result } from "@repo/rdx-utils";
import { CustomerInvoiceProps, InvoiceRecipient } from "../../../domain";
import { CustomerInvoiceModel } from "../../sequelize";
export class InvoiceRecipientDomainMapper {
public mapToDomain(
source: CustomerInvoiceModel,
params?: MapperParamsType
): Result<Maybe<InvoiceRecipient>, Error> {
/**
* - Factura === proforma -> datos de "current_customer"
* - Factura !== proforma -> snapshot de los datos (campos customer_*)
*/
const { errors, attributes } = params as {
errors: ValidationErrorDetail[];
attributes: Partial<CustomerInvoiceProps>;
};
const { isProforma } = attributes;
if (isProforma && !source.current_customer) {
errors.push({
path: "current_customer",
message: "Current customer not included in query (InvoiceRecipientMapper)",
});
}
const _name = isProforma ? source.current_customer.name : source.customer_name!;
const _tin = isProforma ? source.current_customer.tin : source.customer_tin!;
const _street = isProforma ? source.current_customer.street : source.customer_street!;
const _street2 = isProforma ? source.current_customer.street2 : source.customer_street2!;
const _city = isProforma ? source.current_customer.city : source.customer_city!;
const _postal_code = isProforma
? source.current_customer.postal_code
: source.customer_postal_code!;
const _province = isProforma ? source.current_customer.province : source.customer_province!;
const _country = isProforma ? source.current_customer.country : source.customer_country!;
// Customer (snapshot)
const customerName = extractOrPushError(Name.create(_name!), "customer_name", errors);
const customerTin = extractOrPushError(TINNumber.create(_tin!), "customer_tin", errors);
const customerStreet = extractOrPushError(
maybeFromNullableVO(_street, (value) => Street.create(value)),
"customer_street",
errors
);
const customerStreet2 = extractOrPushError(
maybeFromNullableVO(_street2, (value) => Street.create(value)),
"customer_street2",
errors
);
const customerCity = extractOrPushError(
maybeFromNullableVO(_city, (value) => City.create(value)),
"customer_city",
errors
);
const customerProvince = extractOrPushError(
maybeFromNullableVO(_province, (value) => Province.create(value)),
"customer_province",
errors
);
const customerPostalCode = extractOrPushError(
maybeFromNullableVO(_postal_code, (value) => PostalCode.create(value)),
"customer_postal_code",
errors
);
const customerCountry = extractOrPushError(
maybeFromNullableVO(_country, (value) => Country.create(value)),
"customer_country",
errors
);
const createResult = InvoiceRecipient.create({
name: customerName!,
tin: customerTin!,
street: customerStreet!,
street2: customerStreet2!,
city: customerCity!,
postalCode: customerPostalCode!,
province: customerProvince!,
country: customerCountry!,
});
if (createResult.isFailure) {
return Result.fail(
new ValidationErrorCollection("Invoice recipient entity creation failed", [
{ path: "recipient", message: createResult.error.message },
])
);
}
return Result.ok(Maybe.some(createResult.data));
}
}