diff --git a/packages/server/src/interfaces/Ledger.ts b/packages/server/src/interfaces/Ledger.ts index 49419e680..4e021718a 100644 --- a/packages/server/src/interfaces/Ledger.ts +++ b/packages/server/src/interfaces/Ledger.ts @@ -4,6 +4,8 @@ export interface ILedger { getEntries(): ILedgerEntry[]; + filter(cb: (entry: ILedgerEntry) => boolean): ILedger; + whereAccountId(accountId: number): ILedger; whereContactId(contactId: number): ILedger; whereFromDate(fromDate: Date | string): ILedger; diff --git a/packages/server/src/services/Accounting/LedgerContactStorage.ts b/packages/server/src/services/Accounting/LedgerContactStorage.ts index 06b5f9269..f8a484122 100644 --- a/packages/server/src/services/Accounting/LedgerContactStorage.ts +++ b/packages/server/src/services/Accounting/LedgerContactStorage.ts @@ -1,9 +1,14 @@ import { Service, Inject } from 'typedi'; import async from 'async'; import { Knex } from 'knex'; -import { ILedger, ISaleContactsBalanceQueuePayload } from '@/interfaces'; +import { + ILedger, + ILedgerEntry, + ISaleContactsBalanceQueuePayload, +} from '@/interfaces'; import HasTenancyService from '@/services/Tenancy/TenancyService'; import { TenantMetadata } from '@/system/models'; +import { ACCOUNT_TYPE } from '@/data/AccountTypes'; @Service() export class LedgerContactsBalanceStorage { @@ -49,6 +54,29 @@ export class LedgerContactsBalanceStorage { await this.saveContactBalance(tenantId, ledger, contactId, trx); }; + /** + * Filters AP/AR ledger entries. + * @param {number} tenantId + * @param {Knex.Transaction} trx + * @returns {Promise<(entry: ILedgerEntry) => boolean>} + */ + private filterARAPLedgerEntris = async ( + tenantId: number, + trx?: Knex.Transaction + ): Promise<(entry: ILedgerEntry) => boolean> => { + const { Account } = this.tenancy.models(tenantId); + + const ARAPAcounts = await Account.query(trx).whereIn('accountType', [ + ACCOUNT_TYPE.ACCOUNTS_RECEIVABLE, + ACCOUNT_TYPE.ACCOUNTS_PAYABLE, + ]); + const ARAPAcountsIds = ARAPAcounts.map((a) => a.id); + + return (entry: ILedgerEntry) => { + return ARAPAcountsIds.indexOf(entry.accountId) !== -1; + }; + }; + /** * * @param {number} tenantId @@ -63,16 +91,24 @@ export class LedgerContactsBalanceStorage { trx?: Knex.Transaction ): Promise => { const { Contact } = this.tenancy.models(tenantId); - const contact = await Contact.query().findById(contactId); + const contact = await Contact.query(trx).findById(contactId); // Retrieves the given tenant metadata. const tenantMeta = await TenantMetadata.query().findOne({ tenantId }); - + // Detarmines whether the contact has foreign currency. const isForeignContact = contact.currencyCode !== tenantMeta.baseCurrency; // Filters the ledger base on the given contact id. - const contactLedger = ledger.whereContactId(contactId); + const filterARAPLedgerEntris = await this.filterARAPLedgerEntris( + tenantId, + trx + ); + const contactLedger = ledger + // Filter entries only that have contact id. + .whereContactId(contactId) + // Filter entries on AR/AP accounts. + .filter(filterARAPLedgerEntris); const closingBalance = isForeignContact ? contactLedger diff --git a/packages/server/src/services/Contacts/Customers/CRUD/CreateCustomer.ts b/packages/server/src/services/Contacts/Customers/CRUD/CreateCustomer.ts index 0465ecd5f..6969360ff 100644 --- a/packages/server/src/services/Contacts/Customers/CRUD/CreateCustomer.ts +++ b/packages/server/src/services/Contacts/Customers/CRUD/CreateCustomer.ts @@ -55,7 +55,7 @@ export class CreateCustomer { } as ICustomerEventCreatingPayload); // Creates a new contact as customer. - const customer = await Contact.query().insertAndFetch({ + const customer = await Contact.query(trx).insertAndFetch({ ...customerObj, }); // Triggers `onCustomerCreated` event.