import { Inject, Injectable } from '@nestjs/common'; import moment from 'moment'; import { Knex } from 'knex'; import { isEmpty } from 'lodash'; import { ICashFlowStatementQuery } from './Cashflow.types'; import { Account } from '@/modules/Accounts/models/Account.model'; import { AccountTransaction } from '@/modules/Accounts/models/AccountTransaction.model'; import { ModelObject } from 'objection'; @Injectable() export class CashFlowRepository { constructor( @Inject(Account.name) private readonly accountModel: typeof Account, @Inject(AccountTransaction.name) private readonly accountTransactionModel: typeof AccountTransaction, ) {} /** * Retrieve the group type from periods type. * @param {string} displayType * @returns {string} */ protected getGroupTypeFromPeriodsType(displayType: string) { const displayTypes = { year: 'year', day: 'day', month: 'month', quarter: 'month', week: 'day', }; return displayTypes[displayType] || 'month'; } /** * Retrieve the cashflow accounts. * @returns {Promise} */ public async cashFlowAccounts(): Promise { const accounts = await this.accountModel.query(); return accounts; } /** * Retrieve total of csah at beginning transactions. * @param {number} tenantId - * @param {ICashFlowStatementQuery} filter - * @return {Promise} */ public async cashAtBeginningTotalTransactions( filter: ICashFlowStatementQuery, ): Promise[]> { const cashBeginningPeriod = moment(filter.fromDate) .subtract(1, 'day') .toDate(); const transactions = await this.accountTransactionModel .query() .onBuild((query) => { query.modify('creditDebitSummation'); query.select('accountId'); query.groupBy('accountId'); query.withGraphFetched('account'); query.modify('filterDateRange', null, cashBeginningPeriod); this.commonFilterBranchesQuery(filter, query); }); return transactions; } /** * Retrieve accounts transactions. * @param {number} tenantId - * @param {ICashFlowStatementQuery} filter * @return {Promise} */ public async getAccountsTransactions( filter: ICashFlowStatementQuery, ): Promise[]> { const groupByDateType = this.getGroupTypeFromPeriodsType( filter.displayColumnsBy, ); return await this.accountTransactionModel.query().onBuild((query) => { query.modify('creditDebitSummation'); query.modify('groupByDateFormat', groupByDateType); query.select('accountId'); query.groupBy('accountId'); query.withGraphFetched('account'); query.modify('filterDateRange', filter.fromDate, filter.toDate); this.commonFilterBranchesQuery(filter, query); }); } /** * Retrieve the net income tranasctions. * @param {number} tenantId - * @param {ICashFlowStatementQuery} query - * @return {Promise} */ public async getNetIncomeTransactions( filter: ICashFlowStatementQuery, ): Promise { const groupByDateType = this.getGroupTypeFromPeriodsType( filter.displayColumnsBy, ); return await this.accountTransactionModel.query().onBuild((query) => { query.modify('creditDebitSummation'); query.modify('groupByDateFormat', groupByDateType); query.select('accountId'); query.groupBy('accountId'); query.withGraphFetched('account'); query.modify('filterDateRange', filter.fromDate, filter.toDate); this.commonFilterBranchesQuery(filter, query); }); } /** * Retrieve peridos of cash at beginning transactions. * @param {ICashFlowStatementQuery} filter - * @return {Promise[]>} */ public async cashAtBeginningPeriodTransactions( filter: ICashFlowStatementQuery, ): Promise[]> { const groupByDateType = this.getGroupTypeFromPeriodsType( filter.displayColumnsBy, ); return await this.accountTransactionModel.query().onBuild((query) => { query.modify('creditDebitSummation'); query.modify('groupByDateFormat', groupByDateType); query.select('accountId'); query.groupBy('accountId'); query.withGraphFetched('account'); query.modify('filterDateRange', filter.fromDate, filter.toDate); this.commonFilterBranchesQuery(filter, query); }); } /** * Common branches filter query. * @param {Knex.QueryBuilder} query */ private commonFilterBranchesQuery = ( query: ICashFlowStatementQuery, knexQuery: Knex.QueryBuilder, ) => { if (!isEmpty(query.branchesIds)) { knexQuery.modify('filterByBranches', query.branchesIds); } }; }