Files
bigcapital/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetService.ts
2024-01-04 17:22:13 +02:00

140 lines
3.8 KiB
TypeScript

import { Service, Inject } from 'typedi';
import moment from 'moment';
import {
IJournalReportQuery,
IJournalSheet,
IJournalSheetMeta,
IJournalTableData,
} from '@/interfaces';
import JournalSheet from './JournalSheet';
import TenancyService from '@/services/Tenancy/TenancyService';
import Journal from '@/services/Accounting/JournalPoster';
import InventoryService from '@/services/Inventory/Inventory';
import { Tenant } from '@/system/models';
import { parseBoolean, transformToMap } from 'utils';
@Service()
export class JournalSheetService {
@Inject()
private tenancy: TenancyService;
@Inject()
private inventoryService: InventoryService;
/**
* Default journal sheet filter queyr.
*/
get defaultQuery() {
return {
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
toDate: moment().format('YYYY-MM-DD'),
fromRange: null,
toRange: null,
accountsIds: [],
numberFormat: {
noCents: false,
divideOn1000: false,
},
};
}
/**
* Retrieve the balance sheet meta.
* @param {number} tenantId -
* @returns {IBalanceSheetMeta}
*/
reportMetadata(tenantId: number): IJournalSheetMeta {
const settings = this.tenancy.settings(tenantId);
const isCostComputeRunning =
this.inventoryService.isItemsCostComputeRunning(tenantId);
const organizationName = settings.get({
group: 'organization',
key: 'name',
});
const baseCurrency = settings.get({
group: 'organization',
key: 'base_currency',
});
return {
isCostComputeRunning: parseBoolean(isCostComputeRunning, false),
organizationName,
baseCurrency,
};
}
/**
* Journal sheet.
* @param {number} tenantId
* @param {IJournalReportQuery} query
* @returns {Promise<IJournalSheet>}
*/
async journalSheet(
tenantId: number,
query: IJournalReportQuery
): Promise<IJournalSheet> {
const i18n = this.tenancy.i18n(tenantId);
const { accountRepository, transactionsRepository, contactRepository } =
this.tenancy.repositories(tenantId);
const { AccountTransaction } = this.tenancy.models(tenantId);
const filter = {
...this.defaultQuery,
...query,
};
const tenant = await Tenant.query()
.findById(tenantId)
.withGraphFetched('metadata');
// Retrieve all accounts on the storage.
const accountsGraph = await accountRepository.getDependencyGraph();
// Retrieve all contacts on the storage.
const contacts = await contactRepository.all();
const contactsByIdMap = transformToMap(contacts, 'id');
// Retrieve all journal transactions based on the given query.
const transactions = await AccountTransaction.query().onBuild((query) => {
if (filter.fromRange || filter.toRange) {
query.modify('filterAmountRange', filter.fromRange, filter.toRange);
}
query.modify('filterDateRange', filter.fromDate, filter.toDate);
query.orderBy(['date', 'createdAt', 'indexGroup', 'index']);
if (filter.transactionType) {
query.where('reference_type', filter.transactionType);
}
if (filter.transactionType && filter.transactionId) {
query.where('reference_id', filter.transactionId);
}
});
// Transform the transactions array to journal collection.
const transactionsJournal = Journal.fromTransactions(
transactions,
tenantId,
accountsGraph
);
// Journal report instance.
const journalSheetInstance = new JournalSheet(
tenantId,
filter,
transactionsJournal,
accountsGraph,
contactsByIdMap,
tenant.metadata.baseCurrency,
i18n
);
// Retrieve journal report columns.
const journalSheetData = journalSheetInstance.reportData();
return {
data: journalSheetData,
query: filter,
meta: this.reportMetadata(tenantId),
};
}
}