WIP: customer balance report.

This commit is contained in:
a.bouhuolia
2021-05-05 02:19:43 +02:00
parent 8275d3d395
commit 8ca3509f03
14 changed files with 843 additions and 1 deletions

View File

@@ -0,0 +1,81 @@
import * as R from 'ramda';
import FinancialSheet from '../FinancialSheet';
import { IAccountTransaction, ICustomer } from 'interfaces';
import { transaction } from 'objection';
export default class TransactionsByCustomers extends FinancialSheet {
customers: ICustomer[];
transactionsByContact: any;
baseCurrency: string;
/**
* Constructor method.
* @param {ICustomer} customers
* @param transactionsByContact
* @param {string} baseCurrency
*/
constructor(
customers: ICustomer[],
transactionsByContact: Map<number, IAccountTransaction[]>,
baseCurrency: string
) {
super();
this.customers = customers;
this.transactionsByContact = transactionsByContact;
this.baseCurrency = baseCurrency;
}
/**
*
*/
private customerTransactionMapper(
transaction
): ITransactionsByCustomersTransaction {
return {
credit: transaction.credit,
debit: transaction.debit,
transactionNumber: transaction.transactionNumber,
referenceNumber: transaction.referenceNumber,
date: transaction.date,
createdAt: transaction.createdAt,
};
}
private customerTransactionRunningBalance(
openingBalance: number,
transaction: ITransactionsByCustomersTransaction
): ITransactionsByCustomersTransaction {
}
private customerTransactions(customerId: number) {
const transactions = this.transactionsByContact.get(customerId + '') || [];
return R.compose(
R.map(this.customerTransactionMapper),
R.map(R.curry(this.customerTransactionRunningBalance(0)))
).bind(this)(transactions);
}
private customerMapper(customer: ICustomer) {
return {
customerName: customer.displayName,
openingBalance: {},
closingBalance: {},
transactions: this.customerTransactions(customer.id),
};
}
private customersMapper(customers: ICustomer[]) {
return customers.map(this.customerMapper.bind(this));
}
public reportData() {
return this.customersMapper(this.customers);
}
public reportColumns() {
return [];
}
}

View File

@@ -0,0 +1,84 @@
import { Inject } from 'typedi';
import moment from 'moment';
import { groupBy } from 'lodash';
import TenancyService from 'services/Tenancy/TenancyService';
import {
ITransactionsByCustomersService,
ITransactionsByCustomersFilter,
ITransactionsByCustomersStatement,
} from 'interfaces';
import TransactionsByCustomers from './TransactionsByCustomers';
export default class TransactionsByCustomersService implements ITransactionsByCustomersService {
@Inject()
tenancy: TenancyService;
@Inject('logger')
logger: any;
/**
* Defaults balance sheet filter query.
* @return {ICustomerBalanceSummaryQuery}
*/
get defaultQuery(): ITransactionsByCustomersFilter {
return {
fromDate: moment().format('YYYY-MM-DD'),
toDate: moment().format('YYYY-MM-DD'),
numberFormat: {
precision: 2,
divideOn1000: false,
showZero: false,
formatMoney: 'total',
negativeFormat: 'mines',
},
comparison: {
percentageOfColumn: true,
},
noneZero: false,
noneTransactions: false,
};
}
/**
* Retrieve transactions by by the customers.
* @param {number} tenantId
* @param {ITransactionsByCustomersFilter} query
* @return {Promise<ITransactionsByCustomersStatement>}
*/
public async transactionsByCustomers(
tenantId: number,
query: ITransactionsByCustomersFilter
): Promise<ITransactionsByCustomersStatement> {
const { transactionsRepository } = this.tenancy.repositories(tenantId);
const { Customer } = this.tenancy.models(tenantId);
// Settings tenant service.
const settings = this.tenancy.settings(tenantId);
const baseCurrency = settings.get({
group: 'organization',
key: 'base_currency',
});
const customers = await Customer.query().orderBy('displayName');
// Retrieve all journal transactions based on the given query.
const transactions = await transactionsRepository.journal({
fromDate: query.fromDate,
toDate: query.toDate,
});
// Transactions by customers data mapper.
const reportInstance = new TransactionsByCustomers(
customers,
new Map(Object.entries(groupBy(transactions, 'contactId'))),
baseCurrency
);
const reportData = reportInstance.reportData();
const reportColumns = reportInstance.reportColumns();
return {
data: reportData,
columns: reportColumns,
};
}
}