Files
bigcapital/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryService.ts
2023-08-27 00:56:14 +02:00

139 lines
3.7 KiB
TypeScript

import moment from 'moment';
import { Inject, Service } from 'typedi';
import { isEmpty } from 'lodash';
import { IARAgingSummaryQuery, IARAgingSummaryMeta } from '@/interfaces';
import TenancyService from '@/services/Tenancy/TenancyService';
import ARAgingSummarySheet from './ARAgingSummarySheet';
import { Tenant } from '@/system/models';
import ARAgingSummaryTable from './ARAgingSummaryTable';
@Service()
export default class ARAgingSummaryService {
@Inject()
tenancy: TenancyService;
@Inject('logger')
logger: any;
/**
* Default report query.
*/
get defaultQuery(): IARAgingSummaryQuery {
return {
asDate: moment().format('YYYY-MM-DD'),
agingDaysBefore: 30,
agingPeriods: 3,
numberFormat: {
divideOn1000: false,
negativeFormat: 'mines',
showZero: false,
formatMoney: 'total',
precision: 2,
},
customersIds: [],
branchesIds: [],
noneZero: false,
};
}
/**
* Retrieve the balance sheet meta.
* @param {number} tenantId -
* @returns {IBalanceSheetMeta}
*/
reportMetadata(tenantId: number): IARAgingSummaryMeta {
const settings = this.tenancy.settings(tenantId);
const organizationName = settings.get({
group: 'organization',
key: 'name',
});
const baseCurrency = settings.get({
group: 'organization',
key: 'base_currency',
});
return {
organizationName,
baseCurrency,
};
}
/**
* Retrieve A/R aging summary report.
* @param {number} tenantId - Tenant id.
* @param {IARAgingSummaryQuery} query -
*/
async ARAgingSummary(tenantId: number, query: IARAgingSummaryQuery) {
const { SaleInvoice } = this.tenancy.models(tenantId);
const { customerRepository } = this.tenancy.repositories(tenantId);
const filter = {
...this.defaultQuery,
...query,
};
const tenant = await Tenant.query()
.findById(tenantId)
.withGraphFetched('metadata');
// Retrieve all customers from the storage.
const customers =
filter.customersIds.length > 0
? await customerRepository.findWhereIn('id', filter.customersIds)
: await customerRepository.all();
// Common query.
const commonQuery = (query) => {
if (!isEmpty(filter.branchesIds)) {
query.modify('filterByBranches', filter.branchesIds);
}
};
// Retrieve all overdue sale invoices.
const overdueSaleInvoices = await SaleInvoice.query()
.modify('overdueInvoicesFromDate', filter.asDate)
.onBuild(commonQuery);
// Retrieve all due sale invoices.
const currentInvoices = await SaleInvoice.query()
.modify('dueInvoicesFromDate', filter.asDate)
.onBuild(commonQuery);
// AR aging summary report instance.
const ARAgingSummaryReport = new ARAgingSummarySheet(
tenantId,
filter,
customers,
overdueSaleInvoices,
currentInvoices,
tenant.metadata.baseCurrency
);
// AR aging summary report data and columns.
const data = ARAgingSummaryReport.reportData();
const columns = ARAgingSummaryReport.reportColumns();
return {
data,
columns,
query: filter,
meta: this.reportMetadata(tenantId),
};
}
/**
* Retrieves A/R aging summary in table format.
* @param {number} tenantId
* @param {IARAgingSummaryQuery} query
*/
async ARAgingSummaryTable(tenantId: number, query: IARAgingSummaryQuery) {
const report = await this.ARAgingSummary(tenantId, query);
const table = new ARAgingSummaryTable(report.data, query, {});
return {
columns: table.tableColumns(),
rows: table.tableRows(),
meta: report.meta,
query,
};
}
}