import { ISequelizeMapper, MapperParamsType, SequelizeMapper, ValidationErrorCollection, ValidationErrorDetail, extractOrPushError, } from "@erp/core/api"; import { EmailAddress, PhoneNumber, PostalAddress, TINNumber, UniqueID } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; import { Customer, CustomerProps, CustomerStatus } from "../../domain"; import { CustomerCreationAttributes, CustomerModel } from "../sequelize"; export interface ICustomerMapper extends ISequelizeMapper {} export class CustomerMapper extends SequelizeMapper implements ICustomerMapper { public mapToDomain(source: CustomerModel, params?: MapperParamsType): Result { 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 status = extractOrPushError(CustomerStatus.create(source.status), "status", errors); const reference = source.reference?.trim() === "" ? undefined : source.reference; const isCompany = source.is_company ?? true; const name = source.name?.trim() === "" ? undefined : source.name; const tradeName = source.trade_name?.trim() === "" ? undefined : source.trade_name; const tinNumber = extractOrPushError(TINNumber.create(source.tin), "tin", errors); const address = extractOrPushError( PostalAddress.create({ street: source.street, city: source.city, postalCode: source.postal_code, state: source.state, country: source.country, }), "address", errors ); const emailAddress = extractOrPushError(EmailAddress.create(source.email), "email", errors); const phoneNumber = extractOrPushError(PhoneNumber.create(source.phone), "phone", errors); const faxNumber = extractOrPushError(PhoneNumber.create(source.fax), "fax", errors); const website = source.website?.trim() === "" ? undefined : source.website; const legalRecord = source.legal_record?.trim() === "" ? undefined : source.legal_record; const langCode = source.lang_code?.trim() === "" ? undefined : source.lang_code; const currencyCode = source.currency_code?.trim() === "" ? undefined : source.currency_code; if (errors.length > 0) { console.error(errors); return Result.fail(new ValidationErrorCollection("Customer props mapping failed", errors)); } const customerProps: CustomerProps = { companyId: companyId!, status: status!, reference: reference!, isCompany: isCompany, name: name!, tradeName: tradeName!, tin: tinNumber!, address: address!, email: emailAddress!, phone: phoneNumber!, fax: faxNumber!, website: website!, legalRecord: legalRecord!, defaultTax: [], langCode: langCode!, currencyCode: currencyCode!, }; return Customer.create(customerProps, customerId); } catch (err: unknown) { return Result.fail(err as Error); } } public mapToPersistence(source: Customer, params?: MapperParamsType): CustomerCreationAttributes { return { id: source.id.toPrimitive(), company_id: source.companyId.toPrimitive(), reference: source.reference, is_company: source.isCompany, name: source.name, trade_name: source.tradeName, tin: source.tin.toPrimitive(), email: source.email.toPrimitive(), phone: source.phone.toPrimitive(), fax: source.fax.toPrimitive(), website: source.website, default_tax: source.defaultTax.toString(), legal_record: source.legalRecord, lang_code: source.langCode, currency_code: source.currencyCode, status: source.isActive ? "active" : "inactive", street: source.address.street, street2: source.address.street2, city: source.address.city, state: source.address.state, postal_code: source.address.postalCode, country: source.address.country, }; } }