290 lines
8.9 KiB
TypeScript
290 lines
8.9 KiB
TypeScript
|
|
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<CustomerPatchProps>;
|
||
|
|
}
|
||
|
|
|
||
|
|
export class UpdateCustomerInputMapper implements IUpdateCustomerInputMapper {
|
||
|
|
public map(dto: UpdateCustomerByIdRequestDTO, params: { companyId: UniqueID }) {
|
||
|
|
try {
|
||
|
|
const errors: ValidationErrorDetail[] = [];
|
||
|
|
const customerPatchProps: CustomerPatchProps = {};
|
||
|
|
|
||
|
|
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<TaxCode>();
|
||
|
|
/*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;
|
||
|
|
}
|
||
|
|
}
|