mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-18 13:50:31 +00:00
refactor: expense GL to Nestjs
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
import async from 'async';
|
||||
import { Knex } from 'knex';
|
||||
import {
|
||||
ILedger,
|
||||
ILedgerEntry,
|
||||
ISaleContactsBalanceQueuePayload,
|
||||
} from './types/Ledger.types';
|
||||
import { ACCOUNT_TYPE } from '@/constants/accounts';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Contact } from '../Contacts/models/Contact';
|
||||
import { Account } from '../Accounts/models/Account.model';
|
||||
import { TenancyContext } from '../Tenancy/TenancyContext.service';
|
||||
|
||||
@Injectable()
|
||||
export class LedgerContactsBalanceStorage {
|
||||
constructor(
|
||||
private tenancyContext: TenancyContext,
|
||||
|
||||
@Inject(Contact.name)
|
||||
private contactModel: typeof Contact,
|
||||
|
||||
@Inject(Account.name)
|
||||
private accountModel: typeof Account,
|
||||
) {}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {ILedger} ledger
|
||||
* @param {Knex.Transaction} trx
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
public saveContactsBalance = async (
|
||||
ledger: ILedger,
|
||||
trx?: Knex.Transaction,
|
||||
): Promise<void> => {
|
||||
// Save contact balance queue.
|
||||
const saveContactsBalanceQueue = async.queue(
|
||||
this.saveContactBalanceTask,
|
||||
10,
|
||||
);
|
||||
// Retrieves the effected contacts ids.
|
||||
const effectedContactsIds = ledger.getContactsIds();
|
||||
|
||||
effectedContactsIds.forEach((contactId: number) => {
|
||||
saveContactsBalanceQueue.push({ contactId, ledger, trx });
|
||||
});
|
||||
if (effectedContactsIds.length > 0) await saveContactsBalanceQueue.drain();
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {ISaleContactsBalanceQueuePayload} task
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private saveContactBalanceTask = async (
|
||||
task: ISaleContactsBalanceQueuePayload,
|
||||
) => {
|
||||
const { contactId, ledger, trx } = task;
|
||||
|
||||
await this.saveContactBalance(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 ARAPAccounts = await this.accountModel
|
||||
.query(trx)
|
||||
.whereIn('accountType', [
|
||||
ACCOUNT_TYPE.ACCOUNTS_RECEIVABLE,
|
||||
ACCOUNT_TYPE.ACCOUNTS_PAYABLE,
|
||||
]);
|
||||
const ARAPAccountsIds = ARAPAccounts.map((a) => a.id);
|
||||
|
||||
return (entry: ILedgerEntry) => {
|
||||
return ARAPAccountsIds.indexOf(entry.accountId) !== -1;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number} tenantId
|
||||
* @param {ILedger} ledger
|
||||
* @param {number} contactId
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private saveContactBalance = async (
|
||||
tenantId: number,
|
||||
ledger: ILedger,
|
||||
contactId: number,
|
||||
trx?: Knex.Transaction,
|
||||
): Promise<void> => {
|
||||
const contact = await this.contactModel.query(trx).findById(contactId);
|
||||
|
||||
// Retrieves the given tenant metadata.
|
||||
const tenant = await this.tenancyContext.getTenant(true);
|
||||
|
||||
// Detarmines whether the contact has foreign currency.
|
||||
const isForeignContact =
|
||||
contact.currencyCode !== tenant?.metadata.baseCurrency;
|
||||
|
||||
// Filters the ledger base on the given contact id.
|
||||
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
|
||||
.whereCurrencyCode(contact.currencyCode)
|
||||
.getForeignClosingBalance()
|
||||
: contactLedger.getClosingBalance();
|
||||
|
||||
await this.changeContactBalance(tenantId, contactId, closingBalance, trx);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number} tenantId
|
||||
* @param {number} contactId
|
||||
* @param {number} change
|
||||
* @returns
|
||||
*/
|
||||
private changeContactBalance = (
|
||||
tenantId: number,
|
||||
contactId: number,
|
||||
change: number,
|
||||
trx?: Knex.Transaction,
|
||||
) => {
|
||||
return this.contactModel.changeAmount(
|
||||
{ id: contactId },
|
||||
'balance',
|
||||
change,
|
||||
trx,
|
||||
);
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user