Uecko_ERP/modules/customers/src/api/application/mappers/create-customer-input.mapper.ts

239 lines
6.5 KiB
TypeScript
Raw Normal View History

2026-03-09 20:23:48 +00:00
import type { JsonTaxCatalogProvider } from "@erp/core";
import {
City,
Country,
CurrencyCode,
DomainError,
EmailAddress,
LanguageCode,
Name,
PhoneNumber,
type PostalAddressProps,
PostalCode,
Province,
Street,
TINNumber,
type TaxCode,
TextValue,
URLAddress,
UniqueID,
ValidationErrorCollection,
type ValidationErrorDetail,
extractOrPushError,
maybeFromNullableResult,
} from "@repo/rdx-ddd";
2026-03-16 17:45:45 +00:00
import { Result } from "@repo/rdx-utils";
2026-03-09 20:23:48 +00:00
import type { CreateCustomerRequestDTO } from "../../../common";
import { CustomerStatus, type ICustomerCreateProps } from "../../domain";
export interface ICreateCustomerInputMapper {
map(
dto: CreateCustomerRequestDTO,
params: { companyId: UniqueID }
): Result<{ id: UniqueID; props: ICustomerCreateProps }>;
}
export class CreateCustomerInputMapper implements ICreateCustomerInputMapper {
private readonly taxCatalog: JsonTaxCatalogProvider;
constructor(params: { taxCatalog: JsonTaxCatalogProvider }) {
this.taxCatalog = params.taxCatalog;
}
public map(
dto: CreateCustomerRequestDTO,
params: { companyId: UniqueID }
): Result<{ id: UniqueID; props: ICustomerCreateProps }> {
try {
const errors: ValidationErrorDetail[] = [];
const { companyId } = params;
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
);
2026-03-16 17:45:45 +00:00
const defaultTaxes: TaxCode[] = [];
2026-03-09 20:23:48 +00:00
/*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: PostalAddressProps = {
street: street!,
street2: street2!,
city: city!,
postalCode: postalCode!,
province: province!,
country: country!,
};
const customerProps: ICustomerCreateProps = {
companyId,
status: status!,
reference: reference!,
isCompany: isCompany,
name: name!,
tradeName: tradeName!,
tin: tinNumber!,
address: postalAddressProps!,
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 }));
}
}
}