fix: AR/AP aging summary report.

This commit is contained in:
a.bouhuolia
2021-01-14 13:16:32 +02:00
parent 343185b8bd
commit a747750d88
13 changed files with 287 additions and 154 deletions

View File

@@ -83,7 +83,7 @@ export const ARAgingSummaryTableRowsMapper = (sheet, total) => {
const mapAging = (agingPeriods) => { const mapAging = (agingPeriods) => {
return agingPeriods.reduce((acc, aging, index) => { return agingPeriods.reduce((acc, aging, index) => {
acc[`aging-${index}`] = aging.formatted_total; acc[`aging-${index}`] = aging.total.formatted_amount;
return acc; return acc;
}, {}); }, {});
}; };
@@ -94,18 +94,21 @@ export const ARAgingSummaryTableRowsMapper = (sheet, total) => {
rowType: 'customer', rowType: 'customer',
name: customer.customer_name, name: customer.customer_name,
...agingRow, ...agingRow,
current: customer.current.formatted_total, current: customer.current.formatted_amount,
total: customer.total.formatted_total, total: customer.total.formatted_amount,
}); });
}); });
if (rows.length <= 0) {
return [];
}
return [ return [
...rows, ...rows,
{ {
name: 'TOTAL', name: 'TOTAL',
rowType: 'total', rowType: 'total',
current: sheet.total.current.formatted_total, current: sheet.total.current.formatted_amount,
...mapAging(sheet.total.aging), ...mapAging(sheet.total.aging),
total: sheet.total.total.formatted_total, total: sheet.total.total.formatted_amount,
} }
]; ];
}; };

View File

@@ -1,6 +1,7 @@
import { import {
IAgingPeriod, IAgingPeriod,
IAgingPeriodTotal IAgingPeriodTotal,
IAgingAmount
} from './AgingReport'; } from './AgingReport';
import { import {
INumberFormatQuery INumberFormatQuery
@@ -17,14 +18,15 @@ export interface IAPAgingSummaryQuery {
export interface IAPAgingSummaryVendor { export interface IAPAgingSummaryVendor {
vendorName: string, vendorName: string,
current: IAgingPeriodTotal, current: IAgingAmount,
aging: (IAgingPeriod & IAgingPeriodTotal)[], aging: IAgingPeriodTotal[],
total: IAgingPeriodTotal, total: IAgingAmount,
}; };
export interface IAPAgingSummaryTotal { export interface IAPAgingSummaryTotal {
current: IAgingPeriodTotal, current: IAgingAmount,
aging: (IAgingPeriodTotal & IAgingPeriod)[], aging: IAgingPeriodTotal[],
total: IAgingAmount,
}; };
export interface IAPAgingSummaryData { export interface IAPAgingSummaryData {

View File

@@ -1,10 +1,5 @@
import { import { IAgingPeriod, IAgingPeriodTotal, IAgingAmount } from './AgingReport';
IAgingPeriod, import { INumberFormatQuery } from './FinancialStatements';
IAgingPeriodTotal
} from './AgingReport';
import {
INumberFormatQuery
} from './FinancialStatements';
export interface IARAgingSummaryQuery { export interface IARAgingSummaryQuery {
asDate: Date | string; asDate: Date | string;
@@ -17,20 +12,20 @@ export interface IARAgingSummaryQuery {
export interface IARAgingSummaryCustomer { export interface IARAgingSummaryCustomer {
customerName: string; customerName: string;
current: IAgingPeriodTotal, current: IAgingAmount;
aging: (IAgingPeriodTotal & IAgingPeriod)[]; aging: IAgingPeriodTotal[];
total: IAgingPeriodTotal; total: IAgingAmount;
} }
export interface IARAgingSummaryTotal { export interface IARAgingSummaryTotal {
current: IAgingPeriodTotal, current: IAgingAmount;
aging: (IAgingPeriodTotal & IAgingPeriod)[], aging: IAgingPeriodTotal[];
total: IAgingPeriodTotal, total: IAgingAmount;
}; }
export interface IARAgingSummaryData { export interface IARAgingSummaryData {
customers: IARAgingSummaryCustomer[], customers: IARAgingSummaryCustomer[];
total: IARAgingSummaryTotal, total: IARAgingSummaryTotal;
}; }
export type IARAgingSummaryColumns = IAgingPeriod[]; export type IARAgingSummaryColumns = IAgingPeriod[];

View File

@@ -1,12 +1,22 @@
export interface IAgingPeriodTotal { export interface IAgingPeriodTotal extends IAgingPeriod {
total: number; total: IAgingAmount;
formattedTotal: string; };
export interface IAgingAmount {
amount: number;
formattedAmount: string;
currencyCode: string; currencyCode: string;
} }
export interface IAgingPeriod { export interface IAgingPeriod {
fromPeriod: Date|string; fromPeriod: Date | string;
toPeriod: Date|string; toPeriod: Date | string;
beforeDays: number; beforeDays: number;
toDays: number; toDays: number;
} }
export interface IAgingSummaryContact {
current: IAgingAmount;
aging: IAgingPeriodTotal[];
total: IAgingAmount;
}

View File

@@ -7,7 +7,7 @@ export default class CustomerRepository extends TenantRepository {
*/ */
constructor(knex, cache) { constructor(knex, cache) {
super(knex, cache); super(knex, cache);
this.repositoryName = 'ContactRepository'; this.repositoryName = 'CustomerRepository';
} }
/** /**

View File

@@ -7,7 +7,7 @@ export default class VendorRepository extends TenantRepository {
*/ */
constructor(knex, cache) { constructor(knex, cache) {
super(knex, cache); super(knex, cache);
this.repositoryName = 'ContactRepository'; this.repositoryName = 'VendorRepository';
} }
/** /**
@@ -17,6 +17,10 @@ export default class VendorRepository extends TenantRepository {
return Vendor.bindKnex(this.knex); return Vendor.bindKnex(this.knex);
} }
unpaid() {
}
changeBalance(vendorId: number, amount: number) { changeBalance(vendorId: number, amount: number) {
return super.changeNumber({ id: vendorId }, 'balance', amount); return super.changeNumber({ id: vendorId }, 'balance', amount);
} }

View File

@@ -7,9 +7,11 @@ import {
IVendor, IVendor,
IAPAgingSummaryData, IAPAgingSummaryData,
IAPAgingSummaryVendor, IAPAgingSummaryVendor,
IAPAgingSummaryColumns IAPAgingSummaryColumns,
IAPAgingSummaryTotal
} from 'interfaces'; } from 'interfaces';
import { Dictionary } from 'tsyringe/dist/typings/types'; import { Dictionary } from 'tsyringe/dist/typings/types';
export default class APAgingSummarySheet extends AgingSummaryReport { export default class APAgingSummarySheet extends AgingSummaryReport {
readonly tenantId: number; readonly tenantId: number;
readonly query: IAPAgingSummaryQuery; readonly query: IAPAgingSummaryQuery;
@@ -56,6 +58,23 @@ export default class APAgingSummarySheet extends AgingSummaryReport {
); );
} }
/**
* Retrieve the vendors aging and current total.
* @param {IAPAgingSummaryTotal} vendorsAgingPeriods
* @return {IAPAgingSummaryTotal}
*/
getVendorsTotal(vendorsAgingPeriods): IAPAgingSummaryTotal {
const totalAgingPeriods = this.getTotalAgingPeriods(vendorsAgingPeriods);
const totalCurrent = this.getTotalCurrent(vendorsAgingPeriods);
const totalVendorsTotal = this.getTotalContactsTotals(vendorsAgingPeriods);
return {
current: this.formatTotalAmount(totalCurrent),
aging: totalAgingPeriods,
total: this.formatTotalAmount(totalVendorsTotal),
};
}
/** /**
* Retrieve the vendor section data. * Retrieve the vendor section data.
* @param {IVendor} vendor * @param {IVendor} vendor
@@ -85,7 +104,7 @@ export default class APAgingSummarySheet extends AgingSummaryReport {
.map((vendor) => this.vendorData(vendor)) .map((vendor) => this.vendorData(vendor))
.filter( .filter(
(vendor: IAPAgingSummaryVendor) => (vendor: IAPAgingSummaryVendor) =>
!(vendor.total.total === 0 && this.query.noneZero) !(vendor.total.amount === 0 && this.query.noneZero)
); );
} }
@@ -95,16 +114,12 @@ export default class APAgingSummarySheet extends AgingSummaryReport {
*/ */
public reportData(): IAPAgingSummaryData { public reportData(): IAPAgingSummaryData {
const vendorsAgingPeriods = this.vendorsWalker(this.contacts); const vendorsAgingPeriods = this.vendorsWalker(this.contacts);
const totalAgingPeriods = this.getTotalAgingPeriods(vendorsAgingPeriods); const vendorsTotal = this.getVendorsTotal(vendorsAgingPeriods);
const totalCurrent = this.getTotalCurrent(vendorsAgingPeriods);
return { return {
vendors: vendorsAgingPeriods, vendors: vendorsAgingPeriods,
total: { total: vendorsTotal,
current: this.formatTotalAmount(totalCurrent), };
aging: totalAgingPeriods,
},
}
} }
/** /**

View File

@@ -7,6 +7,7 @@ import {
ISaleInvoice, ISaleInvoice,
IARAgingSummaryData, IARAgingSummaryData,
IARAgingSummaryColumns, IARAgingSummaryColumns,
IARAgingSummaryTotal,
} from 'interfaces'; } from 'interfaces';
import AgingSummaryReport from './AgingSummary'; import AgingSummaryReport from './AgingSummary';
import { Dictionary } from 'tsyringe/dist/typings/types'; import { Dictionary } from 'tsyringe/dist/typings/types';
@@ -44,8 +45,14 @@ export default class ARAgingSummarySheet extends AgingSummaryReport {
this.baseCurrency = baseCurrency; this.baseCurrency = baseCurrency;
this.numberFormat = this.query.numberFormat; this.numberFormat = this.query.numberFormat;
this.overdueInvoicesByContactId = groupBy(overdueSaleInvoices, 'customerId'); this.overdueInvoicesByContactId = groupBy(
this.currentInvoicesByContactId = groupBy(currentSaleInvoices, 'customerId'); overdueSaleInvoices,
'customerId'
);
this.currentInvoicesByContactId = groupBy(
currentSaleInvoices,
'customerId'
);
// Initializes the aging periods. // Initializes the aging periods.
this.agingPeriods = this.agingRangePeriods( this.agingPeriods = this.agingRangePeriods(
@@ -84,27 +91,41 @@ export default class ARAgingSummarySheet extends AgingSummaryReport {
.map((customer) => this.customerData(customer)) .map((customer) => this.customerData(customer))
.filter( .filter(
(customer: IARAgingSummaryCustomer) => (customer: IARAgingSummaryCustomer) =>
!(customer.total.total === 0 && this.query.noneZero) !(customer.total.amount === 0 && this.query.noneZero)
); );
} }
/**
* Retrieve the customers aging and current total.
* @param {IARAgingSummaryCustomer} customersAgingPeriods
*/
private getCustomersTotal(
customersAgingPeriods: IARAgingSummaryCustomer[]
): IARAgingSummaryTotal {
const totalAgingPeriods = this.getTotalAgingPeriods(customersAgingPeriods);
const totalCurrent = this.getTotalCurrent(customersAgingPeriods);
const totalCustomersTotal = this.getTotalContactsTotals(
customersAgingPeriods
);
return {
current: this.formatTotalAmount(totalCurrent),
aging: totalAgingPeriods,
total: this.formatTotalAmount(totalCustomersTotal),
};
}
/** /**
* Retrieve A/R aging summary report data. * Retrieve A/R aging summary report data.
* @return {IARAgingSummaryData} * @return {IARAgingSummaryData}
*/ */
public reportData(): IARAgingSummaryData { public reportData(): IARAgingSummaryData {
const customersAgingPeriods = this.customersWalker(this.contacts); const customersAgingPeriods = this.customersWalker(this.contacts);
const totalAgingPeriods = this.getTotalAgingPeriods(customersAgingPeriods); const customersTotal = this.getCustomersTotal(customersAgingPeriods);
const totalCurrent = this.getTotalCurrent(customersAgingPeriods);
const totalCustomersTotal = this.getTotalContactsTotals(customersAgingPeriods);
return { return {
customers: customersAgingPeriods, customers: customersAgingPeriods,
total: { total: customersTotal,
current: this.formatTotalAmount(totalCurrent),
aging: totalAgingPeriods,
total: this.formatTotalAmount(totalCustomersTotal),
}
}; };
} }

View File

@@ -8,6 +8,8 @@ import {
IContact, IContact,
IARAgingSummaryQuery, IARAgingSummaryQuery,
IFormatNumberSettings, IFormatNumberSettings,
IAgingAmount,
IAgingSummaryContact
} from 'interfaces'; } from 'interfaces';
import AgingReport from './AgingReport'; import AgingReport from './AgingReport';
import { Dictionary } from 'tsyringe/dist/typings/types'; import { Dictionary } from 'tsyringe/dist/typings/types';
@@ -25,60 +27,61 @@ export default abstract class AgingSummaryReport extends AgingReport {
>; >;
/** /**
* Setes initial aging periods to the given customer id. * Setes initial aging periods to the contact.
* @param {number} customerId - Customer id.
*/ */
protected getInitialAgingPeriodsTotal() { protected getInitialAgingPeriodsTotal(): IAgingPeriodTotal[] {
return this.agingPeriods.map((agingPeriod) => ({ return this.agingPeriods.map((agingPeriod) => ({
...agingPeriod, ...agingPeriod,
...this.formatAmount(0), total: this.formatAmount(0),
})); }));
} }
/** /**
* Calculates the given contact aging periods. * Calculates the given contact aging periods.
* @param {ICustomer} customer * @param {number} contactId - Contact id.
* @return {(IAgingPeriod & IAgingPeriodTotal)[]} * @return {IAgingPeriodTotal[]}
*/ */
protected getContactAgingPeriods( protected getContactAgingPeriods(contactId: number): IAgingPeriodTotal[] {
contactId: number
): (IAgingPeriod & IAgingPeriodTotal)[] {
const unpaidInvoices = this.getUnpaidInvoicesByContactId(contactId); const unpaidInvoices = this.getUnpaidInvoicesByContactId(contactId);
const initialAgingPeriods = this.getInitialAgingPeriodsTotal(); const initialAgingPeriods = this.getInitialAgingPeriodsTotal();
return unpaidInvoices.reduce((agingPeriods, unpaidInvoice) => { return unpaidInvoices.reduce(
const newAgingPeriods = this.getContactAgingDueAmount( (agingPeriods: IAgingPeriodTotal[], unpaidInvoice) => {
agingPeriods, const newAgingPeriods = this.getContactAgingDueAmount(
unpaidInvoice.dueAmount, agingPeriods,
unpaidInvoice.getOverdueDays(this.query.asDate) unpaidInvoice.dueAmount,
); unpaidInvoice.getOverdueDays(this.query.asDate)
return newAgingPeriods; );
}, initialAgingPeriods); return newAgingPeriods;
},
initialAgingPeriods
);
} }
/** /**
* Sets the customer aging due amount to the table. (Xx) * Sets the contact aging due amount to the table.
* @param {number} customerId - Customer id. * @param {IAgingPeriodTotal} agingPeriods - Aging periods.
* @param {number} dueAmount - Due amount. * @param {number} dueAmount - Due amount.
* @param {number} overdueDays - Overdue days. * @param {number} overdueDays - Overdue days.
* @return {IAgingPeriodTotal[]}
*/ */
protected getContactAgingDueAmount( protected getContactAgingDueAmount(
agingPeriods: any, agingPeriods: IAgingPeriodTotal[],
dueAmount: number, dueAmount: number,
overdueDays: number overdueDays: number
): (IAgingPeriod & IAgingPeriodTotal)[] { ): IAgingPeriodTotal[] {
const newAgingPeriods = agingPeriods.map((agingPeriod) => { const newAgingPeriods = agingPeriods.map((agingPeriod) => {
const isInAgingPeriod = const isInAgingPeriod =
agingPeriod.beforeDays <= overdueDays && agingPeriod.beforeDays <= overdueDays &&
(agingPeriod.toDays > overdueDays || !agingPeriod.toDays); (agingPeriod.toDays > overdueDays || !agingPeriod.toDays);
const total = isInAgingPeriod const total: number = isInAgingPeriod
? agingPeriod.total + dueAmount ? agingPeriod.total.amount + dueAmount
: agingPeriod.total; : agingPeriod.total.amount;
return { return {
...agingPeriod, ...agingPeriod,
total, total: this.formatAmount(total),
}; };
}); });
return newAgingPeriods; return newAgingPeriods;
@@ -87,27 +90,34 @@ export default abstract class AgingSummaryReport extends AgingReport {
/** /**
* Retrieve the aging period total object. * Retrieve the aging period total object.
* @param {number} amount * @param {number} amount
* @return {IAgingPeriodTotal} * @param {IFormatNumberSettings} settings - Override the format number settings.
* @return {IAgingAmount}
*/ */
protected formatAmount( protected formatAmount(
amount: number, amount: number,
settings: IFormatNumberSettings = {} settings: IFormatNumberSettings = {}
): IAgingPeriodTotal { ): IAgingAmount {
return { return {
total: amount, amount,
formattedTotal: this.formatNumber(amount, settings), formattedAmount: this.formatNumber(amount, settings),
currencyCode: this.baseCurrency, currencyCode: this.baseCurrency,
}; };
} }
/**
* Retrieve the aging period total object.
* @param {number} amount
* @param {IFormatNumberSettings} settings - Override the format number settings.
* @return {IAgingPeriodTotal}
*/
protected formatTotalAmount( protected formatTotalAmount(
amount: number, amount: number,
settings: IFormatNumberSettings = {} settings: IFormatNumberSettings = {}
): IAgingPeriodTotal { ): IAgingAmount {
return this.formatAmount(amount, { return this.formatAmount(amount, {
money: true, money: true,
excerptZero: false, excerptZero: false,
...settings ...settings,
}); });
} }
@@ -118,9 +128,9 @@ export default abstract class AgingSummaryReport extends AgingReport {
*/ */
protected getTotalAgingPeriodByIndex( protected getTotalAgingPeriodByIndex(
contactsAgingPeriods: any, contactsAgingPeriods: any,
index: number index: number,
): number { ): number {
return this.contacts.reduce((acc, customer) => { return this.contacts.reduce((acc, contact) => {
const totalPeriod = contactsAgingPeriods[index] const totalPeriod = contactsAgingPeriods[index]
? contactsAgingPeriods[index].total ? contactsAgingPeriods[index].total
: 0; : 0;
@@ -130,9 +140,9 @@ export default abstract class AgingSummaryReport extends AgingReport {
} }
/** /**
* Retrieve the due invoices by the given customer id. * Retrieve the due invoices by the given contact id.
* @param {number} customerId - * @param {number} contactId -
* @return {ISaleInvoice[]} * @return {(ISaleInvoice | IBill)[]}
*/ */
protected getUnpaidInvoicesByContactId( protected getUnpaidInvoicesByContactId(
contactId: number contactId: number
@@ -146,13 +156,23 @@ export default abstract class AgingSummaryReport extends AgingReport {
*/ */
protected getTotalAgingPeriods( protected getTotalAgingPeriods(
contactsAgingPeriods: IARAgingSummaryCustomer[] contactsAgingPeriods: IARAgingSummaryCustomer[]
): (IAgingPeriodTotal & IAgingPeriod)[] { ): IAgingPeriodTotal[] {
return this.agingPeriods.map((agingPeriod, index) => { return this.agingPeriods.map((agingPeriod, index) => {
const total = sumBy(contactsAgingPeriods, `aging[${index}].total`); const total = sumBy(
contactsAgingPeriods,
(summary: IARAgingSummaryCustomer) => {
const aging = summary.aging[index];
if (!aging) {
return 0;
}
return aging.total.amount;
}
);
return { return {
...agingPeriod, ...agingPeriod,
...this.formatTotalAmount(total), total: this.formatTotalAmount(total),
}; };
}); });
} }
@@ -179,14 +199,14 @@ export default abstract class AgingSummaryReport extends AgingReport {
} }
/** /**
* Retrieve to total sumation of the given customers sections. * Retrieve to total sumation of the given contacts summeries sections.
* @param {IARAgingSummaryCustomer[]} contactsSections - * @param {IARAgingSummaryCustomer[]} contactsSections -
* @return {number} * @return {number}
*/ */
protected getTotalCurrent( protected getTotalCurrent(
customersSummary: IARAgingSummaryCustomer[] contactsSummaries: IAgingSummaryContact[]
): number { ): number {
return sumBy(customersSummary, (summary) => summary.current.total); return sumBy(contactsSummaries, (summary) => summary.current.amount);
} }
/** /**
@@ -195,13 +215,16 @@ export default abstract class AgingSummaryReport extends AgingReport {
* @return {number} * @return {number}
*/ */
protected getAgingPeriodsTotal(agingPeriods: IAgingPeriodTotal[]): number { protected getAgingPeriodsTotal(agingPeriods: IAgingPeriodTotal[]): number {
return sumBy(agingPeriods, 'total'); return sumBy(agingPeriods, (period) => period.total.amount);
} }
/**
* Retrieve total of contacts totals.
* @param {IAgingSummaryContact[]} contactsSummaries
*/
protected getTotalContactsTotals( protected getTotalContactsTotals(
customersSummary: IARAgingSummaryCustomer[] contactsSummaries: IAgingSummaryContact[]
): number { ): number {
return sumBy(customersSummary, (summary) => summary.total.total); return sumBy(contactsSummaries, (summary) => summary.total.amount);
} }
} }

View File

@@ -1,16 +1,56 @@
import { import { IFormatNumberSettings, INumberFormatQuery } from 'interfaces';
formatNumber import { formatNumber } from 'utils';
} from 'utils';
export default class FinancialSheet { export default class FinancialSheet {
numberFormat: { noCents: boolean, divideOn1000: boolean }; numberFormat: INumberFormatQuery;
/**
* Transformes the number format query to settings
*/
protected transfromFormatQueryToSettings(): IFormatNumberSettings {
const { numberFormat } = this;
return {
precision: numberFormat.precision,
divideOn1000: numberFormat.divideOn1000,
excerptZero: !numberFormat.showZero,
negativeFormat: numberFormat.negativeFormat,
money: numberFormat.formatMoney === 'always',
};
}
/** /**
* Formating amount based on the given report query. * Formating amount based on the given report query.
* @param {number} number * @param {number} number -
* @param {IFormatNumberSettings} overrideSettings -
* @return {string} * @return {string}
*/ */
protected formatNumber(number): string { protected formatNumber(
return formatNumber(number, this.numberFormat); number,
overrideSettings: IFormatNumberSettings = {}
): string {
const settings = {
...this.transfromFormatQueryToSettings(),
...overrideSettings,
};
return formatNumber(number, settings);
}
/**
* Formatting full amount with different format settings.
* @param {number} amount -
* @param {IFormatNumberSettings} settings -
*/
protected formatTotalNumber(
amount: number,
settings: IFormatNumberSettings = {}
): string {
const { numberFormat } = this;
return this.formatNumber(amount, {
money: numberFormat.formatMoney === 'none' ? false : true,
excerptZero: false,
...settings
});
} }
} }

View File

@@ -7,9 +7,9 @@ import {
IAccount, IAccount,
IJournalPoster, IJournalPoster,
IAccountType, IAccountType,
IJournalEntry IJournalEntry,
} from 'interfaces'; } from 'interfaces';
import FinancialSheet from "../FinancialSheet"; import FinancialSheet from '../FinancialSheet';
export default class GeneralLedgerSheet extends FinancialSheet { export default class GeneralLedgerSheet extends FinancialSheet {
tenantId: number; tenantId: number;
@@ -35,7 +35,7 @@ export default class GeneralLedgerSheet extends FinancialSheet {
transactions: IJournalPoster, transactions: IJournalPoster,
openingBalancesJournal: IJournalPoster, openingBalancesJournal: IJournalPoster,
closingBalancesJournal: IJournalPoster, closingBalancesJournal: IJournalPoster,
baseCurrency: string, baseCurrency: string
) { ) {
super(); super();
@@ -59,24 +59,33 @@ export default class GeneralLedgerSheet extends FinancialSheet {
): IGeneralLedgerSheetAccountTransaction[] { ): IGeneralLedgerSheetAccountTransaction[] {
const entries = this.transactions.getAccountEntries(account.id); const entries = this.transactions.getAccountEntries(account.id);
return entries.map((transaction: IJournalEntry): IGeneralLedgerSheetAccountTransaction => { return entries.map(
let amount = 0; (transaction: IJournalEntry): IGeneralLedgerSheetAccountTransaction => {
let amount = 0;
if (account.type.normal === 'credit') { if (account.type.normal === 'credit') {
amount += transaction.credit - transaction.debit; amount += transaction.credit - transaction.debit;
} else if (account.type.normal === 'debit') { } else if (account.type.normal === 'debit') {
amount += transaction.debit - transaction.credit; amount += transaction.debit - transaction.credit;
}
const formattedAmount = this.formatNumber(amount);
return {
...pick(transaction, [
'id',
'note',
'transactionType',
'referenceType',
'referenceId',
'referenceTypeFormatted',
'date',
]),
amount,
formattedAmount,
currencyCode: this.baseCurrency,
};
} }
const formattedAmount = this.formatNumber(amount); );
return {
...pick(transaction, ['id', 'note', 'transactionType', 'referenceType',
'referenceId', 'date']),
amount,
formattedAmount,
currencyCode: this.baseCurrency,
};
});
} }
/** /**
@@ -84,9 +93,11 @@ export default class GeneralLedgerSheet extends FinancialSheet {
* @param {IAccount} account * @param {IAccount} account
* @return {IGeneralLedgerSheetAccountBalance} * @return {IGeneralLedgerSheetAccountBalance}
*/ */
private accountOpeningBalance(account: IAccount): IGeneralLedgerSheetAccountBalance { private accountOpeningBalance(
account: IAccount
): IGeneralLedgerSheetAccountBalance {
const amount = this.openingBalancesJournal.getAccountBalance(account.id); const amount = this.openingBalancesJournal.getAccountBalance(account.id);
const formattedAmount = this.formatNumber(amount); const formattedAmount = this.formatTotalNumber(amount);
const currencyCode = this.baseCurrency; const currencyCode = this.baseCurrency;
const date = this.query.fromDate; const date = this.query.fromDate;
@@ -98,9 +109,11 @@ export default class GeneralLedgerSheet extends FinancialSheet {
* @param {IAccount} account * @param {IAccount} account
* @return {IGeneralLedgerSheetAccountBalance} * @return {IGeneralLedgerSheetAccountBalance}
*/ */
private accountClosingBalance(account: IAccount): IGeneralLedgerSheetAccountBalance { private accountClosingBalance(
account: IAccount
): IGeneralLedgerSheetAccountBalance {
const amount = this.closingBalancesJournal.getAccountBalance(account.id); const amount = this.closingBalancesJournal.getAccountBalance(account.id);
const formattedAmount = this.formatNumber(amount); const formattedAmount = this.formatTotalNumber(amount);
const currencyCode = this.baseCurrency; const currencyCode = this.baseCurrency;
const date = this.query.toDate; const date = this.query.toDate;
@@ -113,14 +126,14 @@ export default class GeneralLedgerSheet extends FinancialSheet {
* @return {IGeneralLedgerSheetAccount} * @return {IGeneralLedgerSheetAccount}
*/ */
private accountMapper( private accountMapper(
account: IAccount & { type: IAccountType }, account: IAccount & { type: IAccountType }
): IGeneralLedgerSheetAccount { ): IGeneralLedgerSheetAccount {
return { return {
...pick(account, ['id', 'name', 'code', 'index', 'parentAccountId']), ...pick(account, ['id', 'name', 'code', 'index', 'parentAccountId']),
opening: this.accountOpeningBalance(account), opening: this.accountOpeningBalance(account),
transactions: this.accountTransactionsMapper(account), transactions: this.accountTransactionsMapper(account),
closing: this.accountClosingBalance(account), closing: this.accountClosingBalance(account),
} };
} }
/** /**
@@ -131,13 +144,20 @@ export default class GeneralLedgerSheet extends FinancialSheet {
private accountsWalker( private accountsWalker(
accounts: IAccount & { type: IAccountType }[] accounts: IAccount & { type: IAccountType }[]
): IGeneralLedgerSheetAccount[] { ): IGeneralLedgerSheetAccount[] {
return accounts return (
.map((account: IAccount & { type: IAccountType }) => this.accountMapper(account)) accounts
.map((account: IAccount & { type: IAccountType }) =>
// Filter general ledger accounts that have no transactions when `noneTransactions` is on. this.accountMapper(account)
.filter((generalLedgerAccount: IGeneralLedgerSheetAccount) => ( )
!(generalLedgerAccount.transactions.length === 0 && this.query.noneTransactions) // Filter general ledger accounts that have no transactions when `noneTransactions` is on.
)); .filter(
(generalLedgerAccount: IGeneralLedgerSheetAccount) =>
!(
generalLedgerAccount.transactions.length === 0 &&
this.query.noneTransactions
)
)
);
} }
/** /**

View File

@@ -85,8 +85,7 @@ export default class GeneralLedgerService {
group: 'organization', group: 'organization',
key: 'base_currency', key: 'base_currency',
}); });
// Retrieve all accounts with associated type from the storage.
// Retrieve all accounts from the storage.
const accounts = await accountRepository.all('type'); const accounts = await accountRepository.all('type');
const accountsGraph = await accountRepository.getDependencyGraph(); const accountsGraph = await accountRepository.getDependencyGraph();
@@ -111,11 +110,13 @@ export default class GeneralLedgerService {
tenantId, tenantId,
accountsGraph accountsGraph
); );
// Accounts opening transactions.
const openingTransJournal = Journal.fromTransactions( const openingTransJournal = Journal.fromTransactions(
openingBalanceTrans, openingBalanceTrans,
tenantId, tenantId,
accountsGraph accountsGraph
); );
// Accounts closing transactions.
const closingTransJournal = Journal.fromTransactions( const closingTransJournal = Journal.fromTransactions(
closingBalanceTrans, closingBalanceTrans,
tenantId, tenantId,

View File

@@ -57,7 +57,6 @@ export default class JournalSheetService {
group: 'organization', group: 'organization',
key: 'base_currency', key: 'base_currency',
}); });
// Retrieve all accounts on the storage. // Retrieve all accounts on the storage.
const accountsGraph = await accountRepository.getDependencyGraph(); const accountsGraph = await accountRepository.getDependencyGraph();