UNPKG

@tomei/customer-base

Version:

Tomei Customer Base Package

159 lines (145 loc) 5.4 kB
import { Transaction } from 'sequelize'; import { Sequelize } from 'sequelize-typescript'; import { CustomerBaseModel, CustomerIndividualModel, CustomerBusinessModel, BusinessContactModel, ObjectAddressModel, } from '../../models'; import cuid from '../../helpers/cuid'; import { ISyncPayload } from '../../types/sync-payload.type'; import { IBusinessSyncPayload, IIndividualSyncPayload } from '../../interfaces'; import { CustomerStatusEnum, CustomerTypeEnum } from '../../enum'; export class CustomerBaseWriter { constructor(private readonly sequelize: Sequelize) {} async write( payload: ISyncPayload, dbTransaction?: Transaction, ): Promise<void> { let transaction = dbTransaction; const createdTransaction = !transaction; const ctx = { CustomerId: payload?.CustomerId, Type: payload?.Type, SourceSystem: payload?.SourceSystem, }; try { if (!transaction) transaction = await this.sequelize.transaction(); if (!payload.CustomerId) throw new Error('CustomerId is required.'); if (!payload.Type) throw new Error('Type is required (Individual or Business).'); // Customer Base await CustomerBaseModel.upsert( { CustomerId: payload.CustomerId, Type: payload.Type, Email: payload.Email, ContactNo: payload.ContactNo, Status: CustomerStatusEnum.Active, CreatedByUserId: payload.UserId, CreatedByCustomerId: !payload.UserId ? payload.CustomerId : null, CreatedAt: new Date(), UpdatedByUserId: payload.UserId, UpdatedByCustomerId: !payload.UserId ? payload.CustomerId : null, UpdatedAt: new Date(), UpdatedBySystemCode: payload.SourceSystem, }, { transaction }, ); // Type-specific if (payload.Type === CustomerTypeEnum.Individual) { const p = payload as IIndividualSyncPayload; if (!p.FullName) throw new Error('FullName is required.'); if (!p.IdType) throw new Error('IdType is required.'); if (!p.IdNo) throw new Error('IdNo is required.'); await CustomerIndividualModel.upsert( { CustomerId: p.CustomerId, FullName: p.FullName, IdType: p.IdType, IdNo: p.IdNo, Title: p.Title ?? 'N/A', PreferredName: p.PreferredName ?? p.FullName, Birthdate: p.Birthdate ?? undefined, Gender: p.Gender ?? undefined, Ethnicity: p.Ethnicity ?? undefined, Nationality: p.Nationality ?? undefined, PreferredLanguage: p.PreferredLanguage ?? undefined, }, { transaction }, ); } else if (payload.Type === CustomerTypeEnum.Business) { const p = payload as IBusinessSyncPayload; if (!p.CompanyName) throw new Error('Company Name is required.'); await CustomerBusinessModel.upsert( { CustomerId: p.CustomerId, CompanyName: p.CompanyName, RegistrationNo: p.RegistrationNo, TaxIdentificationNo: p.TaxIdentificationNo, }, { transaction }, ); if (payload.PIC) { if (!payload.PIC.Name) throw new Error('PIC Name is required.'); if (!payload.PIC.ContactNo) throw new Error('PIC ContactNo is required.'); await BusinessContactModel.upsert( { ContactId: cuid(), CustomerId: payload.CustomerId, Name: payload.PIC.Name, Email: payload.PIC.Email, ContactNo: payload.PIC.ContactNo, Position: payload.PIC.Position, IsMainYN: payload.PIC.IsMainYN, }, { transaction }, ); } } // Addresses if (payload.Address?.length) { for (const address of payload.Address) { await ObjectAddressModel.upsert( { AddressId: cuid(), ObjectId: payload.CustomerId, ObjectType: 'Customer', AddressLine1: address.AddressLine1, AddressLine2: address.AddressLine2, City: address.City, State: address.State, PostalCode: address.PostCode, Country: address.Country, Latitude: 0, Longitude: 0, AddressType: (address as any).AddressType ?? 'Billing Address', IsDefaultYN: (address as any).IsDefaultYN ?? 'Y', Status: 'Active', CreatedById: payload.UserId ?? payload.CustomerId, CreatedAt: new Date(), UpdatedById: payload.UserId ?? payload.CustomerId, UpdatedAt: new Date(), }, { transaction }, ); } } // Optional cleanup: (left unimplemented) /** * If strict sync: * Remove any existing business_Contact or object_Address not in the incoming payload (based on CustomerId). */ if (createdTransaction) await transaction.commit(); } catch (err) { if (createdTransaction && transaction) await transaction.rollback(); console.error('[CustomerBaseWriter.write] failed', { ...ctx, error: (err as Error)?.message, }); throw err; } } }