286 lines
8.6 KiB
TypeScript
286 lines
8.6 KiB
TypeScript
import {
|
|
City,
|
|
Country,
|
|
CurrencyCode,
|
|
DomainError,
|
|
EmailAddress,
|
|
LanguageCode,
|
|
Name,
|
|
PhoneNumber,
|
|
type PostalAddressPatchProps,
|
|
PostalCode,
|
|
Province,
|
|
Street,
|
|
TINNumber,
|
|
TextValue,
|
|
URLAddress,
|
|
type UniqueID,
|
|
ValidationErrorCollection,
|
|
type ValidationErrorDetail,
|
|
extractOrPushError,
|
|
maybeFromNullableResult,
|
|
} from "@repo/rdx-ddd";
|
|
import { Result, toPatchField } from "@repo/rdx-utils";
|
|
|
|
import type {
|
|
UpdateCustomerAddressPatchRequestDTO,
|
|
UpdateCustomerByIdRequestDTO,
|
|
UpdateCustomerContactPatchRequestDTO,
|
|
} 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<CustomerPatchProps, Error>;
|
|
}
|
|
|
|
export class UpdateCustomerInputMapper implements IUpdateCustomerInputMapper {
|
|
public map(
|
|
dto: UpdateCustomerByIdRequestDTO,
|
|
params: { companyId: UniqueID }
|
|
): Result<CustomerPatchProps, Error> {
|
|
try {
|
|
const errors: ValidationErrorDetail[] = [];
|
|
const customerPatchProps: CustomerPatchProps = {};
|
|
|
|
toPatchField(dto.reference).ifSetOrNull((reference) => {
|
|
customerPatchProps.reference = extractOrPushError(
|
|
maybeFromNullableResult(reference, (value) => Name.create(value)),
|
|
"reference",
|
|
errors
|
|
);
|
|
});
|
|
|
|
toPatchField(dto.is_company).ifSet((isCompany) => {
|
|
customerPatchProps.isCompany = isCompany;
|
|
});
|
|
|
|
toPatchField(dto.name).ifSet((name) => {
|
|
customerPatchProps.name = extractOrPushError(Name.create(name), "name", errors);
|
|
});
|
|
|
|
toPatchField(dto.trade_name).ifSetOrNull((tradeName) => {
|
|
customerPatchProps.tradeName = extractOrPushError(
|
|
maybeFromNullableResult(tradeName, (value) => Name.create(value)),
|
|
"trade_name",
|
|
errors
|
|
);
|
|
});
|
|
|
|
toPatchField(dto.tin).ifSetOrNull((tin) => {
|
|
customerPatchProps.tin = extractOrPushError(
|
|
maybeFromNullableResult(tin, (value) => TINNumber.create(value)),
|
|
"tin",
|
|
errors
|
|
);
|
|
});
|
|
|
|
toPatchField(dto.legal_record).ifSetOrNull((legalRecord) => {
|
|
customerPatchProps.legalRecord = extractOrPushError(
|
|
maybeFromNullableResult(legalRecord, (value) => TextValue.create(value)),
|
|
"legal_record",
|
|
errors
|
|
);
|
|
});
|
|
|
|
toPatchField(dto.language_code).ifSet((languageCode) => {
|
|
customerPatchProps.languageCode = extractOrPushError(
|
|
LanguageCode.create(languageCode),
|
|
"language_code",
|
|
errors
|
|
);
|
|
});
|
|
|
|
toPatchField(dto.currency_code).ifSet((currencyCode) => {
|
|
customerPatchProps.currencyCode = extractOrPushError(
|
|
CurrencyCode.create(currencyCode),
|
|
"currency_code",
|
|
errors
|
|
);
|
|
});
|
|
|
|
/**
|
|
* Se mantiene la compatibilidad con el contrato actual.
|
|
* Cuando defaultTaxes tenga un contrato final estable, aquí conviene
|
|
* mapearlo a CustomerTaxes/Collection<TaxCode> con su schema semántico real.
|
|
*/
|
|
toPatchField(dto.default_taxes).ifSet((_defaultTaxes) => {
|
|
errors.push({
|
|
path: "default_taxes",
|
|
message: "default_taxes mapping is not implemented yet",
|
|
});
|
|
});
|
|
|
|
const addressPatchProps = this.mapPostalAddress(dto.address, errors);
|
|
if (addressPatchProps) {
|
|
customerPatchProps.address = addressPatchProps;
|
|
}
|
|
|
|
this.mapContact(dto.contact, customerPatchProps, errors);
|
|
|
|
if (errors.length > 0) {
|
|
return Result.fail(
|
|
new ValidationErrorCollection("Customer props mapping failed (update)", errors)
|
|
);
|
|
}
|
|
|
|
console.log("Mapped CustomerPatchProps:", customerPatchProps);
|
|
|
|
return Result.ok(customerPatchProps);
|
|
} catch (err: unknown) {
|
|
return Result.fail(new DomainError("Customer props mapping failed (update)", { cause: err }));
|
|
}
|
|
}
|
|
|
|
private mapPostalAddress(
|
|
dto: UpdateCustomerAddressPatchRequestDTO | undefined,
|
|
errors: ValidationErrorDetail[]
|
|
): PostalAddressPatchProps | undefined {
|
|
if (!dto) {
|
|
return undefined;
|
|
}
|
|
|
|
const postalAddressPatchProps: PostalAddressPatchProps = {};
|
|
|
|
toPatchField(dto.street).ifSetOrNull((street) => {
|
|
postalAddressPatchProps.street = extractOrPushError(
|
|
maybeFromNullableResult(street, (value) => Street.create(value)),
|
|
"address.street",
|
|
errors
|
|
);
|
|
});
|
|
|
|
toPatchField(dto.street2).ifSetOrNull((street2) => {
|
|
postalAddressPatchProps.street2 = extractOrPushError(
|
|
maybeFromNullableResult(street2, (value) => Street.create(value)),
|
|
"address.street2",
|
|
errors
|
|
);
|
|
});
|
|
|
|
toPatchField(dto.city).ifSetOrNull((city) => {
|
|
postalAddressPatchProps.city = extractOrPushError(
|
|
maybeFromNullableResult(city, (value) => City.create(value)),
|
|
"address.city",
|
|
errors
|
|
);
|
|
});
|
|
|
|
toPatchField(dto.province).ifSetOrNull((province) => {
|
|
postalAddressPatchProps.province = extractOrPushError(
|
|
maybeFromNullableResult(province, (value) => Province.create(value)),
|
|
"address.province",
|
|
errors
|
|
);
|
|
});
|
|
|
|
toPatchField(dto.postal_code).ifSetOrNull((postalCode) => {
|
|
postalAddressPatchProps.postalCode = extractOrPushError(
|
|
maybeFromNullableResult(postalCode, (value) => PostalCode.create(value)),
|
|
"address.postal_code",
|
|
errors
|
|
);
|
|
});
|
|
|
|
toPatchField(dto.country).ifSetOrNull((country) => {
|
|
postalAddressPatchProps.country = extractOrPushError(
|
|
maybeFromNullableResult(country, (value) => Country.create(value)),
|
|
"address.country",
|
|
errors
|
|
);
|
|
});
|
|
|
|
return Object.keys(postalAddressPatchProps).length > 0 ? postalAddressPatchProps : undefined;
|
|
}
|
|
|
|
private mapContact(
|
|
dto: UpdateCustomerContactPatchRequestDTO | undefined,
|
|
customerPatchProps: CustomerPatchProps,
|
|
errors: ValidationErrorDetail[]
|
|
): void {
|
|
if (!dto) {
|
|
return;
|
|
}
|
|
|
|
toPatchField(dto.email_primary).ifSetOrNull((emailPrimary) => {
|
|
customerPatchProps.emailPrimary = extractOrPushError(
|
|
maybeFromNullableResult(emailPrimary, (value) => EmailAddress.create(value)),
|
|
"contact.email_primary",
|
|
errors
|
|
);
|
|
});
|
|
|
|
toPatchField(dto.email_secondary).ifSetOrNull((emailSecondary) => {
|
|
customerPatchProps.emailSecondary = extractOrPushError(
|
|
maybeFromNullableResult(emailSecondary, (value) => EmailAddress.create(value)),
|
|
"contact.email_secondary",
|
|
errors
|
|
);
|
|
});
|
|
|
|
toPatchField(dto.phone_primary).ifSetOrNull((phonePrimary) => {
|
|
customerPatchProps.phonePrimary = extractOrPushError(
|
|
maybeFromNullableResult(phonePrimary, (value) => PhoneNumber.create(value)),
|
|
"contact.phone_primary",
|
|
errors
|
|
);
|
|
});
|
|
|
|
toPatchField(dto.phone_secondary).ifSetOrNull((phoneSecondary) => {
|
|
customerPatchProps.phoneSecondary = extractOrPushError(
|
|
maybeFromNullableResult(phoneSecondary, (value) => PhoneNumber.create(value)),
|
|
"contact.phone_secondary",
|
|
errors
|
|
);
|
|
});
|
|
|
|
toPatchField(dto.mobile_primary).ifSetOrNull((mobilePrimary) => {
|
|
customerPatchProps.mobilePrimary = extractOrPushError(
|
|
maybeFromNullableResult(mobilePrimary, (value) => PhoneNumber.create(value)),
|
|
"contact.mobile_primary",
|
|
errors
|
|
);
|
|
});
|
|
|
|
toPatchField(dto.mobile_secondary).ifSetOrNull((mobileSecondary) => {
|
|
customerPatchProps.mobileSecondary = extractOrPushError(
|
|
maybeFromNullableResult(mobileSecondary, (value) => PhoneNumber.create(value)),
|
|
"contact.mobile_secondary",
|
|
errors
|
|
);
|
|
});
|
|
|
|
toPatchField(dto.fax).ifSetOrNull((fax) => {
|
|
customerPatchProps.fax = extractOrPushError(
|
|
maybeFromNullableResult(fax, (value) => PhoneNumber.create(value)),
|
|
"contact.fax",
|
|
errors
|
|
);
|
|
});
|
|
|
|
toPatchField(dto.website).ifSetOrNull((website) => {
|
|
customerPatchProps.website = extractOrPushError(
|
|
maybeFromNullableResult(website, (value) => URLAddress.create(value)),
|
|
"contact.website",
|
|
errors
|
|
);
|
|
});
|
|
}
|
|
}
|