This is an automated email from the ASF dual-hosted git repository.
avikg 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 bd99138 FINERACT-893-fixed-deposit-rollover
new 50d5d08 Merge pull request #769 from fynmanoj/findevfdrollover
bd99138 is described below
commit bd99138aadbb184f0ec563c8111cc79f132ee98d
Author: Manoj <[email protected]>
AuthorDate: Sat May 23 22:52:39 2020 +0530
FINERACT-893-fixed-deposit-rollover
---
.../integrationtests/FixedDepositTest.java | 180 +++++++++++++++++++++
.../fixeddeposit/FixedDepositAccountHelper.java | 7 +
.../infrastructure/core/api/JsonCommand.java | 23 +++
.../AccountAssociationsReadPlatformService.java | 2 +
...AccountAssociationsReadPlatformServiceImpl.java | 5 +
.../savings/DepositAccountOnClosureType.java | 19 ++-
.../portfolio/savings/DepositsApiConstants.java | 5 +-
.../api/FixedDepositAccountsApiResource.java | 7 +-
.../savings/data/DepositAccountDataValidator.java | 29 ++++
.../savings/data/FixedDepositAccountData.java | 101 +++++++-----
.../savings/domain/DepositAccountAssembler.java | 12 +-
.../domain/DepositAccountDomainService.java | 9 +-
.../domain/DepositAccountDomainServiceJpa.java | 88 +++++++++-
.../domain/DepositAccountTermAndPreClosure.java | 37 ++++-
.../savings/domain/FixedDepositAccount.java | 30 ++++
.../savings/domain/RecurringDepositAccount.java | 4 +
.../portfolio/savings/domain/SavingsAccount.java | 1 -
.../DepositAccountReadPlatformServiceImpl.java | 19 ++-
...countWritePlatformServiceJpaRepositoryImpl.java | 39 ++++-
.../DepositsDropdownReadPlatformService.java | 2 +
.../DepositsDropdownReadPlatformServiceImpl.java | 12 ++
.../savings/service/SavingsEnumerations.java | 11 +-
.../V358__fixed_deposit_rollover_transfer.sql | 21 +++
23 files changed, 597 insertions(+), 66 deletions(-)
diff --git
a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/FixedDepositTest.java
b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/FixedDepositTest.java
index 815c485..dc06538 100644
---
a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/FixedDepositTest.java
+++
b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/FixedDepositTest.java
@@ -2400,6 +2400,175 @@ public class FixedDepositTest {
Assert.assertEquals("Verifying Pre-Closure maturity amount",
expectedPrematureAmount, maturityAmount);
}
+ /***
+ * Test case for Fixed Deposit Account rollover with maturity
+ * instruction as re invest maturity amount(principal+interest)
+ */
+ @Test
+ public void testFixedDepositAccountWithRolloverMaturityAmount() {
+ this.fixedDepositProductHelper = new
FixedDepositProductHelper(this.requestSpec, this.responseSpec);
+ this.accountHelper = new AccountHelper(this.requestSpec,
this.responseSpec);
+ this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec,
this.responseSpec);
+ this.fixedDepositAccountHelper = new
FixedDepositAccountHelper(this.requestSpec, this.responseSpec);
+
+ /***
+ * Create GL Accounts for product account mapping
+ */
+ final Account assetAccount = this.accountHelper.createAssetAccount();
+ final Account incomeAccount = this.accountHelper.createIncomeAccount();
+ final Account expenseAccount =
this.accountHelper.createExpenseAccount();
+ final Account liabilityAccount =
this.accountHelper.createLiabilityAccount();
+
+ DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy",
Locale.US);
+ DateFormat monthDayFormat = new SimpleDateFormat("dd MMM", Locale.US);
+ DateFormat currentDateFormat = new SimpleDateFormat("dd");
+
+ Calendar todaysDate = Calendar.getInstance();
+ todaysDate.add(Calendar.MONTH, -3);
+ final String VALID_FROM = dateFormat.format(todaysDate.getTime());
+ todaysDate.add(Calendar.YEAR, 10);
+ final String VALID_TO = dateFormat.format(todaysDate.getTime());
+
+ todaysDate = Calendar.getInstance();
+ todaysDate.add(Calendar.MONTH, -1);
+ final String SUBMITTED_ON_DATE =
dateFormat.format(todaysDate.getTime());
+ final String APPROVED_ON_DATE =
dateFormat.format(todaysDate.getTime());
+ final String ACTIVATION_DATE = dateFormat.format(todaysDate.getTime());
+ final String MONTH_DAY = monthDayFormat.format(todaysDate.getTime());
+
+ Integer currentDate =
Integer.valueOf(currentDateFormat.format(todaysDate.getTime()));
+ Integer daysInMonth = todaysDate.getActualMaximum(Calendar.DATE);
+ Integer numberOfDaysLeft = (daysInMonth - currentDate) + 1;
+ todaysDate.add(Calendar.DATE, numberOfDaysLeft);
+ final String INTEREST_POSTED_DATE =
dateFormat.format(todaysDate.getTime());
+ final String CLOSED_ON_DATE =
dateFormat.format(Calendar.getInstance().getTime());
+
+ Integer clientId = ClientHelper.createClient(this.requestSpec,
this.responseSpec);
+ Assert.assertNotNull(clientId);
+
+ /***
+ * Create FD product with CashBased accounting enabled
+ */
+ final String accountingRule = CASH_BASED;
+ Integer fixedDepositProductId = createFixedDepositProduct(VALID_FROM,
VALID_TO, accountingRule, assetAccount, liabilityAccount,
+ incomeAccount, expenseAccount);
+ Assert.assertNotNull(fixedDepositProductId);
+
+ /***
+ * Set maturityInstructionId as re-invest principal+interest
+ * */
+ final Integer maturityInstructionId = 300;
+
+ /***
+ * Apply for FD account with created product and verify status
+ */
+ Integer fixedDepositAccountId =
applyForFixedDepositApplication(clientId.toString(),
fixedDepositProductId.toString(), SUBMITTED_ON_DATE,
+ WHOLE_TERM, maturityInstructionId);
+
+ Assert.assertNotNull(fixedDepositAccountId);
+
+ HashMap fixedDepositAccountStatusHashMap =
FixedDepositAccountStatusChecker.getStatusOfFixedDepositAccount(this.requestSpec,
+ this.responseSpec, fixedDepositAccountId.toString());
+
FixedDepositAccountStatusChecker.verifyFixedDepositIsPending(fixedDepositAccountStatusHashMap);
+
+ /***
+ * Approve the FD account and verify whether account is approved
+ */
+ fixedDepositAccountStatusHashMap =
this.fixedDepositAccountHelper.approveFixedDeposit(fixedDepositAccountId,
APPROVED_ON_DATE);
+
FixedDepositAccountStatusChecker.verifyFixedDepositIsApproved(fixedDepositAccountStatusHashMap);
+
+ /***
+ * Activate the FD Account and verify whether account is activated
+ */
+ fixedDepositAccountStatusHashMap =
this.fixedDepositAccountHelper.activateFixedDeposit(fixedDepositAccountId,
ACTIVATION_DATE);
+
FixedDepositAccountStatusChecker.verifyFixedDepositIsActive(fixedDepositAccountStatusHashMap);
+ }
+
+
+ /***
+ * Test case for Fixed Deposit Account rollover with maturity
+ * instruction as re invest principal only
+ */
+ @Test
+ public void testFixedDepositAccountWithRolloverPrincipal() {
+ this.fixedDepositProductHelper = new
FixedDepositProductHelper(this.requestSpec, this.responseSpec);
+ this.accountHelper = new AccountHelper(this.requestSpec,
this.responseSpec);
+ this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec,
this.responseSpec);
+ this.fixedDepositAccountHelper = new
FixedDepositAccountHelper(this.requestSpec, this.responseSpec);
+
+ /***
+ * Create GL Accounts for product account mapping
+ */
+ final Account assetAccount = this.accountHelper.createAssetAccount();
+ final Account incomeAccount = this.accountHelper.createIncomeAccount();
+ final Account expenseAccount =
this.accountHelper.createExpenseAccount();
+ final Account liabilityAccount =
this.accountHelper.createLiabilityAccount();
+
+ DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy",
Locale.US);
+ DateFormat monthDayFormat = new SimpleDateFormat("dd MMM", Locale.US);
+ DateFormat currentDateFormat = new SimpleDateFormat("dd");
+
+ Calendar todaysDate = Calendar.getInstance();
+ todaysDate.add(Calendar.MONTH, -3);
+ final String VALID_FROM = dateFormat.format(todaysDate.getTime());
+ todaysDate.add(Calendar.YEAR, 10);
+ final String VALID_TO = dateFormat.format(todaysDate.getTime());
+
+ todaysDate = Calendar.getInstance();
+ todaysDate.add(Calendar.MONTH, -1);
+ final String SUBMITTED_ON_DATE =
dateFormat.format(todaysDate.getTime());
+ final String APPROVED_ON_DATE =
dateFormat.format(todaysDate.getTime());
+ final String ACTIVATION_DATE = dateFormat.format(todaysDate.getTime());
+ final String MONTH_DAY = monthDayFormat.format(todaysDate.getTime());
+
+ Integer currentDate =
Integer.valueOf(currentDateFormat.format(todaysDate.getTime()));
+ Integer daysInMonth = todaysDate.getActualMaximum(Calendar.DATE);
+ Integer numberOfDaysLeft = (daysInMonth - currentDate) + 1;
+ todaysDate.add(Calendar.DATE, numberOfDaysLeft);
+ final String INTEREST_POSTED_DATE =
dateFormat.format(todaysDate.getTime());
+ final String CLOSED_ON_DATE =
dateFormat.format(Calendar.getInstance().getTime());
+
+ Integer clientId = ClientHelper.createClient(this.requestSpec,
this.responseSpec);
+ Assert.assertNotNull(clientId);
+
+ /***
+ * Create FD product with CashBased accounting enabled
+ */
+ final String accountingRule = CASH_BASED;
+ Integer fixedDepositProductId = createFixedDepositProduct(VALID_FROM,
VALID_TO, accountingRule, assetAccount, liabilityAccount,
+ incomeAccount, expenseAccount);
+ Assert.assertNotNull(fixedDepositProductId);
+
+ /***
+ * Set maturityInstructionId as re-invest principal
+ * */
+ final Integer maturityInstructionId = 400;
+
+ /***
+ * Apply for FD account with created product and verify status
+ */
+ Integer fixedDepositAccountId =
applyForFixedDepositApplication(clientId.toString(),
fixedDepositProductId.toString(), SUBMITTED_ON_DATE,
+ WHOLE_TERM, maturityInstructionId);
+
+ Assert.assertNotNull(fixedDepositAccountId);
+
+ HashMap fixedDepositAccountStatusHashMap =
FixedDepositAccountStatusChecker.getStatusOfFixedDepositAccount(this.requestSpec,
+ this.responseSpec, fixedDepositAccountId.toString());
+
FixedDepositAccountStatusChecker.verifyFixedDepositIsPending(fixedDepositAccountStatusHashMap);
+
+ /***
+ * Approve the FD account and verify whether account is approved
+ */
+ fixedDepositAccountStatusHashMap =
this.fixedDepositAccountHelper.approveFixedDeposit(fixedDepositAccountId,
APPROVED_ON_DATE);
+
FixedDepositAccountStatusChecker.verifyFixedDepositIsApproved(fixedDepositAccountStatusHashMap);
+
+ /***
+ * Activate the FD Account and verify whether account is activated
+ */
+ fixedDepositAccountStatusHashMap =
this.fixedDepositAccountHelper.activateFixedDeposit(fixedDepositAccountId,
ACTIVATION_DATE);
+
FixedDepositAccountStatusChecker.verifyFixedDepositIsActive(fixedDepositAccountStatusHashMap);
+ }
+
private Integer createFixedDepositProduct(final String validFrom, final
String validTo, final String accountingRule,
Account... accounts) {
LOG.info("------------------------------CREATING NEW FIXED DEPOSIT
PRODUCT ---------------------------------------");
@@ -2471,6 +2640,17 @@ public class FixedDepositTest {
}
private Integer applyForFixedDepositApplication(final String clientID,
final String productID, final String submittedOnDate,
+ final String
penalInterestType, final Integer maturityInstructionId) {
+ LOG.info("--------------------------------APPLYING FOR FIXED DEPOSIT
ACCOUNT --------------------------------");
+ final String fixedDepositApplicationJSON = new
FixedDepositAccountHelper(this.requestSpec, this.responseSpec) //
+ .withSubmittedOnDate(submittedOnDate)
+ .withMaturityInstructionId(maturityInstructionId)
+ .build(clientID, productID, penalInterestType);
+ return this.fixedDepositAccountHelper
+ .applyFixedDepositApplication(fixedDepositApplicationJSON,
this.requestSpec, this.responseSpec);
+ }
+
+ private Integer applyForFixedDepositApplication(final String clientID,
final String productID, final String submittedOnDate,
final String penalInterestType, final String depositAmount, final
String depositPeriod) {
LOG.info("--------------------------------APPLYING FOR FIXED DEPOSIT
ACCOUNT --------------------------------");
final String fixedDepositApplicationJSON = new
FixedDepositAccountHelper(this.requestSpec, this.responseSpec)
diff --git
a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/fixeddeposit/FixedDepositAccountHelper.java
b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/fixeddeposit/FixedDepositAccountHelper.java
index ded5afb..fa4c50b 100644
---
a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/fixeddeposit/FixedDepositAccountHelper.java
+++
b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/fixeddeposit/FixedDepositAccountHelper.java
@@ -96,6 +96,7 @@ public class FixedDepositAccountHelper {
private String submittedOnDate = "";
private String savingsId = null;
private boolean transferInterest = false;
+ private Integer maturityInstructionId;
public String build(final String clientId, final String productId, final
String penalInterestType) {
final HashMap<String, Object> map = new HashMap<>();
@@ -127,6 +128,7 @@ public class FixedDepositAccountHelper {
map.put("submittedOnDate", this.submittedOnDate);
map.put("linkAccountId", savingsId);
map.put("transferInterestToSavings", transferInterest);
+ map.put("maturityInstructionId", maturityInstructionId);
String fixedDepositAccountJson = new Gson().toJson(map);
LOG.info("{}", fixedDepositAccountJson);
@@ -489,4 +491,9 @@ public class FixedDepositAccountHelper {
}
return this.newDepositAmount;
}
+
+ public FixedDepositAccountHelper withMaturityInstructionId(Integer
maturityInstructionId){
+ this.maturityInstructionId = maturityInstructionId;
+ return this;
+ }
}
\ No newline at end of file
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/api/JsonCommand.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/api/JsonCommand.java
index 7ca8d3a..5008fde 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/api/JsonCommand.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/api/JsonCommand.java
@@ -131,6 +131,10 @@ public final class JsonCommand {
return new JsonCommand(resourceId, parsedCommand);
}
+ public static JsonCommand fromJsonElement(final Long resourceId, final
JsonElement parsedCommand, final FromJsonHelper fromApiJsonHelper) {
+ return new JsonCommand(resourceId, parsedCommand, fromApiJsonHelper);
+ }
+
public JsonCommand(final Long resourceId, final JsonElement parsedCommand)
{
this.parsedCommand = parsedCommand;
this.resourceId = resourceId;
@@ -150,6 +154,25 @@ public final class JsonCommand {
this.organisationCreditBureauId=null;
}
+ public JsonCommand(final Long resourceId, final JsonElement parsedCommand,
final FromJsonHelper fromApiJsonHelper) {
+ this.parsedCommand = parsedCommand;
+ this.resourceId = resourceId;
+ this.commandId = null;
+ this.jsonCommand = null;
+ this.fromApiJsonHelper = fromApiJsonHelper;
+ this.entityName = null;
+ this.subresourceId = null;
+ this.groupId = null;
+ this.clientId = null;
+ this.loanId = null;
+ this.savingsId = null;
+ this.transactionId = null;
+ this.url = null;
+ this.productId = null;
+ this.creditBureauId=null;
+ this.organisationCreditBureauId=null;
+ }
+
public Long getOrganisationCreditBureauId() {
return this.organisationCreditBureauId;
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/AccountAssociationsReadPlatformService.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/AccountAssociationsReadPlatformService.java
index aad6f34..2ae6eda 100755
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/AccountAssociationsReadPlatformService.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/AccountAssociationsReadPlatformService.java
@@ -31,4 +31,6 @@ public interface AccountAssociationsReadPlatformService {
public PortfolioAccountData retriveSavingsLinkedAssociation(final Long
savingsId);
public Collection<AccountAssociationsData> retriveLoanAssociations(Long
loanId, Integer associationType);
+
+ PortfolioAccountData retriveSavingsAccount(Long savingsId);
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/AccountAssociationsReadPlatformServiceImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/AccountAssociationsReadPlatformServiceImpl.java
index 8c0bfa4..9f6a9bb 100755
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/AccountAssociationsReadPlatformServiceImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/AccountAssociationsReadPlatformServiceImpl.java
@@ -191,4 +191,9 @@ public class AccountAssociationsReadPlatformServiceImpl
implements AccountAssoci
}
}
+ @Override
+ public PortfolioAccountData retriveSavingsAccount(final Long savingsId){
+ String accountNo = jdbcTemplate.queryForObject("select account_no from
m_savings_account where id = ?", String.class, savingsId);
+ return PortfolioAccountData.lookup(savingsId, accountNo);
+ }
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/DepositAccountOnClosureType.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/DepositAccountOnClosureType.java
index 29ccd73..fc7a2dc 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/DepositAccountOnClosureType.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/DepositAccountOnClosureType.java
@@ -32,7 +32,8 @@ public enum DepositAccountOnClosureType {
INVALID(0, "depositAccountClosureType.invalid"), //
WITHDRAW_DEPOSIT(100, "depositAccountClosureType.withdrawDeposit"), //
TRANSFER_TO_SAVINGS(200, "depositAccountClosureType.transferToSavings"), //
- REINVEST(300, "depositAccountClosureType.reinvest"); //
+ REINVEST_PRINCIPAL_AND_INTEREST(300,
"depositAccountClosureType.reinvestPrincipalAndInterest"),
+ REINVEST_PRINCIPAL_ONLY(400,
"depositAccountClosureType.reinvestPrincipalOnly"); //
private final Integer value;
private final String code;
@@ -63,7 +64,10 @@ public enum DepositAccountOnClosureType {
accountOnClosureType =
DepositAccountOnClosureType.TRANSFER_TO_SAVINGS;
break;
case 300:
- accountOnClosureType = DepositAccountOnClosureType.REINVEST;
+ accountOnClosureType =
DepositAccountOnClosureType.REINVEST_PRINCIPAL_AND_INTEREST;
+ break;
+ case 400:
+ accountOnClosureType =
DepositAccountOnClosureType.REINVEST_PRINCIPAL_ONLY;
break;
}
return accountOnClosureType;
@@ -78,7 +82,16 @@ public enum DepositAccountOnClosureType {
}
public boolean isReinvest() {
- return
this.value.equals(DepositAccountOnClosureType.REINVEST.getValue());
+ return
this.value.equals(DepositAccountOnClosureType.REINVEST_PRINCIPAL_AND_INTEREST.getValue())
||
+
this.value.equals(DepositAccountOnClosureType.REINVEST_PRINCIPAL_ONLY.getValue());
+ }
+
+ public boolean isReinvestPrincipal() {
+ return
this.value.equals(DepositAccountOnClosureType.REINVEST_PRINCIPAL_ONLY.getValue());
+ }
+
+ public boolean isReinvestPrincipalAndInterest() {
+ return
this.value.equals(DepositAccountOnClosureType.REINVEST_PRINCIPAL_AND_INTEREST.getValue());
}
public boolean isInvalid() {
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/DepositsApiConstants.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/DepositsApiConstants.java
index b667fcc..44266f1 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/DepositsApiConstants.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/DepositsApiConstants.java
@@ -190,6 +190,8 @@ public class DepositsApiConstants {
public static final String transferDescriptionParamName =
"transferDescription";
public static final String toSavingsAccountIdParamName =
"toSavingsAccountId";
public static final String savingsAccounts = "savingsAccounts";
+ public static final String maturityInstructionIdParamName =
"maturityInstructionId";
+ public static final String transferToSavingsIdParamName =
"transferToSavingsId";
public static final String preMatureCloseOnDateParamName =
"preMatureCloseOnDate";
@@ -298,7 +300,8 @@ public class DepositsApiConstants {
interestCalculationTypeParamName,
interestCalculationDaysInYearTypeParamName,
lockinPeriodFrequencyParamName,
lockinPeriodFrequencyTypeParamName, chargesParamName,
chartsParamName, depositAmountParamName,
depositPeriodParamName, depositPeriodFrequencyIdParamName,
- savingsAccounts, expectedFirstDepositOnDateParamName,
SavingsApiConstants.withHoldTaxParamName));
+ savingsAccounts, expectedFirstDepositOnDateParamName,
SavingsApiConstants.withHoldTaxParamName,
+ maturityInstructionIdParamName,
transferToSavingsIdParamName));
public static final Set<String>
FIXED_DEPOSIT_ACCOUNT_REQUEST_DATA_PARAMETERS =
fixedDepositAccountRequestData();
public static final Set<String>
FIXED_DEPOSIT_ACCOUNT_RESPONSE_DATA_PARAMETERS =
fixedDepositAccountResponseData();
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/api/FixedDepositAccountsApiResource.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/api/FixedDepositAccountsApiResource.java
index c8ffc35..fa67b79 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/api/FixedDepositAccountsApiResource.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/api/FixedDepositAccountsApiResource.java
@@ -239,6 +239,7 @@ public class FixedDepositAccountsApiResource {
Collection<SavingsAccountTransactionData> transactions = null;
Collection<SavingsAccountChargeData> charges = null;
PortfolioAccountData linkedAccount = null;
+ PortfolioAccountData transferToSavingsAccount = null;
final Set<String> associationParameters =
ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
if (!associationParameters.isEmpty()) {
@@ -272,6 +273,10 @@ public class FixedDepositAccountsApiResource {
}
}
+ if(savingsAccount.getTransferToSavingsId() !=null){
+ transferToSavingsAccount =
this.accountAssociationsReadPlatformService.retriveSavingsAccount(savingsAccount.getTransferToSavingsId());
+ }
+
FixedDepositAccountData templateData = null;
final ApiRequestJsonSerializationSettings settings =
this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
@@ -281,7 +286,7 @@ public class FixedDepositAccountsApiResource {
staffInSelectedOfficeOnly);
}
- return FixedDepositAccountData.associationsAndTemplate(savingsAccount,
templateData, transactions, charges, linkedAccount);
+ return FixedDepositAccountData.associationsAndTemplate(savingsAccount,
templateData, transactions, charges, linkedAccount, transferToSavingsAccount);
}
@PUT
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/DepositAccountDataValidator.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/DepositAccountDataValidator.java
index b95c6c7..cc0a1bf 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/DepositAccountDataValidator.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/DepositAccountDataValidator.java
@@ -29,6 +29,7 @@ import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.isCalen
import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.isMandatoryDepositParamName;
import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.linkedAccountParamName;
import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.mandatoryRecommendedDepositAmountParamName;
+import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.maturityInstructionIdParamName;
import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.maxDepositTermParamName;
import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.maxDepositTermTypeIdParamName;
import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.minDepositTermParamName;
@@ -39,6 +40,7 @@ import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.preClos
import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.recurringFrequencyParamName;
import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.recurringFrequencyTypeParamName;
import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.transferInterestToSavingsParamName;
+import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.transferToSavingsIdParamName;
import static
org.apache.fineract.portfolio.savings.SavingsApiConstants.accountNoParamName;
import static
org.apache.fineract.portfolio.savings.SavingsApiConstants.amountParamName;
import static
org.apache.fineract.portfolio.savings.SavingsApiConstants.chargeIdParamName;
@@ -77,6 +79,7 @@ import
org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
import
org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.portfolio.savings.DepositAccountOnClosureType;
import org.apache.fineract.portfolio.savings.DepositAccountType;
import org.apache.fineract.portfolio.savings.DepositsApiConstants;
import org.apache.fineract.portfolio.savings.PreClosurePenalInterestOnType;
@@ -308,6 +311,19 @@ public class DepositAccountDataValidator {
} else {
baseDataValidator.reset().parameter(linkedAccountParamName).value(linkAccountId).ignoreIfNull().longGreaterThanZero();
}
+
+ if
(this.fromApiJsonHelper.parameterExists(maturityInstructionIdParamName,
element)) {
+ final Integer depositRolloverId =
this.fromApiJsonHelper.extractIntegerSansLocaleNamed(
+ maturityInstructionIdParamName, element);
+
baseDataValidator.reset().parameter(maturityInstructionIdParamName).value(depositRolloverId).notNull()
+
.isOneOfTheseValues(DepositAccountOnClosureType.integerValues());
+
+
if(depositRolloverId.equals(DepositAccountOnClosureType.TRANSFER_TO_SAVINGS.getValue())){
+ final Long transferToSavingsId =
this.fromApiJsonHelper.extractLongNamed(
+ transferToSavingsIdParamName, element);
+
baseDataValidator.reset().parameter(transferToSavingsIdParamName).value(transferToSavingsId).notNull().longGreaterThanZero();
+ }
+ }
}
private void validateDepositDetailsForUpdate(final JsonElement element,
final DataValidatorBuilder baseDataValidator) {
@@ -439,6 +455,19 @@ public class DepositAccountDataValidator {
}
}
+ if
(this.fromApiJsonHelper.parameterExists(maturityInstructionIdParamName,
element)) {
+ final Integer depositRolloverId =
this.fromApiJsonHelper.extractIntegerSansLocaleNamed(
+ maturityInstructionIdParamName, element);
+
baseDataValidator.reset().parameter(maturityInstructionIdParamName).value(depositRolloverId).notNull()
+
.isOneOfTheseValues(DepositAccountOnClosureType.integerValues());
+
+
if(depositRolloverId.equals(DepositAccountOnClosureType.TRANSFER_TO_SAVINGS.getValue())){
+ final Long transferToSavingsId =
this.fromApiJsonHelper.extractLongNamed(
+ transferToSavingsIdParamName, element);
+
baseDataValidator.reset().parameter(transferToSavingsIdParamName).value(transferToSavingsId).notNull().longGreaterThanZero();
+ }
+ }
+
}
private void validatePreClosureDetailForSubmit(final JsonElement element,
final DataValidatorBuilder baseDataValidator) {
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/FixedDepositAccountData.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/FixedDepositAccountData.java
index eb7a74d..63fccc1 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/FixedDepositAccountData.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/FixedDepositAccountData.java
@@ -53,12 +53,14 @@ public class FixedDepositAccountData extends
DepositAccountData {
private Integer depositPeriod;
private EnumOptionData depositPeriodFrequency;
private BigDecimal activationCharge;
+ private Long transferToSavingsId;
// used for account close
private EnumOptionData onAccountClosure;
private final PortfolioAccountData linkedAccount;
private final Boolean transferInterestToSavings;
+ private final PortfolioAccountData transferToSavingsAccount;
private Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions;
private Collection<EnumOptionData> periodFrequencyTypeOptions;
@@ -67,6 +69,7 @@ public class FixedDepositAccountData extends
DepositAccountData {
// for account close
private Collection<EnumOptionData> onAccountClosureOptions;
private Collection<PaymentTypeData> paymentTypeOptions;
+ private final Collection<EnumOptionData> maturityInstructionOptions;
//import fields
private transient Integer rowIndex;
@@ -114,6 +117,7 @@ public class FixedDepositAccountData extends
DepositAccountData {
this.activationCharge = null;
this.onAccountClosure = null;
this.linkedAccount = null;
+ this.transferToSavingsAccount = null;
this.transferInterestToSavings = null;
this.preClosurePenalInterestOnTypeOptions = null;
this.periodFrequencyTypeOptions = null;
@@ -125,6 +129,7 @@ public class FixedDepositAccountData extends
DepositAccountData {
this.locale= locale;
this.submittedOnDate = submittedOnDate;
this.depositPeriodFrequencyId = depositPeriodFrequencyId;
+ this.maturityInstructionOptions = null;
}
public Integer getRowIndex() {
@@ -136,11 +141,14 @@ public class FixedDepositAccountData extends
DepositAccountData {
final Integer maxDepositTerm, final EnumOptionData
minDepositTermType, final EnumOptionData maxDepositTermType,
final Integer inMultiplesOfDepositTerm, final EnumOptionData
inMultiplesOfDepositTermType, final BigDecimal depositAmount,
final BigDecimal maturityAmount, final LocalDate maturityDate,
final Integer depositPeriod,
- final EnumOptionData depositPeriodFrequency, final EnumOptionData
onAccountClosure, final Boolean transferInterestToSavings) {
+ final EnumOptionData depositPeriodFrequency, final EnumOptionData
onAccountClosure, final Boolean transferInterestToSavings,
+ final Long transferToSavingsId) {
final PortfolioAccountData linkedAccount = null;
+ final PortfolioAccountData transferToSavingsAccount = null;
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions
= null;
final Collection<EnumOptionData> periodFrequencyTypeOptions = null;
+ final Collection<EnumOptionData> maturityInstructionOptions = null;
final EnumOptionData depositType =
SavingsEnumerations.depositType(DepositAccountType.FIXED_DEPOSIT.getValue());
final Collection<EnumOptionData> onAccountClosureOptions = null;
@@ -166,7 +174,7 @@ public class FixedDepositAccountData extends
DepositAccountData {
maxDepositTermType, inMultiplesOfDepositTerm,
inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate,
depositPeriod, depositPeriodFrequency,
periodFrequencyTypeOptions, depositType, onAccountClosure,
onAccountClosureOptions,
paymentTypeOptions, savingsAccountDatas, linkedAccount,
transferInterestToSavings, depositAccountData.withHoldTax,
- depositAccountData.taxGroup);
+ depositAccountData.taxGroup, maturityInstructionOptions,
transferToSavingsId, transferToSavingsAccount);
}
public static FixedDepositAccountData withInterestChart(final
FixedDepositAccountData account,
@@ -187,12 +195,13 @@ public class FixedDepositAccountData extends
DepositAccountData {
account.inMultiplesOfDepositTermType, account.depositAmount,
account.maturityAmount, account.maturityDate,
account.depositPeriod, account.depositPeriodFrequency,
account.periodFrequencyTypeOptions, account.depositType,
account.onAccountClosure, account.onAccountClosureOptions,
account.paymentTypeOptions, account.savingsAccounts,
- account.linkedAccount, account.transferInterestToSavings,
account.withHoldTax, account.taxGroup);
+ account.linkedAccount, account.transferInterestToSavings,
account.withHoldTax, account.taxGroup, account.maturityInstructionOptions,
+ account.transferToSavingsId, account.transferToSavingsAccount);
}
public static FixedDepositAccountData associationsAndTemplate(final
FixedDepositAccountData account, FixedDepositAccountData template,
final Collection<SavingsAccountTransactionData> transactions,
final Collection<SavingsAccountChargeData> charges,
- final PortfolioAccountData linkedAccount) {
+ final PortfolioAccountData linkedAccount, PortfolioAccountData
transferToSavingsAccount ) {
if (template == null) {
template = account;
@@ -214,7 +223,8 @@ public class FixedDepositAccountData extends
DepositAccountData {
account.inMultiplesOfDepositTermType, account.depositAmount,
account.maturityAmount, account.maturityDate,
account.depositPeriod, account.depositPeriodFrequency,
template.periodFrequencyTypeOptions, account.depositType,
account.onAccountClosure, account.onAccountClosureOptions,
account.paymentTypeOptions, template.savingsAccounts,
- linkedAccount, account.transferInterestToSavings,
account.withHoldTax, account.taxGroup);
+ linkedAccount, account.transferInterestToSavings,
account.withHoldTax, account.taxGroup, account.maturityInstructionOptions,
+ account.transferToSavingsId, transferToSavingsAccount);
}
public static FixedDepositAccountData withTemplateOptions(final
FixedDepositAccountData account,
@@ -226,7 +236,8 @@ public class FixedDepositAccountData extends
DepositAccountData {
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions,
final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<SavingsAccountTransactionData> transactions,
final Collection<SavingsAccountChargeData> charges,
final Collection<ChargeData> chargeOptions, final
Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions,
- final Collection<EnumOptionData> periodFrequencyTypeOptions, final
Collection<SavingsAccountData> savingsAccounts) {
+ final Collection<EnumOptionData> periodFrequencyTypeOptions, final
Collection<SavingsAccountData> savingsAccounts,
+ final Collection<EnumOptionData> maturityInstructionOptions) {
return new FixedDepositAccountData(account.id, account.accountNo,
account.externalId, account.groupId, account.groupName,
account.clientId, account.clientName,
account.depositProductId, account.depositProductName, account.fieldOfficerId,
@@ -243,7 +254,8 @@ public class FixedDepositAccountData extends
DepositAccountData {
account.inMultiplesOfDepositTermType, account.depositAmount,
account.maturityAmount, account.maturityDate,
account.depositPeriod, account.depositPeriodFrequency,
periodFrequencyTypeOptions, account.depositType,
account.onAccountClosure, account.onAccountClosureOptions,
account.paymentTypeOptions, savingsAccounts,
- account.linkedAccount, account.transferInterestToSavings,
account.withHoldTax, account.taxGroup);
+ account.linkedAccount, account.transferInterestToSavings,
account.withHoldTax, account.taxGroup, maturityInstructionOptions,
+ account.transferToSavingsId, account.transferToSavingsAccount);
}
public static FixedDepositAccountData withClientTemplate(final Long
clientId, final String clientName, final Long groupId,
@@ -304,6 +316,7 @@ public class FixedDepositAccountData extends
DepositAccountData {
final EnumOptionData depositPeriodFrequency = null;
final EnumOptionData onAccountClosure = null;
final PortfolioAccountData linkedAccount = null;
+ final PortfolioAccountData transferToSavingsAccount = null;
final Boolean transferInterestToSavings = null;
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions
= null;
final Collection<EnumOptionData> periodFrequencyTypeOptions = null;
@@ -312,6 +325,8 @@ public class FixedDepositAccountData extends
DepositAccountData {
final Collection<EnumOptionData> onAccountClosureOptions = null;
final Collection<PaymentTypeData> paymentTypeOptions = null;
final Collection<SavingsAccountData> savingsAccountDatas = null;
+ final Collection<EnumOptionData> maturityInstructionOptions = null;
+ final Long transferToSavingsId = null;
return new FixedDepositAccountData(id, accountNo, externalId, groupId,
groupName, clientId, clientName, productId, productName,
fieldOfficerId, fieldOfficerName, status, timeline, currency,
nominalAnnualInterestRate, interestPeriodType,
@@ -324,7 +339,7 @@ public class FixedDepositAccountData extends
DepositAccountData {
maxDepositTerm, minDepositTermType, maxDepositTermType,
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType,
depositAmount, maturityAmount, maturityDate, depositPeriod,
depositPeriodFrequency, periodFrequencyTypeOptions,
depositType, onAccountClosure, onAccountClosureOptions,
paymentTypeOptions, savingsAccountDatas, linkedAccount,
- transferInterestToSavings, withHoldTax, taxGroup);
+ transferInterestToSavings, withHoldTax, taxGroup,
maturityInstructionOptions, transferToSavingsId, transferToSavingsAccount);
}
public static FixedDepositAccountData preClosureDetails(final Long
accountId, BigDecimal maturityAmount,
@@ -393,6 +408,9 @@ public class FixedDepositAccountData extends
DepositAccountData {
final PortfolioAccountData linkedAccount = null;
final boolean withHoldTax = false;
final TaxGroupData taxGroup = null;
+ final Collection<EnumOptionData> maturityInstructionOptions = null;
+ final Long transferToSavingsId = null;
+ final PortfolioAccountData transferToSavingsAccount = null;
return new FixedDepositAccountData(accountId, accountNo, externalId,
groupId, groupName, clientId, clientName, productId,
productName, fieldOfficerId, fieldOfficerName, status,
timeline, currency, nominalAnnualInterestRate, interestPeriodType,
@@ -405,7 +423,7 @@ public class FixedDepositAccountData extends
DepositAccountData {
maxDepositTerm, minDepositTermType, maxDepositTermType,
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType,
depositAmount, maturityAmount, maturityDate, depositPeriod,
depositPeriodFrequency, periodFrequencyTypeOptions,
depositType, onAccountClosure, onAccountClosureOptions,
paymentTypeOptions, savingsAccountDatas, linkedAccount,
- transferInterestToSavings, withHoldTax, taxGroup);
+ transferInterestToSavings, withHoldTax, taxGroup,
maturityInstructionOptions, transferToSavingsId, transferToSavingsAccount);
}
public static FixedDepositAccountData withClosureTemplateDetails(final
FixedDepositAccountData account,
@@ -428,38 +446,40 @@ public class FixedDepositAccountData extends
DepositAccountData {
account.inMultiplesOfDepositTermType, account.depositAmount,
account.maturityAmount, account.maturityDate,
account.depositPeriod, account.depositPeriodFrequency,
account.periodFrequencyTypeOptions, account.depositType,
account.onAccountClosure, onAccountClosureOptions,
paymentTypeOptions, savingsAccountDatas, account.linkedAccount,
- account.transferInterestToSavings, account.withHoldTax,
account.taxGroup);
+ account.transferInterestToSavings, account.withHoldTax,
account.taxGroup, account.maturityInstructionOptions,
+ account.transferToSavingsId, account.transferToSavingsAccount);
}
private FixedDepositAccountData(final Long id, final String accountNo,
final String externalId, final Long groupId,
- final String groupName, final Long clientId, final String
clientName, final Long productId, final String productName,
- final Long fieldofficerId, final String fieldofficerName, final
SavingsAccountStatusEnumData status,
- final SavingsAccountApplicationTimelineData timeline, final
CurrencyData currency, final BigDecimal nominalAnnualInterestRate,
- final EnumOptionData interestPeriodType, final EnumOptionData
interestPostingPeriodType,
- final EnumOptionData interestCalculationType, final EnumOptionData
interestCalculationDaysInYearType,
- final BigDecimal minRequiredOpeningBalance, final Integer
lockinPeriodFrequency,
- final EnumOptionData lockinPeriodFrequencyType, final boolean
withdrawalFeeForTransfers,
- final BigDecimal minBalanceForInterestCalculation, final
SavingsAccountSummaryData summary,
- final Collection<SavingsAccountTransactionData> transactions,
final Collection<DepositProductData> productOptions,
- final Collection<StaffData> fieldOfficerOptions, final
Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
- final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
- final Collection<EnumOptionData> interestCalculationTypeOptions,
- final Collection<EnumOptionData>
interestCalculationDaysInYearTypeOptions,
- final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions,
final Collection<EnumOptionData> withdrawalFeeTypeOptions,
- final Collection<SavingsAccountChargeData> charges, final
Collection<ChargeData> chargeOptions,
- final DepositAccountInterestRateChartData accountChart, final
DepositAccountInterestRateChartData chartTemplate,
- final boolean preClosurePenalApplicable, final BigDecimal
preClosurePenalInterest,
- final EnumOptionData preClosurePenalInterestOnType, final
Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions,
- final Integer minDepositTerm, final Integer maxDepositTerm, final
EnumOptionData minDepositTermType,
- final EnumOptionData maxDepositTermType, final Integer
inMultiplesOfDepositTerm,
- final EnumOptionData inMultiplesOfDepositTermType, final
BigDecimal depositAmount, final BigDecimal maturityAmount,
- final LocalDate maturityDate, final Integer depositPeriod, final
EnumOptionData depositPeriodFrequency,
- final Collection<EnumOptionData> periodFrequencyTypeOptions, final
EnumOptionData depositType,
- final EnumOptionData onAccountClosure, final
Collection<EnumOptionData> onAccountClosureOptions,
- final Collection<PaymentTypeData> paymentTypeOptions, final
Collection<SavingsAccountData> savingsAccountDatas,
- final PortfolioAccountData linkedAccount, final Boolean
transferInterestToSavings, final boolean withHoldTax,
- final TaxGroupData taxGroup) {
+ final String groupName, final Long
clientId, final String clientName, final Long productId, final String
productName,
+ final Long fieldofficerId, final String
fieldofficerName, final SavingsAccountStatusEnumData status,
+ final
SavingsAccountApplicationTimelineData timeline, final CurrencyData currency,
final BigDecimal nominalAnnualInterestRate,
+ final EnumOptionData interestPeriodType,
final EnumOptionData interestPostingPeriodType,
+ final EnumOptionData
interestCalculationType, final EnumOptionData interestCalculationDaysInYearType,
+ final BigDecimal
minRequiredOpeningBalance, final Integer lockinPeriodFrequency,
+ final EnumOptionData
lockinPeriodFrequencyType, final boolean withdrawalFeeForTransfers,
+ final BigDecimal
minBalanceForInterestCalculation, final SavingsAccountSummaryData summary,
+ final
Collection<SavingsAccountTransactionData> transactions, final
Collection<DepositProductData> productOptions,
+ final Collection<StaffData>
fieldOfficerOptions, final Collection<EnumOptionData>
interestCompoundingPeriodTypeOptions,
+ final Collection<EnumOptionData>
interestPostingPeriodTypeOptions,
+ final Collection<EnumOptionData>
interestCalculationTypeOptions,
+ final Collection<EnumOptionData>
interestCalculationDaysInYearTypeOptions,
+ final Collection<EnumOptionData>
lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData>
withdrawalFeeTypeOptions,
+ final Collection<SavingsAccountChargeData>
charges, final Collection<ChargeData> chargeOptions,
+ final DepositAccountInterestRateChartData
accountChart, final DepositAccountInterestRateChartData chartTemplate,
+ final boolean preClosurePenalApplicable,
final BigDecimal preClosurePenalInterest,
+ final EnumOptionData
preClosurePenalInterestOnType, final Collection<EnumOptionData>
preClosurePenalInterestOnTypeOptions,
+ final Integer minDepositTerm, final
Integer maxDepositTerm, final EnumOptionData minDepositTermType,
+ final EnumOptionData maxDepositTermType,
final Integer inMultiplesOfDepositTerm,
+ final EnumOptionData
inMultiplesOfDepositTermType, final BigDecimal depositAmount, final BigDecimal
maturityAmount,
+ final LocalDate maturityDate, final
Integer depositPeriod, final EnumOptionData depositPeriodFrequency,
+ final Collection<EnumOptionData>
periodFrequencyTypeOptions, final EnumOptionData depositType,
+ final EnumOptionData onAccountClosure,
final Collection<EnumOptionData> onAccountClosureOptions,
+ final Collection<PaymentTypeData>
paymentTypeOptions, final Collection<SavingsAccountData> savingsAccountDatas,
+ final PortfolioAccountData linkedAccount,
final Boolean transferInterestToSavings, final boolean withHoldTax,
+ final TaxGroupData taxGroup, final
Collection<EnumOptionData> maturityInstructionOptions, final Long
transferToSavingsId,
+ final PortfolioAccountData
transferToSavingsAccount) {
super(id, accountNo, externalId, groupId, groupName, clientId,
clientName, productId, productName, fieldofficerId,
fieldofficerName, status, timeline, currency,
nominalAnnualInterestRate, interestPeriodType, interestPostingPeriodType,
@@ -485,6 +505,7 @@ public class FixedDepositAccountData extends
DepositAccountData {
this.depositPeriodFrequency = depositPeriodFrequency;
this.onAccountClosure = onAccountClosure;
this.linkedAccount = linkedAccount;
+ this.transferToSavingsAccount = transferToSavingsAccount;
this.transferInterestToSavings = transferInterestToSavings;
// template
@@ -495,6 +516,8 @@ public class FixedDepositAccountData extends
DepositAccountData {
this.onAccountClosureOptions = onAccountClosureOptions;
this.paymentTypeOptions = paymentTypeOptions;
this.savingsAccounts = savingsAccountDatas;
+ this.maturityInstructionOptions = maturityInstructionOptions;
+ this.transferToSavingsId = transferToSavingsId;
}
@Override
@@ -521,4 +544,8 @@ public class FixedDepositAccountData extends
DepositAccountData {
public void setActivationCharge(BigDecimal activationCharge) {
this.activationCharge = activationCharge;
}
+
+ public Long getTransferToSavingsId() {
+ return transferToSavingsId;
+ }
}
\ No newline at end of file
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountAssembler.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountAssembler.java
index 6591ec3..283bfd5 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountAssembler.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountAssembler.java
@@ -32,7 +32,9 @@ import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.expecte
import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.isCalendarInheritedParamName;
import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.isMandatoryDepositParamName;
import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.mandatoryRecommendedDepositAmountParamName;
+import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.maturityInstructionIdParamName;
import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.transferInterestToSavingsParamName;
+import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.transferToSavingsIdParamName;
import static
org.apache.fineract.portfolio.savings.SavingsApiConstants.accountNoParamName;
import static
org.apache.fineract.portfolio.savings.SavingsApiConstants.clientIdParamName;
import static
org.apache.fineract.portfolio.savings.SavingsApiConstants.externalIdParamName;
@@ -298,6 +300,10 @@ public class DepositAccountAssembler {
throw new
UnsupportedParameterException(Arrays.asList(withHoldTaxParamName));
}
}
+ Integer depositRolloverId = null;
+ if(command.parameterExists(maturityInstructionIdParamName)){
+ depositRolloverId =
command.integerValueOfParameterNamed(maturityInstructionIdParamName);
+ }
SavingsAccount account = null;
if (depositAccountType.isFixedDeposit()) {
@@ -375,10 +381,12 @@ public class DepositAccountAssembler {
final BigDecimal maturityAmount = null;// calculated and updated in
// account
final LocalDate maturityDate = null;// calculated and updated in
account
- final DepositAccountOnClosureType accountOnClosureType = null;
+ final Integer accountOnClosureTypeId =
command.integerValueOfParameterNamed(maturityInstructionIdParamName);
+ final DepositAccountOnClosureType accountOnClosureType =
accountOnClosureTypeId != null ?
DepositAccountOnClosureType.fromInt(accountOnClosureTypeId) :null;
+ final Long transferToSavingsId =
command.longValueOfParameterNamed(transferToSavingsIdParamName);
return
DepositAccountTermAndPreClosure.createNew(updatedProductPreClosure,
updatedProductTerm, account, depositAmount,
maturityAmount, maturityDate, depositPeriod,
depositPeriodFrequency, expectedFirstDepositOnDate, accountOnClosureType,
- trasferInterest);
+ trasferInterest, transferToSavingsId);
}
public DepositAccountRecurringDetail assembleAccountRecurringDetail(final
JsonCommand command,
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountDomainService.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountDomainService.java
index 08f602e..40d4a5f 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountDomainService.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountDomainService.java
@@ -25,6 +25,7 @@ import
org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
import org.apache.fineract.useradministration.domain.AppUser;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormatter;
+import org.springframework.transaction.annotation.Transactional;
public interface DepositAccountDomainService {
@@ -43,8 +44,14 @@ public interface DepositAccountDomainService {
Long handleFDAccountClosure(FixedDepositAccount account, PaymentDetail
paymentDetail, AppUser user, JsonCommand command,
LocalDate tenantsTodayDate, Map<String, Object> changes);
+ @Transactional
+ Long handleFDAccountMaturityClosure(FixedDepositAccount account,
PaymentDetail paymentDetail, AppUser user,
+ LocalDate tenantsTodayDate,
DateTimeFormatter fmt,
+ LocalDate closedDate, Integer
onAccountClosureId,
+ Long toSavingsId, String
transferDescription, Map<String, Object> changes);
+
Long handleRDAccountClosure(RecurringDepositAccount account, PaymentDetail
paymentDetail, AppUser user, JsonCommand command,
- LocalDate tenantsTodayDate, Map<String, Object> changes);
+ LocalDate tenantsTodayDate, Map<String,
Object> changes);
Long handleFDAccountPreMatureClosure(FixedDepositAccount account,
PaymentDetail paymentDetail, AppUser user, JsonCommand command,
LocalDate tenantsTodayDate, Map<String, Object> changes);
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountDomainServiceJpa.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountDomainServiceJpa.java
index e8b5d7f..c9a5f97 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountDomainServiceJpa.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountDomainServiceJpa.java
@@ -189,7 +189,7 @@ public class DepositAccountDomainServiceJpa implements
DepositAccountDomainServi
@Transactional
@Override
public Long handleFDAccountClosure(final FixedDepositAccount account,
final PaymentDetail paymentDetail, final AppUser user,
- final JsonCommand command, final LocalDate tenantsTodayDate, final
Map<String, Object> changes) {
+ final JsonCommand command, final
LocalDate tenantsTodayDate, final Map<String, Object> changes) {
final boolean isSavingsInterestPostingAtCurrentPeriodEnd =
this.configurationDomainService
.isSavingsInterestPostingAtCurrentPeriodEnd();
@@ -263,6 +263,85 @@ public class DepositAccountDomainServiceJpa implements
DepositAccountDomainServi
@Transactional
@Override
+ public Long handleFDAccountMaturityClosure(final FixedDepositAccount
account, final PaymentDetail paymentDetail, final AppUser user,
+ final LocalDate
tenantsTodayDate, final DateTimeFormatter fmt,
+ final LocalDate closedDate,
final Integer onAccountClosureId,
+ final Long toSavingsId, final
String transferDescription,
+ Map<String, Object> changes) {
+
+ final boolean isSavingsInterestPostingAtCurrentPeriodEnd =
this.configurationDomainService
+ .isSavingsInterestPostingAtCurrentPeriodEnd();
+ final Integer financialYearBeginningMonth =
this.configurationDomainService.retrieveFinancialYearBeginningMonth();
+
+ boolean isRegularTransaction = false;
+ boolean isAccountTransfer = false;
+ final boolean isPreMatureClosure = false;
+ final Set<Long> existingTransactionIds = new HashSet<>();
+ final Set<Long> existingReversedTransactionIds = new HashSet<>();
+ /***
+ * Update account transactionIds for post journal entries.
+ */
+ updateExistingTransactionsDetails(account, existingTransactionIds,
existingReversedTransactionIds);
+
+ final MathContext mc = MathContext.DECIMAL64;
+ Long savingsTransactionId = null;
+
account.postMaturityInterest(isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth);
+ final DepositAccountOnClosureType onClosureType =
DepositAccountOnClosureType.fromInt(onAccountClosureId);
+ if (onClosureType.isReinvest()) {
+ BigDecimal reInvestAmount;
+ if(onClosureType.isReinvestPrincipal())
+ reInvestAmount = account.getDepositAmount();
+ else
+ reInvestAmount = account.getAccountBalance();
+ FixedDepositAccount reinvestedDeposit =
account.reInvest(reInvestAmount);
+
this.depositAccountAssembler.assignSavingAccountHelpers(reinvestedDeposit);
+
reinvestedDeposit.updateMaturityDateAndAmountBeforeAccountActivation(mc,
isPreMatureClosure,
+ isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth);
+
+ this.savingsAccountRepository.save(reinvestedDeposit);
+ autoGenerateAccountNumber(reinvestedDeposit);
+ final SavingsAccountTransaction withdrawal =
this.handleWithdrawal(account, fmt, closedDate, reInvestAmount,
+ paymentDetail, false, isRegularTransaction);
+ savingsTransactionId = withdrawal.getId();
+
+ if (onClosureType.isReinvestPrincipalAndInterest()) {
+ account.updateClosedStatus();
+ account.updateOnAccountClosureStatus(onClosureType);
+ }
+ changes.put("reinvestedDepositId", reinvestedDeposit.getId());
+
reinvestedDeposit.approveAndActivateApplication(closedDate.toDate(), user);
+ this.savingsAccountRepository.save(reinvestedDeposit);
+
+ } else if (onClosureType.isTransferToSavings()) {
+ final SavingsAccount toSavingsAccount =
this.depositAccountAssembler.assembleFrom(toSavingsId,
+ DepositAccountType.SAVINGS_DEPOSIT);
+ final boolean isExceptionForBalanceCheck = false;
+ final AccountTransferDTO accountTransferDTO = new
AccountTransferDTO(closedDate, account.getAccountBalance(),
+ PortfolioAccountType.SAVINGS,
PortfolioAccountType.SAVINGS, null, null, transferDescription, null, fmt, null,
null,
+ null, null, null,
AccountTransferType.ACCOUNT_TRANSFER.getValue(), null, null, null, null,
toSavingsAccount, account,
+ isAccountTransfer, isExceptionForBalanceCheck);
+
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
+ updateAlreadyPostedTransactions(existingTransactionIds, account);
+ account.updateClosedStatus();
+ account.updateOnAccountClosureStatus(onClosureType);
+ } else {
+ final SavingsAccountTransaction withdrawal =
this.handleWithdrawal(account, fmt, closedDate, account.getAccountBalance(),
+ paymentDetail, false, isRegularTransaction);
+ savingsTransactionId = withdrawal.getId();
+ }
+
+ //if(!processMaturityInstructionOnly)
+ // account.close(user, command, tenantsTodayDate, changes);
+
+ this.savingsAccountRepository.save(account);
+
+ postJournalEntries(account, existingTransactionIds,
existingReversedTransactionIds, isAccountTransfer);
+
+ return savingsTransactionId;
+ }
+
+ @Transactional
+ @Override
public Long handleRDAccountClosure(final RecurringDepositAccount account,
final PaymentDetail paymentDetail, final AppUser user,
final JsonCommand command, final LocalDate tenantsTodayDate, final
Map<String, Object> changes) {
@@ -290,7 +369,12 @@ public class DepositAccountDomainServiceJpa implements
DepositAccountDomainServi
final Integer onAccountClosureId =
command.integerValueOfParameterNamed(onAccountClosureIdParamName);
final DepositAccountOnClosureType onClosureType =
DepositAccountOnClosureType.fromInt(onAccountClosureId);
if (onClosureType.isReinvest()) {
- RecurringDepositAccount reinvestedDeposit =
account.reInvest(transactionAmount);
+ BigDecimal reInvestAmount;
+ if(onClosureType.isReinvestPrincipal())
+ reInvestAmount = account.getDepositAmount();
+ else
+ reInvestAmount = account.getAccountBalance();
+ RecurringDepositAccount reinvestedDeposit =
account.reInvest(reInvestAmount);
depositAccountAssembler.assignSavingAccountHelpers(reinvestedDeposit);
this.savingsAccountRepository.save(reinvestedDeposit);
final CalendarInstance calendarInstance =
getCalendarInstance(account, reinvestedDeposit);
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountTermAndPreClosure.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountTermAndPreClosure.java
index 3b833a5..f13a1b4 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountTermAndPreClosure.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountTermAndPreClosure.java
@@ -24,7 +24,9 @@ import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.deposit
import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.depositPeriodParamName;
import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.expectedFirstDepositOnDateParamName;
import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.localeParamName;
+import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.maturityInstructionIdParamName;
import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.transferInterestToSavingsParamName;
+import static
org.apache.fineract.portfolio.savings.DepositsApiConstants.transferToSavingsIdParamName;
import java.math.BigDecimal;
import java.util.Date;
@@ -90,6 +92,9 @@ public class DepositAccountTermAndPreClosure extends
AbstractPersistableCustom {
@Column(name = "transfer_interest_to_linked_account", nullable = false)
private boolean transferInterestToLinkedAccount;
+ @Column(name = "transfer_to_savings_account_id")
+ private Long transferToSavingsAccountId;
+
protected DepositAccountTermAndPreClosure() {
super();
}
@@ -97,16 +102,16 @@ public class DepositAccountTermAndPreClosure extends
AbstractPersistableCustom {
public static DepositAccountTermAndPreClosure
createNew(DepositPreClosureDetail preClosureDetail, DepositTermDetail
depositTermDetail,
SavingsAccount account, BigDecimal depositAmount, BigDecimal
maturityAmount, final LocalDate maturityDate,
Integer depositPeriod, final SavingsPeriodFrequencyType
depositPeriodFrequency, final LocalDate expectedFirstDepositOnDate,
- final DepositAccountOnClosureType accountOnClosureType, Boolean
trasferInterest) {
+ final DepositAccountOnClosureType accountOnClosureType, Boolean
trasferInterest, Long transferToSavingsId) {
return new DepositAccountTermAndPreClosure(preClosureDetail,
depositTermDetail, account, depositAmount, maturityAmount,
- maturityDate, depositPeriod, depositPeriodFrequency,
expectedFirstDepositOnDate, accountOnClosureType, trasferInterest);
+ maturityDate, depositPeriod, depositPeriodFrequency,
expectedFirstDepositOnDate, accountOnClosureType, trasferInterest,
transferToSavingsId);
}
private DepositAccountTermAndPreClosure(DepositPreClosureDetail
preClosureDetail, DepositTermDetail depositTermDetail,
SavingsAccount account, BigDecimal depositAmount, BigDecimal
maturityAmount, final LocalDate maturityDate,
Integer depositPeriod, final SavingsPeriodFrequencyType
depositPeriodFrequency, final LocalDate expectedFirstDepositOnDate,
- final DepositAccountOnClosureType accountOnClosureType, Boolean
transferInterest) {
+ final DepositAccountOnClosureType accountOnClosureType, Boolean
transferInterest, Long transferToSavingsId) {
this.depositAmount = depositAmount;
this.maturityAmount = maturityAmount;
this.maturityDate = (maturityDate == null) ? null :
maturityDate.toDate();
@@ -118,6 +123,7 @@ public class DepositAccountTermAndPreClosure extends
AbstractPersistableCustom {
this.expectedFirstDepositOnDate = expectedFirstDepositOnDate == null ?
null : expectedFirstDepositOnDate.toDate();
this.onAccountClosureType = (accountOnClosureType == null) ? null :
accountOnClosureType.getValue();
this.transferInterestToLinkedAccount = transferInterest;
+ this.transferToSavingsAccountId = transferToSavingsId;
}
public Map<String, Object> update(final JsonCommand command, final
DataValidatorBuilder baseDataValidator) {
@@ -158,6 +164,20 @@ public class DepositAccountTermAndPreClosure extends
AbstractPersistableCustom {
this.transferInterestToLinkedAccount = newValue;
}
+ if
(command.isChangeInIntegerParameterNamed(maturityInstructionIdParamName,
this.onAccountClosureType) || command.integerValueOfParameterNamed(
+ maturityInstructionIdParamName) == null) {
+ final Integer newValue =
command.integerValueOfParameterNamed(maturityInstructionIdParamName);
+ actualChanges.put(maturityInstructionIdParamName, newValue);
+ this.onAccountClosureType = newValue != null ?
DepositAccountOnClosureType.fromInt(newValue).getValue() : null;
+ }
+
+ if (command.isChangeInLongParameterNamed(transferToSavingsIdParamName,
this.transferToSavingsAccountId) || command.integerValueOfParameterNamed(
+ transferToSavingsIdParamName) == null) {
+ final Long newValue =
command.longValueOfParameterNamed(transferToSavingsIdParamName);
+ actualChanges.put(transferToSavingsIdParamName, newValue);
+ this.transferToSavingsAccountId = newValue ;
+ }
+
if (this.preClosureDetail != null) {
actualChanges.putAll(this.preClosureDetail.update(command,
baseDataValidator));
}
@@ -291,9 +311,10 @@ public class DepositAccountTermAndPreClosure extends
AbstractPersistableCustom {
final Boolean transferInterestToLinkedAccount = false;
final DepositAccountOnClosureType accountOnClosureType = null;
+ final Long transferToSavingsId = null;
return DepositAccountTermAndPreClosure.createNew(preClosureDetail,
depositTermDetail, account, actualDepositAmount, maturityAmount,
maturityDate, depositPeriod, depositPeriodFrequency,
expectedFirstDepositOnDate, accountOnClosureType,
- transferInterestToLinkedAccount);
+ transferInterestToLinkedAccount, transferToSavingsId);
}
public void updateExpectedFirstDepositDate(final LocalDate
expectedFirstDepositOnDate) {
@@ -311,4 +332,12 @@ public class DepositAccountTermAndPreClosure extends
AbstractPersistableCustom {
}
return isAfterExpectedFirstDepositDate;
}
+
+ public Integer getOnAccountClosureType() {
+ return onAccountClosureType;
+ }
+
+ public Long getTransferToSavingsAccountId() {
+ return transferToSavingsAccountId;
+ }
}
\ No newline at end of file
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/FixedDepositAccount.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/FixedDepositAccount.java
index 2c909ef..d5e23b9 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/FixedDepositAccount.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/FixedDepositAccount.java
@@ -259,6 +259,8 @@ public class FixedDepositAccount extends SavingsAccount {
}
}
+
+
public LocalDate calculateMaturityDate() {
final LocalDate startDate = accountSubmittedOrActivationDate();
@@ -489,6 +491,14 @@ public class FixedDepositAccount extends SavingsAccount {
// this.savingsAccountTransactionSummaryWrapper, this.transactions);
}
+ public void updateClosedStatus(){
+ this.status = SavingsAccountStatusType.CLOSED.getValue();
+ }
+
+ public void updateOnAccountClosureStatus(DepositAccountOnClosureType
onClosureType){
+
this.accountTermAndPreClosure.updateOnAccountClosureStatus(onClosureType);
+ }
+
public void postMaturityInterest(final boolean
isSavingsInterestPostingAtCurrentPeriodEnd, final Integer
financialYearBeginningMonth) {
final LocalDate interestPostingUpToDate = maturityDate();
final MathContext mc = MathContext.DECIMAL64;
@@ -756,6 +766,14 @@ public class FixedDepositAccount extends SavingsAccount {
return this.accountTermAndPreClosure.isTransferToSavingsOnClosure();
}
+ public Integer getOnAccountClosureId(){
+ return this.accountTermAndPreClosure.getOnAccountClosureType();
+ }
+
+ public Long getTransferToSavingsAccountId() {
+ return this.accountTermAndPreClosure.getTransferToSavingsAccountId();
+ }
+
public FixedDepositAccount reInvest(BigDecimal depositAmount) {
final DepositAccountTermAndPreClosure newAccountTermAndPreClosure =
this.accountTermAndPreClosure.copy(depositAmount);
@@ -830,4 +848,16 @@ public class FixedDepositAccount extends SavingsAccount {
super.loadLazyCollections();
this.chart.getId() ;
}
+
+ public BigDecimal getDepositAmount() {
+ return this.accountTermAndPreClosure.depositAmount();
+ }
+ @Override
+ public BigDecimal getAccountBalance() {
+ return this.summary.getAccountBalance(this.currency).getAmount();
+ }
+ public boolean isMatured(){
+ return SavingsAccountStatusType.MATURED.getValue().equals(this.status);
+ }
+
}
\ No newline at end of file
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositAccount.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositAccount.java
index 79d592d..670d53c 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositAccount.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositAccount.java
@@ -1232,4 +1232,8 @@ public class RecurringDepositAccount extends
SavingsAccount {
super.loadLazyCollections();
this.chart.getId() ;
}
+
+ public BigDecimal getDepositAmount() {
+ return this.accountTermAndPreClosure.depositAmount();
+ }
}
\ No newline at end of file
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java
index c52e676..a1499c1 100755
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java
@@ -1433,7 +1433,6 @@ public class SavingsAccount extends
AbstractPersistableCustom {
baseDataValidator.reset().parameter(withHoldTaxParamName).failWithCode("not.supported.for.this.account");
}
}
-
validateLockinDetails(baseDataValidator);
esnureOverdraftLimitsSetForOverdraftAccounts();
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountReadPlatformServiceImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountReadPlatformServiceImpl.java
index 1a70557..55b43fc 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountReadPlatformServiceImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountReadPlatformServiceImpl.java
@@ -378,6 +378,8 @@ public class DepositAccountReadPlatformServiceImpl
implements DepositAccountRead
final boolean feeChargesOnly = false;
final Collection<ChargeData> chargeOptions =
this.chargeReadPlatformService.retrieveSavingsProductApplicableCharges(feeChargesOnly);
+ final Collection<EnumOptionData> maturityInstructionOptions =
this.depositsDropdownReadPlatformService.maturityInstructionOptions();
+
Collection<StaffData> fieldOfficerOptions = null;
if (officeId != null) {
@@ -405,7 +407,7 @@ public class DepositAccountReadPlatformServiceImpl
implements DepositAccountRead
}
// retrieve chart Slabs
- final InterestRateChartData productChartData =
this.productChartReadPlatformService.retrieveActiveChartWithTemplate(productId);
+ final InterestRateChartData productChartData =
this.productChartReadPlatformService.retrieveActiveChartWithTemplate(productId);
final DepositAccountInterestRateChartData accountChart =
DepositAccountInterestRateChartData.from(productChartData);
if (depositAccountType.isFixedDeposit()) {
@@ -414,7 +416,7 @@ public class DepositAccountReadPlatformServiceImpl
implements DepositAccountRead
fieldOfficerOptions,
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
withdrawalFeeTypeOptions, transactions, charges,
chargeOptions, preClosurePenalInterestOnTypeOptions,
- periodFrequencyTypeOptions, savingsAccountDatas);
+ periodFrequencyTypeOptions, savingsAccountDatas,
maturityInstructionOptions);
template =
FixedDepositAccountData.withInterestChart((FixedDepositAccountData) template,
accountChart);
} else if (depositAccountType.isRecurringDeposit()) {
@@ -450,6 +452,7 @@ public class DepositAccountReadPlatformServiceImpl
implements DepositAccountRead
final Collection<SavingsAccountTransactionData> transactions =
null;
final Collection<SavingsAccountChargeData> charges = null;
+ final Collection<EnumOptionData> maturityInstructionOptions =
null;
final boolean feeChargesOnly = true;
final Collection<ChargeData> chargeOptions =
this.chargeReadPlatformService.retrieveSavingsProductApplicableCharges(feeChargesOnly);
@@ -462,7 +465,7 @@ public class DepositAccountReadPlatformServiceImpl
implements DepositAccountRead
fieldOfficerOptions,
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
withdrawalFeeTypeOptions, transactions, charges,
chargeOptions, preClosurePenalInterestOnTypeOptions,
- periodFrequencyTypeOptions, savingsAccountDatas);
+ periodFrequencyTypeOptions, savingsAccountDatas,
maturityInstructionOptions);
} else if (depositAccountType.isRecurringDeposit()) {
template =
RecurringDepositAccountData.withClientTemplate(clientId, clientName, groupId,
groupName);
@@ -778,7 +781,8 @@ public class DepositAccountReadPlatformServiceImpl
implements DepositAccountRead
sqlBuilder.append("datp.deposit_period as depositPeriod, ");
sqlBuilder.append("datp.deposit_period_frequency_enum as
depositPeriodFrequencyTypeId, ");
sqlBuilder.append("datp.on_account_closure_enum as
onAccountClosureId, ");
- sqlBuilder.append("datp.transfer_interest_to_linked_account as
transferInterestToSavings ");
+ sqlBuilder.append("datp.transfer_interest_to_linked_account as
transferInterestToSavings, ");
+ sqlBuilder.append("datp.transfer_to_savings_account_id as
transferToSavingsId ");
sqlBuilder.append(super.selectTablesSql());
@@ -826,10 +830,13 @@ public class DepositAccountReadPlatformServiceImpl
implements DepositAccountRead
.depositAccountOnClosureType(onAccountClosureId);
final Boolean transferInterestToSavings =
rs.getBoolean("transferInterestToSavings");
+ final Long transferToSavingsId = JdbcSupport.getLong(rs,
"transferToSavingsId");
+
+
return FixedDepositAccountData.instance(depositAccountData,
preClosurePenalApplicable, preClosurePenalInterest,
preClosurePenalInterestOnType, minDepositTerm,
maxDepositTerm, minDepositTermType, maxDepositTermType,
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType,
depositAmount, maturityAmount, maturityDate, depositPeriod,
- depositPeriodFrequencyType, onAccountClosureType,
transferInterestToSavings);
+ depositPeriodFrequencyType, onAccountClosureType,
transferInterestToSavings, transferToSavingsId);
}
}
@@ -1266,7 +1273,7 @@ public class DepositAccountReadPlatformServiceImpl
implements DepositAccountRead
return FixedDepositAccountData.instance(depositAccountData,
preClosurePenalApplicable, preClosurePenalInterest,
preClosurePenalInterestOnType, minDepositTerm,
maxDepositTerm, minDepositTermType, maxDepositTermType,
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType,
depositAmount, maturityAmount, maturityDate, depositPeriod,
- depositPeriodFrequencyType, onAccountClosureType,
transferInterestToSavings);
+ depositPeriodFrequencyType, onAccountClosureType,
transferInterestToSavings, null);
}
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java
index c1c5fc5..2e42c5c 100755
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java
@@ -28,6 +28,7 @@ import java.math.BigDecimal;
import java.math.MathContext;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
@@ -44,6 +45,7 @@ import
org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuild
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import
org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import
org.apache.fineract.infrastructure.core.exception.PlatformServiceUnavailableException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.infrastructure.jobs.annotation.CronTarget;
import org.apache.fineract.infrastructure.jobs.exception.JobExecutionException;
@@ -145,6 +147,7 @@ public class
DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
private final HolidayRepositoryWrapper holidayRepository;
private final WorkingDaysRepositoryWrapper workingDaysRepository;
private final DepositAccountOnHoldTransactionRepository
depositAccountOnHoldTransactionRepository;
+ private final FromJsonHelper fromApiJsonHelper;
@Autowired
public DepositAccountWritePlatformServiceJpaRepositoryImpl(final
PlatformSecurityContext context,
@@ -164,7 +167,8 @@ public class
DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
final AccountTransfersWritePlatformService
accountTransfersWritePlatformService,
final DepositAccountReadPlatformService
depositAccountReadPlatformService,
final CalendarInstanceRepository calendarInstanceRepository, final
ConfigurationDomainService configurationDomainService,
- final DepositAccountOnHoldTransactionRepository
depositAccountOnHoldTransactionRepository) {
+ final DepositAccountOnHoldTransactionRepository
depositAccountOnHoldTransactionRepository,
+ final FromJsonHelper fromApiJsonHelper) {
this.context = context;
this.savingAccountRepositoryWrapper = savingAccountRepositoryWrapper;
@@ -188,6 +192,7 @@ public class
DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
this.calendarInstanceRepository = calendarInstanceRepository;
this.configurationDomainService = configurationDomainService;
this.depositAccountOnHoldTransactionRepository =
depositAccountOnHoldTransactionRepository;
+ this.fromApiJsonHelper = fromApiJsonHelper;
}
@Transactional
@@ -798,14 +803,14 @@ public class
DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
this.depositAccountTransactionDataValidator.validateClosing(command,
DepositAccountType.FIXED_DEPOSIT, isPreMatureClose);
final Map<String, Object> changes = new LinkedHashMap<>();
- final PaymentDetail paymentDetail =
this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command,
changes);
+ final PaymentDetail
+ paymentDetail =
this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command,
changes);
final FixedDepositAccount account = (FixedDepositAccount)
this.depositAccountAssembler.assembleFrom(savingsId,
DepositAccountType.FIXED_DEPOSIT);
checkClientOrGroupActive(account);
- this.depositAccountDomainService.handleFDAccountClosure(account,
paymentDetail, user, command, DateUtils.getLocalDateOfTenant(),
- changes);
+ this.depositAccountDomainService.handleFDAccountClosure(account,
paymentDetail, user, command, DateUtils.getLocalDateOfTenant(), changes);
final String noteText = command.stringValueOfParameterNamed("note");
if (StringUtils.isNotBlank(noteText)) {
@@ -1352,6 +1357,32 @@ public class
DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
if (depositAccountType.isFixedDeposit()) {
((FixedDepositAccount)
account).updateMaturityStatus(isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth);
+ FixedDepositAccount fdAccount = ((FixedDepositAccount) account);
+ //handle maturity instructions
+
+ if(fdAccount.isMatured() && (fdAccount.isReinvestOnClosure() ||
fdAccount.isTransferToSavingsOnClosure())){
+ DateTimeFormatter fmt =
DateTimeFormat.forPattern("yyyy-MM-dd");
+ Map<String, Object> changes = new HashMap<>();
+ AppUser user = context.authenticatedUser();
+ Long toSavingsId = fdAccount.getTransferToSavingsAccountId();
+
this.depositAccountDomainService.handleFDAccountMaturityClosure(fdAccount,
null, user,
+ fdAccount.maturityDate(), fmt,
fdAccount.maturityDate(),
+ fdAccount.getOnAccountClosureId(), toSavingsId, "Apply
maturity instructions", changes);
+
+ if(changes.get("reinvestedDepositId") != null) {
+ Long reinvestedDepositId = (Long)
changes.get("reinvestedDepositId");
+ Money amountForDeposit = account.activateWithBalance();
+ final FixedDepositAccount reinvestAccount =
(FixedDepositAccount)
this.depositAccountAssembler.assembleFrom(reinvestedDepositId,
+ DepositAccountType.FIXED_DEPOSIT);
+ Money activationChargeAmount =
getActivationCharge(reinvestAccount);
+ if(activationChargeAmount.isGreaterThanZero()){
+ payActivationCharge(reinvestAccount, user);
+ amountForDeposit =
amountForDeposit.plus(activationChargeAmount);
+ }
+
this.depositAccountDomainService.handleFDDeposit(reinvestAccount, fmt,
fdAccount.maturityDate(),
+ amountForDeposit.getAmount(), null);
+ }
+ }
} else if (depositAccountType.isRecurringDeposit()) {
((RecurringDepositAccount)
account).updateMaturityStatus(isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth);
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositsDropdownReadPlatformService.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositsDropdownReadPlatformService.java
index d186a69..07c041f 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositsDropdownReadPlatformService.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositsDropdownReadPlatformService.java
@@ -27,6 +27,8 @@ public interface DepositsDropdownReadPlatformService {
Collection<EnumOptionData> retrievePreClosurePenalInterestOnTypeOptions();
+ Collection<EnumOptionData> maturityInstructionOptions();
+
/*
* Collection<EnumOptionData> retrieveDepositTermTypeOptions();
*
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositsDropdownReadPlatformServiceImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositsDropdownReadPlatformServiceImpl.java
index 70ce68f..7c172e0 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositsDropdownReadPlatformServiceImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositsDropdownReadPlatformServiceImpl.java
@@ -18,8 +18,10 @@
*/
package org.apache.fineract.portfolio.savings.service;
+import java.util.Arrays;
import java.util.Collection;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
+import org.apache.fineract.portfolio.savings.DepositAccountOnClosureType;
import org.apache.fineract.portfolio.savings.PreClosurePenalInterestOnType;
import org.springframework.stereotype.Service;
@@ -48,4 +50,14 @@ public class DepositsDropdownReadPlatformServiceImpl
implements DepositsDropdown
* .recurringDepositFrequencyType(SavingsPeriodFrequencyType.values()); }
*/
+
+ @Override
+ public Collection<EnumOptionData> maturityInstructionOptions() {
+ return Arrays.asList(
+
SavingsEnumerations.depositAccountOnClosureType(DepositAccountOnClosureType.WITHDRAW_DEPOSIT),
+
SavingsEnumerations.depositAccountOnClosureType(DepositAccountOnClosureType.TRANSFER_TO_SAVINGS),
+
SavingsEnumerations.depositAccountOnClosureType(DepositAccountOnClosureType.REINVEST_PRINCIPAL_AND_INTEREST),
+
SavingsEnumerations.depositAccountOnClosureType(DepositAccountOnClosureType.REINVEST_PRINCIPAL_ONLY));
+
+ }
}
\ No newline at end of file
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsEnumerations.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsEnumerations.java
index b552cbd..b0b2644 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsEnumerations.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsEnumerations.java
@@ -795,10 +795,14 @@ public class SavingsEnumerations {
optionData = new
EnumOptionData(DepositAccountOnClosureType.TRANSFER_TO_SAVINGS.getValue().longValue(),
DepositAccountOnClosureType.TRANSFER_TO_SAVINGS.getCode(), "Transfer to
Savings");
break;
- case REINVEST:
- optionData = new
EnumOptionData(DepositAccountOnClosureType.REINVEST.getValue().longValue(),
- DepositAccountOnClosureType.REINVEST.getCode(),
"Re-Invest");
+ case REINVEST_PRINCIPAL_AND_INTEREST:
+ optionData = new
EnumOptionData(DepositAccountOnClosureType.REINVEST_PRINCIPAL_AND_INTEREST.getValue().longValue(),
+
DepositAccountOnClosureType.REINVEST_PRINCIPAL_AND_INTEREST.getCode(),
"Re-Invest Maturity Amount");
break;
+ case REINVEST_PRINCIPAL_ONLY:
+ optionData = new
EnumOptionData(DepositAccountOnClosureType.REINVEST_PRINCIPAL_ONLY.getValue().longValue(),
+
DepositAccountOnClosureType.REINVEST_PRINCIPAL_ONLY.getCode(), "Re-Invest
Principal Only");
+ break;
}
return optionData;
}
@@ -835,5 +839,4 @@ public class SavingsEnumerations {
}
return optionData;
}
-
}
\ No newline at end of file
diff --git
a/fineract-provider/src/main/resources/sql/migrations/core_db/V358__fixed_deposit_rollover_transfer.sql
b/fineract-provider/src/main/resources/sql/migrations/core_db/V358__fixed_deposit_rollover_transfer.sql
new file mode 100644
index 0000000..6bb8300
--- /dev/null
+++
b/fineract-provider/src/main/resources/sql/migrations/core_db/V358__fixed_deposit_rollover_transfer.sql
@@ -0,0 +1,21 @@
+--
+-- 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.
+--
+
+alter table m_deposit_account_term_and_preclosure add column
transfer_to_savings_account_id bigint(20) DEFAULT NULL,
+add CONSTRAINT FOREIGN KEY (`transfer_to_savings_account_id`) REFERENCES
`m_savings_account` (`id`);
\ No newline at end of file