250 lines
7.5 KiB
TypeScript
250 lines
7.5 KiB
TypeScript
import {
|
|
ISequelizeMapper,
|
|
MapperParamsType,
|
|
SequelizeDomainMapper,
|
|
ValidationErrorCollection,
|
|
ValidationErrorDetail,
|
|
extractOrPushError,
|
|
} from "@erp/core/api";
|
|
import {
|
|
City,
|
|
Country,
|
|
CurrencyCode,
|
|
EmailAddress,
|
|
LanguageCode,
|
|
Name,
|
|
PhoneNumber,
|
|
PostalAddress,
|
|
PostalCode,
|
|
Province,
|
|
Street,
|
|
TINNumber,
|
|
TaxCode,
|
|
TextValue,
|
|
URLAddress,
|
|
UniqueID,
|
|
maybeFromNullableVO,
|
|
toNullable,
|
|
} from "@repo/rdx-ddd";
|
|
import { Collection, Result, isNullishOrEmpty } from "@repo/rdx-utils";
|
|
import { Customer, CustomerProps, CustomerStatus } from "../../domain";
|
|
import { CustomerCreationAttributes, CustomerModel } from "../sequelize";
|
|
|
|
export interface ICustomerMapper
|
|
extends ISequelizeMapper<CustomerModel, CustomerCreationAttributes, Customer> {}
|
|
|
|
export class CustomerMapper
|
|
extends SequelizeDomainMapper<CustomerModel, CustomerCreationAttributes, Customer>
|
|
implements ICustomerMapper
|
|
{
|
|
public mapToDomain(source: CustomerModel, params?: MapperParamsType): Result<Customer, Error> {
|
|
try {
|
|
const errors: ValidationErrorDetail[] = [];
|
|
|
|
const customerId = extractOrPushError(UniqueID.create(source.id), "id", errors);
|
|
const companyId = extractOrPushError(
|
|
UniqueID.create(source.company_id),
|
|
"company_id",
|
|
errors
|
|
);
|
|
|
|
const isCompany = source.is_company;
|
|
const status = extractOrPushError(CustomerStatus.create(source.status), "status", errors);
|
|
const reference = extractOrPushError(
|
|
maybeFromNullableVO(source.reference, (value) => Name.create(value)),
|
|
"reference",
|
|
errors
|
|
);
|
|
|
|
const name = extractOrPushError(Name.create(source.name), "name", errors);
|
|
|
|
const tradeName = extractOrPushError(
|
|
maybeFromNullableVO(source.trade_name, (value) => Name.create(value)),
|
|
"trade_name",
|
|
errors
|
|
);
|
|
|
|
const tinNumber = extractOrPushError(
|
|
maybeFromNullableVO(source.tin, (value) => TINNumber.create(value)),
|
|
"tin",
|
|
errors
|
|
);
|
|
|
|
const street = extractOrPushError(
|
|
maybeFromNullableVO(source.street, (value) => Street.create(value)),
|
|
"street",
|
|
errors
|
|
);
|
|
|
|
const street2 = extractOrPushError(
|
|
maybeFromNullableVO(source.street2, (value) => Street.create(value)),
|
|
"street2",
|
|
errors
|
|
);
|
|
|
|
const city = extractOrPushError(
|
|
maybeFromNullableVO(source.city, (value) => City.create(value)),
|
|
"city",
|
|
errors
|
|
);
|
|
|
|
const province = extractOrPushError(
|
|
maybeFromNullableVO(source.province, (value) => Province.create(value)),
|
|
"province",
|
|
errors
|
|
);
|
|
|
|
const postalCode = extractOrPushError(
|
|
maybeFromNullableVO(source.postal_code, (value) => PostalCode.create(value)),
|
|
"postal_code",
|
|
errors
|
|
);
|
|
|
|
const country = extractOrPushError(
|
|
maybeFromNullableVO(source.country, (value) => Country.create(value)),
|
|
"country",
|
|
errors
|
|
);
|
|
|
|
const emailAddress = extractOrPushError(
|
|
maybeFromNullableVO(source.email, (value) => EmailAddress.create(value)),
|
|
"email",
|
|
errors
|
|
);
|
|
|
|
const phoneNumber = extractOrPushError(
|
|
maybeFromNullableVO(source.phone, (value) => PhoneNumber.create(value)),
|
|
"phone",
|
|
errors
|
|
);
|
|
|
|
const faxNumber = extractOrPushError(
|
|
maybeFromNullableVO(source.fax, (value) => PhoneNumber.create(value)),
|
|
"fax",
|
|
errors
|
|
);
|
|
|
|
const website = extractOrPushError(
|
|
maybeFromNullableVO(source.website, (value) => URLAddress.create(value)),
|
|
"website",
|
|
errors
|
|
);
|
|
|
|
const legalRecord = extractOrPushError(
|
|
maybeFromNullableVO(source.legal_record, (value) => TextValue.create(value)),
|
|
"legal_record",
|
|
errors
|
|
);
|
|
|
|
const languageCode = extractOrPushError(
|
|
LanguageCode.create(source.language_code),
|
|
"language_code",
|
|
errors
|
|
);
|
|
|
|
const currencyCode = extractOrPushError(
|
|
CurrencyCode.create(source.currency_code),
|
|
"currency_code",
|
|
errors
|
|
);
|
|
|
|
// source.default_taxes is stored as a comma-separated string
|
|
const defaultTaxes = new Collection<TaxCode>();
|
|
if (!isNullishOrEmpty(source.default_taxes)) {
|
|
source.default_taxes.split(",").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: CustomerProps = {
|
|
companyId: companyId!,
|
|
status: status!,
|
|
reference: reference!,
|
|
|
|
isCompany: isCompany,
|
|
name: name!,
|
|
tradeName: tradeName!,
|
|
tin: tinNumber!,
|
|
|
|
address: postalAddress!,
|
|
|
|
email: emailAddress!,
|
|
phone: phoneNumber!,
|
|
fax: faxNumber!,
|
|
website: website!,
|
|
|
|
legalRecord: legalRecord!,
|
|
defaultTaxes: defaultTaxes!,
|
|
languageCode: languageCode!,
|
|
currencyCode: currencyCode!,
|
|
};
|
|
|
|
return Customer.create(customerProps, customerId);
|
|
} catch (err: unknown) {
|
|
return Result.fail(err as Error);
|
|
}
|
|
}
|
|
|
|
public mapToPersistence(source: Customer, params?: MapperParamsType): CustomerCreationAttributes {
|
|
const customerValues: Partial<CustomerCreationAttributes> = {
|
|
id: source.id.toPrimitive(),
|
|
company_id: source.companyId.toPrimitive(),
|
|
|
|
reference: toNullable(source.reference, (reference) => reference.toPrimitive()),
|
|
is_company: source.isCompany,
|
|
name: source.name.toPrimitive(),
|
|
trade_name: toNullable(source.tradeName, (tradeName) => tradeName.toPrimitive()),
|
|
tin: toNullable(source.tin, (tin) => tin.toPrimitive()),
|
|
|
|
email: toNullable(source.email, (email) => email.toPrimitive()),
|
|
phone: toNullable(source.phone, (phone) => phone.toPrimitive()),
|
|
fax: toNullable(source.fax, (fax) => fax.toPrimitive()),
|
|
website: toNullable(source.website, (website) => website.toPrimitive()),
|
|
|
|
legal_record: toNullable(source.legalRecord, (legalRecord) => legalRecord.toPrimitive()),
|
|
default_taxes: source.defaultTaxes.map((taxItem) => taxItem.toPrimitive()).join(", "),
|
|
|
|
status: source.isActive ? "active" : "inactive",
|
|
language_code: source.languageCode.toPrimitive(),
|
|
currency_code: source.currencyCode.toPrimitive(),
|
|
};
|
|
|
|
if (source.address) {
|
|
Object.assign(customerValues, {
|
|
street: toNullable(source.address.street, (street) => street.toPrimitive()),
|
|
street2: toNullable(source.address.street2, (street2) => street2.toPrimitive()),
|
|
city: toNullable(source.address.city, (city) => city.toPrimitive()),
|
|
province: toNullable(source.address.province, (province) => province.toPrimitive()),
|
|
postal_code: toNullable(source.address.postalCode, (postalCode) =>
|
|
postalCode.toPrimitive()
|
|
),
|
|
country: toNullable(source.address.country, (country) => country.toPrimitive()),
|
|
});
|
|
}
|
|
|
|
return customerValues as CustomerCreationAttributes;
|
|
}
|
|
}
|