import { City, Country, CurrencyCode, DomainError, EmailAddress, LanguageCode, Name, PhoneNumber, type PostalAddressPatchProps, PostalCode, Province, Street, TINNumber, type TaxCode, TextValue, URLAddress, type UniqueID, ValidationErrorCollection, type ValidationErrorDetail, extractOrPushError, maybeFromNullableResult, } from "@repo/rdx-ddd"; import { Collection, Result, isNullishOrEmpty, toPatchField } from "@repo/rdx-utils"; import type { UpdateCustomerByIdRequestDTO } from "../../../common"; import type { CustomerPatchProps } from "../../domain"; /** * UpdateCustomerInputMapper * Convierte el DTO a las props validadas (CustomerProps). * No construye directamente el agregado. * Tri-estado: * - campo omitido → no se cambia * - campo con valor null/"" → se quita el valor -> set(None()), * - campo con valor no-vacío → se pone el nuevo valor -> set(Some(VO)). * * @param dto - DTO con los datos a cambiar en el cliente * @returns Cambios en las propiedades del cliente * */ export interface IUpdateCustomerInputMapper { map( dto: UpdateCustomerByIdRequestDTO, params: { companyId: UniqueID } ): Result; } export class UpdateCustomerInputMapper implements IUpdateCustomerInputMapper { public map(dto: UpdateCustomerByIdRequestDTO, params: { companyId: UniqueID }) { try { const errors: ValidationErrorDetail[] = []; const customerPatchProps: CustomerPatchProps = {}; console.log(dto); toPatchField(dto.reference).ifSet((reference) => { customerPatchProps.reference = extractOrPushError( maybeFromNullableResult(reference, (value) => Name.create(value)), "reference", errors ); }); toPatchField(dto.is_company).ifSet((is_company) => { if (isNullishOrEmpty(is_company)) { errors.push({ path: "is_company", message: "is_company cannot be empty" }); return; } customerPatchProps.isCompany = extractOrPushError( Result.ok(Boolean(is_company!)), "is_company", errors ); }); toPatchField(dto.name).ifSet((name) => { if (isNullishOrEmpty(name)) { errors.push({ path: "name", message: "Name cannot be empty" }); return; } customerPatchProps.name = extractOrPushError(Name.create(name!), "name", errors); }); toPatchField(dto.trade_name).ifSet((trade_name) => { customerPatchProps.tradeName = extractOrPushError( maybeFromNullableResult(trade_name, (value) => Name.create(value)), "trade_name", errors ); }); toPatchField(dto.tin).ifSet((tin) => { customerPatchProps.tin = extractOrPushError( maybeFromNullableResult(tin, (value) => TINNumber.create(value)), "tin", errors ); }); toPatchField(dto.email_primary).ifSet((email_primary) => { customerPatchProps.emailPrimary = extractOrPushError( maybeFromNullableResult(email_primary, (value) => EmailAddress.create(value)), "email_primary", errors ); }); toPatchField(dto.email_secondary).ifSet((email_secondary) => { customerPatchProps.emailSecondary = extractOrPushError( maybeFromNullableResult(email_secondary, (value) => EmailAddress.create(value)), "email_secondary", errors ); }); toPatchField(dto.mobile_primary).ifSet((mobile_primary) => { customerPatchProps.mobilePrimary = extractOrPushError( maybeFromNullableResult(mobile_primary, (value) => PhoneNumber.create(value)), "mobile_primary", errors ); }); toPatchField(dto.mobile_secondary).ifSet((mobile_secondary) => { customerPatchProps.mobilePrimary = extractOrPushError( maybeFromNullableResult(mobile_secondary, (value) => PhoneNumber.create(value)), "mobile_secondary", errors ); }); toPatchField(dto.phone_primary).ifSet((phone_primary) => { customerPatchProps.phonePrimary = extractOrPushError( maybeFromNullableResult(phone_primary, (value) => PhoneNumber.create(value)), "phone_primary", errors ); }); toPatchField(dto.phone_secondary).ifSet((phone_secondary) => { customerPatchProps.phoneSecondary = extractOrPushError( maybeFromNullableResult(phone_secondary, (value) => PhoneNumber.create(value)), "phone_secondary", errors ); }); toPatchField(dto.fax).ifSet((fax) => { customerPatchProps.fax = extractOrPushError( maybeFromNullableResult(fax, (value) => PhoneNumber.create(value)), "fax", errors ); }); toPatchField(dto.website).ifSet((website) => { customerPatchProps.website = extractOrPushError( maybeFromNullableResult(website, (value) => URLAddress.create(value)), "website", errors ); }); toPatchField(dto.legal_record).ifSet((legalRecord) => { customerPatchProps.legalRecord = extractOrPushError( maybeFromNullableResult(legalRecord, (value) => TextValue.create(value)), "legal_record", errors ); }); toPatchField(dto.language_code).ifSet((languageCode) => { if (isNullishOrEmpty(languageCode)) { errors.push({ path: "language_code", message: "Language code cannot be empty" }); return; } customerPatchProps.languageCode = extractOrPushError( LanguageCode.create(languageCode!), "language_code", errors ); }); toPatchField(dto.currency_code).ifSet((currencyCode) => { if (isNullishOrEmpty(currencyCode)) { errors.push({ path: "currency_code", message: "Currency code cannot be empty" }); return; } customerPatchProps.currencyCode = extractOrPushError( CurrencyCode.create(currencyCode!), "currency_code", errors ); }); // Default taxes const defaultTaxesCollection = new Collection(); /*toPatchField(dto.default_taxes).ifSet((defaultTaxes) => { customerPatchProps.defaultTaxes = defaultTaxesCollection; if (isNullishOrEmpty(defaultTaxes)) { return; } defaultTaxes!.forEach((taxCode, index) => { const tax = extractOrPushError(TaxCode.create(taxCode), `default_taxes.${index}`, errors); if (tax && customerPatchProps.defaultTaxes) { customerPatchProps.defaultTaxes.add(tax); } }); });*/ // PostalAddress const addressPatchProps = this.mapPostalAddress(dto, errors); if (addressPatchProps) { customerPatchProps.address = addressPatchProps; } if (errors.length > 0) { return Result.fail( new ValidationErrorCollection("Customer props mapping failed (update)", errors) ); } return Result.ok(customerPatchProps); } catch (err: unknown) { return Result.fail(new DomainError("Customer props mapping failed", { cause: err })); } } public mapPostalAddress( dto: UpdateCustomerByIdRequestDTO, errors: ValidationErrorDetail[] ): PostalAddressPatchProps | undefined { const postalAddressPatchProps: PostalAddressPatchProps = {}; toPatchField(dto.street).ifSet((street) => { postalAddressPatchProps.street = extractOrPushError( maybeFromNullableResult(street, (value) => Street.create(value)), "street", errors ); }); toPatchField(dto.street2).ifSet((street2) => { postalAddressPatchProps.street2 = extractOrPushError( maybeFromNullableResult(street2, (value) => Street.create(value)), "street2", errors ); }); toPatchField(dto.city).ifSet((city) => { postalAddressPatchProps.city = extractOrPushError( maybeFromNullableResult(city, (value) => City.create(value)), "city", errors ); }); toPatchField(dto.province).ifSet((province) => { postalAddressPatchProps.province = extractOrPushError( maybeFromNullableResult(province, (value) => Province.create(value)), "province", errors ); }); toPatchField(dto.postal_code).ifSet((postalCode) => { postalAddressPatchProps.postalCode = extractOrPushError( maybeFromNullableResult(postalCode, (value) => PostalCode.create(value)), "postal_code", errors ); }); toPatchField(dto.country).ifSet((country) => { postalAddressPatchProps.country = extractOrPushError( maybeFromNullableResult(country, (value) => Country.create(value)), "country", errors ); }); return Object.keys(postalAddressPatchProps).length > 0 ? postalAddressPatchProps : undefined; } }