UNPKG

@tomei/customer-base

Version:

Tomei Customer Base Package

125 lines (113 loc) 4.18 kB
import { Op } from 'sequelize'; import { CustomerBaseModel, CustomerIndividualModel, CustomerBusinessModel, BusinessContactModel, ObjectAddressModel, } from '../../models'; import { ISyncPayload } from '../../types/sync-payload.type'; import { IBusinessSyncPayload, IIndividualSyncPayload } from '../../interfaces'; import { CustomerTypeEnum } from '../../enum/customer-type.enum'; import { IAddress } from '@tomei/general'; /** * Builds a normalized ISyncPayload for a given CustomerId by reading CB tables. * Keeps the shape consistent with your discriminated union (Individual | Business) * * @param customerId - The ID of the customer to build the payload for * @returns A promise that resolves to the normalized ISyncPayload */ export async function buildCustomerPayload( customerId: string, ): Promise<ISyncPayload> { const customerBase = await CustomerBaseModel.findByPk(customerId); if (!customerBase) { throw new Error(`CustomerBase not found for CustomerId=${customerId}`); } const addresses = await ObjectAddressModel.findAll({ where: { ObjectId: customerId, ObjectType: 'Customer', Status: { [Op.ne]: 'Deleted' }, }, order: [ ['IsDefaultYN', 'DESC'], ['UpdatedAt', 'DESC'], ], }); const Address: IAddress[] = addresses.map((a) => ({ AddressLine1: a.AddressLine1, AddressLine2: a.AddressLine2 ?? '', City: a.City, State: a.State ?? '', PostCode: a.PostalCode, //DEV WARN: Postcode and/or PostalCode can be not consistent between systems Country: a.Country, AddressType: a.AddressType, IsDefaultYN: a.IsDefaultYN, Latitude: (a as any).Latitude ?? undefined, Longitude: (a as any).Longitude ?? undefined, })); const sourceSystem = customerBase.UpdatedBySystemCode ?? ''; if (customerBase.Type === CustomerTypeEnum.Individual) { const cbIndividual = await CustomerIndividualModel.findByPk(customerId); if (!cbIndividual) { throw new Error( `CustomerIndividual not found for CustomerId=${customerId}`, ); } const payload: IIndividualSyncPayload = { // base payload fields CustomerId: customerBase.CustomerId, Type: CustomerTypeEnum.Individual, Email: customerBase.Email ?? '-', ContactNo: customerBase.ContactNo ?? '-', SourceSystem: sourceSystem, Address, // individual payload fields FullName: cbIndividual.FullName, IdType: cbIndividual.IdType, IdNo: cbIndividual.IdNo, // optional/nullable individual fields Title: cbIndividual.Title ?? 'N/A', PreferredName: cbIndividual.PreferredName ?? cbIndividual.FullName, Birthdate: cbIndividual.Birthdate ?? undefined, Gender: cbIndividual.Gender ?? undefined, Ethnicity: cbIndividual.Ethnicity ?? undefined, Nationality: cbIndividual.Nationality ?? undefined, PreferredLanguage: cbIndividual.PreferredLanguage ?? undefined, }; return payload; } const cbBusiness = await CustomerBusinessModel.findByPk(customerId); if (!cbBusiness) { throw new Error(`CustomerBusiness not found for CustomerId=${customerId}`); } const cbBusinessPIC = await BusinessContactModel.findOne({ where: { CustomerId: customerId, IsMainYN: 'Y' }, order: [['UpdatedAt', 'DESC']], }); const payload: IBusinessSyncPayload = { // base payload fields CustomerId: customerBase.CustomerId, Type: CustomerTypeEnum.Business, Email: customerBase.Email, ContactNo: customerBase.ContactNo, SourceSystem: sourceSystem, Address, // business payload fields CompanyName: cbBusiness.CompanyName, RegistrationNo: cbBusiness.RegistrationNo ?? undefined, TaxIdentificationNo: cbBusiness.TaxIdentificationNo ?? undefined, // PIC is optional in your writer; keep it optional here too PIC: cbBusinessPIC ? { Name: cbBusinessPIC.Name, ContactNo: cbBusinessPIC.ContactNo, Email: cbBusinessPIC.Email ?? undefined, Position: cbBusinessPIC.Position ?? undefined, IsMainYN: cbBusinessPIC.IsMainYN, } : undefined, }; return payload; }