FINERACT-1971: Wrong GL entries on refund with reverse replay and charge off

This commit is contained in:
Ruchi Dhamankar
2024-06-11 16:58:53 +02:00
committed by Adam Saghy
parent f0deb111cb
commit 369b809700
3 changed files with 260 additions and 4 deletions
@@ -60,6 +60,7 @@ import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
@@ -4329,18 +4330,39 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
LoanTransaction chargeOffTransaction = this.loanTransactions.stream().filter(LoanTransaction::isChargeOff)
.filter(LoanTransaction::isNotReversed).findFirst().get();
LoanTransaction originalChargeOffTransaction = getOriginalTransactionIfReverseReplayed(chargeOffTransaction);
this.loanTransactions.stream().filter(chargeOffDateCriteria).forEach(transaction -> {
boolean isExistingTransaction = existingTransactionIds.contains(transaction.getId());
boolean isExistingReversedTransaction = existingReversedTransactionIds.contains(transaction.getId());
List<Map<String, Object>> targetList = (transaction.getId().compareTo(chargeOffTransaction.getId()) < 0)
? newLoanTransactionsBeforeChargeOff
: newLoanTransactionsAfterChargeOff;
if ((transaction.isReversed() && isExistingTransaction && !isExistingReversedTransaction) || !isExistingTransaction) {
List<Map<String, Object>> targetList = null;
if ((transaction.isReversed() && isExistingTransaction && !isExistingReversedTransaction)) {
// reversed transactions
LoanTransaction originalTransaction = getOriginalTransactionIfReverseReplayed(transaction);
targetList = originalTransaction.happenedBefore(originalChargeOffTransaction) ? newLoanTransactionsBeforeChargeOff
: newLoanTransactionsAfterChargeOff;
} else if (!isExistingTransaction) {
// new and replayed transactions
targetList = transaction.happenedBefore(chargeOffTransaction) ? newLoanTransactionsBeforeChargeOff
: newLoanTransactionsAfterChargeOff;
}
if (targetList != null) {
targetList.add(transaction.toMapData(currencyCode));
}
});
}
private LoanTransaction getOriginalTransactionIfReverseReplayed(LoanTransaction loanTransaction) {
if (!loanTransaction.getLoanTransactionRelations().isEmpty()) {
return loanTransaction.getLoanTransactionRelations().stream()
.filter(tr -> LoanTransactionRelationTypeEnum.REPLAYED.equals(tr.getRelationType())).map(tr -> tr.getToTransaction())
.collect(Collectors.toList()).stream().sorted(Comparator.comparingLong(LoanTransaction::getId)).findFirst()
.orElse(loanTransaction);
}
return loanTransaction;
}
public Map<String, Object> deriveAccountingBridgeData(final String currencyCode, final List<Long> existingTransactionIds,
final List<Long> existingReversedTransactionIds, boolean isAccountTransfer) {
@@ -1016,6 +1016,25 @@ public class LoanTransaction extends AbstractAuditableWithUTCDateTimeCustom {
this.loanReAgeParameter = loanReAgeParameter;
}
public boolean happenedBefore(LoanTransaction loanTransaction) {
// compare transaction date, creation date and then transaction id
if (DateUtils.isBefore(getTransactionDate(), loanTransaction.getTransactionDate())) {
return true;
}
if (DateUtils.isEqual(getTransactionDate(), loanTransaction.getTransactionDate())) {
if (DateUtils.isBefore(getCreatedDateTime(), loanTransaction.getCreatedDateTime())) {
return true;
}
if (DateUtils.isEqual(getCreatedDateTime(), loanTransaction.getCreatedDateTime())) {
if (getId().compareTo(loanTransaction.getId()) < 0) {
return true;
}
}
}
return false;
}
// TODO missing hashCode(), equals(Object obj), but probably OK as long as
// this is never stored in a Collection.
}