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 23486d774 FINERACT-1926: COB Effective date fix - [x] Add effectiveTo
filter to decide which transaction is not cancelled or already closed - [x]
Integration test - [x] Database change log for UQ key status +
externalTransferId
23486d774 is described below
commit 23486d77427a5e1b907dbe6a018fb2aaffb95e37
Author: Janos Haber <[email protected]>
AuthorDate: Wed Jul 5 11:17:47 2023 +0200
FINERACT-1926: COB Effective date fix
- [x] Add effectiveTo filter to decide which transaction is not cancelled
or already closed
- [x] Integration test
- [x] Database change log for UQ key status + externalTransferId
---
.../loan/LoanAccountOwnerTransferBusinessStep.java | 3 +-
.../module/investor/module-changelog-master.xml | 1 +
...fer_status_external_transfer_id_constraints.xml | 28 +++
.../InitiateExternalAssetOwnerTransferTest.java | 187 +++++++++++++++++++++
4 files changed, 218 insertions(+), 1 deletion(-)
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 c629fd12f..c85f39342 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
@@ -65,7 +65,8 @@ public class LoanAccountOwnerTransferBusinessStep implements
LoanCOBBusinessStep
List<ExternalAssetOwnerTransfer> transferDataList =
externalAssetOwnerTransferRepository.findAll(
(root, query, criteriaBuilder) ->
criteriaBuilder.and(criteriaBuilder.equal(root.get("loanId"), loanId),
criteriaBuilder.equal(root.get("settlementDate"),
settlementDate),
-
root.get("status").in(List.of(ExternalTransferStatus.PENDING,
ExternalTransferStatus.BUYBACK))),
+
root.get("status").in(List.of(ExternalTransferStatus.PENDING,
ExternalTransferStatus.BUYBACK)),
+
criteriaBuilder.greaterThanOrEqualTo(root.get("effectiveDateTo"),
FUTURE_DATE_9999_12_31)),
Sort.by(Sort.Direction.ASC, "id"));
int size = transferDataList.size();
diff --git
a/fineract-investor/src/main/resources/db/changelog/tenant/module/investor/module-changelog-master.xml
b/fineract-investor/src/main/resources/db/changelog/tenant/module/investor/module-changelog-master.xml
index afdc51ec0..30a63050e 100644
---
a/fineract-investor/src/main/resources/db/changelog/tenant/module/investor/module-changelog-master.xml
+++
b/fineract-investor/src/main/resources/db/changelog/tenant/module/investor/module-changelog-master.xml
@@ -31,4 +31,5 @@
<include relativeToChangelogFile="true"
file="parts/0007_add_external_asset_owner_transfer_details.xml"/>
<include relativeToChangelogFile="true" file="parts/0008_add_mappings.xml"/>
<include relativeToChangelogFile="true"
file="parts/0009_add_loan_ownership_transfer_events.xml"/>
+ <include relativeToChangelogFile="true"
file="parts/0010_external_transafer_status_external_transfer_id_constraints.xml"/>
</databaseChangeLog>
diff --git
a/fineract-investor/src/main/resources/db/changelog/tenant/module/investor/parts/0010_external_transafer_status_external_transfer_id_constraints.xml
b/fineract-investor/src/main/resources/db/changelog/tenant/module/investor/parts/0010_external_transafer_status_external_transfer_id_constraints.xml
new file mode 100644
index 000000000..0bd4fc839
--- /dev/null
+++
b/fineract-investor/src/main/resources/db/changelog/tenant/module/investor/parts/0010_external_transafer_status_external_transfer_id_constraints.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd">
+ <changeSet author="fineract" id="1">
+ <addUniqueConstraint tableName="m_external_asset_owner_transfer"
columnNames="status, external_id"
constraintName="external_transfer_status_external_id"/>
+ </changeSet>
+</databaseChangeLog>
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 c662a73c0..cd5166e28 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
@@ -136,6 +136,193 @@ public class InitiateExternalAssetOwnerTransferTest {
.glAccountId((long) transferAccount.getAccountID()));
}
+ @Test
+ public void
saleActiveLoanToExternalAssetOwnerWithCancelAndBuybackADayLater() {
+ try {
+ GlobalConfigurationHelper.manageConfigurations(REQUEST_SPEC,
RESPONSE_SPEC,
+
GlobalConfigurationHelper.ENABLE_AUTOGENERATED_EXTERNAL_ID, true);
+ setInitialBusinessDate("2020-03-02");
+ Integer clientID = createClient();
+ Integer loanID = createLoanForClient(clientID);
+ addPenaltyForLoan(loanID, "10");
+
+ PostInitiateTransferResponse saleTransferResponse =
createSaleTransfer(loanID, "2020-03-02");
+ validateResponse(saleTransferResponse, loanID);
+ getAndValidateExternalAssetOwnerTransferByLoan(loanID,
+ ExpectedExternalTransferData.expected(PENDING,
saleTransferResponse.getResourceExternalId(), "2020-03-02", "2020-03-02",
+ "9999-12-31", false, new
BigDecimal("15767.420000"), new BigDecimal("15000.000000"),
+ new BigDecimal("757.420000"), new
BigDecimal("10.000000"), new BigDecimal("0.000000"),
+ new BigDecimal("0.000000")));
+
getAndValidateThereIsNoActiveMapping(saleTransferResponse.getResourceExternalId());
+ PageExternalTransferData retrieveResponse =
EXTERNAL_ASSET_OWNER_HELPER.retrieveTransfersByLoanId(loanID.longValue());
+ retrieveResponse.getContent().forEach(transfer ->
getAndValidateThereIsNoJournalEntriesForTransfer(transfer.getTransferId()));
+
+
EXTERNAL_ASSET_OWNER_HELPER.cancelTransferByTransferExternalId(saleTransferResponse.getResourceExternalId());
+
+ getAndValidateExternalAssetOwnerTransferByLoan(loanID,
+ ExpectedExternalTransferData.expected(PENDING,
saleTransferResponse.getResourceExternalId(), "2020-03-02", "2020-03-02",
+ "2020-03-02", false, new
BigDecimal("15767.420000"), new BigDecimal("15000.000000"),
+ new BigDecimal("757.420000"), new
BigDecimal("10.000000"), new BigDecimal("0.000000"),
+ new BigDecimal("0.000000")),
+ ExpectedExternalTransferData.expected(CANCELLED,
saleTransferResponse.getResourceExternalId(), "2020-03-02",
+ "2020-03-02", "2020-03-02", false, new
BigDecimal("15767.420000"), new BigDecimal("15000.000000"),
+ new BigDecimal("757.420000"), new
BigDecimal("10.000000"), new BigDecimal("0.000000"),
+ new BigDecimal("0.000000")));
+ PostInitiateTransferResponse oldSaleTransferResponse =
saleTransferResponse;
+ saleTransferResponse = createSaleTransfer(loanID, "2020-03-02");
+ validateResponse(saleTransferResponse, loanID);
+
+ getAndValidateExternalAssetOwnerTransferByLoan(loanID,
+ ExpectedExternalTransferData.expected(PENDING,
oldSaleTransferResponse.getResourceExternalId(), "2020-03-02",
+ "2020-03-02", "2020-03-02", false, new
BigDecimal("15767.420000"), new BigDecimal("15000.000000"),
+ new BigDecimal("757.420000"), new
BigDecimal("10.000000"), new BigDecimal("0.000000"),
+ new BigDecimal("0.000000")),
+ ExpectedExternalTransferData.expected(CANCELLED,
oldSaleTransferResponse.getResourceExternalId(), "2020-03-02",
+ "2020-03-02", "2020-03-02", false, new
BigDecimal("15767.420000"), new BigDecimal("15000.000000"),
+ new BigDecimal("757.420000"), new
BigDecimal("10.000000"), new BigDecimal("0.000000"),
+ new BigDecimal("0.000000")),
+ ExpectedExternalTransferData.expected(PENDING,
saleTransferResponse.getResourceExternalId(), "2020-03-02", "2020-03-02",
+ "9999-12-31", false, new
BigDecimal("15767.420000"), new BigDecimal("15000.000000"),
+ new BigDecimal("757.420000"), new
BigDecimal("10.000000"), new BigDecimal("0.000000"),
+ new BigDecimal("0.000000")));
+
+ updateBusinessDateAndExecuteCOBJob("2020-03-03");
+ getAndValidateExternalAssetOwnerTransferByLoan(loanID,
+ ExpectedExternalTransferData.expected(PENDING,
oldSaleTransferResponse.getResourceExternalId(), "2020-03-02",
+ "2020-03-02", "2020-03-02", false, new
BigDecimal("15767.420000"), new BigDecimal("15000.000000"),
+ new BigDecimal("757.420000"), new
BigDecimal("10.000000"), new BigDecimal("0.000000"),
+ new BigDecimal("0.000000")),
+ ExpectedExternalTransferData.expected(CANCELLED,
oldSaleTransferResponse.getResourceExternalId(), "2020-03-02",
+ "2020-03-02", "2020-03-02", false, new
BigDecimal("15767.420000"), new BigDecimal("15000.000000"),
+ new BigDecimal("757.420000"), new
BigDecimal("10.000000"), new BigDecimal("0.000000"),
+ new BigDecimal("0.000000")),
+ ExpectedExternalTransferData.expected(PENDING,
saleTransferResponse.getResourceExternalId(), "2020-03-02", "2020-03-02",
+ "2020-03-02", false, new
BigDecimal("15767.420000"), new BigDecimal("15000.000000"),
+ new BigDecimal("757.420000"), new
BigDecimal("10.000000"), new BigDecimal("0.000000"),
+ new BigDecimal("0.000000")),
+ ExpectedExternalTransferData.expected(ACTIVE,
saleTransferResponse.getResourceExternalId(), "2020-03-02", "2020-03-03",
+ "9999-12-31", true, new
BigDecimal("15767.420000"), new BigDecimal("15000.000000"),
+ new BigDecimal("757.420000"), new
BigDecimal("10.000000"), new BigDecimal("0.000000"),
+ new BigDecimal("0.000000")));
+ getAndValidateThereIsActiveMapping(loanID);
+ retrieveResponse =
EXTERNAL_ASSET_OWNER_HELPER.retrieveTransfersByLoanId(loanID.longValue());
+ LocalDate expectedDate = LocalDate.of(2020, 3, 2);
+ int initial = 2;
+
getAndValidateThereIsJournalEntriesForTransfer(retrieveResponse.getContent().get(initial
+ 1).getTransferId(),
+ ExpectedJournalEntryData.expected((long)
ASSET_ACCOUNT.getAccountID(), (long) JournalEntryType.CREDIT.getValue(),
+ BigDecimal.valueOf(15757.420000), expectedDate,
expectedDate),
+ ExpectedJournalEntryData.expected((long)
FEE_PENALTY_ACCOUNT.getAccountID(), (long) JournalEntryType.CREDIT.getValue(),
+ BigDecimal.valueOf(10.000000), expectedDate,
expectedDate),
+ ExpectedJournalEntryData.expected((long)
TRANSFER_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+ BigDecimal.valueOf(15767.420000), expectedDate,
expectedDate),
+ ExpectedJournalEntryData.expected((long)
ASSET_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+ BigDecimal.valueOf(15757.420000), expectedDate,
expectedDate),
+ ExpectedJournalEntryData.expected((long)
FEE_PENALTY_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+ BigDecimal.valueOf(10.000000), expectedDate,
expectedDate),
+ ExpectedJournalEntryData.expected((long)
TRANSFER_ACCOUNT.getAccountID(), (long) JournalEntryType.CREDIT.getValue(),
+ BigDecimal.valueOf(15767.420000), expectedDate,
expectedDate));
+
+ PostInitiateTransferResponse buybackTransferResponse =
createBuybackTransfer(loanID, "2020-03-03");
+ validateResponse(buybackTransferResponse, loanID);
+ getAndValidateExternalAssetOwnerTransferByLoan(loanID,
+ ExpectedExternalTransferData.expected(PENDING,
oldSaleTransferResponse.getResourceExternalId(), "2020-03-02",
+ "2020-03-02", "2020-03-02", false, new
BigDecimal("15767.420000"), new BigDecimal("15000.000000"),
+ new BigDecimal("757.420000"), new
BigDecimal("10.000000"), new BigDecimal("0.000000"),
+ new BigDecimal("0.000000")),
+ ExpectedExternalTransferData.expected(CANCELLED,
oldSaleTransferResponse.getResourceExternalId(), "2020-03-02",
+ "2020-03-02", "2020-03-02", false, new
BigDecimal("15767.420000"), new BigDecimal("15000.000000"),
+ new BigDecimal("757.420000"), new
BigDecimal("10.000000"), new BigDecimal("0.000000"),
+ new BigDecimal("0.000000")),
+ ExpectedExternalTransferData.expected(PENDING,
saleTransferResponse.getResourceExternalId(), "2020-03-02", "2020-03-02",
+ "2020-03-02", false, new
BigDecimal("15767.420000"), new BigDecimal("15000.000000"),
+ new BigDecimal("757.420000"), new
BigDecimal("10.000000"), new BigDecimal("0.000000"),
+ new BigDecimal("0.000000")),
+ ExpectedExternalTransferData.expected(ACTIVE,
saleTransferResponse.getResourceExternalId(), "2020-03-02", "2020-03-03",
+ "9999-12-31", true, new
BigDecimal("15767.420000"), new BigDecimal("15000.000000"),
+ new BigDecimal("757.420000"), new
BigDecimal("10.000000"), new BigDecimal("0.000000"),
+ new BigDecimal("0.000000")),
+ ExpectedExternalTransferData.expected(BUYBACK,
buybackTransferResponse.getResourceExternalId(), "2020-03-03",
+ "2020-03-03", "9999-12-31", false, new
BigDecimal("15767.420000"), new BigDecimal("15000.000000"),
+ new BigDecimal("757.420000"), new
BigDecimal("10.000000"), new BigDecimal("0.000000"),
+ new BigDecimal("0.000000")));
+ getAndValidateThereIsActiveMapping(loanID);
+ retrieveResponse =
EXTERNAL_ASSET_OWNER_HELPER.retrieveTransfersByLoanId(loanID.longValue());
+
getAndValidateThereIsNoJournalEntriesForTransfer(retrieveResponse.getContent().get(initial
+ 2).getTransferId());
+
+ LOAN_TRANSACTION_HELPER.makeLoanRepayment((long) loanID, new
PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy")
+
.transactionDate(dateFormatter.format(expectedDate)).locale("en").transactionAmount(5.0));
+ LocalDate repaymentSubmittedOnDate = expectedDate.plusDays(1);
+ getAndValidateOwnerJournalEntries(ownerExternalId,
+ ExpectedJournalEntryData.expected((long)
ASSET_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+ BigDecimal.valueOf(15757.420000), expectedDate,
expectedDate),
+ ExpectedJournalEntryData.expected((long)
FEE_PENALTY_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+ BigDecimal.valueOf(10.000000), expectedDate,
expectedDate),
+ ExpectedJournalEntryData.expected((long)
FEE_PENALTY_ACCOUNT.getAccountID(), (long) JournalEntryType.CREDIT.getValue(),
+ BigDecimal.valueOf(5.000000), expectedDate,
repaymentSubmittedOnDate),
+ ExpectedJournalEntryData.expected((long)
ASSET_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+ BigDecimal.valueOf(5.000000), expectedDate,
repaymentSubmittedOnDate));
+
+ updateBusinessDateAndExecuteCOBJob("2020-03-04");
+ getAndValidateExternalAssetOwnerTransferByLoan(loanID,
+ ExpectedExternalTransferData.expected(PENDING,
oldSaleTransferResponse.getResourceExternalId(), "2020-03-02",
+ "2020-03-02", "2020-03-02", false, new
BigDecimal("15767.420000"), new BigDecimal("15000.000000"),
+ new BigDecimal("757.420000"), new
BigDecimal("10.000000"), new BigDecimal("0.000000"),
+ new BigDecimal("0.000000")),
+ ExpectedExternalTransferData.expected(CANCELLED,
oldSaleTransferResponse.getResourceExternalId(), "2020-03-02",
+ "2020-03-02", "2020-03-02", false, new
BigDecimal("15767.420000"), new BigDecimal("15000.000000"),
+ new BigDecimal("757.420000"), new
BigDecimal("10.000000"), new BigDecimal("0.000000"),
+ new BigDecimal("0.000000")),
+ ExpectedExternalTransferData.expected(PENDING,
saleTransferResponse.getResourceExternalId(), "2020-03-02", "2020-03-02",
+ "2020-03-02", false, new
BigDecimal("15767.420000"), new BigDecimal("15000.000000"),
+ new BigDecimal("757.420000"), new
BigDecimal("10.000000"), new BigDecimal("0.000000"),
+ new BigDecimal("0.000000")),
+ ExpectedExternalTransferData.expected(ACTIVE,
saleTransferResponse.getResourceExternalId(), "2020-03-02", "2020-03-03",
+ "2020-03-03", true, new
BigDecimal("15767.420000"), new BigDecimal("15000.000000"),
+ new BigDecimal("757.420000"), new
BigDecimal("10.000000"), new BigDecimal("0.000000"),
+ new BigDecimal("0.000000")),
+ ExpectedExternalTransferData.expected(BUYBACK,
buybackTransferResponse.getResourceExternalId(), "2020-03-03",
+ "2020-03-03", "2020-03-03", true, new
BigDecimal("15762.420000"), new BigDecimal("15000.000000"),
+ new BigDecimal("757.420000"), new
BigDecimal("5.000000"), new BigDecimal("0.000000"),
+ new BigDecimal("0.000000")));
+
getAndValidateThereIsNoActiveMapping(saleTransferResponse.getResourceExternalId());
+ retrieveResponse =
EXTERNAL_ASSET_OWNER_HELPER.retrieveTransfersByLoanId(loanID.longValue());
+ expectedDate = LocalDate.of(2020, 3, 3);
+
getAndValidateThereIsJournalEntriesForTransfer(retrieveResponse.getContent().get(initial
+ 2).getTransferId(),
+ ExpectedJournalEntryData.expected((long)
ASSET_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+ BigDecimal.valueOf(15757.420000), expectedDate,
expectedDate),
+ ExpectedJournalEntryData.expected((long)
FEE_PENALTY_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+ BigDecimal.valueOf(5.000000), expectedDate,
expectedDate),
+ ExpectedJournalEntryData.expected((long)
TRANSFER_ACCOUNT.getAccountID(), (long) JournalEntryType.CREDIT.getValue(),
+ BigDecimal.valueOf(15762.420000), expectedDate,
expectedDate),
+ ExpectedJournalEntryData.expected((long)
ASSET_ACCOUNT.getAccountID(), (long) JournalEntryType.CREDIT.getValue(),
+ BigDecimal.valueOf(15757.420000), expectedDate,
expectedDate),
+ ExpectedJournalEntryData.expected((long)
FEE_PENALTY_ACCOUNT.getAccountID(), (long) JournalEntryType.CREDIT.getValue(),
+ BigDecimal.valueOf(5.000000), expectedDate,
expectedDate),
+ ExpectedJournalEntryData.expected((long)
TRANSFER_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+ BigDecimal.valueOf(15762.420000), expectedDate,
expectedDate));
+ LocalDate previousDayDate = LocalDate.of(2020, 3, 2);
+ getAndValidateOwnerJournalEntries(ownerExternalId,
+ ExpectedJournalEntryData.expected((long)
ASSET_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+ BigDecimal.valueOf(15757.420000), previousDayDate,
previousDayDate),
+ ExpectedJournalEntryData.expected((long)
FEE_PENALTY_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+ BigDecimal.valueOf(10.000000), previousDayDate,
previousDayDate),
+ ExpectedJournalEntryData.expected((long)
FEE_PENALTY_ACCOUNT.getAccountID(), (long) JournalEntryType.CREDIT.getValue(),
+ BigDecimal.valueOf(5.000000), previousDayDate,
expectedDate),
+ ExpectedJournalEntryData.expected((long)
ASSET_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+ BigDecimal.valueOf(5.000000), previousDayDate,
expectedDate),
+ ExpectedJournalEntryData.expected((long)
ASSET_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+ BigDecimal.valueOf(9.680000), expectedDate,
expectedDate),
+ ExpectedJournalEntryData.expected((long)
INCOME_ACCOUNT.getAccountID(), (long) JournalEntryType.CREDIT.getValue(),
+ BigDecimal.valueOf(9.680000), expectedDate,
expectedDate),
+ ExpectedJournalEntryData.expected((long)
ASSET_ACCOUNT.getAccountID(), (long) JournalEntryType.CREDIT.getValue(),
+ BigDecimal.valueOf(15757.420000), expectedDate,
expectedDate),
+ ExpectedJournalEntryData.expected((long)
FEE_PENALTY_ACCOUNT.getAccountID(), (long) JournalEntryType.CREDIT.getValue(),
+ BigDecimal.valueOf(5.000000), expectedDate,
expectedDate));
+ } finally {
+ cleanUpAndRestoreBusinessDate();
+ }
+ }
+
@Test
public void saleActiveLoanToExternalAssetOwnerAndBuybackADayLater() {
try {