feat: always show some sections in balance sheet.

This commit is contained in:
a.bouhuolia
2021-01-11 11:21:32 +02:00
parent 8491d44118
commit 80e51cd2f7
9 changed files with 172 additions and 121 deletions

View File

@@ -324,6 +324,7 @@ export default class JournalPoster implements IJournalPoster {
transactions.forEach((transaction) => {
this.entries.push({
...transaction,
referenceTypeFormatted: transaction.referenceTypeFormatted,
account: transaction.accountId,
accountNormal: get(transaction, 'account.type.normal'),
});
@@ -417,7 +418,7 @@ export default class JournalPoster implements IJournalPoster {
* @param {Number} account -
* @param {Date|String} closingDate -
*/
getTrialBalance(accountId, closingDate, dateType) {
getTrialBalance(accountId, closingDate) {
const momentClosingDate = moment(closingDate);
const result = {
credit: 0,
@@ -426,8 +427,8 @@ export default class JournalPoster implements IJournalPoster {
};
this.entries.forEach((entry) => {
if (
(!momentClosingDate.isAfter(entry.date, dateType) &&
!momentClosingDate.isSame(entry.date, dateType)) ||
(!momentClosingDate.isAfter(entry.date, 'day') &&
!momentClosingDate.isSame(entry.date, 'day')) ||
(entry.account !== accountId && accountId)
) {
return;
@@ -478,8 +479,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);

View File

@@ -85,7 +85,7 @@ export default class BalanceSheetStatement extends FinancialSheet {
* @return {IBalanceSheetAccountTotal[]}
*/
private getSectionTotalPeriods(
sections: Array<IBalanceSheetAccount|IBalanceSheetSection>
sections: Array<IBalanceSheetAccount | IBalanceSheetSection>
): IBalanceSheetAccountTotal[] {
return this.dateRangeSet.map((date, index) => {
const amount = sumBy(sections, `totalPeriods[${index}].amount`);
@@ -203,8 +203,8 @@ export default class BalanceSheetStatement extends FinancialSheet {
/**
* Mappes the structure sections.
* @param {IBalanceSheetStructureSection} structure
* @param {IAccount} accounts
* @param {IBalanceSheetStructureSection} structure
* @param {IAccount} accounts
*/
private structureSectionMapper(
structure: IBalanceSheetStructureSection,
@@ -238,12 +238,12 @@ export default class BalanceSheetStatement extends FinancialSheet {
name: structure.name,
sectionType: structure.sectionType,
type: structure.type,
...(structure.type === 'accounts_section')
...(structure.type === 'accounts_section'
? this.structureRelatedAccountsMapper(
structure._accountsTypesRelated,
structure.accountsTypesRelated,
accounts
)
: this.structureSectionMapper(structure, accounts),
: this.structureSectionMapper(structure, accounts)),
};
return result;
}
@@ -259,13 +259,30 @@ export default class BalanceSheetStatement extends FinancialSheet {
): IBalanceSheetSection[] {
return (
reportStructure
.map((structure: IBalanceSheetStructureSection) =>
this.balanceSheetStructureMapper(structure, balanceSheetAccounts)
)
// Filter the structure sections that have no children.
.map((structure: IBalanceSheetStructureSection) => {
const sheetSection = this.balanceSheetStructureMapper(
structure,
balanceSheetAccounts
);
return [sheetSection, structure];
})
// Filter the structure sections that have no children and not always show.
.filter(
(structure: IBalanceSheetSection) =>
structure.children.length > 0 || structure._forceShow
([sheetSection, structure]: [
IBalanceSheetSection,
IBalanceSheetStructureSection
]) => {
return sheetSection.children.length > 0 || structure.alwaysShow;
}
)
// Mappes the balance sheet scetions only
.map(
([sheetSection, structure]: [
IBalanceSheetSection,
IBalanceSheetStructureSection
]) => {
return sheetSection;
}
)
);
}
@@ -295,6 +312,10 @@ export default class BalanceSheetStatement extends FinancialSheet {
* @return {IBalanceSheetSection[]}
*/
public reportData(): IBalanceSheetSection[] {
// Returns nothing if there is no entries in the journal between the given period.
if (this.journalFinancial.entries.length === 0) {
return [];
}
return this.balanceSheetStructureWalker(
BalanceSheetStructure,
this.accounts

View File

@@ -1,12 +1,13 @@
import { sumBy, chain } from 'lodash';
import { sumBy, chain, omit } from 'lodash';
import {
IJournalEntry,
IJournalPoster,
IJournalReportEntriesGroup,
IJournalReportQuery,
IJournalReport
} from "interfaces";
import FinancialSheet from "../FinancialSheet";
IJournalReport,
} from 'interfaces';
import FinancialSheet from '../FinancialSheet';
import { AccountTransaction } from 'models';
export default class JournalSheet extends FinancialSheet {
tenantId: number;
@@ -16,14 +17,14 @@ export default class JournalSheet extends FinancialSheet {
/**
* Constructor method.
* @param {number} tenantId
* @param {IJournalPoster} journal
* @param {number} tenantId
* @param {IJournalPoster} journal
*/
constructor(
tenantId: number,
query: IJournalReportQuery,
journal: IJournalPoster,
baseCurrency: string,
baseCurrency: string
) {
super();
@@ -34,23 +35,38 @@ export default class JournalSheet extends FinancialSheet {
this.baseCurrency = baseCurrency;
}
/**
* Mappes the journal entries.
* @param {IJournalEntry[]} entries -
*/
entriesMapper(
entries: IJournalEntry[],
) {
return entries.map((entry: IJournalEntry) => {
return {
...omit(entry, 'account'),
currencyCode: this.baseCurrency,
};
})
}
/**
* Mapping journal entries groups.
* @param {IJournalEntry[]} entriesGroup -
* @param {string} key -
* @return {IJournalReportEntriesGroup}
*/
entriesGroupMapper(
entriesGroupsMapper(
entriesGroup: IJournalEntry[],
key: string,
key: string
): IJournalReportEntriesGroup {
const totalCredit = sumBy(entriesGroup, 'credit');
const totalDebit = sumBy(entriesGroup, 'debit');
return {
id: key,
entries: entriesGroup,
entries: this.entriesMapper(entriesGroup),
currencyCode: this.baseCurrency,
credit: totalCredit,
@@ -63,16 +79,15 @@ export default class JournalSheet extends FinancialSheet {
/**
* Mapping the journal entries to entries groups.
* @param {IJournalEntry[]} entries
* @param {IJournalEntry[]} entries
* @return {IJournalReportEntriesGroup[]}
*/
entriesWalker(entries: IJournalEntry[]): IJournalReportEntriesGroup[] {
return chain(entries)
.groupBy((entry) => `${entry.referenceId}-${entry.referenceType}`)
.map((
entriesGroup: IJournalEntry[],
key: string
) => this.entriesGroupMapper(entriesGroup, key))
.map((entriesGroup: IJournalEntry[], key: string) =>
this.entriesGroupsMapper(entriesGroup, key)
)
.value();
}
@@ -83,4 +98,4 @@ export default class JournalSheet extends FinancialSheet {
reportData(): IJournalReport {
return this.entriesWalker(this.journal.entries);
}
}
}

View File

@@ -1,4 +1,3 @@
import {
ITrialBalanceSheetQuery,
ITrialBalanceAccount,
@@ -8,7 +7,7 @@ import {
import FinancialSheet from '../FinancialSheet';
import { flatToNestedArray } from 'utils';
export default class TrialBalanceSheet extends FinancialSheet{
export default class TrialBalanceSheet extends FinancialSheet {
tenantId: number;
query: ITrialBalanceSheetQuery;
accounts: IAccount & { type: IAccountType }[];
@@ -17,17 +16,17 @@ export default class TrialBalanceSheet extends FinancialSheet{
/**
* Constructor method.
* @param {number} tenantId
* @param {ITrialBalanceSheetQuery} query
* @param {IAccount[]} accounts
* @param journalFinancial
* @param {number} tenantId
* @param {ITrialBalanceSheetQuery} query
* @param {IAccount[]} accounts
* @param journalFinancial
*/
constructor(
tenantId: number,
query: ITrialBalanceSheetQuery,
accounts: IAccount & { type: IAccountType }[],
journalFinancial: any,
baseCurrency: string,
baseCurrency: string
) {
super();
@@ -42,13 +41,15 @@ export default class TrialBalanceSheet extends FinancialSheet{
/**
* Account mapper.
* @param {IAccount} account
* @param {IAccount} account
*/
private accountMapper(account: IAccount & { type: IAccountType }): ITrialBalanceAccount {
private accountMapper(
account: IAccount & { type: IAccountType }
): ITrialBalanceAccount {
const trial = this.journalFinancial.getTrialBalanceWithDepands(account.id);
// Retrieve all entries that associated to the given account.
const entries = this.journalFinancial.getAccountEntries(account.id)
const entries = this.journalFinancial.getAccountEntries(account.id);
return {
id: account.id,
@@ -71,29 +72,35 @@ export default class TrialBalanceSheet extends FinancialSheet{
/**
* Accounts walker.
* @param {IAccount[]} accounts
* @param {IAccount[]} accounts
*/
private accountsWalker(
accounts: IAccount & { type: IAccountType }[]
): ITrialBalanceAccount[] {
const flattenAccounts = accounts
// Mapping the trial balance accounts sections.
.map((account: IAccount & { type: IAccountType }) => this.accountMapper(account))
.map((account: IAccount & { type: IAccountType }) =>
this.accountMapper(account)
)
// Filter accounts that have no transaction when `noneTransactions` is on.
.filter((trialAccount: ITrialBalanceAccount): boolean =>
!(!trialAccount.hasTransactions && this.query.noneTransactions),
.filter(
(trialAccount: ITrialBalanceAccount): boolean =>
!(!trialAccount.hasTransactions && this.query.noneTransactions)
)
// Filter accounts that have zero total amount when `noneZero` is on.
.filter(
(trialAccount: ITrialBalanceAccount): boolean =>
!(trialAccount.credit === 0 && trialAccount.debit === 0 && this.query.noneZero)
);
return flatToNestedArray(
flattenAccounts,
{ id: 'id', parentId: 'parentAccountId' },
);
!(
trialAccount.credit === 0 &&
trialAccount.debit === 0 &&
this.query.noneZero
)
);
return flatToNestedArray(flattenAccounts, {
id: 'id',
parentId: 'parentAccountId',
});
}
/**
@@ -102,4 +109,4 @@ export default class TrialBalanceSheet extends FinancialSheet{
public reportData() {
return this.accountsWalker(this.accounts);
}
}
}

View File

@@ -1,13 +1,12 @@
import { Service, Inject } from "typedi";
import { Service, Inject } from 'typedi';
import moment from 'moment';
import TenancyService from 'services/Tenancy/TenancyService';
import { ITrialBalanceSheetQuery, ITrialBalanceStatement } from 'interfaces';
import TrialBalanceSheet from "./TrialBalanceSheet";
import TrialBalanceSheet from './TrialBalanceSheet';
import Journal from 'services/Accounting/JournalPoster';
@Service()
export default class TrialBalanceSheetService {
@Inject()
tenancy: TenancyService;
@@ -36,16 +35,15 @@ export default class TrialBalanceSheetService {
/**
* Retrieve trial balance sheet statement.
* -------------
* @param {number} tenantId
* @param {IBalanceSheetQuery} query
*
* @param {number} tenantId
* @param {IBalanceSheetQuery} query
*
* @return {IBalanceSheetStatement}
*/
public async trialBalanceSheet(
tenantId: number,
query: ITrialBalanceSheetQuery,
query: ITrialBalanceSheetQuery
): Promise<ITrialBalanceStatement> {
const filter = {
...this.defaultQuery,
...query,
@@ -57,10 +55,15 @@ export default class TrialBalanceSheetService {
// Settings tenant service.
const settings = this.tenancy.settings(tenantId);
const baseCurrency = settings.get({ group: 'organization', key: 'base_currency' });
this.logger.info('[trial_balance_sheet] trying to calcualte the report.', { tenantId, filter });
const baseCurrency = settings.get({
group: 'organization',
key: 'base_currency',
});
this.logger.info('[trial_balance_sheet] trying to calcualte the report.', {
tenantId,
filter,
});
// Retrieve all accounts on the storage.
const accounts = await accountRepository.all('type');
const accountsGraph = await accountRepository.getDependencyGraph();
@@ -72,8 +75,11 @@ export default class TrialBalanceSheetService {
sumationCreditDebit: true,
});
// Transform transactions array to journal collection.
const transactionsJournal = Journal.fromTransactions(transactions, tenantId, accountsGraph);
const transactionsJournal = Journal.fromTransactions(
transactions,
tenantId,
accountsGraph
);
// Trial balance report instance.
const trialBalanceInstance = new TrialBalanceSheet(
tenantId,
@@ -88,6 +94,6 @@ export default class TrialBalanceSheetService {
return {
data: trialBalanceSheetData,
query: filter,
}
};
}
}
}