import { ApplicationConfig } from '@tomei/config'; import { IOrderCustomerQuery } from '../../interfaces/order-customer-query.interface'; import { OrderCustomerRepository } from './order-customer.repository'; import { LoginUser } from '@tomei/sso'; import { Op } from 'sequelize'; import cuid from '../../helpers/cuid'; import { ActionEnum, Activity } from '@tomei/activity-history'; import { ICompany, IPerson, ObjectBase } from '@tomei/general'; import { Address } from '@tomei/object'; import { OrderCustomerTypeEnum } from '../../enums/order-customer-type.enum'; import { IOrderCustomerAttr } from '../../interfaces/order-customer-attr.interface'; export class OrderCustomer extends ObjectBase implements IOrderCustomerAttr { ObjectId: string; ObjectName: string; ObjectType = 'OrderCustomer'; TableName: string; CustomerId: string; CRMRefNo: string; FullName: string; ContactNo: string; Email: string; IdNo: string; TaxIdentificationNo: string; ContactPersonName: string; ContactPersonContactNo: string; ContactPersonIdType: string; ContactPersonIdNo: string; CreatedById: string; CreatedAt: any; UpdatedById: string; UpdatedAt: any; CustomerType: OrderCustomerTypeEnum; CustomerDetails: IPerson | ICompany; private static _Repo = new OrderCustomerRepository(); get IdType(): string { //If CustomerType is individual, return IdType from CustomerDetails if (this.CustomerType == OrderCustomerTypeEnum.INDIVIDUAL) { if ('IDType' in this.CustomerDetails) { return this.CustomerDetails.IDType; } return null; } else { return 'RegistrationNo'; } } private constructor(cutomerData?: IOrderCustomerAttr) { super(); if (cutomerData) { this.CustomerId = cutomerData.CustomerId; this.CRMRefNo = cutomerData.CRMRefNo; this.FullName = cutomerData.FullName; this.ContactNo = cutomerData.ContactNo; this.Email = cutomerData.Email; this.IdNo = cutomerData.IdNo; this.CreatedById = cutomerData.CreatedById; this.CreatedAt = cutomerData.CreatedAt; this.UpdatedById = cutomerData.UpdatedById; this.UpdatedAt = cutomerData.UpdatedAt; this.CustomerType = cutomerData.CustomerType; this.TaxIdentificationNo = cutomerData.TaxIdentificationNo; this.ContactPersonName = cutomerData.ContactPersonName; this.ContactPersonContactNo = cutomerData.ContactPersonContactNo; this.ContactPersonIdType = cutomerData.ContactPersonIdType; this.ContactPersonIdNo = cutomerData.ContactPersonIdNo; } } static async init(CustomerId?: string, dbTransaction?: any) { if (CustomerId) { const customer = await OrderCustomer._Repo.findByPk(CustomerId, { transaction: dbTransaction, }); if (CustomerId) { return new OrderCustomer({ ...customer?.get({ plain: true }), }); } else { throw Error('CustomerId not found.'); } } return new OrderCustomer(); } public static async getCustomer( loginUser: LoginUser, dbTransaction: any, FullName?: string, ContactNo?: string, Email?: string, IdNo?: string, ) { try { // Privilege checking const systemCode = ApplicationConfig.getComponentConfigValue('system-code'); const isPrivileged = await loginUser.checkPrivileges( systemCode, 'Customer - View', ); if (!isPrivileged) { throw new Error('You do not have permission to list Customer.'); } const query: any = {}; if (FullName) { query.FullName = FullName; } if (ContactNo) { query.ContactNo = ContactNo; } if (Email) { query.Email = Email; } if (IdNo) { query.IdNo = IdNo; } const customerData = await OrderCustomer._Repo.findOne({ where: query, transaction: dbTransaction, }); if (!customerData) { return null; } const customer = new OrderCustomer(customerData); return customer; } catch (error) { throw error; } } public static async getCustomers( loginUser: LoginUser, dbTransaction: any, page: number, row: number, FullName?: string, ContactNo?: string, Email?: string, IdNo?: string, ) { try { // Privilege checking const systemCode = ApplicationConfig.getComponentConfigValue('system-code'); const isPrivileged = await loginUser.checkPrivileges( systemCode, 'OrderCustomer - List', ); if (!isPrivileged) { throw new Error('You do not have permission to list Customer.'); } const query: any = {}; if (FullName) { query.FullName = { [Op.substring]: FullName, }; } if (ContactNo) { query.ContactNo = { [Op.substring]: ContactNo, }; } if (Email) { query.Email = { [Op.substring]: Email, }; } if (IdNo) { query.IdNo = { [Op.substring]: IdNo, }; } let options: any = { where: query, transaction: dbTransaction, }; if (page && row) { options = { ...options, limit: row, offset: row * (page - 1), order: [['FullName', 'ASC']], }; } const data = await OrderCustomer._Repo.findAndCountAll({ where: query, transaction: dbTransaction, }); return data; } catch (error) { throw error; } } public async create(loginUser: LoginUser, dbTransaction: any) { //This method will create new order customer record. //Part 1: Privilege Checking const systemCode = ApplicationConfig.getComponentConfigValue('system-code'); const isPrivileged = await loginUser.checkPrivileges( systemCode, 'OrderCustomer - Create', ); if (!isPrivileged) { throw new Error('You do not have permission to create customer.'); } //Part 2: Create Customer //Set CustomerId to cuid() this.CustomerId = cuid(); //Call OrderCustomer repo create method by passing customer data const entityValueAfter: IOrderCustomerAttr = { CustomerId: this.CustomerId, CRMRefNo: this.CRMRefNo, FullName: this.FullName, ContactNo: this.ContactNo, Email: this.Email, IdNo: this.IdNo, CreatedById: loginUser.ObjectId, UpdatedById: loginUser.ObjectId, CustomerType: this.CustomerType, TaxIdentificationNo: this.TaxIdentificationNo, ContactPersonName: this.ContactPersonName, ContactPersonContactNo: this.ContactPersonContactNo, ContactPersonIdType: this.ContactPersonIdType, ContactPersonIdNo: this.ContactPersonIdNo, CreatedAt: this.CreatedAt, UpdatedAt: this.UpdatedAt, }; const customerData = await OrderCustomer._Repo.create(entityValueAfter, { transaction: dbTransaction, }); //Part 3: Record Activity History //Instantiate new activity from Activity class const activity = new Activity(); activity.ActivityId = activity.createId(); activity.Action = ActionEnum.CREATE; activity.Description = `Add Customer`; activity.EntityId = this.CustomerId; activity.EntityType = 'OrderCustomer'; activity.EntityValueBefore = JSON.stringify({}); activity.EntityValueAfter = JSON.stringify(entityValueAfter); //Call new activity create method. await activity.create(loginUser.ObjectId, dbTransaction); } public async update(loginUser: LoginUser, dbTransaction: any, payload: any) { const systemCode = ApplicationConfig.getComponentConfigValue('system-code'); const isPrivileged = await loginUser.checkPrivileges( systemCode, 'Customer - Update', ); if (!isPrivileged) { throw new Error('You do not have permission to update customer.'); } const entityValueBefore: IOrderCustomerAttr = { CustomerId: this.CustomerId, CRMRefNo: this.CRMRefNo, FullName: this.FullName, ContactNo: this.ContactNo, Email: this.Email, IdNo: this.IdNo, CreatedById: this.CreatedById, CreatedAt: this.CreatedAt, UpdatedById: this.UpdatedById, UpdatedAt: this.UpdatedAt, CustomerType: this.CustomerType, TaxIdentificationNo: this.TaxIdentificationNo, ContactPersonName: this.ContactPersonName, ContactPersonContactNo: this.ContactPersonContactNo, ContactPersonIdType: this.ContactPersonIdType, ContactPersonIdNo: this.ContactPersonIdNo, }; this.FullName = payload?.FullName || this.FullName; this.ContactNo = payload?.ContactNo || this.ContactNo; this.Email = payload?.Email || this.Email; this.IdNo = payload?.IdNo || this.IdNo; this.CustomerType = payload?.CustomerType || this.CustomerType; this.TaxIdentificationNo = payload?.TaxIdentificationNo || this.TaxIdentificationNo; this.ContactPersonName = payload?.ContactPersonName || this.ContactPersonName; this.ContactPersonContactNo = payload?.ContactPersonContactNo || this.ContactPersonContactNo; this.ContactPersonIdType = payload?.ContactPersonIdType || this.ContactPersonIdType; this.ContactPersonIdNo = payload?.ContactPersonIdNo || this.ContactPersonIdNo; this.UpdatedById = loginUser.ObjectId; this.UpdatedAt = new Date(); const data = { ...entityValueBefore, FullName: this.FullName, ContactNo: this.ContactNo, Email: this.Email, IdNo: this.IdNo, UpdatedById: this.UpdatedById, UpdatedAt: this.UpdatedAt, }; const options: any = { where: { CustomerId: this.CustomerId }, transaction: dbTransaction, }; await OrderCustomer._Repo.update(data, options); const entityValueAfter = { ...data, }; const activity = new Activity(); activity.ActivityId = activity.createId(); activity.Action = ActionEnum.UPDATE; activity.Description = `Update Customer`; activity.EntityType = 'OrderCustomer'; activity.EntityId = this.CustomerId; activity.EntityValueBefore = JSON.stringify(entityValueBefore); activity.EntityValueAfter = JSON.stringify(entityValueAfter); await activity.create(loginUser.ObjectId, dbTransaction); } public async getDefaultAddress( loginUser: LoginUser, dbTransaction: any, ): Promise
{ if (!this.CustomerId) { throw new Error('Customer not found.'); } const address = await Address.getDefault( loginUser as any, dbTransaction, 'OrderCustomer', this.CustomerId, ); if (!address) { return null; } return address; } }