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 d65de7a8e FINERACT-1926: Add external id validation for buyback and 
sale
d65de7a8e is described below

commit d65de7a8e922fd41cec81bb261a6ac6e855175c9
Author: Adam Saghy <[email protected]>
AuthorDate: Tue Jul 11 12:25:23 2023 +0200

    FINERACT-1926: Add external id validation for buyback and sale
---
 .../ExternalAssetOwnersWriteServiceImpl.java       | 20 ++++++++++++++++----
 .../InitiateExternalAssetOwnerTransferTest.java    | 22 ++++++++++++++++++++++
 2 files changed, 38 insertions(+), 4 deletions(-)

diff --git 
a/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnersWriteServiceImpl.java
 
b/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnersWriteServiceImpl.java
index 8ee6d264f..a56fca359 100644
--- 
a/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnersWriteServiceImpl.java
+++ 
b/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnersWriteServiceImpl.java
@@ -78,10 +78,14 @@ public class ExternalAssetOwnersWriteServiceImpl implements 
ExternalAssetOwnersW
     @Override
     @Transactional
     public CommandProcessingResult saleLoanByLoanId(JsonCommand command) {
+        final JsonElement json = fromApiJsonHelper.parse(command.json());
+        validateSaleRequestBody(command.json());
+        ExternalId externalId = getTransferExternalIdFromJson(json);
+        validateExternalId(externalId);
         Long loanId = command.getLoanId();
         LoanIdAndExternalIdAndStatus loanIdAndExternalIdAndStatus = 
fetchLoanDetails(loanId);
         validateLoanStatus(loanIdAndExternalIdAndStatus);
-        ExternalAssetOwnerTransfer externalAssetOwnerTransfer = 
createSaleTransfer(loanId, command.json(),
+        ExternalAssetOwnerTransfer externalAssetOwnerTransfer = 
createSaleTransfer(loanId, json,
                 loanIdAndExternalIdAndStatus.getExternalId());
         validateSale(externalAssetOwnerTransfer);
         
externalAssetOwnerTransferRepository.saveAndFlush(externalAssetOwnerTransfer);
@@ -98,12 +102,22 @@ public class ExternalAssetOwnersWriteServiceImpl 
implements ExternalAssetOwnersW
         LocalDate settlementDate = getSettlementDateFromJson(json);
         ExternalId externalId = getTransferExternalIdFromJson(json);
         validateSettlementDate(settlementDate);
+        validateExternalId(externalId);
         ExternalAssetOwnerTransfer effectiveTransfer = 
fetchAndValidateEffectiveTransferForBuyback(loanId, settlementDate);
         ExternalAssetOwnerTransfer externalAssetOwnerTransfer = 
createBuybackTransfer(effectiveTransfer, settlementDate, externalId);
         
externalAssetOwnerTransferRepository.saveAndFlush(externalAssetOwnerTransfer);
         return buildResponseData(externalAssetOwnerTransfer);
     }
 
+    private void validateExternalId(ExternalId externalId) {
+        boolean alreadyExists = externalAssetOwnerTransferRepository
+                .exists((root, query, criteriaBuilder) -> 
criteriaBuilder.equal(root.get("externalId"), externalId));
+        if (alreadyExists) {
+            throw new ExternalAssetOwnerInitiateTransferException(
+                    String.format("Already existing an asset transfer with the 
provided transfer external id: %s", externalId.getValue()));
+        }
+    }
+
     private void validateLoan(Long loanId) {
         if (!loanRepository.existsById(loanId)) {
             throw new LoanNotFoundException(loanId);
@@ -247,11 +261,9 @@ public class ExternalAssetOwnersWriteServiceImpl 
implements ExternalAssetOwnersW
         }
     }
 
-    private ExternalAssetOwnerTransfer createSaleTransfer(Long loanId, String 
apiRequestBodyAsJson, ExternalId externalLoanId) {
+    private ExternalAssetOwnerTransfer createSaleTransfer(Long loanId, 
JsonElement json, ExternalId externalLoanId) {
         ExternalAssetOwnerTransfer externalAssetOwnerTransfer = new 
ExternalAssetOwnerTransfer();
         LocalDate effectiveFrom = ThreadLocalContextUtil.getBusinessDate();
-        validateSaleRequestBody(apiRequestBodyAsJson);
-        final JsonElement json = fromApiJsonHelper.parse(apiRequestBodyAsJson);
 
         ExternalAssetOwner owner = getOwner(json);
         externalAssetOwnerTransfer.setOwner(owner);
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/investor/externalassetowner/InitiateExternalAssetOwnerTransferTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/investor/externalassetowner/InitiateExternalAssetOwnerTransferTest.java
index cd5166e28..ca520088e 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/investor/externalassetowner/InitiateExternalAssetOwnerTransferTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/investor/externalassetowner/InitiateExternalAssetOwnerTransferTest.java
@@ -615,6 +615,16 @@ public class InitiateExternalAssetOwnerTransferTest {
             CallFailedRuntimeException exception5 = 
assertThrows(CallFailedRuntimeException.class,
                     () -> createBuybackTransfer(-1, "2020-03-03"));
             assertTrue(exception5.getMessage().contains("Loan with identifier 
-1 does not exist"));
+
+            String externalId = UUID.randomUUID().toString();
+            CallFailedRuntimeException exception6 = 
assertThrows(CallFailedRuntimeException.class, () -> {
+                Integer clientID = createClient();
+                Integer loanID = createLoanForClient(clientID);
+                createSaleTransfer(loanID, "2020-03-03", externalId, "1", 
"1.0");
+                createBuybackTransfer(loanID, "2020-03-02", externalId);
+            });
+            assertTrue(exception6.getMessage()
+                    .contains(String.format("Already existing an asset 
transfer with the provided transfer external id: %s", externalId)));
         } finally {
             cleanUpAndRestoreBusinessDate();
         }
@@ -657,6 +667,14 @@ public class InitiateExternalAssetOwnerTransferTest {
                 createSaleTransfer(loanID2, "2020-03-05");
             });
             assertTrue(exception6.getMessage().contains("This loan cannot be 
sold, because it is owned by an external asset owner"));
+            String externalId = UUID.randomUUID().toString();
+            CallFailedRuntimeException exception7 = 
assertThrows(CallFailedRuntimeException.class, () -> {
+                Integer loanID2 = createLoanForClient(clientID);
+                createSaleTransfer(loanID2, "2020-03-05", externalId, "1", 
"1.0");
+                createSaleTransfer(loanID2, "2020-03-05", externalId, "1", 
"1.0");
+            });
+            assertTrue(exception7.getMessage()
+                    .contains(String.format("Already existing an asset 
transfer with the provided transfer external id: %s", externalId)));
         } finally {
             cleanUpAndRestoreBusinessDate();
         }
@@ -684,6 +702,10 @@ public class InitiateExternalAssetOwnerTransferTest {
 
     private PostInitiateTransferResponse createBuybackTransfer(Integer loanID, 
String settlementDate) {
         String transferExternalId = UUID.randomUUID().toString();
+        return createBuybackTransfer(loanID, settlementDate, 
transferExternalId);
+    }
+
+    private PostInitiateTransferResponse createBuybackTransfer(Integer loanID, 
String settlementDate, String transferExternalId) {
         PostInitiateTransferResponse saleResponse = 
EXTERNAL_ASSET_OWNER_HELPER.initiateTransferByLoanId(loanID.longValue(), 
"buyback",
                 new 
PostInitiateTransferRequest().settlementDate(settlementDate).dateFormat("yyyy-MM-dd").locale("en")
                         .transferExternalId(transferExternalId));

Reply via email to