import { City, Country, CurrencyCode, DomainError, EmailAddress, LanguageCode, Name, PhoneNumber, PostalAddress, PostalCode, Province, Street, TINNumber, TaxCode, TextValue, URLAddress, UniqueID, ValidationErrorCollection, type ValidationErrorDetail, extractOrPushError, maybeFromNullableResult, } from "@repo/rdx-ddd"; import { Collection, Result, isNullishOrEmpty } from "@repo/rdx-utils"; import type { CreateCustomerRequestDTO } from "../../../../common"; import { type ICustomerProps, CustomerStatus } from "../../../domain"; /** * Convierte el DTO a las props validadas (CustomerProps). * No construye directamente el agregado. * * @param dto - DTO con los datos de la factura de cliente * @returns * */ export function mapDTOToCreateCustomerProps(dto: CreateCustomerRequestDTO) { try { const errors: ValidationErrorDetail[] = []; const customerId = extractOrPushError(UniqueID.create(dto.id), "id", errors); const status = CustomerStatus.createActive(); const isCompany = dto.is_company === "true"; const reference = extractOrPushError( maybeFromNullableResult(dto.reference, (value) => Name.create(value)), "reference", errors ); const name = extractOrPushError(Name.create(dto.name), "name", errors); const tradeName = extractOrPushError( maybeFromNullableResult(dto.trade_name, (value) => Name.create(value)), "trade_name", errors ); const tinNumber = extractOrPushError( maybeFromNullableResult(dto.tin, (value) => TINNumber.create(value)), "tin", errors ); const street = extractOrPushError( maybeFromNullableResult(dto.street, (value) => Street.create(value)), "street", errors ); const street2 = extractOrPushError( maybeFromNullableResult(dto.street2, (value) => Street.create(value)), "street2", errors ); const city = extractOrPushError( maybeFromNullableResult(dto.city, (value) => City.create(value)), "city", errors ); const province = extractOrPushError( maybeFromNullableResult(dto.province, (value) => Province.create(value)), "province", errors ); const postalCode = extractOrPushError( maybeFromNullableResult(dto.postal_code, (value) => PostalCode.create(value)), "postal_code", errors ); const country = extractOrPushError( maybeFromNullableResult(dto.country, (value) => Country.create(value)), "country", errors ); const primaryEmailAddress = extractOrPushError( maybeFromNullableResult(dto.email_primary, (value) => EmailAddress.create(value)), "email_primary", errors ); const secondaryEmailAddress = extractOrPushError( maybeFromNullableResult(dto.email_secondary, (value) => EmailAddress.create(value)), "email_secondary", errors ); const primaryPhoneNumber = extractOrPushError( maybeFromNullableResult(dto.phone_primary, (value) => PhoneNumber.create(value)), "phone_primary", errors ); const secondaryPhoneNumber = extractOrPushError( maybeFromNullableResult(dto.phone_secondary, (value) => PhoneNumber.create(value)), "phone_secondary", errors ); const primaryMobileNumber = extractOrPushError( maybeFromNullableResult(dto.mobile_primary, (value) => PhoneNumber.create(value)), "mobile_primary", errors ); const secondaryMobileNumber = extractOrPushError( maybeFromNullableResult(dto.mobile_secondary, (value) => PhoneNumber.create(value)), "mobile_secondary", errors ); const faxNumber = extractOrPushError( maybeFromNullableResult(dto.fax, (value) => PhoneNumber.create(value)), "fax", errors ); const website = extractOrPushError( maybeFromNullableResult(dto.website, (value) => URLAddress.create(value)), "website", errors ); const legalRecord = extractOrPushError( maybeFromNullableResult(dto.legal_record, (value) => TextValue.create(value)), "legal_record", errors ); const languageCode = extractOrPushError( LanguageCode.create(dto.language_code), "language_code", errors ); const currencyCode = extractOrPushError( CurrencyCode.create(dto.currency_code), "currency_code", errors ); const defaultTaxes = new Collection(); if (!isNullishOrEmpty(dto.default_taxes)) { dto.default_taxes!.map((taxCode, index) => { const tax = extractOrPushError(TaxCode.create(taxCode), `default_taxes.${index}`, errors); if (tax) { defaultTaxes.add(tax!); } }); } if (errors.length > 0) { return Result.fail(new ValidationErrorCollection("Customer props mapping failed", errors)); } const postalAddressProps = { street: street!, street2: street2!, city: city!, postalCode: postalCode!, province: province!, country: country!, }; const postalAddress = extractOrPushError( PostalAddress.create(postalAddressProps), "address", errors ); const customerProps: Omit = { status: status!, reference: reference!, isCompany: isCompany, name: name!, tradeName: tradeName!, tin: tinNumber!, address: postalAddress!, emailPrimary: primaryEmailAddress!, emailSecondary: secondaryEmailAddress!, phonePrimary: primaryPhoneNumber!, phoneSecondary: secondaryPhoneNumber!, mobilePrimary: primaryMobileNumber!, mobileSecondary: secondaryMobileNumber!, fax: faxNumber!, website: website!, legalRecord: legalRecord!, defaultTaxes: defaultTaxes!, languageCode: languageCode!, currencyCode: currencyCode!, }; return Result.ok({ id: customerId!, props: customerProps }); } catch (err: unknown) { return Result.fail(new DomainError("Customer props mapping failed", { cause: err })); } }