add server to monorepo.

This commit is contained in:
a.bouhuolia
2023-02-03 11:57:50 +02:00
parent 28e309981b
commit 80b97b5fdc
1303 changed files with 137049 additions and 0 deletions

View File

@@ -0,0 +1,195 @@
import { sumBy, defaultTo } from 'lodash';
import {
ITransactionsByContactsTransaction,
ITransactionsByContactsAmount,
ITransactionsByContactsFilter,
ITransactionsByContactsContact,
IContact,
ILedger,
ILedgerEntry,
} from '@/interfaces';
import FinancialSheet from '../FinancialSheet';
import { allPassedConditionsPass } from 'utils';
export default class TransactionsByContact extends FinancialSheet {
readonly contacts: IContact[];
readonly ledger: ILedger;
readonly filter: ITransactionsByContactsFilter;
readonly accountsGraph: any;
/**
* Customer transaction mapper.
* @param {any} transaction -
* @return {Omit<ITransactionsByContactsTransaction, 'runningBalance'>}
*/
protected contactTransactionMapper(
entry: ILedgerEntry
): Omit<ITransactionsByContactsTransaction, 'runningBalance'> {
const account = this.accountsGraph.getNodeData(entry.accountId);
const currencyCode = this.baseCurrency;
return {
credit: this.getContactAmount(entry.credit, currencyCode),
debit: this.getContactAmount(entry.debit, currencyCode),
accountName: account.name,
currencyCode: this.baseCurrency,
transactionNumber: entry.transactionNumber,
transactionType: this.i18n.__(entry.referenceTypeFormatted),
date: entry.date,
createdAt: entry.createdAt,
};
}
/**
* Customer transactions mapper with running balance.
* @param {number} openingBalance
* @param {ITransactionsByContactsTransaction[]} transactions
* @returns {ITransactionsByContactsTransaction[]}
*/
protected contactTransactionRunningBalance(
openingBalance: number,
accountNormal: 'credit' | 'debit',
transactions: Omit<ITransactionsByContactsTransaction, 'runningBalance'>[]
): any {
let _openingBalance = openingBalance;
return transactions.map(
(transaction: ITransactionsByContactsTransaction) => {
_openingBalance +=
accountNormal === 'debit'
? transaction.debit.amount
: -1 * transaction.debit.amount;
_openingBalance +=
accountNormal === 'credit'
? transaction.credit.amount
: -1 * transaction.credit.amount;
const runningBalance = this.getTotalAmountMeta(
_openingBalance,
transaction.currencyCode
);
return { ...transaction, runningBalance };
}
);
}
/**
* Retrieve the customer closing balance from the given transactions and opening balance.
* @param {number} customerTransactions
* @param {number} openingBalance
* @returns {number}
*/
protected getContactClosingBalance(
customerTransactions: ITransactionsByContactsTransaction[],
contactNormal: 'credit' | 'debit',
openingBalance: number
): number {
const closingBalance = openingBalance;
const totalCredit = sumBy(customerTransactions, 'credit.amount');
const totalDebit = sumBy(customerTransactions, 'debit.amount');
const total =
contactNormal === 'debit'
? totalDebit - totalCredit
: totalCredit - totalDebit;
return closingBalance + total;
}
/**
* Retrieve the given customer opening balance from the given customer id.
* @param {number} customerId
* @returns {number}
*/
protected getContactOpeningBalance(customerId: number): number {
const openingBalanceLedger = this.ledger
.whereContactId(customerId)
.whereToDate(this.filter.fromDate);
// Retrieve the closing balance of the ledger.
const openingBalance = openingBalanceLedger.getClosingBalance();
return defaultTo(openingBalance, 0);
}
/**
* Retrieve the customer amount format meta.
* @param {number} amount
* @param {string} currencyCode
* @returns {ITransactionsByContactsAmount}
*/
protected getContactAmount(
amount: number,
currencyCode: string
): ITransactionsByContactsAmount {
return {
amount,
formattedAmount: this.formatNumber(amount, { currencyCode }),
currencyCode,
};
}
/**
* Retrieve the contact total amount format meta.
* @param {number} amount - Amount.
* @param {string} currencyCode - Currency code./
* @returns {ITransactionsByContactsAmount}
*/
protected getTotalAmountMeta(amount: number, currencyCode: string) {
return {
amount,
formattedAmount: this.formatTotalNumber(amount, { currencyCode }),
currencyCode,
};
}
/**
* Filter customer section that has no transactions.
* @param {ITransactionsByCustomersCustomer} transactionsByCustomer
* @returns {boolean}
*/
private filterContactByNoneTransaction = (
transactionsByContact: ITransactionsByContactsContact
): boolean => {
return transactionsByContact.transactions.length > 0;
};
/**
* Filters customer section has zero closing balnace.
* @param {ITransactionsByCustomersCustomer} transactionsByCustomer
* @returns {boolean}
*/
private filterContactNoneZero = (
transactionsByContact: ITransactionsByContactsContact
): boolean => {
return transactionsByContact.closingBalance.amount !== 0;
};
/**
* Filters the given customer node;
* @param {ICustomerBalanceSummaryCustomer} customer
*/
private contactNodeFilter = (node: ITransactionsByContactsContact) => {
const { noneTransactions, noneZero } = this.filter;
// Conditions pair filter detarminer.
const condsPairFilters = [
[noneTransactions, this.filterContactByNoneTransaction],
[noneZero, this.filterContactNoneZero],
];
return allPassedConditionsPass(condsPairFilters)(node);
};
/**
* Filters the given customers nodes.
* @param {ICustomerBalanceSummaryCustomer[]} nodes
* @returns {ICustomerBalanceSummaryCustomer[]}
*/
protected contactsFilter = (
nodes: ITransactionsByContactsContact[]
): ITransactionsByContactsContact[] => {
return nodes.filter(this.contactNodeFilter);
};
}

View File

@@ -0,0 +1,81 @@
import moment from 'moment';
import * as R from 'ramda';
import { tableMapper, tableRowMapper } from 'utils';
import { ITransactionsByContactsContact, ITableRow } from '@/interfaces';
enum ROW_TYPE {
OPENING_BALANCE = 'OPENING_BALANCE',
CLOSING_BALANCE = 'CLOSING_BALANCE',
TRANSACTION = 'TRANSACTION',
CUSTOMER = 'CUSTOMER',
}
export default class TransactionsByContactsTableRows {
private dateAccessor = (value): string => {
return moment(value.date).format('YYYY MMM DD');
};
/**
* Retrieve the table rows of contact transactions.
* @param {ITransactionsByCustomersCustomer} contact
* @returns {ITableRow[]}
*/
protected contactTransactions = (
contact: ITransactionsByContactsContact
): ITableRow[] => {
const columns = [
{ key: 'date', accessor: this.dateAccessor },
{ key: 'account', accessor: 'accountName' },
{ key: 'transactionType', accessor: 'transactionType' },
{ key: 'transactionNumber', accessor: 'transactionNumber' },
{ key: 'credit', accessor: 'credit.formattedAmount' },
{ key: 'debit', accessor: 'debit.formattedAmount' },
{ key: 'runningBalance', accessor: 'runningBalance.formattedAmount' },
];
return tableMapper(contact.transactions, columns, {
rowTypes: [ROW_TYPE.TRANSACTION],
});
};
/**
* Retrieve the table row of contact opening balance.
* @param {ITransactionsByCustomersCustomer} contact
* @returns {ITableRow}
*/
protected contactOpeningBalance = (
contact: ITransactionsByContactsContact
): ITableRow => {
const columns = [
{ key: 'openingBalanceLabel', value: this.i18n.__('Opening balance') },
...R.repeat({ key: 'empty', value: '' }, 5),
{
key: 'openingBalanceValue',
accessor: 'openingBalance.formattedAmount',
},
];
return tableRowMapper(contact, columns, {
rowTypes: [ROW_TYPE.OPENING_BALANCE],
});
};
/**
* Retrieve the table row of contact closing balance.
* @param {ITransactionsByCustomersCustomer} contact -
* @returns {ITableRow}
*/
protected contactClosingBalance = (
contact: ITransactionsByContactsContact
): ITableRow => {
const columns = [
{ key: 'closingBalanceLabel', value: this.i18n.__('Closing balance') },
...R.repeat({ key: 'empty', value: '' }, 5),
{
key: 'closingBalanceValue',
accessor: 'closingBalance.formattedAmount',
},
];
return tableRowMapper(contact, columns, {
rowTypes: [ROW_TYPE.CLOSING_BALANCE],
});
};
}