fix: vendor summary balance and transaction report.

This commit is contained in:
a.bouhuolia
2021-05-08 04:32:13 +02:00
parent 531949e090
commit e174b81e16
8 changed files with 237 additions and 94 deletions

View File

@@ -1,20 +1,24 @@
import { Inject } from 'typedi';
import moment from 'moment';
import { map } from 'lodash';
import * as R from 'ramda';
import TenancyService from 'services/Tenancy/TenancyService';
import Journal from 'services/Accounting/JournalPoster';
import {
IVendor,
IVendorBalanceSummaryService,
IVendorBalanceSummaryQuery,
IVendorBalanceSummaryStatement,
} from 'interfaces';
import { VendorBalanceSummaryReport } from './VendorBalanceSummary';
import { isEmpty } from 'lodash';
import { ACCOUNT_TYPE } from 'data/AccountTypes';
import Ledger from 'services/Accounting/Ledger';
export default class VendorBalanceSummaryService
implements IVendorBalanceSummaryService {
@Inject()
tenancy: TenancyService;
@Inject('logger')
logger: any;
@@ -40,70 +44,110 @@ export default class VendorBalanceSummaryService
};
}
/**
* Retrieve the report vendors.
* @param {number} tenantId
* @param {number[]} vendorsIds - Vendors ids.
* @returns {IVendor[]}
*/
getReportVendors(
tenantId: number,
vendorsIds?: number[]
): Promise<IVendor[]> {
const { Vendor } = this.tenancy.models(tenantId);
return Vendor.query()
.orderBy('displayName')
.onBuild((query) => {
if (!isEmpty(vendorsIds)) {
query.whereIn('id', vendorsIds);
}
});
}
getPayableAccounts(tenantId: number) {
const { Account } = this.tenancy.models(tenantId);
return Account.query().where('accountType', ACCOUNT_TYPE.ACCOUNTS_PAYABLE);
}
/**
* Retrieve
* @param tenantId
* @param asDate
* @returns
*/
async getReportVendorsTransactions(tenantId: number, asDate: Date | string) {
const { AccountTransaction } = this.tenancy.models(tenantId);
// Retrieve payable accounts .
const payableAccounts = await this.getPayableAccounts(tenantId);
const payableAccountsIds = map(payableAccounts, 'id');
// Retrieve the customers transactions of A/R accounts.
const customersTranasctions = await AccountTransaction.query().onBuild(
(query) => {
query.whereIn('accountId', payableAccountsIds);
query.modify('filterDateRange', null, asDate);
query.groupBy('contactId');
query.sum('credit as credit');
query.sum('debit as debit');
query.select('contactId');
}
);
const commonProps = { accountNormal: 'credit', date: asDate };
return R.map(R.merge(commonProps))(customersTranasctions);
}
/**
* Retrieve the statment of customer balance summary report.
* @param {number} tenantId - Tenant id.
* @param {IVendorBalanceSummaryQuery} query -
* @param {IVendorBalanceSummaryQuery} query -
* @return {Promise<IVendorBalanceSummaryStatement>}
*/
async vendorBalanceSummary(
tenantId: number,
query: IVendorBalanceSummaryQuery
): Promise<IVendorBalanceSummaryStatement> {
const {
accountRepository,
transactionsRepository,
} = this.tenancy.repositories(tenantId);
const { Vendor } = this.tenancy.models(tenantId);
// Settings tenant service.
const settings = this.tenancy.settings(tenantId);
const baseCurrency = settings.get({
group: 'organization', key: 'base_currency',
group: 'organization',
key: 'base_currency',
});
const filter = {
...this.defaultQuery,
...query,
};
this.logger.info('[customer_balance_summary] trying to calculate the report.', {
filter,
const filter = { ...this.defaultQuery, ...query };
this.logger.info(
'[customer_balance_summary] trying to calculate the report.',
{
filter,
tenantId,
}
);
// Retrieve the vendors transactions.
const vendorsTransactions = await this.getReportVendorsTransactions(
tenantId,
});
// Retrieve all accounts on the storage.
const accounts = await accountRepository.all();
const accountsGraph = await accountRepository.getDependencyGraph();
// Retrieve all journal transactions based on the given query.
const transactions = await transactionsRepository.journal({
toDate: query.asDate,
});
// Transform transactions to journal collection.
const transactionsJournal = Journal.fromTransactions(
transactions,
tenantId,
accountsGraph
query.asDate
);
// Retrieve the customers list ordered by the display name.
const vendors = await Vendor.query().orderBy('displayName');
const vendors = await this.getReportVendors(tenantId, query.vendorsIds);
// Ledger query.
const ledger = new Ledger(vendorsTransactions);
// Report instance.
const reportInstance = new VendorBalanceSummaryReport(
transactionsJournal,
ledger,
vendors,
filter,
baseCurrency,
baseCurrency
);
// Retrieve the report statement.
const reportData = reportInstance.reportData();
// Retrieve the report columns.
const reportColumns = reportInstance.reportColumns();
return {
data: reportData,
columns: reportColumns,
data: reportInstance.reportData(),
columns: reportInstance.reportColumns(),
query: filter,
};
}
}