mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-18 13:50:31 +00:00
fix: match uncategorized bank transactions
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
import { isEmpty, sumBy } from 'lodash';
|
import { isEmpty, round, sumBy } from 'lodash';
|
||||||
import { ERRORS, MatchedTransactionPOJO } from './types';
|
import { ERRORS, MatchedTransactionPOJO } from './types';
|
||||||
import { ServiceError } from '../Items/ServiceError';
|
import { ServiceError } from '../Items/ServiceError';
|
||||||
|
|
||||||
@@ -22,18 +22,24 @@ export const sortClosestMatchTransactions = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const sumMatchTranasctions = (transactions: Array<any>) => {
|
export const sumMatchTranasctions = (transactions: Array<any>) => {
|
||||||
return transactions.reduce(
|
const total = transactions.reduce(
|
||||||
(total, item) =>
|
(sum, item) => {
|
||||||
total +
|
const amount = parseFloat(item.amount) || 0;
|
||||||
(item.transactionNormal === 'debit' ? 1 : -1) * parseFloat(item.amount),
|
const multiplier = item.transactionNormal === 'debit' ? 1 : -1;
|
||||||
|
return sum + multiplier * amount;
|
||||||
|
},
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
// Round to 2 decimal places to avoid floating-point precision issues
|
||||||
|
return round(total, 2);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const sumUncategorizedTransactions = (
|
export const sumUncategorizedTransactions = (
|
||||||
uncategorizedTransactions: Array<any>
|
uncategorizedTransactions: Array<any>
|
||||||
) => {
|
) => {
|
||||||
return sumBy(uncategorizedTransactions, 'amount');
|
const total = sumBy(uncategorizedTransactions, 'amount');
|
||||||
|
// Round to 2 decimal places to avoid floating-point precision issues
|
||||||
|
return round(total, 2);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const validateUncategorizedTransactionsNotMatched = (
|
export const validateUncategorizedTransactionsNotMatched = (
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export class MatchBankTransactions {
|
|||||||
private readonly uncategorizedBankTransactionModel: TenantModelProxy<
|
private readonly uncategorizedBankTransactionModel: TenantModelProxy<
|
||||||
typeof UncategorizedBankTransaction
|
typeof UncategorizedBankTransaction
|
||||||
>,
|
>,
|
||||||
) {}
|
) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates the match bank transactions DTO.
|
* Validates the match bank transactions DTO.
|
||||||
@@ -100,7 +100,10 @@ export class MatchBankTransactions {
|
|||||||
);
|
);
|
||||||
// Validates the total given matching transcations whether is not equal
|
// Validates the total given matching transcations whether is not equal
|
||||||
// uncategorized transaction amount.
|
// uncategorized transaction amount.
|
||||||
if (totalUncategorizedTransactions !== totalMatchedTranasctions) {
|
// Use tolerance-based comparison to handle floating-point precision issues
|
||||||
|
const tolerance = 0.01; // Allow 0.01 difference for floating-point precision
|
||||||
|
const difference = Math.abs(totalUncategorizedTransactions - totalMatchedTranasctions);
|
||||||
|
if (difference > tolerance) {
|
||||||
throw new ServiceError(ERRORS.TOTAL_MATCHING_TRANSACTIONS_INVALID);
|
throw new ServiceError(ERRORS.TOTAL_MATCHING_TRANSACTIONS_INVALID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,24 +12,30 @@ export class MatchTransactionsTypes {
|
|||||||
private static registry: MatchTransactionsTypesRegistry;
|
private static registry: MatchTransactionsTypesRegistry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Consttuctor method.
|
* Constructor method.
|
||||||
*/
|
*/
|
||||||
constructor() {
|
constructor(
|
||||||
|
private readonly getMatchedInvoicesService: GetMatchedTransactionsByInvoices,
|
||||||
|
private readonly getMatchedBillsService: GetMatchedTransactionsByBills,
|
||||||
|
private readonly getMatchedExpensesService: GetMatchedTransactionsByExpenses,
|
||||||
|
private readonly getMatchedManualJournalsService: GetMatchedTransactionsByManualJournals,
|
||||||
|
private readonly getMatchedCashflowService: GetMatchedTransactionsByCashflow,
|
||||||
|
) {
|
||||||
this.boot();
|
this.boot();
|
||||||
}
|
}
|
||||||
|
|
||||||
get registered() {
|
get registered() {
|
||||||
return [
|
return [
|
||||||
{ type: 'SaleInvoice', service: GetMatchedTransactionsByInvoices },
|
{ type: 'SaleInvoice', service: this.getMatchedInvoicesService },
|
||||||
{ type: 'Bill', service: GetMatchedTransactionsByBills },
|
{ type: 'Bill', service: this.getMatchedBillsService },
|
||||||
{ type: 'Expense', service: GetMatchedTransactionsByExpenses },
|
{ type: 'Expense', service: this.getMatchedExpensesService },
|
||||||
{
|
{
|
||||||
type: 'ManualJournal',
|
type: 'ManualJournal',
|
||||||
service: GetMatchedTransactionsByManualJournals,
|
service: this.getMatchedManualJournalsService,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'CashflowTransaction',
|
type: 'CashflowTransaction',
|
||||||
service: GetMatchedTransactionsByCashflow,
|
service: this.getMatchedCashflowService,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -50,14 +56,13 @@ export class MatchTransactionsTypes {
|
|||||||
* Boots all the registered importables.
|
* Boots all the registered importables.
|
||||||
*/
|
*/
|
||||||
public boot() {
|
public boot() {
|
||||||
if (!MatchTransactionsTypes.registry) {
|
const instance = MatchTransactionsTypesRegistry.getInstance();
|
||||||
const instance = MatchTransactionsTypesRegistry.getInstance();
|
|
||||||
|
|
||||||
this.registered.forEach((registered) => {
|
// Always register services to ensure they're available
|
||||||
// const serviceInstanace = Container.get(registered.service);
|
this.registered.forEach((registered) => {
|
||||||
// instance.register(registered.type, serviceInstanace);
|
instance.register(registered.type, registered.service);
|
||||||
});
|
});
|
||||||
MatchTransactionsTypes.registry = instance;
|
|
||||||
}
|
MatchTransactionsTypes.registry = instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user