This is an automated email from the ASF dual-hosted git repository.
adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
The following commit(s) were added to refs/heads/develop by this push:
new ce2f05ee7 FINERACT-1926: Fix No Such Element exception in Asset buyback
ce2f05ee7 is described below
commit ce2f05ee783254d9467680be42c31b433d4048e9
Author: Jose Alberto Hernandez <[email protected]>
AuthorDate: Wed Apr 10 18:11:51 2024 -0600
FINERACT-1926: Fix No Such Element exception in Asset buyback
---
.../loan/LoanAccountOwnerTransferBusinessStep.java | 16 ++++---
.../LoanAccountOwnerTransferBusinessStepTest.java | 49 ++++++++++++++++++++++
2 files changed, 60 insertions(+), 5 deletions(-)
diff --git
a/fineract-investor/src/main/java/org/apache/fineract/investor/cob/loan/LoanAccountOwnerTransferBusinessStep.java
b/fineract-investor/src/main/java/org/apache/fineract/investor/cob/loan/LoanAccountOwnerTransferBusinessStep.java
index 65a6b4edf..99b9c8ef8 100644
---
a/fineract-investor/src/main/java/org/apache/fineract/investor/cob/loan/LoanAccountOwnerTransferBusinessStep.java
+++
b/fineract-investor/src/main/java/org/apache/fineract/investor/cob/loan/LoanAccountOwnerTransferBusinessStep.java
@@ -22,6 +22,7 @@ import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import java.util.Objects;
+import java.util.Optional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.cob.loan.LoanCOBBusinessStep;
@@ -103,14 +104,19 @@ public class LoanAccountOwnerTransferBusinessStep
implements LoanCOBBusinessStep
private void handleBuyback(final Loan loan, final LocalDate settlementDate,
final ExternalAssetOwnerTransfer
buybackExternalAssetOwnerTransfer) {
- ExternalAssetOwnerTransfer activeExternalAssetOwnerTransfer =
externalAssetOwnerTransferRepository
+ Optional<ExternalAssetOwnerTransfer>
optActiveExternalAssetOwnerTransfer = externalAssetOwnerTransferRepository
.findOne((root, query, criteriaBuilder) ->
criteriaBuilder.and(criteriaBuilder.equal(root.get("loanId"), loan.getId()),
criteriaBuilder.equal(root.get("owner"),
buybackExternalAssetOwnerTransfer.getOwner()),
criteriaBuilder.equal(root.get("status"),
ExternalTransferStatus.ACTIVE),
- criteriaBuilder.equal(root.get("effectiveDateTo"),
FUTURE_DATE_9999_12_31)))
- .orElseThrow();
- ExternalAssetOwnerTransfer newExternalAssetOwnerTransfer =
buybackAsset(loan, settlementDate, buybackExternalAssetOwnerTransfer,
- activeExternalAssetOwnerTransfer);
+ criteriaBuilder.equal(root.get("effectiveDateTo"),
FUTURE_DATE_9999_12_31)));
+ ExternalAssetOwnerTransfer newExternalAssetOwnerTransfer;
+ if (!optActiveExternalAssetOwnerTransfer.isPresent()) {
+ newExternalAssetOwnerTransfer = createNewEntry(settlementDate,
buybackExternalAssetOwnerTransfer,
+ ExternalTransferStatus.CANCELLED,
ExternalTransferSubStatus.UNSOLD, settlementDate, settlementDate);
+ } else {
+ newExternalAssetOwnerTransfer = buybackAsset(loan, settlementDate,
buybackExternalAssetOwnerTransfer,
+ optActiveExternalAssetOwnerTransfer.get());
+ }
businessEventNotifierService.notifyPostBusinessEvent(new
LoanOwnershipTransferBusinessEvent(newExternalAssetOwnerTransfer, loan));
businessEventNotifierService.notifyPostBusinessEvent(new
LoanAccountSnapshotBusinessEvent(loan));
}
diff --git
a/fineract-investor/src/test/java/org/apache/fineract/investor/cob/loan/LoanAccountOwnerTransferBusinessStepTest.java
b/fineract-investor/src/test/java/org/apache/fineract/investor/cob/loan/LoanAccountOwnerTransferBusinessStepTest.java
index 8286eed6f..02643749b 100644
---
a/fineract-investor/src/test/java/org/apache/fineract/investor/cob/loan/LoanAccountOwnerTransferBusinessStepTest.java
+++
b/fineract-investor/src/test/java/org/apache/fineract/investor/cob/loan/LoanAccountOwnerTransferBusinessStepTest.java
@@ -383,6 +383,55 @@ public class LoanAccountOwnerTransferBusinessStepTest {
assertEquals("Execute external asset owner transfer", actualEnumName);
}
+ @Test
+ public void givenLoanSaleAnsBuyBackButBalanceIsNegative() {
+ // given
+ final Loan loanForProcessing = Mockito.mock(Loan.class);
+ when(loanForProcessing.getId()).thenReturn(1L);
+ LoanSummary loanSummary = Mockito.mock(LoanSummary.class);
+ when(loanForProcessing.getLoanSummary()).thenReturn(loanSummary);
+ when(loanSummary.getTotalOutstanding()).thenReturn(BigDecimal.ZERO);
+ when(loanForProcessing.getTotalOverpaid()).thenReturn(BigDecimal.ONE);
+ ExternalAssetOwnerTransfer firstResponseItem =
Mockito.mock(ExternalAssetOwnerTransfer.class);
+ ExternalAssetOwnerTransfer secondResponseItem =
Mockito.mock(ExternalAssetOwnerTransfer.class);
+ secondResponseItem.setSettlementDate(actualDate.plusDays(2));
+
+ ExternalAssetOwnerTransfer firstSaveResult =
Mockito.mock(ExternalAssetOwnerTransfer.class);
+ ExternalAssetOwnerTransfer secondSaveResult =
Mockito.mock(ExternalAssetOwnerTransfer.class);
+ secondSaveResult.setSettlementDate(actualDate.plusDays(2));
+ ExternalAssetOwnerTransfer thirdSaveResult =
Mockito.mock(ExternalAssetOwnerTransfer.class);
+ ExternalAssetOwnerTransfer fourthSaveResult =
Mockito.mock(ExternalAssetOwnerTransfer.class);
+
+
when(firstResponseItem.getStatus()).thenReturn(ExternalTransferStatus.PENDING);
+
when(externalAssetOwnerTransferRepository.save(any(ExternalAssetOwnerTransfer.class))).thenReturn(firstSaveResult)
+
.thenReturn(secondSaveResult).thenReturn(thirdSaveResult).thenReturn(fourthSaveResult);
+ List<ExternalAssetOwnerTransfer> response = List.of(firstResponseItem);
+
when(externalAssetOwnerTransferRepository.findAll(any(Specification.class),
eq(Sort.by(Sort.Direction.ASC, "id"))))
+ .thenReturn(response);
+ ArgumentCaptor<ExternalAssetOwnerTransfer>
externalAssetOwnerTransferArgumentCaptor = ArgumentCaptor
+ .forClass(ExternalAssetOwnerTransfer.class);
+ // when
+ Loan processedLoan = underTest.execute(loanForProcessing);
+ // then
+ verify(externalAssetOwnerTransferRepository,
times(1)).findAll(any(Specification.class), eq(Sort.by(Sort.Direction.ASC,
"id")));
+ verify(firstResponseItem).setEffectiveDateTo(actualDate);
+ verify(externalAssetOwnerTransferRepository,
times(2)).save(externalAssetOwnerTransferArgumentCaptor.capture());
+
+
assertEquals(externalAssetOwnerTransferArgumentCaptor.getAllValues().get(0).getOwner(),
+
externalAssetOwnerTransferArgumentCaptor.getAllValues().get(1).getOwner());
+
assertEquals(externalAssetOwnerTransferArgumentCaptor.getAllValues().get(0).getExternalId(),
+
externalAssetOwnerTransferArgumentCaptor.getAllValues().get(1).getExternalId());
+ assertEquals(ExternalTransferStatus.DECLINED,
externalAssetOwnerTransferArgumentCaptor.getAllValues().get(1).getStatus());
+ assertEquals(ExternalTransferSubStatus.BALANCE_NEGATIVE,
+
externalAssetOwnerTransferArgumentCaptor.getAllValues().get(1).getSubStatus());
+ assertEquals(actualDate,
externalAssetOwnerTransferArgumentCaptor.getAllValues().get(1).getSettlementDate());
+
+ assertEquals(processedLoan, loanForProcessing);
+
+ ArgumentCaptor<BusinessEvent<?>> businessEventArgumentCaptor =
verifyBusinessEvents(2);
+ verifyLoanTransferBusinessEvent(businessEventArgumentCaptor, 0,
loanForProcessing, secondSaveResult);
+ }
+
@NotNull
private ArgumentCaptor<BusinessEvent<?>> verifyBusinessEvents(int
expectedBusinessEvents) {
@SuppressWarnings("unchecked")