diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm
index bc54776a7..2b96329b8 100644
--- a/api-docs/apiLive.htm
+++ b/api-docs/apiLive.htm
@@ -19297,7 +19297,7 @@ No Request Body:
Optional Fields |
- | accountNo, externalId, fieldOfficerId,linkAccountId |
+ | accountNo, externalId, fieldOfficerId,linkAccountId(if provided initial deposit amount will be collected from this account),transferInterestToSavings(By enabling this flag all interest postings will be transferred to linked saving account ) |
diff --git a/mifosng-db/migrations/core_db/V168__added_transfer_fixed_deposit_interest_to_linked_account.sql b/mifosng-db/migrations/core_db/V168__added_transfer_fixed_deposit_interest_to_linked_account.sql
new file mode 100755
index 000000000..9f03d7854
--- /dev/null
+++ b/mifosng-db/migrations/core_db/V168__added_transfer_fixed_deposit_interest_to_linked_account.sql
@@ -0,0 +1,9 @@
+ALTER TABLE `job_run_history`
+ CHANGE COLUMN `error_message` `error_message` TEXT NULL DEFAULT NULL AFTER `status`;
+
+ALTER TABLE `m_deposit_account_term_and_preclosure`
+ ADD COLUMN `transfer_interest_to_linked_account` TINYINT(1) NOT NULL DEFAULT '0' AFTER `expected_firstdepositon_date`;
+
+UPDATE `job` SET `scheduler_group`=1 WHERE `name`='Post Interest For Savings';
+
+INSERT INTO `job` (`name`, `display_name`, `cron_expression`, `create_time`, `task_priority`, `group_name`, `previous_run_start_time`, `next_run_time`, `job_key`, `initializing_errorlog`, `is_active`, `currently_running`, `updates_allowed`, `scheduler_group`, `is_misfired`) VALUES ('Transfer Interest To Savings', 'Transfer Interest To Savings', '0 2 0 1/1 * ? *', now(), 4, NULL, NULL, NULL, NULL, NULL, 1, 0, 1, 1, 0);
\ No newline at end of file
diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/FixedDepositTest.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/FixedDepositTest.java
index fb8dd4431..1876cabb2 100644
--- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/FixedDepositTest.java
+++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/FixedDepositTest.java
@@ -506,9 +506,6 @@ public class FixedDepositTest {
this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec);
this.fixedDepositAccountHelper = new FixedDepositAccountHelper(this.requestSpec, this.responseSpec);
- FixedDepositAccountHelper fixedDepositAccountHelperValidationError = new FixedDepositAccountHelper(this.requestSpec,
- new ResponseSpecBuilder().build());
-
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy");
DateFormat monthDayFormat = new SimpleDateFormat("dd MMM");
diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/SchedulerJobsTestResults.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/SchedulerJobsTestResults.java
index 973f9e329..65af04720 100644
--- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/SchedulerJobsTestResults.java
+++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/SchedulerJobsTestResults.java
@@ -1,6 +1,9 @@
package org.mifosplatform.integrationtests;
+import static org.junit.Assert.assertEquals;
+
import java.text.DateFormat;
+import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
@@ -22,6 +25,9 @@ import org.mifosplatform.integrationtests.common.accounting.GLAccountBuilder;
import org.mifosplatform.integrationtests.common.accounting.JournalEntry;
import org.mifosplatform.integrationtests.common.accounting.JournalEntryHelper;
import org.mifosplatform.integrationtests.common.charges.ChargesHelper;
+import org.mifosplatform.integrationtests.common.fixeddeposit.FixedDepositAccountHelper;
+import org.mifosplatform.integrationtests.common.fixeddeposit.FixedDepositAccountStatusChecker;
+import org.mifosplatform.integrationtests.common.fixeddeposit.FixedDepositProductHelper;
import org.mifosplatform.integrationtests.common.loans.LoanApplicationTestBuilder;
import org.mifosplatform.integrationtests.common.loans.LoanProductTestBuilder;
import org.mifosplatform.integrationtests.common.loans.LoanStatusChecker;
@@ -669,7 +675,7 @@ public class SchedulerJobsTestResults {
Assert.assertEquals("Verifying From Penalty Charges due fot first Repayment after Successful completion of Scheduler Job",
chargeAmount, (Float) repaymentScheduleDataAfter.get(1).get("penaltyChargesDue"));
-
+
loanStatusHashMap = this.loanTransactionHelper.undoDisbursal(loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
@@ -708,6 +714,88 @@ public class SchedulerJobsTestResults {
Assert.assertTrue(isNPAAfter);
}
+ @Test
+ public void testInterestTransferForSavings() throws InterruptedException {
+ this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec);
+ this.schedulerJobHelper = new SchedulerJobHelper(this.requestSpec, this.responseSpec);
+ FixedDepositProductHelper fixedDepositProductHelper = new FixedDepositProductHelper(this.requestSpec, this.responseSpec);
+ AccountHelper accountHelper = new AccountHelper(this.requestSpec, this.responseSpec);
+ FixedDepositAccountHelper fixedDepositAccountHelper = new FixedDepositAccountHelper(this.requestSpec, this.responseSpec);
+
+ DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy");
+ DateFormat monthDayFormat = new SimpleDateFormat("dd MMM");
+
+ 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, -2);
+ 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());
+ todaysDate.add(Calendar.MONTH, 1);
+ final String WHOLE_TERM = "1";
+
+ Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec);
+ Assert.assertNotNull(clientId);
+ Float balance = new Float(MINIMUM_OPENING_BALANCE) + new Float(FixedDepositAccountHelper.depositAmount);
+ final Integer savingsProductID = createSavingsProduct(this.requestSpec, this.responseSpec, String.valueOf(balance));
+ Assert.assertNotNull(savingsProductID);
+
+ final Integer savingsId = this.savingsAccountHelper.applyForSavingsApplication(clientId, savingsProductID,
+ ClientSavingsIntegrationTest.ACCOUNT_TYPE_INDIVIDUAL);
+ Assert.assertNotNull(savingsId);
+
+ HashMap savingsStatusHashMap = SavingsStatusChecker.getStatusOfSavings(this.requestSpec, this.responseSpec, savingsId);
+ SavingsStatusChecker.verifySavingsIsPending(savingsStatusHashMap);
+
+ savingsStatusHashMap = this.savingsAccountHelper.approveSavings(savingsId);
+ SavingsStatusChecker.verifySavingsIsApproved(savingsStatusHashMap);
+
+ savingsStatusHashMap = this.savingsAccountHelper.activateSavings(savingsId);
+ SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
+ HashMap summary = savingsAccountHelper.getSavingsSummary(savingsId);
+ assertEquals("Verifying opening Balance", balance, summary.get("accountBalance"));
+
+ Integer fixedDepositProductId = createFixedDepositProduct(VALID_FROM, VALID_TO);
+ Assert.assertNotNull(fixedDepositProductId);
+
+ Integer fixedDepositAccountId = applyForFixedDepositApplication(clientId.toString(), fixedDepositProductId.toString(), VALID_FROM,
+ VALID_TO, SUBMITTED_ON_DATE, WHOLE_TERM, savingsId.toString(), true, fixedDepositAccountHelper);
+ Assert.assertNotNull(fixedDepositAccountId);
+
+ HashMap fixedDepositAccountStatusHashMap = FixedDepositAccountStatusChecker.getStatusOfFixedDepositAccount(this.requestSpec,
+ this.responseSpec, fixedDepositAccountId.toString());
+ FixedDepositAccountStatusChecker.verifyFixedDepositIsPending(fixedDepositAccountStatusHashMap);
+
+ fixedDepositAccountStatusHashMap = fixedDepositAccountHelper.approveFixedDeposit(fixedDepositAccountId, APPROVED_ON_DATE);
+ FixedDepositAccountStatusChecker.verifyFixedDepositIsApproved(fixedDepositAccountStatusHashMap);
+
+ fixedDepositAccountStatusHashMap = fixedDepositAccountHelper.activateFixedDeposit(fixedDepositAccountId, ACTIVATION_DATE);
+ FixedDepositAccountStatusChecker.verifyFixedDepositIsActive(fixedDepositAccountStatusHashMap);
+ summary = savingsAccountHelper.getSavingsSummary(savingsId);
+ balance = new Float(MINIMUM_OPENING_BALANCE);
+ assertEquals("Verifying Balance", balance, summary.get("accountBalance"));
+
+ fixedDepositAccountHelper.postInterestForFixedDeposit(fixedDepositAccountId);
+
+ HashMap fixedDepositSummary = savingsAccountHelper.getSavingsSummary(fixedDepositAccountId);
+ Float interestPosted = (Float) fixedDepositSummary.get("accountBalance") - new Float(FixedDepositAccountHelper.depositAmount);
+
+ String JobName = "Transfer Interest To Savings";
+ excuteJob(JobName);
+ fixedDepositSummary = savingsAccountHelper.getSavingsSummary(fixedDepositAccountId);
+ assertEquals("Verifying opening Balance", new Float(FixedDepositAccountHelper.depositAmount),
+ fixedDepositSummary.get("accountBalance"));
+
+ summary = savingsAccountHelper.getSavingsSummary(savingsId);
+ balance = new Float(MINIMUM_OPENING_BALANCE) + interestPosted;
+ validateNumberForEqualExcludePrecission(String.valueOf(balance), String.valueOf(summary.get("accountBalance")));
+ }
+
private void excuteJob(String JobName) throws InterruptedException {
ArrayList allSchedulerJobsData = this.schedulerJobHelper.getAllSchedulerJobs(this.requestSpec, this.responseSpec);
Assert.assertNotNull(allSchedulerJobsData);
@@ -797,4 +885,30 @@ public class SchedulerJobsTestResults {
.build(clientID, loanProductID, savingsID);
return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
}
+
+ private Integer createFixedDepositProduct(final String validFrom, final String validTo, Account... accounts) {
+ System.out.println("------------------------------CREATING NEW FIXED DEPOSIT PRODUCT ---------------------------------------");
+ FixedDepositProductHelper fixedDepositProductHelper = new FixedDepositProductHelper(this.requestSpec, this.responseSpec);
+ final String fixedDepositProductJSON = fixedDepositProductHelper //
+ // .withAccountingRuleAsCashBased(accounts)
+ .build(validFrom, validTo);
+ return FixedDepositProductHelper.createFixedDepositProduct(fixedDepositProductJSON, requestSpec, responseSpec);
+ }
+
+ private Integer applyForFixedDepositApplication(final String clientID, final String productID, final String validFrom,
+ final String validTo, final String submittedOnDate, final String penalInterestType, String savingsId,
+ final boolean transferInterest, final FixedDepositAccountHelper fixedDepositAccountHelper) {
+ System.out.println("--------------------------------APPLYING FOR FIXED DEPOSIT ACCOUNT --------------------------------");
+ final String fixedDepositApplicationJSON = new FixedDepositAccountHelper(this.requestSpec, this.responseSpec)
+ //
+ .withSubmittedOnDate(submittedOnDate).withSavings(savingsId).transferInterest(true)
+ .withLockinPeriodFrequency("1", FixedDepositAccountHelper.DAYS)
+ .build(clientID, productID, validFrom, validTo, penalInterestType);
+ return fixedDepositAccountHelper.applyFixedDepositApplication(fixedDepositApplicationJSON, this.requestSpec, this.responseSpec);
+ }
+
+ public void validateNumberForEqualExcludePrecission(String val, String val2) {
+ DecimalFormat twoDForm = new DecimalFormat("#");
+ Assert.assertTrue(new Float(twoDForm.format(new Float(val))).compareTo(new Float(twoDForm.format(new Float(val2)))) == 0);
+ }
}
diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/fixeddeposit/FixedDepositAccountHelper.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/fixeddeposit/FixedDepositAccountHelper.java
index be314127e..8faeb2538 100644
--- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/fixeddeposit/FixedDepositAccountHelper.java
+++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/fixeddeposit/FixedDepositAccountHelper.java
@@ -49,7 +49,7 @@ public class FixedDepositAccountHelper {
private static final String DIGITS_AFTER_DECIMAL = "4";
private static final String IN_MULTIPLES_OF = "100";
private static final String USD = "USD";
- private static final String DAYS = "0";
+ public static final String DAYS = "0";
private static final String WEEKS = "1";
private static final String MONTHS = "2";
private static final String YEARS = "3";
@@ -83,6 +83,7 @@ public class FixedDepositAccountHelper {
private final String depositPeriodFrequencyId = MONTHS;
private String submittedOnDate = "";
private String savingsId = null;
+ private boolean transferInterest = false;
public String build(final String clientId, final String productId, final String validFrom, final String validTo,
final String penalInterestType) {
@@ -162,6 +163,7 @@ public class FixedDepositAccountHelper {
map.put("depositPeriodFrequencyId", this.depositPeriodFrequencyId);
map.put("submittedOnDate", this.submittedOnDate);
map.put("linkAccountId", savingsId);
+ map.put("transferInterestToSavings", transferInterest);
String fixedDepositAccountJson = new Gson().toJson(map);
System.out.println(fixedDepositAccountJson);
@@ -432,4 +434,15 @@ public class FixedDepositAccountHelper {
this.savingsId = savingsId;
return this;
}
+
+ public FixedDepositAccountHelper transferInterest(final boolean transferInterest) {
+ this.transferInterest = transferInterest;
+ return this;
+ }
+
+ public FixedDepositAccountHelper withLockinPeriodFrequency(final String lockingPeriodFrequencyType, final String lockinPeriodFrequency) {
+ this.lockingPeriodFrequencyType = lockingPeriodFrequencyType;
+ this.lockinPeriodFrequency = lockinPeriodFrequency;
+ return this;
+ }
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/jobs/service/JobName.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/jobs/service/JobName.java
index db614f928..82c6f29d7 100755
--- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/jobs/service/JobName.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/jobs/service/JobName.java
@@ -15,7 +15,8 @@ public enum JobName {
EXECUTE_STANDING_INSTRUCTIONS("Execute Standing Instruction"),
ADD_ACCRUAL_ENTRIES("Add Accrual Transactions"),
UPDATE_NPA("Update Non Performing Assets"),
- UPDATE_DEPOSITS_ACCOUNT_MATURITY_DETAILS("Update Deposit Accounts Maturity details");
+ UPDATE_DEPOSITS_ACCOUNT_MATURITY_DETAILS("Update Deposit Accounts Maturity details"),
+ TRANSFER_INTEREST_TO_SAVINGS("Transfer Interest To Savings");
private final String name;
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/domain/AccountTransferType.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/domain/AccountTransferType.java
index 4e67e35d4..3b19671a3 100755
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/domain/AccountTransferType.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/domain/AccountTransferType.java
@@ -13,7 +13,8 @@ public enum AccountTransferType {
INVALID(0, "accountTransferType.invalid"), //
ACCOUNT_TRANSFER(1, "accountTransferType.account.transfer"), //
LOAN_REPAYMENT(2, "accountTransferType.loan.repayment"), //
- CHARGE_PAYMENT(3, "accountTransferType.charge.payment"); //
+ CHARGE_PAYMENT(3, "accountTransferType.charge.payment"), //
+ INTEREST_TRANSFER(4, "accountTransferType.interest.transfer"); //
private final Integer value;
private final String code;
@@ -31,6 +32,9 @@ public enum AccountTransferType {
case 3:
enumeration = AccountTransferType.CHARGE_PAYMENT;
break;
+ case 4:
+ enumeration = AccountTransferType.INTEREST_TRANSFER;
+ break;
}
return enumeration;
}
@@ -63,4 +67,8 @@ public enum AccountTransferType {
public boolean isChargePayment() {
return this.value.equals(AccountTransferType.CHARGE_PAYMENT.getValue());
}
+
+ public boolean isInterestTransfer() {
+ return this.value.equals(AccountTransferType.INTEREST_TRANSFER.getValue());
+ }
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/AccountTransfersReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/AccountTransfersReadPlatformService.java
index 31fe4ed65..7c84ecccc 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/AccountTransfersReadPlatformService.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/AccountTransfersReadPlatformService.java
@@ -5,6 +5,8 @@
*/
package org.mifosplatform.portfolio.account.service;
+import java.util.Collection;
+
import org.mifosplatform.infrastructure.core.service.Page;
import org.mifosplatform.portfolio.account.PortfolioAccountType;
import org.mifosplatform.portfolio.account.data.AccountTransferData;
@@ -22,4 +24,6 @@ public interface AccountTransfersReadPlatformService {
boolean isAccountTransfer(Long transactionId, PortfolioAccountType accountType);
Page retrieveByStandingInstruction(Long id, SearchParameters searchParameters);
+
+ Collection fetchPostInterestTransactionIds(Long accountId);
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/AccountTransfersReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/AccountTransfersReadPlatformServiceImpl.java
index 1090afaab..201f8af59 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/AccountTransfersReadPlatformServiceImpl.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/AccountTransfersReadPlatformServiceImpl.java
@@ -11,6 +11,7 @@ import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
@@ -25,6 +26,7 @@ import org.mifosplatform.organisation.office.service.OfficeReadPlatformService;
import org.mifosplatform.portfolio.account.PortfolioAccountType;
import org.mifosplatform.portfolio.account.data.AccountTransferData;
import org.mifosplatform.portfolio.account.data.PortfolioAccountData;
+import org.mifosplatform.portfolio.account.domain.AccountTransferType;
import org.mifosplatform.portfolio.account.exception.AccountTransferNotFoundException;
import org.mifosplatform.portfolio.client.data.ClientData;
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
@@ -188,15 +190,15 @@ public class AccountTransfersReadPlatformServiceImpl implements AccountTransfers
}
@Override
- public Page retrieveAll(final SearchParameters searchParameters,final Long accountDetailId) {
+ public Page retrieveAll(final SearchParameters searchParameters, final Long accountDetailId) {
final StringBuilder sqlBuilder = new StringBuilder(200);
sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
sqlBuilder.append(this.accountTransfersMapper.schema());
Object[] finalObjectArray = {};
- if(accountDetailId != null){
+ if (accountDetailId != null) {
sqlBuilder.append(" where att.account_transfer_details_id=?");
- finalObjectArray = new Object[]{ accountDetailId };
+ finalObjectArray = new Object[] { accountDetailId };
}
if (searchParameters.isOrderByRequested()) {
@@ -231,6 +233,16 @@ public class AccountTransfersReadPlatformServiceImpl implements AccountTransfers
}
}
+ @Override
+ public Collection fetchPostInterestTransactionIds(final Long accountId) {
+ final String sql = "select att.from_savings_transaction_id from m_account_transfer_transaction att inner join m_account_transfer_details atd on atd.id = att.account_transfer_details_id where atd.from_savings_account_id=? and att.is_reversed =0 and atd.transfer_type = ?";
+
+ final List transactionId = this.jdbcTemplate.queryForList(sql, Long.class, accountId,
+ AccountTransferType.INTEREST_TRANSFER.getValue());
+
+ return transactionId;
+ }
+
private static final class AccountTransfersMapper implements RowMapper {
private final String schemaSql;
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/AccountTransfersWritePlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/AccountTransfersWritePlatformServiceImpl.java
index e02036e23..983c3333e 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/AccountTransfersWritePlatformServiceImpl.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/AccountTransfersWritePlatformServiceImpl.java
@@ -98,13 +98,15 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
final PaymentDetail paymentDetail = null;
Long fromSavingsAccountId = null;
Long transferDetailId = null;
+ boolean isInterestTransfer = false;
if (isSavingsToSavingsAccountTransfer(fromAccountType, toAccountType)) {
fromSavingsAccountId = command.longValueOfParameterNamed(fromAccountIdParamName);
final SavingsAccount fromSavingsAccount = this.savingsAccountAssembler.assembleFrom(fromSavingsAccountId);
final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(fromSavingsAccount, fmt,
- transactionDate, transactionAmount, paymentDetail, fromSavingsAccount.isWithdrawalFeeApplicableForTransfer());
+ transactionDate, transactionAmount, paymentDetail, fromSavingsAccount.isWithdrawalFeeApplicableForTransfer(),
+ isInterestTransfer);
final Long toSavingsId = command.longValueOfParameterNamed(toAccountIdParamName);
final SavingsAccount toSavingsAccount = this.savingsAccountAssembler.assembleFrom(toSavingsId);
@@ -123,7 +125,8 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
final SavingsAccount fromSavingsAccount = this.savingsAccountAssembler.assembleFrom(fromSavingsAccountId);
final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(fromSavingsAccount, fmt,
- transactionDate, transactionAmount, paymentDetail, fromSavingsAccount.isWithdrawalFeeApplicableForTransfer());
+ transactionDate, transactionAmount, paymentDetail, fromSavingsAccount.isWithdrawalFeeApplicableForTransfer(),
+ isInterestTransfer);
final Long toLoanAccountId = command.longValueOfParameterNamed(toAccountIdParamName);
final Loan toLoanAccount = this.loanAccountAssembler.assembleFrom(toLoanAccountId);
@@ -244,7 +247,8 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(fromSavingsAccount,
accountTransferDTO.getFmt(), accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(),
- accountTransferDTO.getPaymentDetail(), fromSavingsAccount.isWithdrawalFeeApplicableForTransfer());
+ accountTransferDTO.getPaymentDetail(), fromSavingsAccount.isWithdrawalFeeApplicableForTransfer(), AccountTransferType
+ .fromInt(accountTransferDTO.getTransferType()).isInterestTransfer());
LoanTransaction loanTransaction = null;
@@ -284,7 +288,8 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
}
final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(fromSavingsAccount,
accountTransferDTO.getFmt(), accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(),
- accountTransferDTO.getPaymentDetail(), fromSavingsAccount.isWithdrawalFeeApplicableForTransfer());
+ accountTransferDTO.getPaymentDetail(), fromSavingsAccount.isWithdrawalFeeApplicableForTransfer(), AccountTransferType
+ .fromInt(accountTransferDTO.getTransferType()).isInterestTransfer());
final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(toSavingsAccount,
accountTransferDTO.getFmt(), accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(),
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/DepositsApiConstants.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/DepositsApiConstants.java
index 05260989e..074e15f71 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/DepositsApiConstants.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/DepositsApiConstants.java
@@ -179,6 +179,7 @@ public class DepositsApiConstants {
public static final String preMatureCloseOnDateParamName = "preMatureCloseOnDate";
public static final String linkedAccountParamName = "linkAccountId";
+ public static final String transferInterestToSavingsParamName = "transferInterestToSavings";
// template
public static final String chartTemplate = "chartTemplate";
@@ -216,13 +217,11 @@ public class DepositsApiConstants {
private static final Set DEPOSIT_TERM_REQUEST_DATA_PARAMETERS = new HashSet(Arrays.asList(minDepositTermParamName,
maxDepositTermParamName, minDepositTermTypeIdParamName, maxDepositTermTypeIdParamName, inMultiplesOfDepositTermParamName,
- inMultiplesOfDepositTermTypeIdParamName, depositAmountParamName,
- depositMinAmountParamName, depositMaxAmountParamName));
+ inMultiplesOfDepositTermTypeIdParamName, depositAmountParamName, depositMinAmountParamName, depositMaxAmountParamName));
private static final Set DEPOSIT_TERM_RESPONSE_DATA_PARAMETERS = new HashSet(Arrays.asList(minDepositTermParamName,
maxDepositTermParamName, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTermParamName,
- inMultiplesOfDepositTermType, depositAmountParamName,
- depositMinAmountParamName, depositMaxAmountParamName));
+ inMultiplesOfDepositTermType, depositAmountParamName, depositMinAmountParamName, depositMaxAmountParamName));
private static final Set RECURRING_DETAILS_REQUEST_DATA_PARAMETERS = new HashSet(Arrays.asList(
recurringDepositAmountParamName, recurringDepositTypeIdParamName, recurringDepositFrequencyTypeIdParamName,
@@ -298,6 +297,7 @@ public class DepositsApiConstants {
fixedDepositRequestData.addAll(PRECLOSURE_REQUEST_DATA_PARAMETERS);
fixedDepositRequestData.addAll(DEPOSIT_TERM_REQUEST_DATA_PARAMETERS);
fixedDepositRequestData.add(linkedAccountParamName);
+ fixedDepositRequestData.add(transferInterestToSavingsParamName);
return fixedDepositRequestData;
}
@@ -307,6 +307,7 @@ public class DepositsApiConstants {
fixedDepositResponseData.addAll(PRECLOSURE_RESPONSE_DATA_PARAMETERS);
fixedDepositResponseData.addAll(DEPOSIT_TERM_RESPONSE_DATA_PARAMETERS);
fixedDepositResponseData.add(linkedAccountParamName);
+ fixedDepositResponseData.add(transferInterestToSavingsParamName);
return fixedDepositResponseData;
}
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/DepositAccountDataValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/DepositAccountDataValidator.java
index 0ea946cf3..97a13a947 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/DepositAccountDataValidator.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/DepositAccountDataValidator.java
@@ -45,6 +45,7 @@ import static org.mifosplatform.portfolio.savings.SavingsApiConstants.minRequire
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.nominalAnnualInterestRateParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.productIdParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.submittedOnDateParamName;
+import static org.mifosplatform.portfolio.savings.DepositsApiConstants.transferInterestToSavingsParamName;
import java.lang.reflect.Type;
import java.math.BigDecimal;
@@ -279,8 +280,15 @@ public class DepositAccountDataValidator {
}
}
- if (this.fromApiJsonHelper.parameterExists(linkedAccountParamName, element)) {
- final Long linkAccountId = this.fromApiJsonHelper.extractLongNamed(linkedAccountParamName, element);
+ boolean isLinkedAccRequired = false;
+ if (fromApiJsonHelper.parameterExists(transferInterestToSavingsParamName, element)) {
+ isLinkedAccRequired = fromApiJsonHelper.extractBooleanNamed(transferInterestToSavingsParamName, element);
+ }
+
+ final Long linkAccountId = this.fromApiJsonHelper.extractLongNamed(linkedAccountParamName, element);
+ if (isLinkedAccRequired) {
+ baseDataValidator.reset().parameter(linkedAccountParamName).value(linkAccountId).notNull().longGreaterThanZero();
+ } else {
baseDataValidator.reset().parameter(linkedAccountParamName).value(linkAccountId).ignoreIfNull().longGreaterThanZero();
}
}
@@ -400,9 +408,18 @@ public class DepositAccountDataValidator {
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).inMinMaxRange(0, 3);
}
+ boolean isLinkedAccRequired = false;
+ if (fromApiJsonHelper.parameterExists(transferInterestToSavingsParamName, element)) {
+ isLinkedAccRequired = fromApiJsonHelper.extractBooleanNamed(transferInterestToSavingsParamName, element);
+ }
+
if (this.fromApiJsonHelper.parameterExists(linkedAccountParamName, element)) {
final Long linkAccountId = this.fromApiJsonHelper.extractLongNamed(linkedAccountParamName, element);
- baseDataValidator.reset().parameter(linkedAccountParamName).value(linkAccountId).ignoreIfNull().longGreaterThanZero();
+ if (isLinkedAccRequired) {
+ baseDataValidator.reset().parameter(linkedAccountParamName).value(linkAccountId).notNull().longGreaterThanZero();
+ } else {
+ baseDataValidator.reset().parameter(linkedAccountParamName).value(linkAccountId).ignoreIfNull().longGreaterThanZero();
+ }
}
}
@@ -585,6 +602,15 @@ public class DepositAccountDataValidator {
"Validation errors exist.", dataValidationErrors); }
}
+ public void throwLinkedAccountRequiredError() {
+ final List dataValidationErrors = new ArrayList();
+ final ApiParameterError error = ApiParameterError.parameterError(
+ "validation.msg.fixeddepositaccount.linkAccountId.cannot.be.blank", "Linked Savings account required", "linkAccountId");
+ dataValidationErrors.add(error);
+ throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
+ dataValidationErrors);
+ }
+
private void validateSavingsCharges(final JsonElement element, final DataValidatorBuilder baseDataValidator) {
if (element.isJsonObject()) {
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/FixedDepositAccountData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/FixedDepositAccountData.java
index a6b34fca0..bc3fec635 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/FixedDepositAccountData.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/FixedDepositAccountData.java
@@ -49,6 +49,7 @@ public class FixedDepositAccountData extends DepositAccountData {
private EnumOptionData onAccountClosure;
private final PortfolioAccountData linkedAccount;
+ private final Boolean transferInterestToSavings;
private Collection interestFreePeriodTypeOptions;
private Collection preClosurePenalInterestOnTypeOptions;
@@ -68,7 +69,7 @@ public class FixedDepositAccountData extends DepositAccountData {
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 EnumOptionData onAccountClosure, final Boolean transferInterestToSavings) {
final PortfolioAccountData linkedAccount = null;
final Collection interestFreePeriodTypeOptions = null;
@@ -101,7 +102,7 @@ public class FixedDepositAccountData extends DepositAccountData {
maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate,
depositPeriod, depositPeriodFrequency, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions,
depositPeriodFrequencyOptions, depositType, onAccountClosure, onAccountClosureOptions, paymentTypeOptions,
- savingsAccountDatas, linkedAccount);
+ savingsAccountDatas, linkedAccount, transferInterestToSavings);
}
public static FixedDepositAccountData withInterestChart(final FixedDepositAccountData account,
@@ -123,7 +124,8 @@ public class FixedDepositAccountData extends DepositAccountData {
account.inMultiplesOfDepositTerm, account.inMultiplesOfDepositTermType, account.depositAmount, account.maturityAmount,
account.maturityDate, account.depositPeriod, account.depositPeriodFrequency, account.depositTermTypeOptions,
account.inMultiplesOfDepositTermTypeOptions, account.depositTermTypeOptions, account.depositType, account.onAccountClosure,
- account.onAccountClosureOptions, account.paymentTypeOptions, account.savingsAccounts, account.linkedAccount);
+ account.onAccountClosureOptions, account.paymentTypeOptions, account.savingsAccounts, account.linkedAccount,
+ account.transferInterestToSavings);
}
public static FixedDepositAccountData associationsAndTemplate(final FixedDepositAccountData account, FixedDepositAccountData template,
@@ -152,7 +154,7 @@ public class FixedDepositAccountData extends DepositAccountData {
account.maturityAmount, account.maturityDate, account.depositPeriod, account.depositPeriodFrequency,
template.depositTermTypeOptions, template.inMultiplesOfDepositTermTypeOptions, template.depositPeriodFrequencyOptions,
account.depositType, account.onAccountClosure, account.onAccountClosureOptions, account.paymentTypeOptions,
- template.savingsAccounts, linkedAccount);
+ template.savingsAccounts, linkedAccount, account.transferInterestToSavings);
}
public static FixedDepositAccountData withTemplateOptions(final FixedDepositAccountData account,
@@ -184,7 +186,8 @@ public class FixedDepositAccountData extends DepositAccountData {
account.inMultiplesOfDepositTerm, account.inMultiplesOfDepositTermType, account.depositAmount, account.maturityAmount,
account.maturityDate, account.depositPeriod, account.depositPeriodFrequency, depositTermTypeOptions,
inMultiplesOfDepositTermTypeOptions, depositPeriodFrequencyOptions, account.depositType, account.onAccountClosure,
- account.onAccountClosureOptions, account.paymentTypeOptions, savingsAccounts, account.linkedAccount);
+ account.onAccountClosureOptions, account.paymentTypeOptions, savingsAccounts, account.linkedAccount,
+ account.transferInterestToSavings);
}
public static FixedDepositAccountData withClientTemplate(final Long clientId, final String clientName, final Long groupId,
@@ -246,6 +249,7 @@ public class FixedDepositAccountData extends DepositAccountData {
final EnumOptionData depositPeriodFrequency = null;
final EnumOptionData onAccountClosure = null;
final PortfolioAccountData linkedAccount = null;
+ final Boolean transferInterestToSavings = null;
final Collection interestFreePeriodTypeOptions = null;
final Collection preClosurePenalInterestOnTypeOptions = null;
@@ -269,7 +273,8 @@ public class FixedDepositAccountData extends DepositAccountData {
preClosurePenalInterestOnTypeOptions, minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType,
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate, depositPeriod,
depositPeriodFrequency, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions, depositPeriodFrequencyOptions,
- depositType, onAccountClosure, onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas, linkedAccount);
+ depositType, onAccountClosure, onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas, linkedAccount,
+ transferInterestToSavings);
}
public static FixedDepositAccountData preClosureDetails(final Long accountId, BigDecimal maturityAmount,
@@ -333,6 +338,7 @@ public class FixedDepositAccountData extends DepositAccountData {
final Integer depositPeriod = null;
final EnumOptionData depositPeriodFrequency = null;
final EnumOptionData onAccountClosure = null;
+ final Boolean transferInterestToSavings = null;
final Collection interestFreePeriodTypeOptions = null;
final Collection preClosurePenalInterestOnTypeOptions = null;
@@ -354,7 +360,8 @@ public class FixedDepositAccountData extends DepositAccountData {
preClosurePenalInterestOnTypeOptions, minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType,
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate, depositPeriod,
depositPeriodFrequency, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions, depositPeriodFrequencyOptions,
- depositType, onAccountClosure, onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas, linkedAccount);
+ depositType, onAccountClosure, onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas, linkedAccount,
+ transferInterestToSavings);
}
public static FixedDepositAccountData withClosureTemplateDetails(final FixedDepositAccountData account,
@@ -378,7 +385,8 @@ public class FixedDepositAccountData extends DepositAccountData {
account.inMultiplesOfDepositTerm, account.inMultiplesOfDepositTermType, account.depositAmount, account.maturityAmount,
account.maturityDate, account.depositPeriod, account.depositPeriodFrequency, account.depositTermTypeOptions,
account.inMultiplesOfDepositTermTypeOptions, account.depositPeriodFrequencyOptions, account.depositType,
- account.onAccountClosure, onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas, account.linkedAccount);
+ account.onAccountClosure, onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas, account.linkedAccount,
+ account.transferInterestToSavings);
}
private FixedDepositAccountData(final Long id, final String accountNo, final String externalId, final Long groupId,
@@ -411,7 +419,7 @@ public class FixedDepositAccountData extends DepositAccountData {
final Collection depositPeriodFrequencyOptions, final EnumOptionData depositType,
final EnumOptionData onAccountClosure, final Collection onAccountClosureOptions,
final Collection paymentTypeOptions, final Collection savingsAccountDatas,
- final PortfolioAccountData linkedAccount) {
+ final PortfolioAccountData linkedAccount, final Boolean transferInterestToSavings) {
super(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName, fieldofficerId,
fieldofficerName, status, timeline, currency, nominalAnnualInterestRate, interestPeriodType, interestPostingPeriodType,
@@ -442,6 +450,7 @@ public class FixedDepositAccountData extends DepositAccountData {
this.depositPeriodFrequency = depositPeriodFrequency;
this.onAccountClosure = onAccountClosure;
this.linkedAccount = linkedAccount;
+ this.transferInterestToSavings = transferInterestToSavings;
// template
this.interestFreePeriodTypeOptions = interestFreePeriodTypeOptions;
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountAssembler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountAssembler.java
index 084b4db31..67a4d27cb 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountAssembler.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountAssembler.java
@@ -9,11 +9,12 @@ import static org.mifosplatform.portfolio.savings.DepositsApiConstants.chartIdPa
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositAmountParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositPeriodFrequencyIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositPeriodParamName;
+import static org.mifosplatform.portfolio.savings.DepositsApiConstants.expectedFirstDepositOnDateParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositAmountParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositTypeIdParamName;
-import static org.mifosplatform.portfolio.savings.DepositsApiConstants.expectedFirstDepositOnDateParamName;
+import static org.mifosplatform.portfolio.savings.DepositsApiConstants.transferInterestToSavingsParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.accountNoParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.clientIdParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.externalIdParamName;
@@ -40,6 +41,7 @@ import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.infrastructure.core.service.DateUtils;
import org.mifosplatform.organisation.staff.domain.Staff;
import org.mifosplatform.organisation.staff.domain.StaffRepositoryWrapper;
+import org.mifosplatform.portfolio.account.service.AccountTransfersReadPlatformService;
import org.mifosplatform.portfolio.accountdetails.domain.AccountType;
import org.mifosplatform.portfolio.client.domain.Client;
import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper;
@@ -71,7 +73,7 @@ import com.google.gson.JsonElement;
public class DepositAccountAssembler {
private final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper;
- private final SavingsHelper savingsHelper = new SavingsHelper();
+ private final SavingsHelper savingsHelper;
private final ClientRepositoryWrapper clientRepository;
private final GroupRepositoryWrapper groupRepository;
private final StaffRepositoryWrapper staffRepository;
@@ -88,7 +90,9 @@ public class DepositAccountAssembler {
final StaffRepositoryWrapper staffRepository, final FixedDepositProductRepository fixedDepositProductRepository,
final SavingsAccountRepositoryWrapper savingsAccountRepository,
final SavingsAccountChargeAssembler savingsAccountChargeAssembler, final FromJsonHelper fromApiJsonHelper,
- final DepositProductAssembler depositProductAssembler, final RecurringDepositProductRepository recurringDepositProductRepository) {
+ final DepositProductAssembler depositProductAssembler,
+ final RecurringDepositProductRepository recurringDepositProductRepository,
+ final AccountTransfersReadPlatformService accountTransfersReadPlatformService) {
this.savingsAccountTransactionSummaryWrapper = savingsAccountTransactionSummaryWrapper;
this.clientRepository = clientRepository;
this.groupRepository = groupRepository;
@@ -99,6 +103,7 @@ public class DepositAccountAssembler {
this.fromApiJsonHelper = fromApiJsonHelper;
this.depositProductAssembler = depositProductAssembler;
this.recurringDepositProductRepository = recurringDepositProductRepository;
+ this.savingsHelper = new SavingsHelper(accountTransfersReadPlatformService);
}
/**
@@ -314,6 +319,7 @@ public class DepositAccountAssembler {
final SavingsPeriodFrequencyType depositPeriodFrequency = SavingsPeriodFrequencyType.fromInt(depositPeriodFrequencyId);
final SavingsAccount account = null;
final LocalDate expectedFirstDepositOnDate = command.localDateValueOfParameterNamed(expectedFirstDepositOnDateParamName);
+ final Boolean trasferInterest = command.booleanPrimitiveValueOfParameterNamed(transferInterestToSavingsParamName);
// calculate maturity amount
final BigDecimal maturityAmount = null;// calculated and updated in
@@ -321,7 +327,8 @@ public class DepositAccountAssembler {
final LocalDate maturityDate = null;// calculated and updated in account
final DepositAccountOnClosureType accountOnClosureType = null;
return DepositAccountTermAndPreClosure.createNew(updatedProductPreClosure, updatedProductTerm, account, depositAmount,
- maturityAmount, maturityDate, depositPeriod, depositPeriodFrequency, expectedFirstDepositOnDate, accountOnClosureType);
+ maturityAmount, maturityDate, depositPeriod, depositPeriodFrequency, expectedFirstDepositOnDate, accountOnClosureType,
+ trasferInterest);
}
public DepositAccountRecurringDetail assembleAccountRecurringDetail(final JsonCommand command,
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountDomainServiceJpa.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountDomainServiceJpa.java
index 4be91950c..d829da2f1 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountDomainServiceJpa.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountDomainServiceJpa.java
@@ -82,14 +82,14 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
paymentDetail, new Date());
final SavingsAccountTransaction withdrawal = account.withdraw(transactionDTO, applyWithdrawFee);
-
+ boolean isInterestTransfer = false;
final MathContext mc = MathContext.DECIMAL64;
if (account.isBeforeLastPostingPeriod(transactionDate)) {
final LocalDate today = DateUtils.getLocalDateOfTenant();
- account.postInterest(mc, today);
+ account.postInterest(mc, today, isInterestTransfer);
} else {
final LocalDate today = DateUtils.getLocalDateOfTenant();
- account.calculateInterestUsing(mc, today);
+ account.calculateInterestUsing(mc, today, isInterestTransfer);
}
account.validateAccountBalanceDoesNotBecomeNegative(transactionAmount);
saveTransactionToGenerateTransactionId(withdrawal);
@@ -111,14 +111,14 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
paymentDetail, new Date());
final SavingsAccountTransaction deposit = account.deposit(transactionDTO);
-
+ boolean isInterestTransfer = false;
final MathContext mc = MathContext.DECIMAL64;
if (account.isBeforeLastPostingPeriod(transactionDate)) {
final LocalDate today = DateUtils.getLocalDateOfTenant();
- account.postInterest(mc, today);
+ account.postInterest(mc, today, isInterestTransfer);
} else {
final LocalDate today = DateUtils.getLocalDateOfTenant();
- account.calculateInterestUsing(mc, today);
+ account.calculateInterestUsing(mc, today, isInterestTransfer);
}
saveTransactionToGenerateTransactionId(deposit);
@@ -217,7 +217,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
}
this.savingsAccountRepository.save(account);
-
+
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
return withdrawal;
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountTermAndPreClosure.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountTermAndPreClosure.java
index 46149de9e..eee1b0488 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountTermAndPreClosure.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountTermAndPreClosure.java
@@ -9,6 +9,7 @@ import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositAm
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositPeriodFrequencyIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositPeriodParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.expectedFirstDepositOnDateParamName;
+import static org.mifosplatform.portfolio.savings.DepositsApiConstants.transferInterestToSavingsParamName;
import java.math.BigDecimal;
import java.util.Date;
@@ -75,6 +76,9 @@ public class DepositAccountTermAndPreClosure extends AbstractPersistable {
@JoinColumn(name = "savings_account_id", nullable = false)
private SavingsAccount account;
+ @Column(name = "transfer_interest_to_linked_account", nullable = false)
+ private boolean transferInterestToLinkedAccount;
+
protected DepositAccountTermAndPreClosure() {
super();
}
@@ -82,16 +86,16 @@ public class DepositAccountTermAndPreClosure extends AbstractPersistable {
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) {
+ final DepositAccountOnClosureType accountOnClosureType, Boolean trasferInterest) {
return new DepositAccountTermAndPreClosure(preClosureDetail, depositTermDetail, account, depositAmount, maturityAmount,
- maturityDate, depositPeriod, depositPeriodFrequency, expectedFirstDepositOnDate, accountOnClosureType);
+ maturityDate, depositPeriod, depositPeriodFrequency, expectedFirstDepositOnDate, accountOnClosureType, trasferInterest);
}
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) {
+ final DepositAccountOnClosureType accountOnClosureType, Boolean transferInterest) {
this.depositAmount = depositAmount;
this.maturityAmount = maturityAmount;
this.maturityDate = (maturityDate == null) ? null : maturityDate.toDate();
@@ -102,6 +106,7 @@ public class DepositAccountTermAndPreClosure extends AbstractPersistable {
this.account = account;
this.expectedFirstDepositOnDate = expectedFirstDepositOnDate == null ? null : expectedFirstDepositOnDate.toDate();
this.onAccountClosureType = (accountOnClosureType == null) ? null : accountOnClosureType.getValue();
+ this.transferInterestToLinkedAccount = transferInterest;
}
public Map update(final JsonCommand command, final DataValidatorBuilder baseDataValidator) {
@@ -124,10 +129,10 @@ public class DepositAccountTermAndPreClosure extends AbstractPersistable {
actualChanges.put(depositPeriodFrequencyIdParamName, SavingsEnumerations.depositTermFrequencyType(newValue));
this.depositPeriodFrequency = newValue;
}
-
+
final String localeAsInput = command.locale();
final String dateFormat = command.dateFormat();
-
+
if (command.isChangeInLocalDateParameterNamed(expectedFirstDepositOnDateParamName, getExpectedFirstDepositOnDate())) {
final LocalDate newValue = command.localDateValueOfParameterNamed(expectedFirstDepositOnDateParamName);
final String newValueAsString = command.stringValueOfParameterNamed(expectedFirstDepositOnDateParamName);
@@ -137,6 +142,12 @@ public class DepositAccountTermAndPreClosure extends AbstractPersistable {
this.expectedFirstDepositOnDate = newValue.toDate();
}
+ if (command.isChangeInBooleanParameterNamed(transferInterestToSavingsParamName, this.transferInterestToLinkedAccount)) {
+ final Boolean newValue = command.booleanPrimitiveValueOfParameterNamed(transferInterestToSavingsParamName);
+ actualChanges.put(transferInterestToSavingsParamName, newValue);
+ this.transferInterestToLinkedAccount = newValue;
+ }
+
if (this.preClosureDetail != null) {
actualChanges.putAll(this.preClosureDetail.update(command, baseDataValidator));
}
@@ -262,13 +273,20 @@ public class DepositAccountTermAndPreClosure extends AbstractPersistable {
final DepositPreClosureDetail preClosureDetail = this.preClosureDetail.copy();
final DepositTermDetail depositTermDetail = this.depositTermDetail.copy();
final LocalDate expectedFirstDepositOnDate = null;
+ final Boolean transferInterestToLinkedAccount = null;
final DepositAccountOnClosureType accountOnClosureType = null;
return DepositAccountTermAndPreClosure.createNew(preClosureDetail, depositTermDetail, account, actualDepositAmount, maturityAmount,
- maturityDate, depositPeriod, depositPeriodFrequency, expectedFirstDepositOnDate, accountOnClosureType);
+ maturityDate, depositPeriod, depositPeriodFrequency, expectedFirstDepositOnDate, accountOnClosureType,
+ transferInterestToLinkedAccount);
}
public void updateExpectedFirstDepositDate(final LocalDate expectedFirstDepositOnDate) {
this.expectedFirstDepositOnDate = expectedFirstDepositOnDate.toDate();
}
+
+
+ public boolean isTransferInterestToLinkedAccount() {
+ return this.transferInterestToLinkedAccount;
+ }
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/FixedDepositAccount.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/FixedDepositAccount.java
index 6dabb1909..f02d629a6 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/FixedDepositAccount.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/FixedDepositAccount.java
@@ -13,6 +13,7 @@ import static org.mifosplatform.portfolio.savings.DepositsApiConstants.onAccount
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Locale;
@@ -259,11 +260,13 @@ public class FixedDepositAccount extends SavingsAccount {
final SavingsInterestCalculationType interestCalculationType = SavingsInterestCalculationType.fromInt(this.interestCalculationType);
final BigDecimal interestRateAsFraction = getEffectiveInterestRateAsFraction(mc, maturityDate);
+ final Collection interestPostTransactions = this.savingsHelper.fetchPostInterestTransactionIds(getId());
+ boolean isInterestTransfer = false;
for (final LocalDateInterval periodInterval : postingPeriodIntervals) {
final PostingPeriod postingPeriod = PostingPeriod.createFrom(periodInterval, periodStartingBalance, transactions,
this.currency, compoundingPeriodType, interestCalculationType, interestRateAsFraction, daysInYearType.getValue(),
- maturityDate);
+ maturityDate, interestPostTransactions, isInterestTransfer);
periodStartingBalance = postingPeriod.closingBalance();
@@ -271,7 +274,8 @@ public class FixedDepositAccount extends SavingsAccount {
}
this.summary.updateFromInterestPeriodSummaries(this.currency, allPostingPeriods);
- this.savingsHelper.calculateInterestForAllPostingPeriods(this.currency, allPostingPeriods);
+ this.savingsHelper.calculateInterestForAllPostingPeriods(this.currency, allPostingPeriods, this.getLockedInUntilLocalDate(),
+ isTransferInterestToOtherAccount());
return allPostingPeriods;
}
@@ -429,8 +433,8 @@ public class FixedDepositAccount extends SavingsAccount {
public void postMaturityInterest(final LocalDate interestPostingUpToDate) {
final MathContext mc = MathContext.DECIMAL64;
-
- final List postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate);
+ final boolean isInterestTransfer = false;
+ final List postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate, isInterestTransfer);
Money interestPostedToDate = Money.zero(this.currency);
@@ -526,15 +530,15 @@ public class FixedDepositAccount extends SavingsAccount {
}
@Override
- public void postInterest(final MathContext mc, final LocalDate postingDate) {
+ public void postInterest(final MathContext mc, final LocalDate postingDate, boolean isInterestTransfer) {
final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
- super.postInterest(mc, interestPostingUpToDate);
+ super.postInterest(mc, interestPostingUpToDate, isInterestTransfer);
}
@Override
- public List calculateInterestUsing(final MathContext mc, final LocalDate postingDate) {
+ public List calculateInterestUsing(final MathContext mc, final LocalDate postingDate, boolean isInterestTransfer) {
final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
- return super.calculateInterestUsing(mc, interestPostingUpToDate);
+ return super.calculateInterestUsing(mc, interestPostingUpToDate, isInterestTransfer);
}
private LocalDate interestPostingUpToDate(final LocalDate interestPostingDate) {
@@ -680,4 +684,9 @@ public class FixedDepositAccount extends SavingsAccount {
return reInvestedAccount;
}
+
+ @Override
+ protected boolean isTransferInterestToOtherAccount() {
+ return this.accountTermAndPreClosure.isTransferInterestToLinkedAccount();
+ }
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/RecurringDepositAccount.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/RecurringDepositAccount.java
index 4c001e520..36c72f761 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/RecurringDepositAccount.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/RecurringDepositAccount.java
@@ -13,6 +13,7 @@ import static org.mifosplatform.portfolio.savings.DepositsApiConstants.onAccount
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
@@ -281,18 +282,20 @@ public class RecurringDepositAccount extends SavingsAccount {
final SavingsInterestCalculationType interestCalculationType = SavingsInterestCalculationType.fromInt(this.interestCalculationType);
final BigDecimal interestRateAsFraction = getEffectiveInterestRateAsFraction(mc, maturityDate);
-
+ final Collection interestPostTransactions = this.savingsHelper.fetchPostInterestTransactionIds(getId());
+ boolean isInterestTransfer = false;
for (final LocalDateInterval periodInterval : postingPeriodIntervals) {
final PostingPeriod postingPeriod = PostingPeriod.createFrom(periodInterval, periodStartingBalance, transactions,
this.currency, compoundingPeriodType, interestCalculationType, interestRateAsFraction, daysInYearType.getValue(),
- maturityDate);
+ maturityDate, interestPostTransactions, isInterestTransfer);
periodStartingBalance = postingPeriod.closingBalance();
allPostingPeriods.add(postingPeriod);
}
- this.savingsHelper.calculateInterestForAllPostingPeriods(this.currency, allPostingPeriods);
+ this.savingsHelper.calculateInterestForAllPostingPeriods(this.currency, allPostingPeriods, this.getLockedInUntilLocalDate(),
+ isTransferInterestToOtherAccount());
// this.summary.updateFromInterestPeriodSummaries(this.currency,
// allPostingPeriods);
return allPostingPeriods;
@@ -538,8 +541,8 @@ public class RecurringDepositAccount extends SavingsAccount {
public void postMaturityInterest(final LocalDate interestPostingUpToDate) {
final MathContext mc = MathContext.DECIMAL64;
-
- final List postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate);
+ boolean isInterestTransfer = false;
+ final List postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate,isInterestTransfer);
Money interestPostedToDate = Money.zero(this.currency);
@@ -634,15 +637,15 @@ public class RecurringDepositAccount extends SavingsAccount {
}
@Override
- public void postInterest(final MathContext mc, final LocalDate postingDate) {
+ public void postInterest(final MathContext mc, final LocalDate postingDate,final boolean isInterestTransfer) {
final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
- super.postInterest(mc, interestPostingUpToDate);
+ super.postInterest(mc, interestPostingUpToDate, isInterestTransfer);
}
@Override
- public List calculateInterestUsing(final MathContext mc, final LocalDate postingDate) {
+ public List calculateInterestUsing(final MathContext mc, final LocalDate postingDate, boolean isInterestTransfer) {
final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
- return super.calculateInterestUsing(mc, interestPostingUpToDate);
+ return super.calculateInterestUsing(mc, interestPostingUpToDate, isInterestTransfer);
}
private LocalDate interestPostingUpToDate(final LocalDate interestPostingDate) {
@@ -891,4 +894,8 @@ public class RecurringDepositAccount extends SavingsAccount {
this.activatedOnDate = now.toDate();
}
+ @Override
+ protected boolean isTransferInterestToOtherAccount() {
+ return this.accountTermAndPreClosure.isTransferInterestToLinkedAccount();
+ }
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccount.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccount.java
index 9c7dc3e14..906de0c8a 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccount.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccount.java
@@ -370,9 +370,9 @@ public class SavingsAccount extends AbstractPersistable {
return SavingsAccountStatusType.fromInt(this.status).isClosed();
}
- public void postInterest(final MathContext mc, final LocalDate interestPostingUpToDate) {
+ public void postInterest(final MathContext mc, final LocalDate interestPostingUpToDate, final boolean isInterestTransfer) {
- final List postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate);
+ final List postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate, isInterestTransfer);
Money interestPostedToDate = Money.zero(this.currency);
@@ -447,8 +447,9 @@ public class SavingsAccount extends AbstractPersistable {
* calculate the amount of interest due at the end of each 'crediting'
* period check if an existing 'interest posting' transaction exists for
* date and matches the amount posted
+ * @param isInterestTransfer TODO
*/
- public List calculateInterestUsing(final MathContext mc, final LocalDate upToInterestCalculationDate) {
+ public List calculateInterestUsing(final MathContext mc, final LocalDate upToInterestCalculationDate, boolean isInterestTransfer) {
// no openingBalance concept supported yet but probably will to allow
// for migrations.
@@ -480,18 +481,20 @@ public class SavingsAccount extends AbstractPersistable {
final SavingsInterestCalculationType interestCalculationType = SavingsInterestCalculationType.fromInt(this.interestCalculationType);
final BigDecimal interestRateAsFraction = getEffectiveInterestRateAsFraction(mc, upToInterestCalculationDate);
+ final Collection interestPostTransactions = this.savingsHelper.fetchPostInterestTransactionIds(getId());
for (final LocalDateInterval periodInterval : postingPeriodIntervals) {
final PostingPeriod postingPeriod = PostingPeriod.createFrom(periodInterval, periodStartingBalance,
retreiveOrderedNonInterestPostingTransactions(), this.currency, compoundingPeriodType, interestCalculationType,
- interestRateAsFraction, daysInYearType.getValue(), upToInterestCalculationDate);
+ interestRateAsFraction, daysInYearType.getValue(), upToInterestCalculationDate, interestPostTransactions, isInterestTransfer);
periodStartingBalance = postingPeriod.closingBalance();
allPostingPeriods.add(postingPeriod);
}
- this.savingsHelper.calculateInterestForAllPostingPeriods(this.currency, allPostingPeriods);
+ this.savingsHelper.calculateInterestForAllPostingPeriods(this.currency, allPostingPeriods, getLockedInUntilLocalDate(),
+ isTransferInterestToOtherAccount());
this.summary.updateFromInterestPeriodSummaries(this.currency, allPostingPeriods);
this.summary.updateSummary(this.currency, this.savingsAccountTransactionSummaryWrapper, this.transactions);
@@ -809,7 +812,7 @@ public class SavingsAccount extends AbstractPersistable {
return isLocked;
}
- private LocalDate getLockedInUntilLocalDate() {
+ protected LocalDate getLockedInUntilLocalDate() {
LocalDate lockedInUntilLocalDate = null;
if (this.lockedInUntilDate != null) {
lockedInUntilLocalDate = new LocalDate(this.lockedInUntilDate);
@@ -2036,4 +2039,8 @@ public class SavingsAccount extends AbstractPersistable {
public DepositAccountType depositAccountType() {
return DepositAccountType.fromInt(depositType);
}
+
+ protected boolean isTransferInterestToOtherAccount() {
+ return false;
+ }
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountAssembler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountAssembler.java
index ee48b48f4..a437cca99 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountAssembler.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountAssembler.java
@@ -34,6 +34,7 @@ import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.infrastructure.core.service.DateUtils;
import org.mifosplatform.organisation.staff.domain.Staff;
import org.mifosplatform.organisation.staff.domain.StaffRepositoryWrapper;
+import org.mifosplatform.portfolio.account.service.AccountTransfersReadPlatformService;
import org.mifosplatform.portfolio.accountdetails.domain.AccountType;
import org.mifosplatform.portfolio.client.domain.Client;
import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper;
@@ -59,7 +60,7 @@ import com.google.gson.JsonElement;
public class SavingsAccountAssembler {
private final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper;
- private final SavingsHelper savingsHelper = new SavingsHelper();
+ private final SavingsHelper savingsHelper;
private final ClientRepositoryWrapper clientRepository;
private final GroupRepositoryWrapper groupRepository;
private final StaffRepositoryWrapper staffRepository;
@@ -73,7 +74,8 @@ public class SavingsAccountAssembler {
final ClientRepositoryWrapper clientRepository, final GroupRepositoryWrapper groupRepository,
final StaffRepositoryWrapper staffRepository, final SavingsProductRepository savingProductRepository,
final SavingsAccountRepositoryWrapper savingsAccountRepository,
- final SavingsAccountChargeAssembler savingsAccountChargeAssembler, final FromJsonHelper fromApiJsonHelper) {
+ final SavingsAccountChargeAssembler savingsAccountChargeAssembler, final FromJsonHelper fromApiJsonHelper,
+ final AccountTransfersReadPlatformService accountTransfersReadPlatformService) {
this.savingsAccountTransactionSummaryWrapper = savingsAccountTransactionSummaryWrapper;
this.clientRepository = clientRepository;
this.groupRepository = groupRepository;
@@ -82,6 +84,7 @@ public class SavingsAccountAssembler {
this.savingsAccountRepository = savingsAccountRepository;
this.savingsAccountChargeAssembler = savingsAccountChargeAssembler;
this.fromApiJsonHelper = fromApiJsonHelper;
+ savingsHelper = new SavingsHelper(accountTransfersReadPlatformService);
}
/**
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountDomainService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountDomainService.java
index 30e0394ce..a16fad418 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountDomainService.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountDomainService.java
@@ -14,7 +14,7 @@ import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
public interface SavingsAccountDomainService {
SavingsAccountTransaction handleWithdrawal(SavingsAccount account, DateTimeFormatter fmt, LocalDate transactionDate,
- BigDecimal transactionAmount, PaymentDetail paymentDetail, boolean applyWithdrawFee);
+ BigDecimal transactionAmount, PaymentDetail paymentDetail, boolean applyWithdrawFee, boolean isInterestTransfer);
SavingsAccountTransaction handleDeposit(SavingsAccount account, DateTimeFormatter fmt, LocalDate transactionDate,
BigDecimal transactionAmount, PaymentDetail paymentDetail);
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountDomainServiceJpa.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountDomainServiceJpa.java
index ad39f6402..f3b7287c8 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountDomainServiceJpa.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountDomainServiceJpa.java
@@ -48,7 +48,7 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
@Override
public SavingsAccountTransaction handleWithdrawal(final SavingsAccount account, final DateTimeFormatter fmt,
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail,
- final boolean applyWithdrawFee) {
+ final boolean applyWithdrawFee, boolean isInterestTransfer) {
final Set existingTransactionIds = new HashSet();
final Set existingReversedTransactionIds = new HashSet();
@@ -60,10 +60,10 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
final MathContext mc = MathContext.DECIMAL64;
if (account.isBeforeLastPostingPeriod(transactionDate)) {
final LocalDate today = DateUtils.getLocalDateOfTenant();
- account.postInterest(mc, today);
+ account.postInterest(mc, today, isInterestTransfer);
} else {
final LocalDate today = DateUtils.getLocalDateOfTenant();
- account.calculateInterestUsing(mc, today);
+ account.calculateInterestUsing(mc, today, isInterestTransfer);
}
account.validateAccountBalanceDoesNotBecomeNegative(transactionAmount);
saveTransactionToGenerateTransactionId(withdrawal);
@@ -79,6 +79,7 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
public SavingsAccountTransaction handleDeposit(final SavingsAccount account, final DateTimeFormatter fmt,
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail) {
+ boolean isInterestTransfer = false;
final Set existingTransactionIds = new HashSet();
final Set existingReversedTransactionIds = new HashSet();
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
@@ -89,10 +90,10 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
final MathContext mc = MathContext.DECIMAL64;
if (account.isBeforeLastPostingPeriod(transactionDate)) {
final LocalDate today = DateUtils.getLocalDateOfTenant();
- account.postInterest(mc, today);
+ account.postInterest(mc, today, isInterestTransfer);
} else {
final LocalDate today = DateUtils.getLocalDateOfTenant();
- account.calculateInterestUsing(mc, today);
+ account.calculateInterestUsing(mc, today, isInterestTransfer);
}
saveTransactionToGenerateTransactionId(deposit);
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountTransaction.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountTransaction.java
index 9c4367bd4..ce0b09ae3 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountTransaction.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountTransaction.java
@@ -445,13 +445,15 @@ public final class SavingsAccountTransaction extends AbstractPersistable {
if (isDeposit()) {
// endOfDayBalance = openingBalance.plus(getAmount(currency));
// if (endOfDayBalance.isLessThanZero()) {
- endOfDayBalance = Money.of(currency, this.runningBalance);
+ endOfDayBalance = endOfDayBalance.plus(getAmount(currency));
// }
} else if (isWithdrawal() || isChargeTransactionAndNotReversed()) {
// endOfDayBalance = openingBalance.minus(getAmount(currency));
- // if (endOfDayBalance.isLessThanZero()) {
- endOfDayBalance = Money.of(currency, this.runningBalance);
- // }
+ if (endOfDayBalance.isGreaterThanZero()) {
+ endOfDayBalance = endOfDayBalance.minus(getAmount(currency));
+ } else {
+ endOfDayBalance = Money.of(currency, this.runningBalance);
+ }
}
}
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsHelper.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsHelper.java
index 15e14d8eb..656955661 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsHelper.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsHelper.java
@@ -1,6 +1,7 @@
package org.mifosplatform.portfolio.savings.domain;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import org.joda.time.DateTime;
@@ -8,12 +9,19 @@ import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.domain.LocalDateInterval;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money;
+import org.mifosplatform.portfolio.account.service.AccountTransfersReadPlatformService;
import org.mifosplatform.portfolio.savings.SavingsPostingInterestPeriodType;
import org.mifosplatform.portfolio.savings.domain.interest.CompoundInterestHelper;
import org.mifosplatform.portfolio.savings.domain.interest.PostingPeriod;
public final class SavingsHelper {
+ AccountTransfersReadPlatformService accountTransfersReadPlatformService = null;
+
+ public SavingsHelper(AccountTransfersReadPlatformService accountTransfersReadPlatformService) {
+ this.accountTransfersReadPlatformService = accountTransfersReadPlatformService;
+ }
+
private final CompoundInterestHelper compoundInterestHelper = new CompoundInterestHelper();
public List determineInterestPostingPeriods(final LocalDate activationLocalDate,
@@ -26,7 +34,8 @@ public final class SavingsHelper {
while (!periodStartDate.isAfter(interestPostingUpToDate) && !periodEndDate.isAfter(interestPostingUpToDate)) {
- final LocalDate interestPostingLocalDate = determineInterestPostingPeriodEndDateFrom(periodStartDate, postingPeriodType, interestPostingUpToDate);
+ final LocalDate interestPostingLocalDate = determineInterestPostingPeriodEndDateFrom(periodStartDate, postingPeriodType,
+ interestPostingUpToDate);
periodEndDate = interestPostingLocalDate.minusDays(1);
if (!interestPostingLocalDate.isAfter(interestPostingUpToDate)) {
@@ -61,7 +70,7 @@ public final class SavingsHelper {
final int monthofYear = periodStartDate.getMonthOfYear();
if (monthofYear <= 3) {
periodEndDate = new DateTime().withDate(year, 3, 31).toLocalDate();
- } else if (monthofYear <= 6) {
+ } else if (monthofYear <= 6) {
periodEndDate = new DateTime().withDate(year, 6, 30).toLocalDate();
} else if (monthofYear <= 9) {
periodEndDate = new DateTime().withDate(year, 9, 30).toLocalDate();
@@ -70,14 +79,14 @@ public final class SavingsHelper {
}
break;
case BIANNUAL:
- final int byear = periodStartDate.getYearOfEra();
- final int bmonthofYear = periodStartDate.getMonthOfYear();
+ final int byear = periodStartDate.getYearOfEra();
+ final int bmonthofYear = periodStartDate.getMonthOfYear();
if (bmonthofYear <= 6) {
periodEndDate = new DateTime().withDate(byear, 6, 30).toLocalDate();
} else if (bmonthofYear <= 12) {
periodEndDate = new DateTime().withDate(byear, 12, 31).toLocalDate();
}
- break;
+ break;
case ANNUAL:
periodEndDate = periodStartDate.monthOfYear().withMaximumValue();
periodEndDate = periodEndDate.dayOfMonth().withMaximumValue();
@@ -90,7 +99,13 @@ public final class SavingsHelper {
return periodEndDate;
}
- public Money calculateInterestForAllPostingPeriods(final MonetaryCurrency currency, final List allPeriods) {
- return this.compoundInterestHelper.calculateInterestForAllPostingPeriods(currency, allPeriods);
+ public Money calculateInterestForAllPostingPeriods(final MonetaryCurrency currency, final List allPeriods,
+ LocalDate accountLockedUntil, Boolean immediateWithdrawalOfInterest) {
+ return this.compoundInterestHelper.calculateInterestForAllPostingPeriods(currency, allPeriods, accountLockedUntil,
+ immediateWithdrawalOfInterest);
+ }
+
+ public Collection fetchPostInterestTransactionIds(Long accountId) {
+ return this.accountTransfersReadPlatformService.fetchPostInterestTransactionIds(accountId);
}
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/interest/CompoundInterestHelper.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/interest/CompoundInterestHelper.java
index 4bdd187dc..0ba75941b 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/interest/CompoundInterestHelper.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/interest/CompoundInterestHelper.java
@@ -3,12 +3,26 @@ package org.mifosplatform.portfolio.savings.domain.interest;
import java.math.BigDecimal;
import java.util.List;
+import org.joda.time.LocalDate;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money;
public class CompoundInterestHelper {
- public Money calculateInterestForAllPostingPeriods(final MonetaryCurrency currency, final List allPeriods) {
+ /**
+ * @param currency
+ * @param allPeriods
+ * @param lockUntil
+ * - account locked date used with the combination of
+ * immediateWithdrawalOfInterest to avoid exclusion of
+ * interestEarned
+ * @param interestTransferEnabled
+ * - boolean flag used to avoid addition of interest to next
+ * posting period as income while calculating interest
+ * @return
+ */
+ public Money calculateInterestForAllPostingPeriods(final MonetaryCurrency currency, final List allPeriods,
+ LocalDate lockUntil, Boolean interestTransferEnabled) {
// sum up the 'rounded' values that are posted each posting period
Money interestEarned = Money.zero(currency);
@@ -22,8 +36,14 @@ public class CompoundInterestHelper {
final Money moneyToBePostedForPeriod = Money.of(currency, interestEarnedThisPeriod);
interestEarned = interestEarned.plus(moneyToBePostedForPeriod);
-
- interestEarnedButNotPosted = interestEarnedButNotPosted.add(moneyToBePostedForPeriod.getAmount());
+ // these checks are for fixed deposit account for not include
+ // interest for accounts which has post interest to linked savings
+ // account and if already transfered then it includes in interest
+ // calculation.
+ if (postingPeriod.isInterestTransfered() || !interestTransferEnabled
+ || (lockUntil != null && !postingPeriod.dateOfPostingTransaction().isAfter(lockUntil))) {
+ interestEarnedButNotPosted = interestEarnedButNotPosted.add(moneyToBePostedForPeriod.getAmount());
+ }
}
return interestEarned;
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/interest/PostingPeriod.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/interest/PostingPeriod.java
index 06d948531..6a7c1e735 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/interest/PostingPeriod.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/interest/PostingPeriod.java
@@ -2,6 +2,7 @@ package org.mifosplatform.portfolio.savings.domain.interest;
import java.math.BigDecimal;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import org.joda.time.DateTime;
@@ -33,13 +34,18 @@ public class PostingPeriod {
private final Money closingBalance;
private final SavingsInterestCalculationType interestCalculationType;
+ // include in compounding interest
+ private boolean interestTransfered = false;
+
+ // isInterestTransfer boolean is to identify newly created transaction is interest transfer
public static PostingPeriod createFrom(final LocalDateInterval periodInterval, final Money periodStartingBalance,
final List orderedListOfTransactions, final MonetaryCurrency currency,
final SavingsCompoundingInterestPeriodType interestCompoundingPeriodType,
- final SavingsInterestCalculationType interestCalculationType, final BigDecimal interestRateAsFraction, final long daysInYear, final LocalDate upToInterestCalculationDate) {
+ final SavingsInterestCalculationType interestCalculationType, final BigDecimal interestRateAsFraction, final long daysInYear,
+ final LocalDate upToInterestCalculationDate, Collection interestPostTransactions, boolean isInterestTransfer) {
final List accountEndOfDayBalances = new ArrayList();
-
+ boolean interestTransfered = false;
Money openingDayBalance = periodStartingBalance;
Money closeOfDayBalance = openingDayBalance;
for (final SavingsAccountTransaction transaction : orderedListOfTransactions) {
@@ -51,6 +57,7 @@ public class PostingPeriod {
accountEndOfDayBalances.add(endOfDayBalance);
openingDayBalance = endOfDayBalance.closingBalance();
+
} else if (transaction.spansAnyPortionOf(periodInterval)) {
final EndOfDayBalance endOfDayBalance = transaction.toEndOfDayBalanceBoundedBy(openingDayBalance, periodInterval);
accountEndOfDayBalances.add(endOfDayBalance);
@@ -58,22 +65,32 @@ public class PostingPeriod {
closeOfDayBalance = endOfDayBalance.closingBalance();
openingDayBalance = closeOfDayBalance;
}
+
+ // this check is to make sure to add interest if withdrawal is happened for already
+ if (transaction.occursOn(periodInterval.endDate().plusDays(1))) {
+ if (transaction.getId() == null) {
+ interestTransfered = isInterestTransfer;
+ } else if (interestPostTransactions.contains(transaction.getId())) {
+ interestTransfered = true;
+ }
+ }
+
}
if (accountEndOfDayBalances.isEmpty()) {
LocalDate balanceStartDate = periodInterval.startDate();
LocalDate balanceEndDate = periodInterval.endDate();
Integer numberOfDaysOfBalance = periodInterval.daysInPeriodInclusiveOfEndDate();
-
+
if (balanceEndDate.isAfter(upToInterestCalculationDate)) {
balanceEndDate = upToInterestCalculationDate;
final LocalDateInterval spanOfBalance = LocalDateInterval.create(balanceStartDate, balanceEndDate);
numberOfDaysOfBalance = spanOfBalance.daysInPeriodInclusiveOfEndDate();
}
-
+
final EndOfDayBalance endOfDayBalance = EndOfDayBalance.from(balanceStartDate, openingDayBalance, closeOfDayBalance,
numberOfDaysOfBalance);
-
+
accountEndOfDayBalances.add(endOfDayBalance);
closeOfDayBalance = endOfDayBalance.closingBalance();
@@ -84,13 +101,13 @@ public class PostingPeriod {
accountEndOfDayBalances, upToInterestCalculationDate);
return new PostingPeriod(periodInterval, currency, periodStartingBalance, openingDayBalance, interestCompoundingPeriodType,
- interestCalculationType, interestRateAsFraction, daysInYear, compoundingPeriods);
+ interestCalculationType, interestRateAsFraction, daysInYear, compoundingPeriods, interestTransfered);
}
private PostingPeriod(final LocalDateInterval periodInterval, final MonetaryCurrency currency, final Money openingBalance,
final Money closingBalance, final SavingsCompoundingInterestPeriodType interestCompoundingType,
final SavingsInterestCalculationType interestCalculationType, final BigDecimal interestRateAsFraction, final long daysInYear,
- final List compoundingPeriods) {
+ final List compoundingPeriods, boolean interestTransfered) {
this.periodInterval = periodInterval;
this.currency = currency;
this.openingBalance = openingBalance;
@@ -102,6 +119,7 @@ public class PostingPeriod {
this.compoundingPeriods = compoundingPeriods;
this.dateOfPostingTransaction = periodInterval.endDate().plusDays(1);
+ this.interestTransfered = interestTransfered;
}
public Money interest() {
@@ -115,7 +133,7 @@ public class PostingPeriod {
public Money closingBalance() {
return this.closingBalance;
}
-
+
public Money openingBalance() {
return this.openingBalance;
}
@@ -145,7 +163,8 @@ public class PostingPeriod {
}
private static List compoundingPeriodsInPostingPeriod(final LocalDateInterval postingPeriodInterval,
- final SavingsCompoundingInterestPeriodType interestPeriodType, final List allEndOfDayBalances, final LocalDate upToInterestCalculationDate) {
+ final SavingsCompoundingInterestPeriodType interestPeriodType, final List allEndOfDayBalances,
+ final LocalDate upToInterestCalculationDate) {
final List compoundingPeriods = new ArrayList();
@@ -174,7 +193,8 @@ public class PostingPeriod {
final LocalDateInterval compoundingPeriodInterval = LocalDateInterval.create(periodStartDate, periodEndDate);
if (postingPeriodInterval.contains(compoundingPeriodInterval)) {
- compoundingPeriod = MonthlyCompoundingPeriod.create(compoundingPeriodInterval, allEndOfDayBalances, upToInterestCalculationDate);
+ compoundingPeriod = MonthlyCompoundingPeriod.create(compoundingPeriodInterval, allEndOfDayBalances,
+ upToInterestCalculationDate);
compoundingPeriods.add(compoundingPeriod);
}
@@ -182,11 +202,11 @@ public class PostingPeriod {
periodStartDate = periodEndDate.plusDays(1);
}
break;
- // case WEEKLY:
- // break;
- // case BIWEEKLY:
- // break;
- case QUATERLY:
+ // case WEEKLY:
+ // break;
+ // case BIWEEKLY:
+ // break;
+ case QUATERLY:
final LocalDate qPostingPeriodEndDate = postingPeriodInterval.endDate();
periodStartDate = postingPeriodInterval.startDate();
@@ -210,7 +230,7 @@ public class PostingPeriod {
// move periodStartDate forward to day after this period
periodStartDate = periodEndDate.plusDays(1);
}
- break;
+ break;
case BI_ANNUAL:
final LocalDate bPostingPeriodEndDate = postingPeriodInterval.endDate();
@@ -235,7 +255,7 @@ public class PostingPeriod {
// move periodStartDate forward to day after this period
periodStartDate = periodEndDate.plusDays(1);
}
- break;
+ break;
case ANNUAL:
final LocalDate aPostingPeriodEndDate = postingPeriodInterval.endDate();
@@ -260,9 +280,9 @@ public class PostingPeriod {
// move periodStartDate forward to day after this period
periodStartDate = periodEndDate.plusDays(1);
}
- break;
- // case NO_COMPOUNDING_SIMPLE_INTEREST:
- // break;
+ break;
+ // case NO_COMPOUNDING_SIMPLE_INTEREST:
+ // break;
}
return compoundingPeriods;
@@ -291,7 +311,7 @@ public class PostingPeriod {
// produce period end date on last day of current month
periodEndDate = periodStartDate.dayOfMonth().withMaximumValue();
break;
- case QUATERLY:
+ case QUATERLY:
// // jan 1st to mar 31st, 1st apr to jun 30, jul 1st to sept
// 30,
// // oct 1st to dec 31
@@ -306,7 +326,7 @@ public class PostingPeriod {
} else if (monthofYear <= 12) {
periodEndDate = new DateTime().withDate(year, 12, 31).toLocalDate();
}
- break;
+ break;
case BI_ANNUAL:
// // jan 1st to 30, jul 1st to dec 31
year = periodStartDate.getYearOfEra();
@@ -316,18 +336,22 @@ public class PostingPeriod {
} else if (monthofYear <= 12) {
periodEndDate = new DateTime().withDate(year, 12, 31).toLocalDate();
}
- break;
+ break;
case ANNUAL:
periodEndDate = periodStartDate.monthOfYear().withMaximumValue();
periodEndDate = periodEndDate.dayOfMonth().withMaximumValue();
- break;
+ break;
- // case NO_COMPOUNDING_SIMPLE_INTEREST:
- // periodEndDate = periodStartDate.monthOfYear().withMaximumValue();
- // periodEndDate = periodEndDate.dayOfMonth().withMaximumValue();
- // break;
+ // case NO_COMPOUNDING_SIMPLE_INTEREST:
+ // periodEndDate = periodStartDate.monthOfYear().withMaximumValue();
+ // periodEndDate = periodEndDate.dayOfMonth().withMaximumValue();
+ // break;
}
return periodEndDate;
}
+
+ public boolean isInterestTransfered() {
+ return this.interestTransfered;
+ }
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountReadPlatformService.java
index 27a0c409a..f95cde9fc 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountReadPlatformService.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountReadPlatformService.java
@@ -9,6 +9,7 @@ import java.util.Collection;
import org.mifosplatform.infrastructure.core.data.PaginationParameters;
import org.mifosplatform.infrastructure.core.service.Page;
+import org.mifosplatform.portfolio.account.data.AccountTransferDTO;
import org.mifosplatform.portfolio.savings.DepositAccountType;
import org.mifosplatform.portfolio.savings.data.DepositAccountData;
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionData;
@@ -34,4 +35,6 @@ public interface DepositAccountReadPlatformService {
Collection retrieveForMaturityUpdate();
SavingsAccountTransactionData retrieveRecurringAccountDepositTransactionTemplate(final Long accountId);
+
+ Collection retrieveDataForInterestTransfer();
}
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountReadPlatformServiceImpl.java
index c38583dcc..088be592e 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountReadPlatformServiceImpl.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountReadPlatformServiceImpl.java
@@ -26,7 +26,10 @@ import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext
import org.mifosplatform.organisation.monetary.data.CurrencyData;
import org.mifosplatform.organisation.staff.data.StaffData;
import org.mifosplatform.organisation.staff.service.StaffReadPlatformService;
+import org.mifosplatform.portfolio.account.PortfolioAccountType;
+import org.mifosplatform.portfolio.account.data.AccountTransferDTO;
import org.mifosplatform.portfolio.account.data.AccountTransferData;
+import org.mifosplatform.portfolio.account.domain.AccountTransferType;
import org.mifosplatform.portfolio.charge.data.ChargeData;
import org.mifosplatform.portfolio.charge.service.ChargeReadPlatformService;
import org.mifosplatform.portfolio.client.data.ClientData;
@@ -464,6 +467,22 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
}
}
+ @Override
+ public Collection retrieveDataForInterestTransfer() {
+ final StringBuilder sqlBuilder = new StringBuilder(300);
+ AccountTransferMapper mapper = new AccountTransferMapper();
+ sqlBuilder.append("SELECT ");
+ sqlBuilder.append(mapper.schema());
+ sqlBuilder.append(" where da.transfer_interest_to_linked_account = 1 and ");
+ sqlBuilder
+ .append("st.transaction_date > (select IFNULL(max(sat.transaction_date),sa.activatedon_date) from m_savings_account_transaction sat where sat.transaction_type_enum = ? and sat.savings_account_id = sa.id and sat.is_reversed=0) ");
+ sqlBuilder
+ .append("and st.transaction_type_enum = ? and sa.status_enum = ? and st.is_reversed=0 and st.transaction_date > IFNULL(sa.lockedin_until_date_derived,sa.activatedon_date)");
+
+ return this.jdbcTemplate.query(sqlBuilder.toString(), mapper, new Object[] { SavingsAccountTransactionType.WITHDRAWAL.getValue(),
+ SavingsAccountTransactionType.INTEREST_POSTING.getValue(), SavingsAccountStatusType.ACTIVE.getValue() });
+ }
+
private static abstract class DepositAccountMapper implements RowMapper {
private final String selectFieldsSql;
@@ -697,7 +716,8 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
sqlBuilder.append("datp.maturity_date as maturityDate, ");
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.on_account_closure_enum as onAccountClosureId, ");
+ sqlBuilder.append("datp.transfer_interest_to_linked_account as transferInterestToSavings ");
sqlBuilder.append(super.selectTablesSql());
@@ -750,12 +770,13 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
final Integer onAccountClosureId = JdbcSupport.getInteger(rs, "onAccountClosureId");
final EnumOptionData onAccountClosureType = (onAccountClosureId == null) ? null : SavingsEnumerations
.depositAccountOnClosureType(onAccountClosureId);
+ final Boolean transferInterestToSavings = rs.getBoolean("transferInterestToSavings");
return FixedDepositAccountData.instance(depositAccountData, interestFreePeriodApplicable, interestFreeFromPeriod,
interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest,
preClosurePenalInterestOnType, minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType,
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate, depositPeriod,
- depositPeriodFrequencyType, onAccountClosureType);
+ depositPeriodFrequencyType, onAccountClosureType, transferInterestToSavings);
}
}
@@ -1182,12 +1203,13 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
final Integer depositPeriod = null;
final EnumOptionData depositPeriodFrequencyType = null;
final EnumOptionData onAccountClosureType = null;
+ final Boolean transferInterestToSavings = false;
return FixedDepositAccountData.instance(depositAccountData, interestFreePeriodApplicable, interestFreeFromPeriod,
interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest,
preClosurePenalInterestOnType, minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType,
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate, depositPeriod,
- depositPeriodFrequencyType, onAccountClosureType);
+ depositPeriodFrequencyType, onAccountClosureType, transferInterestToSavings);
}
}
@@ -1375,4 +1397,36 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
DateUtils.getLocalDateOfTenant(), currency, recurringDepositAmount, runningBalance, false, transfer);
}
}
+
+ private class AccountTransferMapper implements RowMapper {
+
+ private final String schemaSql;
+
+ public AccountTransferMapper() {
+ final StringBuilder sqlBuilder = new StringBuilder(400);
+ sqlBuilder
+ .append("sa.id as fromAcc ,aa.linked_savings_account_id as toAcc,st.amount as amount, st.transaction_date as transactionDate ")
+ .append(" from m_deposit_account_term_and_preclosure da ")
+ .append(" inner join m_savings_account sa on da.savings_account_id = sa.id")
+ .append(" inner join m_savings_account_transaction st on st.savings_account_id = sa.id")
+ .append(" inner join m_portfolio_account_associations aa on aa.savings_account_id=sa.id");
+ schemaSql = sqlBuilder.toString();
+ }
+
+ public String schema() {
+ return this.schemaSql;
+ }
+
+ @Override
+ public AccountTransferDTO mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException {
+ final Long fromAccountId = rs.getLong("fromAcc");
+ final Long toAccountId = rs.getLong("toAcc");
+ final BigDecimal transactionAmount = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "amount");
+ final LocalDate transactionDate = JdbcSupport.getLocalDate(rs, "transactionDate");
+ return new AccountTransferDTO(transactionDate, transactionAmount, PortfolioAccountType.SAVINGS, PortfolioAccountType.SAVINGS,
+ fromAccountId, toAccountId, "trasfer interest to savings", null, null, null, null, null, null, null,
+ AccountTransferType.INTEREST_TRANSFER.getValue(), null, null, null, null, null);
+ }
+
+ }
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountWritePlatformService.java
index 764139b43..88e2aecaa 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountWritePlatformService.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountWritePlatformService.java
@@ -8,6 +8,7 @@ package org.mifosplatform.portfolio.savings.service;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
+import org.mifosplatform.infrastructure.jobs.exception.JobExecutionException;
import org.mifosplatform.organisation.office.domain.Office;
import org.mifosplatform.organisation.staff.domain.Staff;
import org.mifosplatform.portfolio.savings.DepositAccountType;
@@ -54,4 +55,6 @@ public interface DepositAccountWritePlatformService {
void applyChargeDue(final Long savingsAccountChargeId, final Long accountId, final DepositAccountType depositAccountType);
void updateMaturityDetails(final Long depositAccountId, final DepositAccountType depositAccountType);
+
+ void transferInterestToSavings() throws JobExecutionException;
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java
index 534be73c7..b239775ca 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java
@@ -14,6 +14,7 @@ import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
@@ -34,6 +35,9 @@ import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
import org.mifosplatform.infrastructure.core.exception.PlatformServiceUnavailableException;
import org.mifosplatform.infrastructure.core.service.DateUtils;
+import org.mifosplatform.infrastructure.jobs.annotation.CronTarget;
+import org.mifosplatform.infrastructure.jobs.exception.JobExecutionException;
+import org.mifosplatform.infrastructure.jobs.service.JobName;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.holiday.service.HolidayWritePlatformService;
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
@@ -78,6 +82,7 @@ import org.mifosplatform.portfolio.savings.domain.SavingsAccountStatusType;
import org.mifosplatform.portfolio.savings.domain.SavingsAccountTransaction;
import org.mifosplatform.portfolio.savings.domain.SavingsAccountTransactionRepository;
import org.mifosplatform.portfolio.savings.exception.DepositAccountTransactionNotAllowedException;
+import org.mifosplatform.portfolio.savings.exception.InsufficientAccountBalanceException;
import org.mifosplatform.portfolio.savings.exception.SavingsAccountTransactionNotFoundException;
import org.mifosplatform.portfolio.savings.exception.TransactionUpdateNotAllowedException;
import org.mifosplatform.useradministration.domain.AppUser;
@@ -106,6 +111,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
private final WorkingDaysWritePlatformService workingDaysWritePlatformService;
private final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService;
private final AccountTransfersWritePlatformService accountTransfersWritePlatformService;
+ private final DepositAccountReadPlatformService depositAccountReadPlatformService;
@Autowired
public DepositAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
@@ -123,7 +129,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
final HolidayWritePlatformService holidayWritePlatformService,
final WorkingDaysWritePlatformService workingDaysWritePlatformService,
final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService,
- final AccountTransfersWritePlatformService accountTransfersWritePlatformService) {
+ final AccountTransfersWritePlatformService accountTransfersWritePlatformService,
+ final DepositAccountReadPlatformService depositAccountReadPlatformService) {
this.context = context;
this.savingAccountRepository = savingAccountRepository;
this.savingsAccountTransactionRepository = savingsAccountTransactionRepository;
@@ -142,6 +149,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
this.workingDaysWritePlatformService = workingDaysWritePlatformService;
this.accountAssociationsReadPlatformService = accountAssociationsReadPlatformService;
this.accountTransfersWritePlatformService = accountTransfersWritePlatformService;
+ this.depositAccountReadPlatformService = depositAccountReadPlatformService;
}
@Transactional
@@ -282,8 +290,9 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
final LocalDate today = DateUtils.getLocalDateOfTenant();
final MathContext mc = new MathContext(15, RoundingMode.HALF_EVEN);
+ boolean isInterestTransfer = false;
- account.calculateInterestUsing(mc, today);
+ account.calculateInterestUsing(mc, today, isInterestTransfer);
this.savingAccountRepository.save(account);
@@ -319,13 +328,33 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
final LocalDate today = DateUtils.getLocalDateOfTenant();
final MathContext mc = new MathContext(10, RoundingMode.HALF_EVEN);
-
- account.postInterest(mc, today);
+ boolean isInterestTransfer = false;
+ account.postInterest(mc, today, isInterestTransfer);
this.savingAccountRepository.save(account);
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
}
+ @Override
+ @CronTarget(jobName = JobName.TRANSFER_INTEREST_TO_SAVINGS)
+ public void transferInterestToSavings() throws JobExecutionException {
+ Collection accountTrasferData = this.depositAccountReadPlatformService.retrieveDataForInterestTransfer();
+ StringBuilder sb = new StringBuilder(200);
+ for (AccountTransferDTO accountTransferDTO : accountTrasferData) {
+ try {
+ this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
+ } catch (final PlatformApiDataValidationException e) {
+ sb.append("Validation exception while trasfering Interest form ").append(accountTransferDTO.getFromAccountId())
+ .append(" to ").append(accountTransferDTO.getToAccountId()).append("--------");
+ } catch (final InsufficientAccountBalanceException e) {
+ sb.append("InsufficientAccountBalance Exception while trasfering Interest form ")
+ .append(accountTransferDTO.getFromAccountId()).append(" to ").append(accountTransferDTO.getToAccountId())
+ .append("--------");
+ }
+ }
+ if (sb.length() > 0) { throw new JobExecutionException(sb.toString()); }
+ }
+
@Override
public CommandProcessingResult undoTransaction(final Long savingsId, final Long transactionId,
final boolean allowAccountTransferModification, final DepositAccountType depositAccountType) {
@@ -354,13 +383,13 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
throwValidationForActiveStatus(SavingsApiConstants.undoTransactionAction);
}
account.undoTransaction(transactionId);
-
+ boolean isInterestTransfer = false;
checkClientOrGroupActive(account);
if (savingsAccountTransaction.isPostInterestCalculationRequired()
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
- account.postInterest(mc, today);
+ account.postInterest(mc, today, isInterestTransfer);
} else {
- account.calculateInterestUsing(mc, today);
+ account.calculateInterestUsing(mc, today, isInterestTransfer);
}
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.undoTransactionAction);
account.activateAccountBasedOnBalance();
@@ -425,12 +454,12 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
transaction = account.withdraw(transactionDTO, true);
}
final Long newtransactionId = saveTransactionToGenerateTransactionId(transaction);
-
+ boolean isInterestTransfer = false;
if (account.isBeforeLastPostingPeriod(transactionDate)
|| account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
- account.postInterest(mc, today);
+ account.postInterest(mc, today, isInterestTransfer);
} else {
- account.calculateInterestUsing(mc, today);
+ account.calculateInterestUsing(mc, today, isInterestTransfer);
}
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.adjustTransactionAction);
account.activateAccountBasedOnBalance();
@@ -548,7 +577,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
savingsAccount.getTransactions().add(newTransferTransaction);
savingsAccount.setStatus(SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getValue());
final MathContext mc = MathContext.DECIMAL64;
- savingsAccount.calculateInterestUsing(mc, transferDate);
+ boolean isInterestTransfer = false;
+ savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer);
this.savingsAccountTransactionRepository.save(newTransferTransaction);
this.savingAccountRepository.save(savingsAccount);
@@ -572,7 +602,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
savingsAccount.getTransactions().add(withdrawtransferTransaction);
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
final MathContext mc = MathContext.DECIMAL64;
- savingsAccount.calculateInterestUsing(mc, transferDate);
+ boolean isInterestTransfer = false;
+ savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer);
this.savingsAccountTransactionRepository.save(withdrawtransferTransaction);
this.savingAccountRepository.save(savingsAccount);
@@ -605,9 +636,9 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
if (fieldOfficer != null) {
savingsAccount.update(fieldOfficer);
}
-
+ boolean isInterestTransfer = false;
final MathContext mc = MathContext.DECIMAL64;
- savingsAccount.calculateInterestUsing(mc, transferDate);
+ savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer);
this.savingsAccountTransactionRepository.save(acceptTransferTransaction);
this.savingAccountRepository.save(savingsAccount);
@@ -745,14 +776,14 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
account.waiveCharge(savingsAccountChargeId);
-
+ boolean isInterestTransfer = false;
final MathContext mc = MathContext.DECIMAL64;
if (account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueLocalDate())) {
final LocalDate today = DateUtils.getLocalDateOfTenant();
- account.postInterest(mc, today);
+ account.postInterest(mc, today, isInterestTransfer);
} else {
final LocalDate today = DateUtils.getLocalDateOfTenant();
- account.calculateInterestUsing(mc, today);
+ account.calculateInterestUsing(mc, today, isInterestTransfer);
}
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.waiveChargeTransactionAction);
@@ -863,14 +894,14 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
final Set existingReversedTransactionIds = new HashSet();
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
account.payCharge(savingsAccountCharge, amountPaid, transactionDate, formatter);
-
+ boolean isInterestTransfer = false;
final MathContext mc = MathContext.DECIMAL64;
if (account.isBeforeLastPostingPeriod(transactionDate)) {
final LocalDate today = DateUtils.getLocalDateOfTenant();
- account.postInterest(mc, today);
+ account.postInterest(mc, today, isInterestTransfer);
} else {
final LocalDate today = DateUtils.getLocalDateOfTenant();
- account.calculateInterestUsing(mc, today);
+ account.calculateInterestUsing(mc, today, isInterestTransfer);
}
account.validateAccountBalanceDoesNotBecomeNegative("." + SavingsAccountTransactionType.PAY_CHARGE.getCode());
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl.java
index 022ff2cfa..ba51f3528 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl.java
@@ -5,6 +5,9 @@
*/
package org.mifosplatform.portfolio.savings.service;
+import static org.mifosplatform.portfolio.savings.DepositsApiConstants.linkedAccountParamName;
+import static org.mifosplatform.portfolio.savings.DepositsApiConstants.transferInterestToSavingsParamName;
+
import java.math.MathContext;
import java.util.ArrayList;
import java.util.LinkedHashMap;
@@ -272,13 +275,15 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
if (depositAccountType.isFixedDeposit()) {
((FixedDepositAccount) account).updateMaturityDateAndAmountBeforeAccountActivation(mc);
} else if (depositAccountType.isRecurringDeposit()) {
- final LocalDate transactionStartDate = ((RecurringDepositAccount) account).depositStartDate();
+ final LocalDate transactionStartDate = ((RecurringDepositAccount) account).depositStartDate();
((RecurringDepositAccount) account).updateMaturityDateAndAmount(mc, transactionStartDate);
}
this.savingAccountRepository.saveAndFlush(account);
}
+ boolean isLinkedAccRequired = command.booleanPrimitiveValueOfParameterNamed(transferInterestToSavingsParamName);
+
// Save linked account information
final Long savingsAccountId = command.longValueOfParameterNamed(DepositsApiConstants.linkedAccountParamName);
AccountAssociations accountAssociations = this.accountAssociationsRepository.findBySavingsId(accountId);
@@ -287,7 +292,12 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
if (this.fromJsonHelper.parameterExists(DepositsApiConstants.linkedAccountParamName, command.parsedJson())) {
this.accountAssociationsRepository.delete(accountAssociations);
changes.put(DepositsApiConstants.linkedAccountParamName, null);
+ if (isLinkedAccRequired) {
+ this.depositAccountDataValidator.throwLinkedAccountRequiredError();
+ }
}
+ } else if (isLinkedAccRequired) {
+ this.depositAccountDataValidator.throwLinkedAccountRequiredError();
}
} else {
boolean isModified = false;
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java
index d2787bba4..fcaa554cc 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java
@@ -234,9 +234,10 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
checkClientOrGroupActive(account);
+ boolean isInterestTransfer = false;
final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(account, fmt, transactionDate,
- transactionAmount, paymentDetail, true);
+ transactionAmount, paymentDetail, true, isInterestTransfer);
return new CommandProcessingResultBuilder() //
.withEntityId(withdrawal.getId()) //
@@ -277,8 +278,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final LocalDate today = DateUtils.getLocalDateOfTenant();
final MathContext mc = new MathContext(15, RoundingMode.HALF_EVEN);
-
- account.calculateInterestUsing(mc, today);
+ boolean isInterestTransfer = false;
+ account.calculateInterestUsing(mc, today, isInterestTransfer);
this.savingAccountRepository.save(account);
@@ -315,8 +316,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
final LocalDate today = DateUtils.getLocalDateOfTenant();
final MathContext mc = new MathContext(10, RoundingMode.HALF_EVEN);
-
- account.postInterest(mc, today);
+ boolean isInterestTransfer = false;
+ account.postInterest(mc, today, isInterestTransfer);
// for generating transaction id's
List transactions = account.getTransactions();
@@ -378,13 +379,13 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
account.undoTransaction(transactionId + 1);
}
}
-
+ boolean isInterestTransfer = false;
checkClientOrGroupActive(account);
if (savingsAccountTransaction.isPostInterestCalculationRequired()
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
- account.postInterest(mc, today);
+ account.postInterest(mc, today, isInterestTransfer);
} else {
- account.calculateInterestUsing(mc, today);
+ account.calculateInterestUsing(mc, today, isInterestTransfer);
}
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.undoTransactionAction);
account.activateAccountBasedOnBalance();
@@ -443,6 +444,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
}
SavingsAccountTransaction transaction = null;
+ boolean isInterestTransfer = false;
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
paymentDetail, savingsAccountTransaction.createdDate());
if (savingsAccountTransaction.isDeposit()) {
@@ -454,9 +456,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
if (account.isBeforeLastPostingPeriod(transactionDate)
|| account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
- account.postInterest(mc, today);
+ account.postInterest(mc, today, isInterestTransfer);
} else {
- account.calculateInterestUsing(mc, today);
+ account.calculateInterestUsing(mc, today, isInterestTransfer);
}
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.adjustTransactionAction);
account.activateAccountBasedOnBalance();
@@ -541,7 +543,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
savingsAccount.getTransactions().add(newTransferTransaction);
savingsAccount.setStatus(SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getValue());
final MathContext mc = MathContext.DECIMAL64;
- savingsAccount.calculateInterestUsing(mc, transferDate);
+ boolean isInterestTransfer = false;
+ savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer);
this.savingsAccountTransactionRepository.save(newTransferTransaction);
this.savingAccountRepository.save(savingsAccount);
@@ -564,7 +567,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
savingsAccount.getTransactions().add(withdrawtransferTransaction);
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
final MathContext mc = MathContext.DECIMAL64;
- savingsAccount.calculateInterestUsing(mc, transferDate);
+ boolean isInterestTransfer = false;
+ savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer);
this.savingsAccountTransactionRepository.save(withdrawtransferTransaction);
this.savingAccountRepository.save(savingsAccount);
@@ -597,9 +601,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
if (fieldOfficer != null) {
savingsAccount.update(fieldOfficer);
}
-
+ boolean isInterestTransfer = false;
final MathContext mc = MathContext.DECIMAL64;
- savingsAccount.calculateInterestUsing(mc, transferDate);
+ savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer);
this.savingsAccountTransactionRepository.save(acceptTransferTransaction);
this.savingAccountRepository.save(savingsAccount);
@@ -736,14 +740,14 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
account.waiveCharge(savingsAccountChargeId);
-
+ boolean isInterestTransfer = false;
final MathContext mc = MathContext.DECIMAL64;
if (account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueLocalDate())) {
final LocalDate today = DateUtils.getLocalDateOfTenant();
- account.postInterest(mc, today);
+ account.postInterest(mc, today, isInterestTransfer);
} else {
final LocalDate today = DateUtils.getLocalDateOfTenant();
- account.calculateInterestUsing(mc, today);
+ account.calculateInterestUsing(mc, today, isInterestTransfer);
}
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.waiveChargeTransactionAction);
@@ -852,14 +856,14 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final Set existingReversedTransactionIds = new HashSet();
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
account.payCharge(savingsAccountCharge, amountPaid, transactionDate, formatter);
-
+ boolean isInterestTransfer = false;
final MathContext mc = MathContext.DECIMAL64;
if (account.isBeforeLastPostingPeriod(transactionDate)) {
final LocalDate today = DateUtils.getLocalDateOfTenant();
- account.postInterest(mc, today);
+ account.postInterest(mc, today, isInterestTransfer);
} else {
final LocalDate today = DateUtils.getLocalDateOfTenant();
- account.calculateInterestUsing(mc, today);
+ account.calculateInterestUsing(mc, today, isInterestTransfer);
}
account.validateAccountBalanceDoesNotBecomeNegative("." + SavingsAccountTransactionType.PAY_CHARGE.getCode());