Skip to content

Commit

Permalink
FINERACT-2107: Adjust event trigger on refund reversion
Browse files Browse the repository at this point in the history
  • Loading branch information
leksinomi authored and adamsaghy committed Nov 13, 2024
1 parent a5acbd8 commit 7408f10
Show file tree
Hide file tree
Showing 3 changed files with 362 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2360,7 +2360,7 @@ public void makeRefund(final LoanTransaction loanTransaction, final LoanLifecycl
doPostLoanTransactionChecks(loanTransaction.getTransactionDate(), loanLifecycleStateMachine);
}

private ChangedTransactionDetail handleRepaymentOrRecoveryOrWaiverTransaction(final LoanTransaction loanTransaction,
public ChangedTransactionDetail handleRepaymentOrRecoveryOrWaiverTransaction(final LoanTransaction loanTransaction,
final LoanLifecycleStateMachine loanLifecycleStateMachine, final LoanTransaction adjustedTransaction,
final ScheduleGeneratorDTO scheduleGeneratorDTO) {
ChangedTransactionDetail changedTransactionDetail = null;
Expand Down Expand Up @@ -2681,60 +2681,6 @@ public LoanTransaction deriveDefaultInterestWaiverTransaction() {
possibleInterestToWaive.zero(), ExternalId.empty());
}

public ChangedTransactionDetail adjustExistingTransaction(final LoanTransaction newTransactionDetail,
final LoanLifecycleStateMachine loanLifecycleStateMachine, final LoanTransaction transactionForAdjustment,
final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
final ScheduleGeneratorDTO scheduleGeneratorDTO, final ExternalId reversalExternalId) {

ChangedTransactionDetail changedTransactionDetail = null;

existingTransactionIds.addAll(findExistingTransactionIds());
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());

validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.LOAN_REPAYMENT_OR_WAIVER,
transactionForAdjustment.getTransactionDate());

if (transactionForAdjustment.isNotRepaymentLikeType() && transactionForAdjustment.isNotWaiver()
&& transactionForAdjustment.isNotCreditBalanceRefund()) {
final String errorMessage = "Only (non-reversed) transactions of type repayment, waiver or credit balance refund can be adjusted.";
throw new InvalidLoanTransactionTypeException("transaction",
"adjustment.is.only.allowed.to.repayment.or.waiver.or.creditbalancerefund.transactions", errorMessage);
}

transactionForAdjustment.reverse(reversalExternalId);
transactionForAdjustment.manuallyAdjustedOrReversed();

if (transactionForAdjustment.getTypeOf().equals(LoanTransactionType.MERCHANT_ISSUED_REFUND)
|| transactionForAdjustment.getTypeOf().equals(LoanTransactionType.PAYOUT_REFUND)) {
getLoanTransactions().stream() //
.filter(LoanTransaction::isNotReversed)
.filter(loanTransaction -> loanTransaction.getLoanTransactionRelations().stream()
.anyMatch(relation -> relation.getRelationType().equals(LoanTransactionRelationTypeEnum.RELATED)
&& relation.getToTransaction().getId().equals(transactionForAdjustment.getId())))
.forEach(loanTransaction -> {
loanTransaction.reverse();
loanTransaction.manuallyAdjustedOrReversed();
});
}

if (isClosedWrittenOff()) {
// find write off transaction and reverse it
final LoanTransaction writeOffTransaction = findWriteOffTransaction();
writeOffTransaction.reverse();
}

if (isClosedObligationsMet() || isClosedWrittenOff() || isClosedWithOutstandingAmountMarkedForReschedule()) {
loanLifecycleStateMachine.transition(LoanEvent.LOAN_ADJUST_TRANSACTION, this);
}

if (newTransactionDetail.isRepaymentLikeType() || newTransactionDetail.isInterestWaiver()) {
changedTransactionDetail = handleRepaymentOrRecoveryOrWaiverTransaction(newTransactionDetail, loanLifecycleStateMachine,
transactionForAdjustment, scheduleGeneratorDTO);
}

return changedTransactionDetail;
}

public ChangedTransactionDetail undoWrittenOff(LoanLifecycleStateMachine loanLifecycleStateMachine,
final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
final ScheduleGeneratorDTO scheduleGeneratorDTO) {
Expand Down Expand Up @@ -3087,7 +3033,7 @@ public boolean isClosedWrittenOff() {
return getStatus().isClosedWrittenOff();
}

private boolean isClosedWithOutstandingAmountMarkedForReschedule() {
public boolean isClosedWithOutstandingAmountMarkedForReschedule() {
return getStatus().isClosedWithOutsandingAmountMarkedForReschedule();
}

Expand Down Expand Up @@ -3777,7 +3723,7 @@ public void removeLoanTransaction(final LoanTransaction loanTransaction) {
this.loanTransactions.remove(loanTransaction);
}

private void validateActivityNotBeforeClientOrGroupTransferDate(final LoanEvent event, final LocalDate activityDate) {
public void validateActivityNotBeforeClientOrGroupTransferDate(final LoanEvent event, final LocalDate activityDate) {
if (this.client != null && this.client.getOfficeJoiningDate() != null) {
final LocalDate clientOfficeJoiningDate = this.client.getOfficeJoiningDate();
if (DateUtils.isBefore(activityDate, clientOfficeJoiningDate)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1489,7 +1489,7 @@ public CommandProcessingResult adjustLoanTransaction(final Long loanId, final Lo
loanTransactionValidator.validateRepaymentDateIsOnNonWorkingDay(newTransactionDetail.getTransactionDate(),
holidayDetailDTO.getWorkingDays(), holidayDetailDTO.isAllowTransactionsOnNonWorkingDay());

final ChangedTransactionDetail changedTransactionDetail = loan.adjustExistingTransaction(newTransactionDetail,
final ChangedTransactionDetail changedTransactionDetail = adjustExistingTransaction(loan, newTransactionDetail,
loanLifecycleStateMachine, transactionToAdjust, existingTransactionIds, existingReversedTransactionIds,
scheduleGeneratorDTO, reversalTxnExternalId);

Expand Down Expand Up @@ -1583,6 +1583,62 @@ public CommandProcessingResult adjustLoanTransaction(final Long loanId, final Lo
.with(changes).build();
}

public ChangedTransactionDetail adjustExistingTransaction(final Loan loan, final LoanTransaction newTransactionDetail,
final LoanLifecycleStateMachine loanLifecycleStateMachine, final LoanTransaction transactionForAdjustment,
final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
final ScheduleGeneratorDTO scheduleGeneratorDTO, final ExternalId reversalExternalId) {

ChangedTransactionDetail changedTransactionDetail = null;

existingTransactionIds.addAll(loan.findExistingTransactionIds());
existingReversedTransactionIds.addAll(loan.findExistingReversedTransactionIds());

loan.validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.LOAN_REPAYMENT_OR_WAIVER,
transactionForAdjustment.getTransactionDate());

if (transactionForAdjustment.isNotRepaymentLikeType() && transactionForAdjustment.isNotWaiver()
&& transactionForAdjustment.isNotCreditBalanceRefund()) {
final String errorMessage = "Only (non-reversed) transactions of type repayment, waiver or credit balance refund can be adjusted.";
throw new InvalidLoanTransactionTypeException("transaction",
"adjustment.is.only.allowed.to.repayment.or.waiver.or.creditbalancerefund.transactions", errorMessage);
}

transactionForAdjustment.reverse(reversalExternalId);
transactionForAdjustment.manuallyAdjustedOrReversed();

if (transactionForAdjustment.getTypeOf().equals(LoanTransactionType.MERCHANT_ISSUED_REFUND)
|| transactionForAdjustment.getTypeOf().equals(LoanTransactionType.PAYOUT_REFUND)) {
loan.getLoanTransactions().stream() //
.filter(LoanTransaction::isNotReversed)
.filter(loanTransaction -> loanTransaction.getLoanTransactionRelations().stream()
.anyMatch(relation -> relation.getRelationType().equals(LoanTransactionRelationTypeEnum.RELATED)
&& relation.getToTransaction().getId().equals(transactionForAdjustment.getId())))
.forEach(loanTransaction -> {
loanTransaction.reverse();
loanTransaction.manuallyAdjustedOrReversed();
LoanAdjustTransactionBusinessEvent.Data eventData = new LoanAdjustTransactionBusinessEvent.Data(loanTransaction);
businessEventNotifierService.notifyPostBusinessEvent(new LoanAdjustTransactionBusinessEvent(eventData));
});
}

if (loan.isClosedWrittenOff()) {
// find write off transaction and reverse it
final LoanTransaction writeOffTransaction = loan.findWriteOffTransaction();
writeOffTransaction.reverse();
}

if (loan.isClosedObligationsMet() || loan.isClosedWrittenOff() || loan.isClosedWithOutstandingAmountMarkedForReschedule()) {
loanLifecycleStateMachine.transition(LoanEvent.LOAN_ADJUST_TRANSACTION, loan);
}

if (newTransactionDetail.isRepaymentLikeType() || newTransactionDetail.isInterestWaiver()) {
changedTransactionDetail = loan.handleRepaymentOrRecoveryOrWaiverTransaction(newTransactionDetail, loanLifecycleStateMachine,
transactionForAdjustment, scheduleGeneratorDTO);
}

return changedTransactionDetail;
}

@Transactional
@Override
public CommandProcessingResult chargebackLoanTransaction(final Long loanId, final Long transactionId, final JsonCommand command) {
Expand Down
Loading

0 comments on commit 7408f10

Please sign in to comment.