diff --git a/server/src/lib/AccountTypes/index.ts b/server/src/lib/AccountTypes/index.ts index 04bbdaf93..4d5c9b839 100644 --- a/server/src/lib/AccountTypes/index.ts +++ b/server/src/lib/AccountTypes/index.ts @@ -2,7 +2,6 @@ import { get } from 'lodash'; import { ACCOUNT_TYPES } from 'data/AccountTypes'; export default class AccountTypesUtils { - /** * Retrieve account types list. */ @@ -11,15 +10,16 @@ export default class AccountTypesUtils { } /** - * - * @param {string} rootType + * Retrieve accounts types by the given root type. + * @param {string} rootType - + * @return {string} */ static getTypesByRootType(rootType: string) { return ACCOUNT_TYPES.filter((type) => type.rootType === rootType); } /** - * + * Retrieve account type by the given account type key. * @param {string} key * @param {string} accessor */ @@ -33,7 +33,7 @@ export default class AccountTypesUtils { } /** - * + * Retrieve accounts types by the parent account type. * @param {string} parentType */ static getTypesByParentType(parentType: string) { @@ -41,20 +41,19 @@ export default class AccountTypesUtils { } /** - * + * Retrieve accounts types by the given account normal. * @param {string} normal */ static getTypesByNormal(normal: string) { return ACCOUNT_TYPES.filter((type) => type.normal === normal); } - /** - * + * Detarmines whether the root type equals the account type. * @param {string} key * @param {string} rootType */ - static isRootTypeEqualsKey(key: string, rootType: string) { + static isRootTypeEqualsKey(key: string, rootType: string): boolean { return ACCOUNT_TYPES.some((type) => { const isType = type.key === key; const isRootType = type.rootType === rootType; @@ -64,11 +63,11 @@ export default class AccountTypesUtils { } /** - * - * @param {string} key - * @param {string} parentType + * Detarmines whether the parent account type equals the account type key. + * @param {string} key - Account type key. + * @param {string} parentType - Account parent type. */ - static isParentTypeEqualsKey(key: string, parentType: string) { + static isParentTypeEqualsKey(key: string, parentType: string): boolean { return ACCOUNT_TYPES.some((type) => { const isType = type.key === key; const isParentType = type.parentType === parentType; @@ -78,10 +77,11 @@ export default class AccountTypesUtils { } /** + * Detarmines whether account type has balance sheet. + * @param {string} key - Account type key. * - * @param {string} key */ - static isTypeBalanceSheet(key: string) { + static isTypeBalanceSheet(key: string): boolean { return ACCOUNT_TYPES.some((type) => { const isType = type.key === key; return isType && type.balanceSheet; @@ -89,10 +89,10 @@ export default class AccountTypesUtils { } /** - * - * @param {string} key + * Detarmines whether account type has profit/loss sheet. + * @param {string} key - Account type key. */ - static isTypePLSheet(key: string) { + static isTypePLSheet(key: string): boolean { return ACCOUNT_TYPES.some((type) => { const isType = type.key === key; return isType && type.incomeSheet; diff --git a/server/src/services/Accounting/JournalPoster.ts b/server/src/services/Accounting/JournalPoster.ts index 5f6299d90..c1fa61623 100644 --- a/server/src/services/Accounting/JournalPoster.ts +++ b/server/src/services/Accounting/JournalPoster.ts @@ -23,16 +23,13 @@ export default class JournalPoster implements IJournalPoster { balancesChange: IAccountsChange = {}; accountsDepGraph: IAccountsChange; - accountsBalanceTable: { [key: number]: number; } = {}; + accountsBalanceTable: { [key: number]: number } = {}; /** * Journal poster constructor. - * @param {number} tenantId - + * @param {number} tenantId - */ - constructor( - tenantId: number, - accountsGraph?: any, - ) { + constructor(tenantId: number, accountsGraph?: any) { this.initTenancy(); this.tenantId = tenantId; @@ -59,7 +56,7 @@ export default class JournalPoster implements IJournalPoster { /** * Async initialize acccounts dependency graph. - * @private + * @private * @returns {Promise} */ public async initAccountsDepGraph(): Promise { @@ -72,7 +69,7 @@ export default class JournalPoster implements IJournalPoster { } /** - * + * */ public isEmpty() { return this.entries.length === 0; @@ -118,7 +115,7 @@ export default class JournalPoster implements IJournalPoster { /** * Sets account balance change. * @private - * @param {number} accountId - + * @param {number} accountId - * @param {IAccountChange} accountChange */ private _setAccountBalanceChange( @@ -126,21 +123,23 @@ export default class JournalPoster implements IJournalPoster { accountChange: IAccountChange ) { this.balancesChange = this.accountBalanceChangeReducer( - this.balancesChange, accountId, accountChange, + this.balancesChange, + accountId, + accountChange ); } /** * Accounts balance change reducer. - * @param {IAccountsChange} balancesChange - * @param {number} accountId + * @param {IAccountsChange} balancesChange + * @param {number} accountId * @param {IAccountChange} accountChange - * @return {IAccountChange} + * @return {IAccountChange} */ private accountBalanceChangeReducer( balancesChange: IAccountsChange, accountId: number, - accountChange: IAccountChange, + accountChange: IAccountChange ) { const change = { ...balancesChange }; @@ -159,31 +158,37 @@ export default class JournalPoster implements IJournalPoster { /** * Converts balance changes to array. * @private - * @param {IAccountsChange} accountsChange - + * @param {IAccountsChange} accountsChange - * @return {Promise<{ account: number, change: number }>} */ private async convertBalanceChangesToArr( accountsChange: IAccountsChange - ) : Promise<{ account: number, change: number }[]>{ - const mappedList: { account: number, change: number }[] = []; - const accountsIds: number[] = Object.keys(accountsChange).map(id => parseInt(id, 10)); + ): Promise<{ account: number; change: number }[]> { + const mappedList: { account: number; change: number }[] = []; + const accountsIds: number[] = Object.keys(accountsChange).map((id) => + parseInt(id, 10) + ); await Promise.all( accountsIds.map(async (account: number) => { const accountChange = accountsChange[account]; const accountNode = this.accountsDepGraph.getNodeData(account); - - const { normal }: { normal: TEntryType } = accountNode.accountNormal; + const normal = accountNode.accountNormal; + let change = 0; if (accountChange.credit) { - change = (normal === 'credit') ? accountChange.credit : -1 * accountChange.credit; + change = + normal === 'credit' + ? accountChange.credit + : -1 * accountChange.credit; } if (accountChange.debit) { - change = (normal === 'debit') ? accountChange.debit : -1 * accountChange.debit; + change = + normal === 'debit' ? accountChange.debit : -1 * accountChange.debit; } mappedList.push({ account, change }); - }), + }) ); return mappedList; } @@ -198,20 +203,26 @@ export default class JournalPoster implements IJournalPoster { const { Account } = this.models; const accountsChange = this.balanceChangeWithDepends(this.balancesChange); const balancesList = await this.convertBalanceChangesToArr(accountsChange); - const balancesAccounts = balancesList.map(b => b.account); + const balancesAccounts = balancesList.map((b) => b.account); // Ensure the accounts has atleast zero in amount. - await Account.query().where('amount', null).whereIn('id', balancesAccounts) + await Account.query() + .where('amount', null) + .whereIn('id', balancesAccounts) .patch({ amount: 0 }); const balanceUpdateOpers: Promise[] = []; - balancesList.forEach((balance: { account: number, change: number }) => { - const method: string = (balance.change < 0) ? 'decrement' : 'increment'; + balancesList.forEach((balance: { account: number; change: number }) => { + const method: string = balance.change < 0 ? 'decrement' : 'increment'; - this.logger.info('[journal_poster] increment/decrement account balance.', { - balance, tenantId: this.tenantId, - }) + this.logger.info( + '[journal_poster] increment/decrement account balance.', + { + balance, + tenantId: this.tenantId, + } + ); const query = Account.query() [method]('amount', Math.abs(balance.change)) .where('id', balance.account); @@ -225,19 +236,25 @@ export default class JournalPoster implements IJournalPoster { /** * Changes all accounts that dependencies of changed accounts. - * @param {IAccountsChange} accountsChange + * @param {IAccountsChange} accountsChange * @returns {IAccountsChange} */ - private balanceChangeWithDepends(accountsChange: IAccountsChange): IAccountsChange { + private balanceChangeWithDepends( + accountsChange: IAccountsChange + ): IAccountsChange { const accountsIds = Object.keys(accountsChange); let changes: IAccountsChange = {}; accountsIds.forEach((accountId) => { const accountChange = accountsChange[accountId]; - const depAccountsIds = this.accountsDepGraph.dependenciesOf(accountId); - + const depAccountsIds = this.accountsDepGraph.dependantsOf(accountId); + [accountId, ...depAccountsIds].forEach((account) => { - changes = this.accountBalanceChangeReducer(changes, account, accountChange); + changes = this.accountBalanceChangeReducer( + changes, + account, + accountChange + ); }); }); return changes; @@ -260,11 +277,10 @@ export default class JournalPoster implements IJournalPoster { const saveOperations: Promise[] = []; this.entries.forEach((entry) => { - const oper = transactionsRepository - .create({ - accountId: entry.account, - ...omit(entry, ['account']), - }); + const oper = transactionsRepository.create({ + accountId: entry.account, + ...omit(entry, ['account']), + }); saveOperations.push(oper); }); await Promise.all(saveOperations); @@ -361,14 +377,14 @@ export default class JournalPoster implements IJournalPoster { /** * Retrieve the closing balance for the given account and closing date. - * @param {Number} accountId - - * @param {Date} closingDate - - * @param {string} dataType? - + * @param {Number} accountId - + * @param {Date} closingDate - + * @param {string} dataType? - * @return {number} */ getClosingBalance( accountId: number, - closingDate: Date|string, + closingDate: Date | string, dateType: string = 'day' ): number { let closingBalance = 0; @@ -399,11 +415,16 @@ export default class JournalPoster implements IJournalPoster { * @param {String} dateType - * @return {Number} */ - getAccountBalance(accountId: number, closingDate: Date|string, dateType: string) { + getAccountBalance( + accountId: number, + closingDate: Date | string, + dateType: string + ) { const accountNode = this.accountsDepGraph.getNodeData(accountId); const depAccountsIds = this.accountsDepGraph.dependenciesOf(accountId); - const depAccounts = depAccountsIds - .map((id) => this.accountsDepGraph.getNodeData(id)); + const depAccounts = depAccountsIds.map((id) => + this.accountsDepGraph.getNodeData(id) + ); let balance: number = 0; @@ -459,7 +480,11 @@ export default class JournalPoster implements IJournalPoster { * @return {Number} */ - getTrialBalanceWithDepands(accountId: number, closingDate: Date, dateType: string) { + getTrialBalanceWithDepands( + accountId: number, + closingDate: Date, + dateType: string + ) { const accountNode = this.accountsDepGraph.getNodeData(accountId); const depAccountsIds = this.accountsDepGraph.dependenciesOf(accountId); const depAccounts = depAccountsIds.map((id) => @@ -485,8 +510,8 @@ export default class JournalPoster implements IJournalPoster { accountId: number, contactId: number, contactType: string, - closingDate?: Date|string, - openingDate?: Date|string, + closingDate?: Date | string, + openingDate?: Date | string ) { const momentClosingDate = moment(closingDate); const momentOpeningDate = moment(openingDate); @@ -534,7 +559,7 @@ export default class JournalPoster implements IJournalPoster { contactId: number, contactType: string, closingDate: Date, - openingDate: Date, + openingDate: Date ) { const momentClosingDate = moment(closingDate); let balance = 0; diff --git a/server/src/services/ManualJournals/ManualJournalsService.ts b/server/src/services/ManualJournals/ManualJournalsService.ts index 0aece462e..d46cdaa01 100644 --- a/server/src/services/ManualJournals/ManualJournalsService.ts +++ b/server/src/services/ManualJournals/ManualJournalsService.ts @@ -197,7 +197,7 @@ export default class ManualJournalsService implements IManualJournalsService { } /** - * + * Validate accounts with contact type. * @param {number} tenantId * @param {IManualJournalDTO} manualJournalDTO * @param {string} accountBySlug