Merge branch 'develop' of git://github.com/pramodn02/mifosx into pramodn02-develop
This commit is contained in:
@@ -19297,7 +19297,7 @@ No Request Body:
|
|||||||
<br/>
|
<br/>
|
||||||
<table class=matrixHeading>
|
<table class=matrixHeading>
|
||||||
<tr class="matrixHeadingBG"><td><div class="mifosXHeading2">Optional Fields</div></td></tr>
|
<tr class="matrixHeadingBG"><td><div class="mifosXHeading2">Optional Fields</div></td></tr>
|
||||||
<tr class=alt><td>accountNo, externalId, fieldOfficerId,linkAccountId</td></tr>
|
<tr class=alt><td>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 )</td></tr>
|
||||||
</table>
|
</table>
|
||||||
<br/>
|
<br/>
|
||||||
<table class=matrixHeading>
|
<table class=matrixHeading>
|
||||||
|
|||||||
Executable
+9
@@ -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);
|
||||||
-3
@@ -506,9 +506,6 @@ public class FixedDepositTest {
|
|||||||
this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec);
|
this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec);
|
||||||
this.fixedDepositAccountHelper = new FixedDepositAccountHelper(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 dateFormat = new SimpleDateFormat("dd MMMM yyyy");
|
||||||
DateFormat monthDayFormat = new SimpleDateFormat("dd MMM");
|
DateFormat monthDayFormat = new SimpleDateFormat("dd MMM");
|
||||||
|
|
||||||
|
|||||||
+115
-1
@@ -1,6 +1,9 @@
|
|||||||
package org.mifosplatform.integrationtests;
|
package org.mifosplatform.integrationtests;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
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.JournalEntry;
|
||||||
import org.mifosplatform.integrationtests.common.accounting.JournalEntryHelper;
|
import org.mifosplatform.integrationtests.common.accounting.JournalEntryHelper;
|
||||||
import org.mifosplatform.integrationtests.common.charges.ChargesHelper;
|
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.LoanApplicationTestBuilder;
|
||||||
import org.mifosplatform.integrationtests.common.loans.LoanProductTestBuilder;
|
import org.mifosplatform.integrationtests.common.loans.LoanProductTestBuilder;
|
||||||
import org.mifosplatform.integrationtests.common.loans.LoanStatusChecker;
|
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",
|
Assert.assertEquals("Verifying From Penalty Charges due fot first Repayment after Successful completion of Scheduler Job",
|
||||||
chargeAmount, (Float) repaymentScheduleDataAfter.get(1).get("penaltyChargesDue"));
|
chargeAmount, (Float) repaymentScheduleDataAfter.get(1).get("penaltyChargesDue"));
|
||||||
|
|
||||||
loanStatusHashMap = this.loanTransactionHelper.undoDisbursal(loanID);
|
loanStatusHashMap = this.loanTransactionHelper.undoDisbursal(loanID);
|
||||||
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
|
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
|
||||||
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
|
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
|
||||||
@@ -708,6 +714,88 @@ public class SchedulerJobsTestResults {
|
|||||||
Assert.assertTrue(isNPAAfter);
|
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 {
|
private void excuteJob(String JobName) throws InterruptedException {
|
||||||
ArrayList<HashMap> allSchedulerJobsData = this.schedulerJobHelper.getAllSchedulerJobs(this.requestSpec, this.responseSpec);
|
ArrayList<HashMap> allSchedulerJobsData = this.schedulerJobHelper.getAllSchedulerJobs(this.requestSpec, this.responseSpec);
|
||||||
Assert.assertNotNull(allSchedulerJobsData);
|
Assert.assertNotNull(allSchedulerJobsData);
|
||||||
@@ -797,4 +885,30 @@ public class SchedulerJobsTestResults {
|
|||||||
.build(clientID, loanProductID, savingsID);
|
.build(clientID, loanProductID, savingsID);
|
||||||
return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-1
@@ -49,7 +49,7 @@ public class FixedDepositAccountHelper {
|
|||||||
private static final String DIGITS_AFTER_DECIMAL = "4";
|
private static final String DIGITS_AFTER_DECIMAL = "4";
|
||||||
private static final String IN_MULTIPLES_OF = "100";
|
private static final String IN_MULTIPLES_OF = "100";
|
||||||
private static final String USD = "USD";
|
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 WEEKS = "1";
|
||||||
private static final String MONTHS = "2";
|
private static final String MONTHS = "2";
|
||||||
private static final String YEARS = "3";
|
private static final String YEARS = "3";
|
||||||
@@ -83,6 +83,7 @@ public class FixedDepositAccountHelper {
|
|||||||
private final String depositPeriodFrequencyId = MONTHS;
|
private final String depositPeriodFrequencyId = MONTHS;
|
||||||
private String submittedOnDate = "";
|
private String submittedOnDate = "";
|
||||||
private String savingsId = null;
|
private String savingsId = null;
|
||||||
|
private boolean transferInterest = false;
|
||||||
|
|
||||||
public String build(final String clientId, final String productId, final String validFrom, final String validTo,
|
public String build(final String clientId, final String productId, final String validFrom, final String validTo,
|
||||||
final String penalInterestType) {
|
final String penalInterestType) {
|
||||||
@@ -162,6 +163,7 @@ public class FixedDepositAccountHelper {
|
|||||||
map.put("depositPeriodFrequencyId", this.depositPeriodFrequencyId);
|
map.put("depositPeriodFrequencyId", this.depositPeriodFrequencyId);
|
||||||
map.put("submittedOnDate", this.submittedOnDate);
|
map.put("submittedOnDate", this.submittedOnDate);
|
||||||
map.put("linkAccountId", savingsId);
|
map.put("linkAccountId", savingsId);
|
||||||
|
map.put("transferInterestToSavings", transferInterest);
|
||||||
|
|
||||||
String fixedDepositAccountJson = new Gson().toJson(map);
|
String fixedDepositAccountJson = new Gson().toJson(map);
|
||||||
System.out.println(fixedDepositAccountJson);
|
System.out.println(fixedDepositAccountJson);
|
||||||
@@ -432,4 +434,15 @@ public class FixedDepositAccountHelper {
|
|||||||
this.savingsId = savingsId;
|
this.savingsId = savingsId;
|
||||||
return this;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+2
-1
@@ -15,7 +15,8 @@ public enum JobName {
|
|||||||
EXECUTE_STANDING_INSTRUCTIONS("Execute Standing Instruction"),
|
EXECUTE_STANDING_INSTRUCTIONS("Execute Standing Instruction"),
|
||||||
ADD_ACCRUAL_ENTRIES("Add Accrual Transactions"),
|
ADD_ACCRUAL_ENTRIES("Add Accrual Transactions"),
|
||||||
UPDATE_NPA("Update Non Performing Assets"),
|
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;
|
private final String name;
|
||||||
|
|
||||||
|
|||||||
+9
-1
@@ -13,7 +13,8 @@ public enum AccountTransferType {
|
|||||||
INVALID(0, "accountTransferType.invalid"), //
|
INVALID(0, "accountTransferType.invalid"), //
|
||||||
ACCOUNT_TRANSFER(1, "accountTransferType.account.transfer"), //
|
ACCOUNT_TRANSFER(1, "accountTransferType.account.transfer"), //
|
||||||
LOAN_REPAYMENT(2, "accountTransferType.loan.repayment"), //
|
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 Integer value;
|
||||||
private final String code;
|
private final String code;
|
||||||
@@ -31,6 +32,9 @@ public enum AccountTransferType {
|
|||||||
case 3:
|
case 3:
|
||||||
enumeration = AccountTransferType.CHARGE_PAYMENT;
|
enumeration = AccountTransferType.CHARGE_PAYMENT;
|
||||||
break;
|
break;
|
||||||
|
case 4:
|
||||||
|
enumeration = AccountTransferType.INTEREST_TRANSFER;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return enumeration;
|
return enumeration;
|
||||||
}
|
}
|
||||||
@@ -63,4 +67,8 @@ public enum AccountTransferType {
|
|||||||
public boolean isChargePayment() {
|
public boolean isChargePayment() {
|
||||||
return this.value.equals(AccountTransferType.CHARGE_PAYMENT.getValue());
|
return this.value.equals(AccountTransferType.CHARGE_PAYMENT.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isInterestTransfer() {
|
||||||
|
return this.value.equals(AccountTransferType.INTEREST_TRANSFER.getValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+4
@@ -5,6 +5,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.portfolio.account.service;
|
package org.mifosplatform.portfolio.account.service;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.mifosplatform.infrastructure.core.service.Page;
|
import org.mifosplatform.infrastructure.core.service.Page;
|
||||||
import org.mifosplatform.portfolio.account.PortfolioAccountType;
|
import org.mifosplatform.portfolio.account.PortfolioAccountType;
|
||||||
import org.mifosplatform.portfolio.account.data.AccountTransferData;
|
import org.mifosplatform.portfolio.account.data.AccountTransferData;
|
||||||
@@ -22,4 +24,6 @@ public interface AccountTransfersReadPlatformService {
|
|||||||
boolean isAccountTransfer(Long transactionId, PortfolioAccountType accountType);
|
boolean isAccountTransfer(Long transactionId, PortfolioAccountType accountType);
|
||||||
|
|
||||||
Page<AccountTransferData> retrieveByStandingInstruction(Long id, SearchParameters searchParameters);
|
Page<AccountTransferData> retrieveByStandingInstruction(Long id, SearchParameters searchParameters);
|
||||||
|
|
||||||
|
Collection<Long> fetchPostInterestTransactionIds(Long accountId);
|
||||||
}
|
}
|
||||||
+15
-3
@@ -11,6 +11,7 @@ import java.sql.SQLException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
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.PortfolioAccountType;
|
||||||
import org.mifosplatform.portfolio.account.data.AccountTransferData;
|
import org.mifosplatform.portfolio.account.data.AccountTransferData;
|
||||||
import org.mifosplatform.portfolio.account.data.PortfolioAccountData;
|
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.account.exception.AccountTransferNotFoundException;
|
||||||
import org.mifosplatform.portfolio.client.data.ClientData;
|
import org.mifosplatform.portfolio.client.data.ClientData;
|
||||||
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
|
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
|
||||||
@@ -188,15 +190,15 @@ public class AccountTransfersReadPlatformServiceImpl implements AccountTransfers
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<AccountTransferData> retrieveAll(final SearchParameters searchParameters,final Long accountDetailId) {
|
public Page<AccountTransferData> retrieveAll(final SearchParameters searchParameters, final Long accountDetailId) {
|
||||||
|
|
||||||
final StringBuilder sqlBuilder = new StringBuilder(200);
|
final StringBuilder sqlBuilder = new StringBuilder(200);
|
||||||
sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
|
sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
|
||||||
sqlBuilder.append(this.accountTransfersMapper.schema());
|
sqlBuilder.append(this.accountTransfersMapper.schema());
|
||||||
Object[] finalObjectArray = {};
|
Object[] finalObjectArray = {};
|
||||||
if(accountDetailId != null){
|
if (accountDetailId != null) {
|
||||||
sqlBuilder.append(" where att.account_transfer_details_id=?");
|
sqlBuilder.append(" where att.account_transfer_details_id=?");
|
||||||
finalObjectArray = new Object[]{ accountDetailId };
|
finalObjectArray = new Object[] { accountDetailId };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (searchParameters.isOrderByRequested()) {
|
if (searchParameters.isOrderByRequested()) {
|
||||||
@@ -231,6 +233,16 @@ public class AccountTransfersReadPlatformServiceImpl implements AccountTransfers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Long> 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<Long> transactionId = this.jdbcTemplate.queryForList(sql, Long.class, accountId,
|
||||||
|
AccountTransferType.INTEREST_TRANSFER.getValue());
|
||||||
|
|
||||||
|
return transactionId;
|
||||||
|
}
|
||||||
|
|
||||||
private static final class AccountTransfersMapper implements RowMapper<AccountTransferData> {
|
private static final class AccountTransfersMapper implements RowMapper<AccountTransferData> {
|
||||||
|
|
||||||
private final String schemaSql;
|
private final String schemaSql;
|
||||||
|
|||||||
+9
-4
@@ -98,13 +98,15 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
|
|||||||
final PaymentDetail paymentDetail = null;
|
final PaymentDetail paymentDetail = null;
|
||||||
Long fromSavingsAccountId = null;
|
Long fromSavingsAccountId = null;
|
||||||
Long transferDetailId = null;
|
Long transferDetailId = null;
|
||||||
|
boolean isInterestTransfer = false;
|
||||||
if (isSavingsToSavingsAccountTransfer(fromAccountType, toAccountType)) {
|
if (isSavingsToSavingsAccountTransfer(fromAccountType, toAccountType)) {
|
||||||
|
|
||||||
fromSavingsAccountId = command.longValueOfParameterNamed(fromAccountIdParamName);
|
fromSavingsAccountId = command.longValueOfParameterNamed(fromAccountIdParamName);
|
||||||
final SavingsAccount fromSavingsAccount = this.savingsAccountAssembler.assembleFrom(fromSavingsAccountId);
|
final SavingsAccount fromSavingsAccount = this.savingsAccountAssembler.assembleFrom(fromSavingsAccountId);
|
||||||
|
|
||||||
final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(fromSavingsAccount, fmt,
|
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 Long toSavingsId = command.longValueOfParameterNamed(toAccountIdParamName);
|
||||||
final SavingsAccount toSavingsAccount = this.savingsAccountAssembler.assembleFrom(toSavingsId);
|
final SavingsAccount toSavingsAccount = this.savingsAccountAssembler.assembleFrom(toSavingsId);
|
||||||
@@ -123,7 +125,8 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
|
|||||||
final SavingsAccount fromSavingsAccount = this.savingsAccountAssembler.assembleFrom(fromSavingsAccountId);
|
final SavingsAccount fromSavingsAccount = this.savingsAccountAssembler.assembleFrom(fromSavingsAccountId);
|
||||||
|
|
||||||
final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(fromSavingsAccount, fmt,
|
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 Long toLoanAccountId = command.longValueOfParameterNamed(toAccountIdParamName);
|
||||||
final Loan toLoanAccount = this.loanAccountAssembler.assembleFrom(toLoanAccountId);
|
final Loan toLoanAccount = this.loanAccountAssembler.assembleFrom(toLoanAccountId);
|
||||||
@@ -244,7 +247,8 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
|
|||||||
|
|
||||||
final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(fromSavingsAccount,
|
final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(fromSavingsAccount,
|
||||||
accountTransferDTO.getFmt(), accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(),
|
accountTransferDTO.getFmt(), accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(),
|
||||||
accountTransferDTO.getPaymentDetail(), fromSavingsAccount.isWithdrawalFeeApplicableForTransfer());
|
accountTransferDTO.getPaymentDetail(), fromSavingsAccount.isWithdrawalFeeApplicableForTransfer(), AccountTransferType
|
||||||
|
.fromInt(accountTransferDTO.getTransferType()).isInterestTransfer());
|
||||||
|
|
||||||
LoanTransaction loanTransaction = null;
|
LoanTransaction loanTransaction = null;
|
||||||
|
|
||||||
@@ -284,7 +288,8 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
|
|||||||
}
|
}
|
||||||
final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(fromSavingsAccount,
|
final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(fromSavingsAccount,
|
||||||
accountTransferDTO.getFmt(), accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(),
|
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,
|
final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(toSavingsAccount,
|
||||||
accountTransferDTO.getFmt(), accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(),
|
accountTransferDTO.getFmt(), accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(),
|
||||||
|
|||||||
+5
-4
@@ -179,6 +179,7 @@ public class DepositsApiConstants {
|
|||||||
public static final String preMatureCloseOnDateParamName = "preMatureCloseOnDate";
|
public static final String preMatureCloseOnDateParamName = "preMatureCloseOnDate";
|
||||||
|
|
||||||
public static final String linkedAccountParamName = "linkAccountId";
|
public static final String linkedAccountParamName = "linkAccountId";
|
||||||
|
public static final String transferInterestToSavingsParamName = "transferInterestToSavings";
|
||||||
|
|
||||||
// template
|
// template
|
||||||
public static final String chartTemplate = "chartTemplate";
|
public static final String chartTemplate = "chartTemplate";
|
||||||
@@ -216,13 +217,11 @@ public class DepositsApiConstants {
|
|||||||
|
|
||||||
private static final Set<String> DEPOSIT_TERM_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(minDepositTermParamName,
|
private static final Set<String> DEPOSIT_TERM_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(minDepositTermParamName,
|
||||||
maxDepositTermParamName, minDepositTermTypeIdParamName, maxDepositTermTypeIdParamName, inMultiplesOfDepositTermParamName,
|
maxDepositTermParamName, minDepositTermTypeIdParamName, maxDepositTermTypeIdParamName, inMultiplesOfDepositTermParamName,
|
||||||
inMultiplesOfDepositTermTypeIdParamName, depositAmountParamName,
|
inMultiplesOfDepositTermTypeIdParamName, depositAmountParamName, depositMinAmountParamName, depositMaxAmountParamName));
|
||||||
depositMinAmountParamName, depositMaxAmountParamName));
|
|
||||||
|
|
||||||
private static final Set<String> DEPOSIT_TERM_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(minDepositTermParamName,
|
private static final Set<String> DEPOSIT_TERM_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(minDepositTermParamName,
|
||||||
maxDepositTermParamName, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTermParamName,
|
maxDepositTermParamName, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTermParamName,
|
||||||
inMultiplesOfDepositTermType, depositAmountParamName,
|
inMultiplesOfDepositTermType, depositAmountParamName, depositMinAmountParamName, depositMaxAmountParamName));
|
||||||
depositMinAmountParamName, depositMaxAmountParamName));
|
|
||||||
|
|
||||||
private static final Set<String> RECURRING_DETAILS_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(
|
private static final Set<String> RECURRING_DETAILS_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(
|
||||||
recurringDepositAmountParamName, recurringDepositTypeIdParamName, recurringDepositFrequencyTypeIdParamName,
|
recurringDepositAmountParamName, recurringDepositTypeIdParamName, recurringDepositFrequencyTypeIdParamName,
|
||||||
@@ -298,6 +297,7 @@ public class DepositsApiConstants {
|
|||||||
fixedDepositRequestData.addAll(PRECLOSURE_REQUEST_DATA_PARAMETERS);
|
fixedDepositRequestData.addAll(PRECLOSURE_REQUEST_DATA_PARAMETERS);
|
||||||
fixedDepositRequestData.addAll(DEPOSIT_TERM_REQUEST_DATA_PARAMETERS);
|
fixedDepositRequestData.addAll(DEPOSIT_TERM_REQUEST_DATA_PARAMETERS);
|
||||||
fixedDepositRequestData.add(linkedAccountParamName);
|
fixedDepositRequestData.add(linkedAccountParamName);
|
||||||
|
fixedDepositRequestData.add(transferInterestToSavingsParamName);
|
||||||
return fixedDepositRequestData;
|
return fixedDepositRequestData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,6 +307,7 @@ public class DepositsApiConstants {
|
|||||||
fixedDepositResponseData.addAll(PRECLOSURE_RESPONSE_DATA_PARAMETERS);
|
fixedDepositResponseData.addAll(PRECLOSURE_RESPONSE_DATA_PARAMETERS);
|
||||||
fixedDepositResponseData.addAll(DEPOSIT_TERM_RESPONSE_DATA_PARAMETERS);
|
fixedDepositResponseData.addAll(DEPOSIT_TERM_RESPONSE_DATA_PARAMETERS);
|
||||||
fixedDepositResponseData.add(linkedAccountParamName);
|
fixedDepositResponseData.add(linkedAccountParamName);
|
||||||
|
fixedDepositResponseData.add(transferInterestToSavingsParamName);
|
||||||
return fixedDepositResponseData;
|
return fixedDepositResponseData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+29
-3
@@ -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.nominalAnnualInterestRateParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.productIdParamName;
|
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.productIdParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.submittedOnDateParamName;
|
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.submittedOnDateParamName;
|
||||||
|
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.transferInterestToSavingsParamName;
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
@@ -279,8 +280,15 @@ public class DepositAccountDataValidator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.fromApiJsonHelper.parameterExists(linkedAccountParamName, element)) {
|
boolean isLinkedAccRequired = false;
|
||||||
final Long linkAccountId = this.fromApiJsonHelper.extractLongNamed(linkedAccountParamName, element);
|
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();
|
baseDataValidator.reset().parameter(linkedAccountParamName).value(linkAccountId).ignoreIfNull().longGreaterThanZero();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -400,9 +408,18 @@ public class DepositAccountDataValidator {
|
|||||||
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).inMinMaxRange(0, 3);
|
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)) {
|
if (this.fromApiJsonHelper.parameterExists(linkedAccountParamName, element)) {
|
||||||
final Long linkAccountId = this.fromApiJsonHelper.extractLongNamed(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); }
|
"Validation errors exist.", dataValidationErrors); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void throwLinkedAccountRequiredError() {
|
||||||
|
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||||
|
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) {
|
private void validateSavingsCharges(final JsonElement element, final DataValidatorBuilder baseDataValidator) {
|
||||||
|
|
||||||
if (element.isJsonObject()) {
|
if (element.isJsonObject()) {
|
||||||
|
|||||||
+18
-9
@@ -49,6 +49,7 @@ public class FixedDepositAccountData extends DepositAccountData {
|
|||||||
private EnumOptionData onAccountClosure;
|
private EnumOptionData onAccountClosure;
|
||||||
|
|
||||||
private final PortfolioAccountData linkedAccount;
|
private final PortfolioAccountData linkedAccount;
|
||||||
|
private final Boolean transferInterestToSavings;
|
||||||
|
|
||||||
private Collection<EnumOptionData> interestFreePeriodTypeOptions;
|
private Collection<EnumOptionData> interestFreePeriodTypeOptions;
|
||||||
private Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions;
|
private Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions;
|
||||||
@@ -68,7 +69,7 @@ public class FixedDepositAccountData extends DepositAccountData {
|
|||||||
final EnumOptionData minDepositTermType, final EnumOptionData maxDepositTermType, final Integer inMultiplesOfDepositTerm,
|
final EnumOptionData minDepositTermType, final EnumOptionData maxDepositTermType, final Integer inMultiplesOfDepositTerm,
|
||||||
final EnumOptionData inMultiplesOfDepositTermType, final BigDecimal depositAmount, final BigDecimal maturityAmount,
|
final EnumOptionData inMultiplesOfDepositTermType, final BigDecimal depositAmount, final BigDecimal maturityAmount,
|
||||||
final LocalDate maturityDate, final Integer depositPeriod, final EnumOptionData depositPeriodFrequency,
|
final LocalDate maturityDate, final Integer depositPeriod, final EnumOptionData depositPeriodFrequency,
|
||||||
final EnumOptionData onAccountClosure) {
|
final EnumOptionData onAccountClosure, final Boolean transferInterestToSavings) {
|
||||||
|
|
||||||
final PortfolioAccountData linkedAccount = null;
|
final PortfolioAccountData linkedAccount = null;
|
||||||
final Collection<EnumOptionData> interestFreePeriodTypeOptions = null;
|
final Collection<EnumOptionData> interestFreePeriodTypeOptions = null;
|
||||||
@@ -101,7 +102,7 @@ public class FixedDepositAccountData extends DepositAccountData {
|
|||||||
maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate,
|
maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate,
|
||||||
depositPeriod, depositPeriodFrequency, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions,
|
depositPeriod, depositPeriodFrequency, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions,
|
||||||
depositPeriodFrequencyOptions, depositType, onAccountClosure, onAccountClosureOptions, paymentTypeOptions,
|
depositPeriodFrequencyOptions, depositType, onAccountClosure, onAccountClosureOptions, paymentTypeOptions,
|
||||||
savingsAccountDatas, linkedAccount);
|
savingsAccountDatas, linkedAccount, transferInterestToSavings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FixedDepositAccountData withInterestChart(final FixedDepositAccountData account,
|
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.inMultiplesOfDepositTerm, account.inMultiplesOfDepositTermType, account.depositAmount, account.maturityAmount,
|
||||||
account.maturityDate, account.depositPeriod, account.depositPeriodFrequency, account.depositTermTypeOptions,
|
account.maturityDate, account.depositPeriod, account.depositPeriodFrequency, account.depositTermTypeOptions,
|
||||||
account.inMultiplesOfDepositTermTypeOptions, account.depositTermTypeOptions, account.depositType, account.onAccountClosure,
|
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,
|
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,
|
account.maturityAmount, account.maturityDate, account.depositPeriod, account.depositPeriodFrequency,
|
||||||
template.depositTermTypeOptions, template.inMultiplesOfDepositTermTypeOptions, template.depositPeriodFrequencyOptions,
|
template.depositTermTypeOptions, template.inMultiplesOfDepositTermTypeOptions, template.depositPeriodFrequencyOptions,
|
||||||
account.depositType, account.onAccountClosure, account.onAccountClosureOptions, account.paymentTypeOptions,
|
account.depositType, account.onAccountClosure, account.onAccountClosureOptions, account.paymentTypeOptions,
|
||||||
template.savingsAccounts, linkedAccount);
|
template.savingsAccounts, linkedAccount, account.transferInterestToSavings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FixedDepositAccountData withTemplateOptions(final FixedDepositAccountData account,
|
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.inMultiplesOfDepositTerm, account.inMultiplesOfDepositTermType, account.depositAmount, account.maturityAmount,
|
||||||
account.maturityDate, account.depositPeriod, account.depositPeriodFrequency, depositTermTypeOptions,
|
account.maturityDate, account.depositPeriod, account.depositPeriodFrequency, depositTermTypeOptions,
|
||||||
inMultiplesOfDepositTermTypeOptions, depositPeriodFrequencyOptions, account.depositType, account.onAccountClosure,
|
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,
|
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 depositPeriodFrequency = null;
|
||||||
final EnumOptionData onAccountClosure = null;
|
final EnumOptionData onAccountClosure = null;
|
||||||
final PortfolioAccountData linkedAccount = null;
|
final PortfolioAccountData linkedAccount = null;
|
||||||
|
final Boolean transferInterestToSavings = null;
|
||||||
|
|
||||||
final Collection<EnumOptionData> interestFreePeriodTypeOptions = null;
|
final Collection<EnumOptionData> interestFreePeriodTypeOptions = null;
|
||||||
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
|
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
|
||||||
@@ -269,7 +273,8 @@ public class FixedDepositAccountData extends DepositAccountData {
|
|||||||
preClosurePenalInterestOnTypeOptions, minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType,
|
preClosurePenalInterestOnTypeOptions, minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType,
|
||||||
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate, depositPeriod,
|
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate, depositPeriod,
|
||||||
depositPeriodFrequency, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions, depositPeriodFrequencyOptions,
|
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,
|
public static FixedDepositAccountData preClosureDetails(final Long accountId, BigDecimal maturityAmount,
|
||||||
@@ -333,6 +338,7 @@ public class FixedDepositAccountData extends DepositAccountData {
|
|||||||
final Integer depositPeriod = null;
|
final Integer depositPeriod = null;
|
||||||
final EnumOptionData depositPeriodFrequency = null;
|
final EnumOptionData depositPeriodFrequency = null;
|
||||||
final EnumOptionData onAccountClosure = null;
|
final EnumOptionData onAccountClosure = null;
|
||||||
|
final Boolean transferInterestToSavings = null;
|
||||||
|
|
||||||
final Collection<EnumOptionData> interestFreePeriodTypeOptions = null;
|
final Collection<EnumOptionData> interestFreePeriodTypeOptions = null;
|
||||||
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
|
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
|
||||||
@@ -354,7 +360,8 @@ public class FixedDepositAccountData extends DepositAccountData {
|
|||||||
preClosurePenalInterestOnTypeOptions, minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType,
|
preClosurePenalInterestOnTypeOptions, minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType,
|
||||||
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate, depositPeriod,
|
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate, depositPeriod,
|
||||||
depositPeriodFrequency, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions, depositPeriodFrequencyOptions,
|
depositPeriodFrequency, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions, depositPeriodFrequencyOptions,
|
||||||
depositType, onAccountClosure, onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas, linkedAccount);
|
depositType, onAccountClosure, onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas, linkedAccount,
|
||||||
|
transferInterestToSavings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FixedDepositAccountData withClosureTemplateDetails(final FixedDepositAccountData account,
|
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.inMultiplesOfDepositTerm, account.inMultiplesOfDepositTermType, account.depositAmount, account.maturityAmount,
|
||||||
account.maturityDate, account.depositPeriod, account.depositPeriodFrequency, account.depositTermTypeOptions,
|
account.maturityDate, account.depositPeriod, account.depositPeriodFrequency, account.depositTermTypeOptions,
|
||||||
account.inMultiplesOfDepositTermTypeOptions, account.depositPeriodFrequencyOptions, account.depositType,
|
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,
|
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<EnumOptionData> depositPeriodFrequencyOptions, final EnumOptionData depositType,
|
final Collection<EnumOptionData> depositPeriodFrequencyOptions, final EnumOptionData depositType,
|
||||||
final EnumOptionData onAccountClosure, final Collection<EnumOptionData> onAccountClosureOptions,
|
final EnumOptionData onAccountClosure, final Collection<EnumOptionData> onAccountClosureOptions,
|
||||||
final Collection<CodeValueData> paymentTypeOptions, final Collection<SavingsAccountData> savingsAccountDatas,
|
final Collection<CodeValueData> paymentTypeOptions, final Collection<SavingsAccountData> savingsAccountDatas,
|
||||||
final PortfolioAccountData linkedAccount) {
|
final PortfolioAccountData linkedAccount, final Boolean transferInterestToSavings) {
|
||||||
|
|
||||||
super(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName, fieldofficerId,
|
super(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName, fieldofficerId,
|
||||||
fieldofficerName, status, timeline, currency, nominalAnnualInterestRate, interestPeriodType, interestPostingPeriodType,
|
fieldofficerName, status, timeline, currency, nominalAnnualInterestRate, interestPeriodType, interestPostingPeriodType,
|
||||||
@@ -442,6 +450,7 @@ public class FixedDepositAccountData extends DepositAccountData {
|
|||||||
this.depositPeriodFrequency = depositPeriodFrequency;
|
this.depositPeriodFrequency = depositPeriodFrequency;
|
||||||
this.onAccountClosure = onAccountClosure;
|
this.onAccountClosure = onAccountClosure;
|
||||||
this.linkedAccount = linkedAccount;
|
this.linkedAccount = linkedAccount;
|
||||||
|
this.transferInterestToSavings = transferInterestToSavings;
|
||||||
|
|
||||||
// template
|
// template
|
||||||
this.interestFreePeriodTypeOptions = interestFreePeriodTypeOptions;
|
this.interestFreePeriodTypeOptions = interestFreePeriodTypeOptions;
|
||||||
|
|||||||
+11
-4
@@ -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.depositAmountParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositPeriodFrequencyIdParamName;
|
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositPeriodFrequencyIdParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositPeriodParamName;
|
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.recurringDepositAmountParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyParamName;
|
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyTypeIdParamName;
|
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyTypeIdParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositTypeIdParamName;
|
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.accountNoParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.clientIdParamName;
|
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.clientIdParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.externalIdParamName;
|
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.infrastructure.core.service.DateUtils;
|
||||||
import org.mifosplatform.organisation.staff.domain.Staff;
|
import org.mifosplatform.organisation.staff.domain.Staff;
|
||||||
import org.mifosplatform.organisation.staff.domain.StaffRepositoryWrapper;
|
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.accountdetails.domain.AccountType;
|
||||||
import org.mifosplatform.portfolio.client.domain.Client;
|
import org.mifosplatform.portfolio.client.domain.Client;
|
||||||
import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper;
|
import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper;
|
||||||
@@ -71,7 +73,7 @@ import com.google.gson.JsonElement;
|
|||||||
public class DepositAccountAssembler {
|
public class DepositAccountAssembler {
|
||||||
|
|
||||||
private final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper;
|
private final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper;
|
||||||
private final SavingsHelper savingsHelper = new SavingsHelper();
|
private final SavingsHelper savingsHelper;
|
||||||
private final ClientRepositoryWrapper clientRepository;
|
private final ClientRepositoryWrapper clientRepository;
|
||||||
private final GroupRepositoryWrapper groupRepository;
|
private final GroupRepositoryWrapper groupRepository;
|
||||||
private final StaffRepositoryWrapper staffRepository;
|
private final StaffRepositoryWrapper staffRepository;
|
||||||
@@ -88,7 +90,9 @@ public class DepositAccountAssembler {
|
|||||||
final StaffRepositoryWrapper staffRepository, final FixedDepositProductRepository fixedDepositProductRepository,
|
final StaffRepositoryWrapper staffRepository, final FixedDepositProductRepository fixedDepositProductRepository,
|
||||||
final SavingsAccountRepositoryWrapper savingsAccountRepository,
|
final SavingsAccountRepositoryWrapper savingsAccountRepository,
|
||||||
final SavingsAccountChargeAssembler savingsAccountChargeAssembler, final FromJsonHelper fromApiJsonHelper,
|
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.savingsAccountTransactionSummaryWrapper = savingsAccountTransactionSummaryWrapper;
|
||||||
this.clientRepository = clientRepository;
|
this.clientRepository = clientRepository;
|
||||||
this.groupRepository = groupRepository;
|
this.groupRepository = groupRepository;
|
||||||
@@ -99,6 +103,7 @@ public class DepositAccountAssembler {
|
|||||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||||
this.depositProductAssembler = depositProductAssembler;
|
this.depositProductAssembler = depositProductAssembler;
|
||||||
this.recurringDepositProductRepository = recurringDepositProductRepository;
|
this.recurringDepositProductRepository = recurringDepositProductRepository;
|
||||||
|
this.savingsHelper = new SavingsHelper(accountTransfersReadPlatformService);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -314,6 +319,7 @@ public class DepositAccountAssembler {
|
|||||||
final SavingsPeriodFrequencyType depositPeriodFrequency = SavingsPeriodFrequencyType.fromInt(depositPeriodFrequencyId);
|
final SavingsPeriodFrequencyType depositPeriodFrequency = SavingsPeriodFrequencyType.fromInt(depositPeriodFrequencyId);
|
||||||
final SavingsAccount account = null;
|
final SavingsAccount account = null;
|
||||||
final LocalDate expectedFirstDepositOnDate = command.localDateValueOfParameterNamed(expectedFirstDepositOnDateParamName);
|
final LocalDate expectedFirstDepositOnDate = command.localDateValueOfParameterNamed(expectedFirstDepositOnDateParamName);
|
||||||
|
final Boolean trasferInterest = command.booleanPrimitiveValueOfParameterNamed(transferInterestToSavingsParamName);
|
||||||
|
|
||||||
// calculate maturity amount
|
// calculate maturity amount
|
||||||
final BigDecimal maturityAmount = null;// calculated and updated in
|
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 LocalDate maturityDate = null;// calculated and updated in account
|
||||||
final DepositAccountOnClosureType accountOnClosureType = null;
|
final DepositAccountOnClosureType accountOnClosureType = null;
|
||||||
return DepositAccountTermAndPreClosure.createNew(updatedProductPreClosure, updatedProductTerm, account, depositAmount,
|
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,
|
public DepositAccountRecurringDetail assembleAccountRecurringDetail(final JsonCommand command,
|
||||||
|
|||||||
+7
-7
@@ -82,14 +82,14 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
|||||||
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
||||||
paymentDetail, new Date());
|
paymentDetail, new Date());
|
||||||
final SavingsAccountTransaction withdrawal = account.withdraw(transactionDTO, applyWithdrawFee);
|
final SavingsAccountTransaction withdrawal = account.withdraw(transactionDTO, applyWithdrawFee);
|
||||||
|
boolean isInterestTransfer = false;
|
||||||
final MathContext mc = MathContext.DECIMAL64;
|
final MathContext mc = MathContext.DECIMAL64;
|
||||||
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
account.postInterest(mc, today);
|
account.postInterest(mc, today, isInterestTransfer);
|
||||||
} else {
|
} else {
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
account.calculateInterestUsing(mc, today);
|
account.calculateInterestUsing(mc, today, isInterestTransfer);
|
||||||
}
|
}
|
||||||
account.validateAccountBalanceDoesNotBecomeNegative(transactionAmount);
|
account.validateAccountBalanceDoesNotBecomeNegative(transactionAmount);
|
||||||
saveTransactionToGenerateTransactionId(withdrawal);
|
saveTransactionToGenerateTransactionId(withdrawal);
|
||||||
@@ -111,14 +111,14 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
|||||||
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
||||||
paymentDetail, new Date());
|
paymentDetail, new Date());
|
||||||
final SavingsAccountTransaction deposit = account.deposit(transactionDTO);
|
final SavingsAccountTransaction deposit = account.deposit(transactionDTO);
|
||||||
|
boolean isInterestTransfer = false;
|
||||||
final MathContext mc = MathContext.DECIMAL64;
|
final MathContext mc = MathContext.DECIMAL64;
|
||||||
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
account.postInterest(mc, today);
|
account.postInterest(mc, today, isInterestTransfer);
|
||||||
} else {
|
} else {
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
account.calculateInterestUsing(mc, today);
|
account.calculateInterestUsing(mc, today, isInterestTransfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
saveTransactionToGenerateTransactionId(deposit);
|
saveTransactionToGenerateTransactionId(deposit);
|
||||||
@@ -217,7 +217,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.savingsAccountRepository.save(account);
|
this.savingsAccountRepository.save(account);
|
||||||
|
|
||||||
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
|
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
|
||||||
return withdrawal;
|
return withdrawal;
|
||||||
|
|||||||
+24
-6
@@ -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.depositPeriodFrequencyIdParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositPeriodParamName;
|
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositPeriodParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.expectedFirstDepositOnDateParamName;
|
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.expectedFirstDepositOnDateParamName;
|
||||||
|
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.transferInterestToSavingsParamName;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@@ -75,6 +76,9 @@ public class DepositAccountTermAndPreClosure extends AbstractPersistable<Long> {
|
|||||||
@JoinColumn(name = "savings_account_id", nullable = false)
|
@JoinColumn(name = "savings_account_id", nullable = false)
|
||||||
private SavingsAccount account;
|
private SavingsAccount account;
|
||||||
|
|
||||||
|
@Column(name = "transfer_interest_to_linked_account", nullable = false)
|
||||||
|
private boolean transferInterestToLinkedAccount;
|
||||||
|
|
||||||
protected DepositAccountTermAndPreClosure() {
|
protected DepositAccountTermAndPreClosure() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
@@ -82,16 +86,16 @@ public class DepositAccountTermAndPreClosure extends AbstractPersistable<Long> {
|
|||||||
public static DepositAccountTermAndPreClosure createNew(DepositPreClosureDetail preClosureDetail, DepositTermDetail depositTermDetail,
|
public static DepositAccountTermAndPreClosure createNew(DepositPreClosureDetail preClosureDetail, DepositTermDetail depositTermDetail,
|
||||||
SavingsAccount account, BigDecimal depositAmount, BigDecimal maturityAmount, final LocalDate maturityDate,
|
SavingsAccount account, BigDecimal depositAmount, BigDecimal maturityAmount, final LocalDate maturityDate,
|
||||||
Integer depositPeriod, final SavingsPeriodFrequencyType depositPeriodFrequency, final LocalDate expectedFirstDepositOnDate,
|
Integer depositPeriod, final SavingsPeriodFrequencyType depositPeriodFrequency, final LocalDate expectedFirstDepositOnDate,
|
||||||
final DepositAccountOnClosureType accountOnClosureType) {
|
final DepositAccountOnClosureType accountOnClosureType, Boolean trasferInterest) {
|
||||||
|
|
||||||
return new DepositAccountTermAndPreClosure(preClosureDetail, depositTermDetail, account, depositAmount, maturityAmount,
|
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,
|
private DepositAccountTermAndPreClosure(DepositPreClosureDetail preClosureDetail, DepositTermDetail depositTermDetail,
|
||||||
SavingsAccount account, BigDecimal depositAmount, BigDecimal maturityAmount, final LocalDate maturityDate,
|
SavingsAccount account, BigDecimal depositAmount, BigDecimal maturityAmount, final LocalDate maturityDate,
|
||||||
Integer depositPeriod, final SavingsPeriodFrequencyType depositPeriodFrequency, final LocalDate expectedFirstDepositOnDate,
|
Integer depositPeriod, final SavingsPeriodFrequencyType depositPeriodFrequency, final LocalDate expectedFirstDepositOnDate,
|
||||||
final DepositAccountOnClosureType accountOnClosureType) {
|
final DepositAccountOnClosureType accountOnClosureType, Boolean transferInterest) {
|
||||||
this.depositAmount = depositAmount;
|
this.depositAmount = depositAmount;
|
||||||
this.maturityAmount = maturityAmount;
|
this.maturityAmount = maturityAmount;
|
||||||
this.maturityDate = (maturityDate == null) ? null : maturityDate.toDate();
|
this.maturityDate = (maturityDate == null) ? null : maturityDate.toDate();
|
||||||
@@ -102,6 +106,7 @@ public class DepositAccountTermAndPreClosure extends AbstractPersistable<Long> {
|
|||||||
this.account = account;
|
this.account = account;
|
||||||
this.expectedFirstDepositOnDate = expectedFirstDepositOnDate == null ? null : expectedFirstDepositOnDate.toDate();
|
this.expectedFirstDepositOnDate = expectedFirstDepositOnDate == null ? null : expectedFirstDepositOnDate.toDate();
|
||||||
this.onAccountClosureType = (accountOnClosureType == null) ? null : accountOnClosureType.getValue();
|
this.onAccountClosureType = (accountOnClosureType == null) ? null : accountOnClosureType.getValue();
|
||||||
|
this.transferInterestToLinkedAccount = transferInterest;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Object> update(final JsonCommand command, final DataValidatorBuilder baseDataValidator) {
|
public Map<String, Object> update(final JsonCommand command, final DataValidatorBuilder baseDataValidator) {
|
||||||
@@ -124,10 +129,10 @@ public class DepositAccountTermAndPreClosure extends AbstractPersistable<Long> {
|
|||||||
actualChanges.put(depositPeriodFrequencyIdParamName, SavingsEnumerations.depositTermFrequencyType(newValue));
|
actualChanges.put(depositPeriodFrequencyIdParamName, SavingsEnumerations.depositTermFrequencyType(newValue));
|
||||||
this.depositPeriodFrequency = newValue;
|
this.depositPeriodFrequency = newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
final String localeAsInput = command.locale();
|
final String localeAsInput = command.locale();
|
||||||
final String dateFormat = command.dateFormat();
|
final String dateFormat = command.dateFormat();
|
||||||
|
|
||||||
if (command.isChangeInLocalDateParameterNamed(expectedFirstDepositOnDateParamName, getExpectedFirstDepositOnDate())) {
|
if (command.isChangeInLocalDateParameterNamed(expectedFirstDepositOnDateParamName, getExpectedFirstDepositOnDate())) {
|
||||||
final LocalDate newValue = command.localDateValueOfParameterNamed(expectedFirstDepositOnDateParamName);
|
final LocalDate newValue = command.localDateValueOfParameterNamed(expectedFirstDepositOnDateParamName);
|
||||||
final String newValueAsString = command.stringValueOfParameterNamed(expectedFirstDepositOnDateParamName);
|
final String newValueAsString = command.stringValueOfParameterNamed(expectedFirstDepositOnDateParamName);
|
||||||
@@ -137,6 +142,12 @@ public class DepositAccountTermAndPreClosure extends AbstractPersistable<Long> {
|
|||||||
this.expectedFirstDepositOnDate = newValue.toDate();
|
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) {
|
if (this.preClosureDetail != null) {
|
||||||
actualChanges.putAll(this.preClosureDetail.update(command, baseDataValidator));
|
actualChanges.putAll(this.preClosureDetail.update(command, baseDataValidator));
|
||||||
}
|
}
|
||||||
@@ -262,13 +273,20 @@ public class DepositAccountTermAndPreClosure extends AbstractPersistable<Long> {
|
|||||||
final DepositPreClosureDetail preClosureDetail = this.preClosureDetail.copy();
|
final DepositPreClosureDetail preClosureDetail = this.preClosureDetail.copy();
|
||||||
final DepositTermDetail depositTermDetail = this.depositTermDetail.copy();
|
final DepositTermDetail depositTermDetail = this.depositTermDetail.copy();
|
||||||
final LocalDate expectedFirstDepositOnDate = null;
|
final LocalDate expectedFirstDepositOnDate = null;
|
||||||
|
final Boolean transferInterestToLinkedAccount = null;
|
||||||
|
|
||||||
final DepositAccountOnClosureType accountOnClosureType = null;
|
final DepositAccountOnClosureType accountOnClosureType = null;
|
||||||
return DepositAccountTermAndPreClosure.createNew(preClosureDetail, depositTermDetail, account, actualDepositAmount, maturityAmount,
|
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) {
|
public void updateExpectedFirstDepositDate(final LocalDate expectedFirstDepositOnDate) {
|
||||||
this.expectedFirstDepositOnDate = expectedFirstDepositOnDate.toDate();
|
this.expectedFirstDepositOnDate = expectedFirstDepositOnDate.toDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isTransferInterestToLinkedAccount() {
|
||||||
|
return this.transferInterestToLinkedAccount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+17
-8
@@ -13,6 +13,7 @@ import static org.mifosplatform.portfolio.savings.DepositsApiConstants.onAccount
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.MathContext;
|
import java.math.MathContext;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@@ -259,11 +260,13 @@ public class FixedDepositAccount extends SavingsAccount {
|
|||||||
|
|
||||||
final SavingsInterestCalculationType interestCalculationType = SavingsInterestCalculationType.fromInt(this.interestCalculationType);
|
final SavingsInterestCalculationType interestCalculationType = SavingsInterestCalculationType.fromInt(this.interestCalculationType);
|
||||||
final BigDecimal interestRateAsFraction = getEffectiveInterestRateAsFraction(mc, maturityDate);
|
final BigDecimal interestRateAsFraction = getEffectiveInterestRateAsFraction(mc, maturityDate);
|
||||||
|
final Collection<Long> interestPostTransactions = this.savingsHelper.fetchPostInterestTransactionIds(getId());
|
||||||
|
boolean isInterestTransfer = false;
|
||||||
for (final LocalDateInterval periodInterval : postingPeriodIntervals) {
|
for (final LocalDateInterval periodInterval : postingPeriodIntervals) {
|
||||||
|
|
||||||
final PostingPeriod postingPeriod = PostingPeriod.createFrom(periodInterval, periodStartingBalance, transactions,
|
final PostingPeriod postingPeriod = PostingPeriod.createFrom(periodInterval, periodStartingBalance, transactions,
|
||||||
this.currency, compoundingPeriodType, interestCalculationType, interestRateAsFraction, daysInYearType.getValue(),
|
this.currency, compoundingPeriodType, interestCalculationType, interestRateAsFraction, daysInYearType.getValue(),
|
||||||
maturityDate);
|
maturityDate, interestPostTransactions, isInterestTransfer);
|
||||||
|
|
||||||
periodStartingBalance = postingPeriod.closingBalance();
|
periodStartingBalance = postingPeriod.closingBalance();
|
||||||
|
|
||||||
@@ -271,7 +274,8 @@ public class FixedDepositAccount extends SavingsAccount {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.summary.updateFromInterestPeriodSummaries(this.currency, allPostingPeriods);
|
this.summary.updateFromInterestPeriodSummaries(this.currency, allPostingPeriods);
|
||||||
this.savingsHelper.calculateInterestForAllPostingPeriods(this.currency, allPostingPeriods);
|
this.savingsHelper.calculateInterestForAllPostingPeriods(this.currency, allPostingPeriods, this.getLockedInUntilLocalDate(),
|
||||||
|
isTransferInterestToOtherAccount());
|
||||||
return allPostingPeriods;
|
return allPostingPeriods;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -429,8 +433,8 @@ public class FixedDepositAccount extends SavingsAccount {
|
|||||||
public void postMaturityInterest(final LocalDate interestPostingUpToDate) {
|
public void postMaturityInterest(final LocalDate interestPostingUpToDate) {
|
||||||
|
|
||||||
final MathContext mc = MathContext.DECIMAL64;
|
final MathContext mc = MathContext.DECIMAL64;
|
||||||
|
final boolean isInterestTransfer = false;
|
||||||
final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate);
|
final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate, isInterestTransfer);
|
||||||
|
|
||||||
Money interestPostedToDate = Money.zero(this.currency);
|
Money interestPostedToDate = Money.zero(this.currency);
|
||||||
|
|
||||||
@@ -526,15 +530,15 @@ public class FixedDepositAccount extends SavingsAccount {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
|
||||||
super.postInterest(mc, interestPostingUpToDate);
|
super.postInterest(mc, interestPostingUpToDate, isInterestTransfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<PostingPeriod> calculateInterestUsing(final MathContext mc, final LocalDate postingDate) {
|
public List<PostingPeriod> calculateInterestUsing(final MathContext mc, final LocalDate postingDate, boolean isInterestTransfer) {
|
||||||
final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
|
final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
|
||||||
return super.calculateInterestUsing(mc, interestPostingUpToDate);
|
return super.calculateInterestUsing(mc, interestPostingUpToDate, isInterestTransfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private LocalDate interestPostingUpToDate(final LocalDate interestPostingDate) {
|
private LocalDate interestPostingUpToDate(final LocalDate interestPostingDate) {
|
||||||
@@ -680,4 +684,9 @@ public class FixedDepositAccount extends SavingsAccount {
|
|||||||
return reInvestedAccount;
|
return reInvestedAccount;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isTransferInterestToOtherAccount() {
|
||||||
|
return this.accountTermAndPreClosure.isTransferInterestToLinkedAccount();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+16
-9
@@ -13,6 +13,7 @@ import static org.mifosplatform.portfolio.savings.DepositsApiConstants.onAccount
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.MathContext;
|
import java.math.MathContext;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -281,18 +282,20 @@ public class RecurringDepositAccount extends SavingsAccount {
|
|||||||
|
|
||||||
final SavingsInterestCalculationType interestCalculationType = SavingsInterestCalculationType.fromInt(this.interestCalculationType);
|
final SavingsInterestCalculationType interestCalculationType = SavingsInterestCalculationType.fromInt(this.interestCalculationType);
|
||||||
final BigDecimal interestRateAsFraction = getEffectiveInterestRateAsFraction(mc, maturityDate);
|
final BigDecimal interestRateAsFraction = getEffectiveInterestRateAsFraction(mc, maturityDate);
|
||||||
|
final Collection<Long> interestPostTransactions = this.savingsHelper.fetchPostInterestTransactionIds(getId());
|
||||||
|
boolean isInterestTransfer = false;
|
||||||
for (final LocalDateInterval periodInterval : postingPeriodIntervals) {
|
for (final LocalDateInterval periodInterval : postingPeriodIntervals) {
|
||||||
final PostingPeriod postingPeriod = PostingPeriod.createFrom(periodInterval, periodStartingBalance, transactions,
|
final PostingPeriod postingPeriod = PostingPeriod.createFrom(periodInterval, periodStartingBalance, transactions,
|
||||||
this.currency, compoundingPeriodType, interestCalculationType, interestRateAsFraction, daysInYearType.getValue(),
|
this.currency, compoundingPeriodType, interestCalculationType, interestRateAsFraction, daysInYearType.getValue(),
|
||||||
maturityDate);
|
maturityDate, interestPostTransactions, isInterestTransfer);
|
||||||
|
|
||||||
periodStartingBalance = postingPeriod.closingBalance();
|
periodStartingBalance = postingPeriod.closingBalance();
|
||||||
|
|
||||||
allPostingPeriods.add(postingPeriod);
|
allPostingPeriods.add(postingPeriod);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.savingsHelper.calculateInterestForAllPostingPeriods(this.currency, allPostingPeriods);
|
this.savingsHelper.calculateInterestForAllPostingPeriods(this.currency, allPostingPeriods, this.getLockedInUntilLocalDate(),
|
||||||
|
isTransferInterestToOtherAccount());
|
||||||
// this.summary.updateFromInterestPeriodSummaries(this.currency,
|
// this.summary.updateFromInterestPeriodSummaries(this.currency,
|
||||||
// allPostingPeriods);
|
// allPostingPeriods);
|
||||||
return allPostingPeriods;
|
return allPostingPeriods;
|
||||||
@@ -538,8 +541,8 @@ public class RecurringDepositAccount extends SavingsAccount {
|
|||||||
public void postMaturityInterest(final LocalDate interestPostingUpToDate) {
|
public void postMaturityInterest(final LocalDate interestPostingUpToDate) {
|
||||||
|
|
||||||
final MathContext mc = MathContext.DECIMAL64;
|
final MathContext mc = MathContext.DECIMAL64;
|
||||||
|
boolean isInterestTransfer = false;
|
||||||
final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate);
|
final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate,isInterestTransfer);
|
||||||
|
|
||||||
Money interestPostedToDate = Money.zero(this.currency);
|
Money interestPostedToDate = Money.zero(this.currency);
|
||||||
|
|
||||||
@@ -634,15 +637,15 @@ public class RecurringDepositAccount extends SavingsAccount {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
|
||||||
super.postInterest(mc, interestPostingUpToDate);
|
super.postInterest(mc, interestPostingUpToDate, isInterestTransfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<PostingPeriod> calculateInterestUsing(final MathContext mc, final LocalDate postingDate) {
|
public List<PostingPeriod> calculateInterestUsing(final MathContext mc, final LocalDate postingDate, boolean isInterestTransfer) {
|
||||||
final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
|
final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
|
||||||
return super.calculateInterestUsing(mc, interestPostingUpToDate);
|
return super.calculateInterestUsing(mc, interestPostingUpToDate, isInterestTransfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private LocalDate interestPostingUpToDate(final LocalDate interestPostingDate) {
|
private LocalDate interestPostingUpToDate(final LocalDate interestPostingDate) {
|
||||||
@@ -891,4 +894,8 @@ public class RecurringDepositAccount extends SavingsAccount {
|
|||||||
this.activatedOnDate = now.toDate();
|
this.activatedOnDate = now.toDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isTransferInterestToOtherAccount() {
|
||||||
|
return this.accountTermAndPreClosure.isTransferInterestToLinkedAccount();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+13
-6
@@ -370,9 +370,9 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
return SavingsAccountStatusType.fromInt(this.status).isClosed();
|
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<PostingPeriod> postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate);
|
final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate, isInterestTransfer);
|
||||||
|
|
||||||
Money interestPostedToDate = Money.zero(this.currency);
|
Money interestPostedToDate = Money.zero(this.currency);
|
||||||
|
|
||||||
@@ -447,8 +447,9 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
* calculate the amount of interest due at the end of each 'crediting'
|
* calculate the amount of interest due at the end of each 'crediting'
|
||||||
* period check if an existing 'interest posting' transaction exists for
|
* period check if an existing 'interest posting' transaction exists for
|
||||||
* date and matches the amount posted
|
* date and matches the amount posted
|
||||||
|
* @param isInterestTransfer TODO
|
||||||
*/
|
*/
|
||||||
public List<PostingPeriod> calculateInterestUsing(final MathContext mc, final LocalDate upToInterestCalculationDate) {
|
public List<PostingPeriod> calculateInterestUsing(final MathContext mc, final LocalDate upToInterestCalculationDate, boolean isInterestTransfer) {
|
||||||
|
|
||||||
// no openingBalance concept supported yet but probably will to allow
|
// no openingBalance concept supported yet but probably will to allow
|
||||||
// for migrations.
|
// for migrations.
|
||||||
@@ -480,18 +481,20 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
|
|
||||||
final SavingsInterestCalculationType interestCalculationType = SavingsInterestCalculationType.fromInt(this.interestCalculationType);
|
final SavingsInterestCalculationType interestCalculationType = SavingsInterestCalculationType.fromInt(this.interestCalculationType);
|
||||||
final BigDecimal interestRateAsFraction = getEffectiveInterestRateAsFraction(mc, upToInterestCalculationDate);
|
final BigDecimal interestRateAsFraction = getEffectiveInterestRateAsFraction(mc, upToInterestCalculationDate);
|
||||||
|
final Collection<Long> interestPostTransactions = this.savingsHelper.fetchPostInterestTransactionIds(getId());
|
||||||
for (final LocalDateInterval periodInterval : postingPeriodIntervals) {
|
for (final LocalDateInterval periodInterval : postingPeriodIntervals) {
|
||||||
|
|
||||||
final PostingPeriod postingPeriod = PostingPeriod.createFrom(periodInterval, periodStartingBalance,
|
final PostingPeriod postingPeriod = PostingPeriod.createFrom(periodInterval, periodStartingBalance,
|
||||||
retreiveOrderedNonInterestPostingTransactions(), this.currency, compoundingPeriodType, interestCalculationType,
|
retreiveOrderedNonInterestPostingTransactions(), this.currency, compoundingPeriodType, interestCalculationType,
|
||||||
interestRateAsFraction, daysInYearType.getValue(), upToInterestCalculationDate);
|
interestRateAsFraction, daysInYearType.getValue(), upToInterestCalculationDate, interestPostTransactions, isInterestTransfer);
|
||||||
|
|
||||||
periodStartingBalance = postingPeriod.closingBalance();
|
periodStartingBalance = postingPeriod.closingBalance();
|
||||||
|
|
||||||
allPostingPeriods.add(postingPeriod);
|
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.updateFromInterestPeriodSummaries(this.currency, allPostingPeriods);
|
||||||
this.summary.updateSummary(this.currency, this.savingsAccountTransactionSummaryWrapper, this.transactions);
|
this.summary.updateSummary(this.currency, this.savingsAccountTransactionSummaryWrapper, this.transactions);
|
||||||
@@ -809,7 +812,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
return isLocked;
|
return isLocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
private LocalDate getLockedInUntilLocalDate() {
|
protected LocalDate getLockedInUntilLocalDate() {
|
||||||
LocalDate lockedInUntilLocalDate = null;
|
LocalDate lockedInUntilLocalDate = null;
|
||||||
if (this.lockedInUntilDate != null) {
|
if (this.lockedInUntilDate != null) {
|
||||||
lockedInUntilLocalDate = new LocalDate(this.lockedInUntilDate);
|
lockedInUntilLocalDate = new LocalDate(this.lockedInUntilDate);
|
||||||
@@ -2036,4 +2039,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
public DepositAccountType depositAccountType() {
|
public DepositAccountType depositAccountType() {
|
||||||
return DepositAccountType.fromInt(depositType);
|
return DepositAccountType.fromInt(depositType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean isTransferInterestToOtherAccount() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+5
-2
@@ -34,6 +34,7 @@ import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
|||||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||||
import org.mifosplatform.organisation.staff.domain.Staff;
|
import org.mifosplatform.organisation.staff.domain.Staff;
|
||||||
import org.mifosplatform.organisation.staff.domain.StaffRepositoryWrapper;
|
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.accountdetails.domain.AccountType;
|
||||||
import org.mifosplatform.portfolio.client.domain.Client;
|
import org.mifosplatform.portfolio.client.domain.Client;
|
||||||
import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper;
|
import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper;
|
||||||
@@ -59,7 +60,7 @@ import com.google.gson.JsonElement;
|
|||||||
public class SavingsAccountAssembler {
|
public class SavingsAccountAssembler {
|
||||||
|
|
||||||
private final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper;
|
private final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper;
|
||||||
private final SavingsHelper savingsHelper = new SavingsHelper();
|
private final SavingsHelper savingsHelper;
|
||||||
private final ClientRepositoryWrapper clientRepository;
|
private final ClientRepositoryWrapper clientRepository;
|
||||||
private final GroupRepositoryWrapper groupRepository;
|
private final GroupRepositoryWrapper groupRepository;
|
||||||
private final StaffRepositoryWrapper staffRepository;
|
private final StaffRepositoryWrapper staffRepository;
|
||||||
@@ -73,7 +74,8 @@ public class SavingsAccountAssembler {
|
|||||||
final ClientRepositoryWrapper clientRepository, final GroupRepositoryWrapper groupRepository,
|
final ClientRepositoryWrapper clientRepository, final GroupRepositoryWrapper groupRepository,
|
||||||
final StaffRepositoryWrapper staffRepository, final SavingsProductRepository savingProductRepository,
|
final StaffRepositoryWrapper staffRepository, final SavingsProductRepository savingProductRepository,
|
||||||
final SavingsAccountRepositoryWrapper savingsAccountRepository,
|
final SavingsAccountRepositoryWrapper savingsAccountRepository,
|
||||||
final SavingsAccountChargeAssembler savingsAccountChargeAssembler, final FromJsonHelper fromApiJsonHelper) {
|
final SavingsAccountChargeAssembler savingsAccountChargeAssembler, final FromJsonHelper fromApiJsonHelper,
|
||||||
|
final AccountTransfersReadPlatformService accountTransfersReadPlatformService) {
|
||||||
this.savingsAccountTransactionSummaryWrapper = savingsAccountTransactionSummaryWrapper;
|
this.savingsAccountTransactionSummaryWrapper = savingsAccountTransactionSummaryWrapper;
|
||||||
this.clientRepository = clientRepository;
|
this.clientRepository = clientRepository;
|
||||||
this.groupRepository = groupRepository;
|
this.groupRepository = groupRepository;
|
||||||
@@ -82,6 +84,7 @@ public class SavingsAccountAssembler {
|
|||||||
this.savingsAccountRepository = savingsAccountRepository;
|
this.savingsAccountRepository = savingsAccountRepository;
|
||||||
this.savingsAccountChargeAssembler = savingsAccountChargeAssembler;
|
this.savingsAccountChargeAssembler = savingsAccountChargeAssembler;
|
||||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||||
|
savingsHelper = new SavingsHelper(accountTransfersReadPlatformService);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@ import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
|||||||
public interface SavingsAccountDomainService {
|
public interface SavingsAccountDomainService {
|
||||||
|
|
||||||
SavingsAccountTransaction handleWithdrawal(SavingsAccount account, DateTimeFormatter fmt, LocalDate transactionDate,
|
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,
|
SavingsAccountTransaction handleDeposit(SavingsAccount account, DateTimeFormatter fmt, LocalDate transactionDate,
|
||||||
BigDecimal transactionAmount, PaymentDetail paymentDetail);
|
BigDecimal transactionAmount, PaymentDetail paymentDetail);
|
||||||
|
|||||||
+6
-5
@@ -48,7 +48,7 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
|||||||
@Override
|
@Override
|
||||||
public SavingsAccountTransaction handleWithdrawal(final SavingsAccount account, final DateTimeFormatter fmt,
|
public SavingsAccountTransaction handleWithdrawal(final SavingsAccount account, final DateTimeFormatter fmt,
|
||||||
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail,
|
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail,
|
||||||
final boolean applyWithdrawFee) {
|
final boolean applyWithdrawFee, boolean isInterestTransfer) {
|
||||||
|
|
||||||
final Set<Long> existingTransactionIds = new HashSet<Long>();
|
final Set<Long> existingTransactionIds = new HashSet<Long>();
|
||||||
final Set<Long> existingReversedTransactionIds = new HashSet<Long>();
|
final Set<Long> existingReversedTransactionIds = new HashSet<Long>();
|
||||||
@@ -60,10 +60,10 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
|||||||
final MathContext mc = MathContext.DECIMAL64;
|
final MathContext mc = MathContext.DECIMAL64;
|
||||||
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
account.postInterest(mc, today);
|
account.postInterest(mc, today, isInterestTransfer);
|
||||||
} else {
|
} else {
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
account.calculateInterestUsing(mc, today);
|
account.calculateInterestUsing(mc, today, isInterestTransfer);
|
||||||
}
|
}
|
||||||
account.validateAccountBalanceDoesNotBecomeNegative(transactionAmount);
|
account.validateAccountBalanceDoesNotBecomeNegative(transactionAmount);
|
||||||
saveTransactionToGenerateTransactionId(withdrawal);
|
saveTransactionToGenerateTransactionId(withdrawal);
|
||||||
@@ -79,6 +79,7 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
|||||||
public SavingsAccountTransaction handleDeposit(final SavingsAccount account, final DateTimeFormatter fmt,
|
public SavingsAccountTransaction handleDeposit(final SavingsAccount account, final DateTimeFormatter fmt,
|
||||||
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail) {
|
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail) {
|
||||||
|
|
||||||
|
boolean isInterestTransfer = false;
|
||||||
final Set<Long> existingTransactionIds = new HashSet<Long>();
|
final Set<Long> existingTransactionIds = new HashSet<Long>();
|
||||||
final Set<Long> existingReversedTransactionIds = new HashSet<Long>();
|
final Set<Long> existingReversedTransactionIds = new HashSet<Long>();
|
||||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||||
@@ -89,10 +90,10 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
|||||||
final MathContext mc = MathContext.DECIMAL64;
|
final MathContext mc = MathContext.DECIMAL64;
|
||||||
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
account.postInterest(mc, today);
|
account.postInterest(mc, today, isInterestTransfer);
|
||||||
} else {
|
} else {
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
account.calculateInterestUsing(mc, today);
|
account.calculateInterestUsing(mc, today, isInterestTransfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
saveTransactionToGenerateTransactionId(deposit);
|
saveTransactionToGenerateTransactionId(deposit);
|
||||||
|
|||||||
+6
-4
@@ -445,13 +445,15 @@ public final class SavingsAccountTransaction extends AbstractPersistable<Long> {
|
|||||||
if (isDeposit()) {
|
if (isDeposit()) {
|
||||||
// endOfDayBalance = openingBalance.plus(getAmount(currency));
|
// endOfDayBalance = openingBalance.plus(getAmount(currency));
|
||||||
// if (endOfDayBalance.isLessThanZero()) {
|
// if (endOfDayBalance.isLessThanZero()) {
|
||||||
endOfDayBalance = Money.of(currency, this.runningBalance);
|
endOfDayBalance = endOfDayBalance.plus(getAmount(currency));
|
||||||
// }
|
// }
|
||||||
} else if (isWithdrawal() || isChargeTransactionAndNotReversed()) {
|
} else if (isWithdrawal() || isChargeTransactionAndNotReversed()) {
|
||||||
// endOfDayBalance = openingBalance.minus(getAmount(currency));
|
// endOfDayBalance = openingBalance.minus(getAmount(currency));
|
||||||
// if (endOfDayBalance.isLessThanZero()) {
|
if (endOfDayBalance.isGreaterThanZero()) {
|
||||||
endOfDayBalance = Money.of(currency, this.runningBalance);
|
endOfDayBalance = endOfDayBalance.minus(getAmount(currency));
|
||||||
// }
|
} else {
|
||||||
|
endOfDayBalance = Money.of(currency, this.runningBalance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+22
-7
@@ -1,6 +1,7 @@
|
|||||||
package org.mifosplatform.portfolio.savings.domain;
|
package org.mifosplatform.portfolio.savings.domain;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
@@ -8,12 +9,19 @@ import org.joda.time.LocalDate;
|
|||||||
import org.mifosplatform.infrastructure.core.domain.LocalDateInterval;
|
import org.mifosplatform.infrastructure.core.domain.LocalDateInterval;
|
||||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
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.SavingsPostingInterestPeriodType;
|
||||||
import org.mifosplatform.portfolio.savings.domain.interest.CompoundInterestHelper;
|
import org.mifosplatform.portfolio.savings.domain.interest.CompoundInterestHelper;
|
||||||
import org.mifosplatform.portfolio.savings.domain.interest.PostingPeriod;
|
import org.mifosplatform.portfolio.savings.domain.interest.PostingPeriod;
|
||||||
|
|
||||||
public final class SavingsHelper {
|
public final class SavingsHelper {
|
||||||
|
|
||||||
|
AccountTransfersReadPlatformService accountTransfersReadPlatformService = null;
|
||||||
|
|
||||||
|
public SavingsHelper(AccountTransfersReadPlatformService accountTransfersReadPlatformService) {
|
||||||
|
this.accountTransfersReadPlatformService = accountTransfersReadPlatformService;
|
||||||
|
}
|
||||||
|
|
||||||
private final CompoundInterestHelper compoundInterestHelper = new CompoundInterestHelper();
|
private final CompoundInterestHelper compoundInterestHelper = new CompoundInterestHelper();
|
||||||
|
|
||||||
public List<LocalDateInterval> determineInterestPostingPeriods(final LocalDate activationLocalDate,
|
public List<LocalDateInterval> determineInterestPostingPeriods(final LocalDate activationLocalDate,
|
||||||
@@ -26,7 +34,8 @@ public final class SavingsHelper {
|
|||||||
|
|
||||||
while (!periodStartDate.isAfter(interestPostingUpToDate) && !periodEndDate.isAfter(interestPostingUpToDate)) {
|
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);
|
periodEndDate = interestPostingLocalDate.minusDays(1);
|
||||||
|
|
||||||
if (!interestPostingLocalDate.isAfter(interestPostingUpToDate)) {
|
if (!interestPostingLocalDate.isAfter(interestPostingUpToDate)) {
|
||||||
@@ -61,7 +70,7 @@ public final class SavingsHelper {
|
|||||||
final int monthofYear = periodStartDate.getMonthOfYear();
|
final int monthofYear = periodStartDate.getMonthOfYear();
|
||||||
if (monthofYear <= 3) {
|
if (monthofYear <= 3) {
|
||||||
periodEndDate = new DateTime().withDate(year, 3, 31).toLocalDate();
|
periodEndDate = new DateTime().withDate(year, 3, 31).toLocalDate();
|
||||||
} else if (monthofYear <= 6) {
|
} else if (monthofYear <= 6) {
|
||||||
periodEndDate = new DateTime().withDate(year, 6, 30).toLocalDate();
|
periodEndDate = new DateTime().withDate(year, 6, 30).toLocalDate();
|
||||||
} else if (monthofYear <= 9) {
|
} else if (monthofYear <= 9) {
|
||||||
periodEndDate = new DateTime().withDate(year, 9, 30).toLocalDate();
|
periodEndDate = new DateTime().withDate(year, 9, 30).toLocalDate();
|
||||||
@@ -70,14 +79,14 @@ public final class SavingsHelper {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BIANNUAL:
|
case BIANNUAL:
|
||||||
final int byear = periodStartDate.getYearOfEra();
|
final int byear = periodStartDate.getYearOfEra();
|
||||||
final int bmonthofYear = periodStartDate.getMonthOfYear();
|
final int bmonthofYear = periodStartDate.getMonthOfYear();
|
||||||
if (bmonthofYear <= 6) {
|
if (bmonthofYear <= 6) {
|
||||||
periodEndDate = new DateTime().withDate(byear, 6, 30).toLocalDate();
|
periodEndDate = new DateTime().withDate(byear, 6, 30).toLocalDate();
|
||||||
} else if (bmonthofYear <= 12) {
|
} else if (bmonthofYear <= 12) {
|
||||||
periodEndDate = new DateTime().withDate(byear, 12, 31).toLocalDate();
|
periodEndDate = new DateTime().withDate(byear, 12, 31).toLocalDate();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ANNUAL:
|
case ANNUAL:
|
||||||
periodEndDate = periodStartDate.monthOfYear().withMaximumValue();
|
periodEndDate = periodStartDate.monthOfYear().withMaximumValue();
|
||||||
periodEndDate = periodEndDate.dayOfMonth().withMaximumValue();
|
periodEndDate = periodEndDate.dayOfMonth().withMaximumValue();
|
||||||
@@ -90,7 +99,13 @@ public final class SavingsHelper {
|
|||||||
return periodEndDate;
|
return periodEndDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Money calculateInterestForAllPostingPeriods(final MonetaryCurrency currency, final List<PostingPeriod> allPeriods) {
|
public Money calculateInterestForAllPostingPeriods(final MonetaryCurrency currency, final List<PostingPeriod> allPeriods,
|
||||||
return this.compoundInterestHelper.calculateInterestForAllPostingPeriods(currency, allPeriods);
|
LocalDate accountLockedUntil, Boolean immediateWithdrawalOfInterest) {
|
||||||
|
return this.compoundInterestHelper.calculateInterestForAllPostingPeriods(currency, allPeriods, accountLockedUntil,
|
||||||
|
immediateWithdrawalOfInterest);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<Long> fetchPostInterestTransactionIds(Long accountId) {
|
||||||
|
return this.accountTransfersReadPlatformService.fetchPostInterestTransactionIds(accountId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+23
-3
@@ -3,12 +3,26 @@ package org.mifosplatform.portfolio.savings.domain.interest;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.joda.time.LocalDate;
|
||||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||||
|
|
||||||
public class CompoundInterestHelper {
|
public class CompoundInterestHelper {
|
||||||
|
|
||||||
public Money calculateInterestForAllPostingPeriods(final MonetaryCurrency currency, final List<PostingPeriod> 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<PostingPeriod> allPeriods,
|
||||||
|
LocalDate lockUntil, Boolean interestTransferEnabled) {
|
||||||
|
|
||||||
// sum up the 'rounded' values that are posted each posting period
|
// sum up the 'rounded' values that are posted each posting period
|
||||||
Money interestEarned = Money.zero(currency);
|
Money interestEarned = Money.zero(currency);
|
||||||
@@ -22,8 +36,14 @@ public class CompoundInterestHelper {
|
|||||||
final Money moneyToBePostedForPeriod = Money.of(currency, interestEarnedThisPeriod);
|
final Money moneyToBePostedForPeriod = Money.of(currency, interestEarnedThisPeriod);
|
||||||
|
|
||||||
interestEarned = interestEarned.plus(moneyToBePostedForPeriod);
|
interestEarned = interestEarned.plus(moneyToBePostedForPeriod);
|
||||||
|
// these checks are for fixed deposit account for not include
|
||||||
interestEarnedButNotPosted = interestEarnedButNotPosted.add(moneyToBePostedForPeriod.getAmount());
|
// 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;
|
return interestEarned;
|
||||||
|
|||||||
+52
-28
@@ -2,6 +2,7 @@ package org.mifosplatform.portfolio.savings.domain.interest;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
@@ -33,13 +34,18 @@ public class PostingPeriod {
|
|||||||
private final Money closingBalance;
|
private final Money closingBalance;
|
||||||
private final SavingsInterestCalculationType interestCalculationType;
|
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,
|
public static PostingPeriod createFrom(final LocalDateInterval periodInterval, final Money periodStartingBalance,
|
||||||
final List<SavingsAccountTransaction> orderedListOfTransactions, final MonetaryCurrency currency,
|
final List<SavingsAccountTransaction> orderedListOfTransactions, final MonetaryCurrency currency,
|
||||||
final SavingsCompoundingInterestPeriodType interestCompoundingPeriodType,
|
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<Long> interestPostTransactions, boolean isInterestTransfer) {
|
||||||
|
|
||||||
final List<EndOfDayBalance> accountEndOfDayBalances = new ArrayList<EndOfDayBalance>();
|
final List<EndOfDayBalance> accountEndOfDayBalances = new ArrayList<EndOfDayBalance>();
|
||||||
|
boolean interestTransfered = false;
|
||||||
Money openingDayBalance = periodStartingBalance;
|
Money openingDayBalance = periodStartingBalance;
|
||||||
Money closeOfDayBalance = openingDayBalance;
|
Money closeOfDayBalance = openingDayBalance;
|
||||||
for (final SavingsAccountTransaction transaction : orderedListOfTransactions) {
|
for (final SavingsAccountTransaction transaction : orderedListOfTransactions) {
|
||||||
@@ -51,6 +57,7 @@ public class PostingPeriod {
|
|||||||
accountEndOfDayBalances.add(endOfDayBalance);
|
accountEndOfDayBalances.add(endOfDayBalance);
|
||||||
|
|
||||||
openingDayBalance = endOfDayBalance.closingBalance();
|
openingDayBalance = endOfDayBalance.closingBalance();
|
||||||
|
|
||||||
} else if (transaction.spansAnyPortionOf(periodInterval)) {
|
} else if (transaction.spansAnyPortionOf(periodInterval)) {
|
||||||
final EndOfDayBalance endOfDayBalance = transaction.toEndOfDayBalanceBoundedBy(openingDayBalance, periodInterval);
|
final EndOfDayBalance endOfDayBalance = transaction.toEndOfDayBalanceBoundedBy(openingDayBalance, periodInterval);
|
||||||
accountEndOfDayBalances.add(endOfDayBalance);
|
accountEndOfDayBalances.add(endOfDayBalance);
|
||||||
@@ -58,22 +65,32 @@ public class PostingPeriod {
|
|||||||
closeOfDayBalance = endOfDayBalance.closingBalance();
|
closeOfDayBalance = endOfDayBalance.closingBalance();
|
||||||
openingDayBalance = closeOfDayBalance;
|
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()) {
|
if (accountEndOfDayBalances.isEmpty()) {
|
||||||
LocalDate balanceStartDate = periodInterval.startDate();
|
LocalDate balanceStartDate = periodInterval.startDate();
|
||||||
LocalDate balanceEndDate = periodInterval.endDate();
|
LocalDate balanceEndDate = periodInterval.endDate();
|
||||||
Integer numberOfDaysOfBalance = periodInterval.daysInPeriodInclusiveOfEndDate();
|
Integer numberOfDaysOfBalance = periodInterval.daysInPeriodInclusiveOfEndDate();
|
||||||
|
|
||||||
if (balanceEndDate.isAfter(upToInterestCalculationDate)) {
|
if (balanceEndDate.isAfter(upToInterestCalculationDate)) {
|
||||||
balanceEndDate = upToInterestCalculationDate;
|
balanceEndDate = upToInterestCalculationDate;
|
||||||
final LocalDateInterval spanOfBalance = LocalDateInterval.create(balanceStartDate, balanceEndDate);
|
final LocalDateInterval spanOfBalance = LocalDateInterval.create(balanceStartDate, balanceEndDate);
|
||||||
numberOfDaysOfBalance = spanOfBalance.daysInPeriodInclusiveOfEndDate();
|
numberOfDaysOfBalance = spanOfBalance.daysInPeriodInclusiveOfEndDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
final EndOfDayBalance endOfDayBalance = EndOfDayBalance.from(balanceStartDate, openingDayBalance, closeOfDayBalance,
|
final EndOfDayBalance endOfDayBalance = EndOfDayBalance.from(balanceStartDate, openingDayBalance, closeOfDayBalance,
|
||||||
numberOfDaysOfBalance);
|
numberOfDaysOfBalance);
|
||||||
|
|
||||||
accountEndOfDayBalances.add(endOfDayBalance);
|
accountEndOfDayBalances.add(endOfDayBalance);
|
||||||
|
|
||||||
closeOfDayBalance = endOfDayBalance.closingBalance();
|
closeOfDayBalance = endOfDayBalance.closingBalance();
|
||||||
@@ -84,13 +101,13 @@ public class PostingPeriod {
|
|||||||
accountEndOfDayBalances, upToInterestCalculationDate);
|
accountEndOfDayBalances, upToInterestCalculationDate);
|
||||||
|
|
||||||
return new PostingPeriod(periodInterval, currency, periodStartingBalance, openingDayBalance, interestCompoundingPeriodType,
|
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,
|
private PostingPeriod(final LocalDateInterval periodInterval, final MonetaryCurrency currency, final Money openingBalance,
|
||||||
final Money closingBalance, final SavingsCompoundingInterestPeriodType interestCompoundingType,
|
final Money closingBalance, final SavingsCompoundingInterestPeriodType interestCompoundingType,
|
||||||
final SavingsInterestCalculationType interestCalculationType, final BigDecimal interestRateAsFraction, final long daysInYear,
|
final SavingsInterestCalculationType interestCalculationType, final BigDecimal interestRateAsFraction, final long daysInYear,
|
||||||
final List<CompoundingPeriod> compoundingPeriods) {
|
final List<CompoundingPeriod> compoundingPeriods, boolean interestTransfered) {
|
||||||
this.periodInterval = periodInterval;
|
this.periodInterval = periodInterval;
|
||||||
this.currency = currency;
|
this.currency = currency;
|
||||||
this.openingBalance = openingBalance;
|
this.openingBalance = openingBalance;
|
||||||
@@ -102,6 +119,7 @@ public class PostingPeriod {
|
|||||||
this.compoundingPeriods = compoundingPeriods;
|
this.compoundingPeriods = compoundingPeriods;
|
||||||
|
|
||||||
this.dateOfPostingTransaction = periodInterval.endDate().plusDays(1);
|
this.dateOfPostingTransaction = periodInterval.endDate().plusDays(1);
|
||||||
|
this.interestTransfered = interestTransfered;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Money interest() {
|
public Money interest() {
|
||||||
@@ -115,7 +133,7 @@ public class PostingPeriod {
|
|||||||
public Money closingBalance() {
|
public Money closingBalance() {
|
||||||
return this.closingBalance;
|
return this.closingBalance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Money openingBalance() {
|
public Money openingBalance() {
|
||||||
return this.openingBalance;
|
return this.openingBalance;
|
||||||
}
|
}
|
||||||
@@ -145,7 +163,8 @@ public class PostingPeriod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static List<CompoundingPeriod> compoundingPeriodsInPostingPeriod(final LocalDateInterval postingPeriodInterval,
|
private static List<CompoundingPeriod> compoundingPeriodsInPostingPeriod(final LocalDateInterval postingPeriodInterval,
|
||||||
final SavingsCompoundingInterestPeriodType interestPeriodType, final List<EndOfDayBalance> allEndOfDayBalances, final LocalDate upToInterestCalculationDate) {
|
final SavingsCompoundingInterestPeriodType interestPeriodType, final List<EndOfDayBalance> allEndOfDayBalances,
|
||||||
|
final LocalDate upToInterestCalculationDate) {
|
||||||
|
|
||||||
final List<CompoundingPeriod> compoundingPeriods = new ArrayList<CompoundingPeriod>();
|
final List<CompoundingPeriod> compoundingPeriods = new ArrayList<CompoundingPeriod>();
|
||||||
|
|
||||||
@@ -174,7 +193,8 @@ public class PostingPeriod {
|
|||||||
final LocalDateInterval compoundingPeriodInterval = LocalDateInterval.create(periodStartDate, periodEndDate);
|
final LocalDateInterval compoundingPeriodInterval = LocalDateInterval.create(periodStartDate, periodEndDate);
|
||||||
if (postingPeriodInterval.contains(compoundingPeriodInterval)) {
|
if (postingPeriodInterval.contains(compoundingPeriodInterval)) {
|
||||||
|
|
||||||
compoundingPeriod = MonthlyCompoundingPeriod.create(compoundingPeriodInterval, allEndOfDayBalances, upToInterestCalculationDate);
|
compoundingPeriod = MonthlyCompoundingPeriod.create(compoundingPeriodInterval, allEndOfDayBalances,
|
||||||
|
upToInterestCalculationDate);
|
||||||
compoundingPeriods.add(compoundingPeriod);
|
compoundingPeriods.add(compoundingPeriod);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,11 +202,11 @@ public class PostingPeriod {
|
|||||||
periodStartDate = periodEndDate.plusDays(1);
|
periodStartDate = periodEndDate.plusDays(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// case WEEKLY:
|
// case WEEKLY:
|
||||||
// break;
|
// break;
|
||||||
// case BIWEEKLY:
|
// case BIWEEKLY:
|
||||||
// break;
|
// break;
|
||||||
case QUATERLY:
|
case QUATERLY:
|
||||||
final LocalDate qPostingPeriodEndDate = postingPeriodInterval.endDate();
|
final LocalDate qPostingPeriodEndDate = postingPeriodInterval.endDate();
|
||||||
|
|
||||||
periodStartDate = postingPeriodInterval.startDate();
|
periodStartDate = postingPeriodInterval.startDate();
|
||||||
@@ -210,7 +230,7 @@ public class PostingPeriod {
|
|||||||
// move periodStartDate forward to day after this period
|
// move periodStartDate forward to day after this period
|
||||||
periodStartDate = periodEndDate.plusDays(1);
|
periodStartDate = periodEndDate.plusDays(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BI_ANNUAL:
|
case BI_ANNUAL:
|
||||||
final LocalDate bPostingPeriodEndDate = postingPeriodInterval.endDate();
|
final LocalDate bPostingPeriodEndDate = postingPeriodInterval.endDate();
|
||||||
|
|
||||||
@@ -235,7 +255,7 @@ public class PostingPeriod {
|
|||||||
// move periodStartDate forward to day after this period
|
// move periodStartDate forward to day after this period
|
||||||
periodStartDate = periodEndDate.plusDays(1);
|
periodStartDate = periodEndDate.plusDays(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ANNUAL:
|
case ANNUAL:
|
||||||
final LocalDate aPostingPeriodEndDate = postingPeriodInterval.endDate();
|
final LocalDate aPostingPeriodEndDate = postingPeriodInterval.endDate();
|
||||||
|
|
||||||
@@ -260,9 +280,9 @@ public class PostingPeriod {
|
|||||||
// move periodStartDate forward to day after this period
|
// move periodStartDate forward to day after this period
|
||||||
periodStartDate = periodEndDate.plusDays(1);
|
periodStartDate = periodEndDate.plusDays(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// case NO_COMPOUNDING_SIMPLE_INTEREST:
|
// case NO_COMPOUNDING_SIMPLE_INTEREST:
|
||||||
// break;
|
// break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return compoundingPeriods;
|
return compoundingPeriods;
|
||||||
@@ -291,7 +311,7 @@ public class PostingPeriod {
|
|||||||
// produce period end date on last day of current month
|
// produce period end date on last day of current month
|
||||||
periodEndDate = periodStartDate.dayOfMonth().withMaximumValue();
|
periodEndDate = periodStartDate.dayOfMonth().withMaximumValue();
|
||||||
break;
|
break;
|
||||||
case QUATERLY:
|
case QUATERLY:
|
||||||
// // jan 1st to mar 31st, 1st apr to jun 30, jul 1st to sept
|
// // jan 1st to mar 31st, 1st apr to jun 30, jul 1st to sept
|
||||||
// 30,
|
// 30,
|
||||||
// // oct 1st to dec 31
|
// // oct 1st to dec 31
|
||||||
@@ -306,7 +326,7 @@ public class PostingPeriod {
|
|||||||
} else if (monthofYear <= 12) {
|
} else if (monthofYear <= 12) {
|
||||||
periodEndDate = new DateTime().withDate(year, 12, 31).toLocalDate();
|
periodEndDate = new DateTime().withDate(year, 12, 31).toLocalDate();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BI_ANNUAL:
|
case BI_ANNUAL:
|
||||||
// // jan 1st to 30, jul 1st to dec 31
|
// // jan 1st to 30, jul 1st to dec 31
|
||||||
year = periodStartDate.getYearOfEra();
|
year = periodStartDate.getYearOfEra();
|
||||||
@@ -316,18 +336,22 @@ public class PostingPeriod {
|
|||||||
} else if (monthofYear <= 12) {
|
} else if (monthofYear <= 12) {
|
||||||
periodEndDate = new DateTime().withDate(year, 12, 31).toLocalDate();
|
periodEndDate = new DateTime().withDate(year, 12, 31).toLocalDate();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ANNUAL:
|
case ANNUAL:
|
||||||
periodEndDate = periodStartDate.monthOfYear().withMaximumValue();
|
periodEndDate = periodStartDate.monthOfYear().withMaximumValue();
|
||||||
periodEndDate = periodEndDate.dayOfMonth().withMaximumValue();
|
periodEndDate = periodEndDate.dayOfMonth().withMaximumValue();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// case NO_COMPOUNDING_SIMPLE_INTEREST:
|
// case NO_COMPOUNDING_SIMPLE_INTEREST:
|
||||||
// periodEndDate = periodStartDate.monthOfYear().withMaximumValue();
|
// periodEndDate = periodStartDate.monthOfYear().withMaximumValue();
|
||||||
// periodEndDate = periodEndDate.dayOfMonth().withMaximumValue();
|
// periodEndDate = periodEndDate.dayOfMonth().withMaximumValue();
|
||||||
// break;
|
// break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return periodEndDate;
|
return periodEndDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isInterestTransfered() {
|
||||||
|
return this.interestTransfered;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+3
@@ -9,6 +9,7 @@ import java.util.Collection;
|
|||||||
|
|
||||||
import org.mifosplatform.infrastructure.core.data.PaginationParameters;
|
import org.mifosplatform.infrastructure.core.data.PaginationParameters;
|
||||||
import org.mifosplatform.infrastructure.core.service.Page;
|
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.DepositAccountType;
|
||||||
import org.mifosplatform.portfolio.savings.data.DepositAccountData;
|
import org.mifosplatform.portfolio.savings.data.DepositAccountData;
|
||||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionData;
|
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionData;
|
||||||
@@ -34,4 +35,6 @@ public interface DepositAccountReadPlatformService {
|
|||||||
Collection<DepositAccountData> retrieveForMaturityUpdate();
|
Collection<DepositAccountData> retrieveForMaturityUpdate();
|
||||||
|
|
||||||
SavingsAccountTransactionData retrieveRecurringAccountDepositTransactionTemplate(final Long accountId);
|
SavingsAccountTransactionData retrieveRecurringAccountDepositTransactionTemplate(final Long accountId);
|
||||||
|
|
||||||
|
Collection<AccountTransferDTO> retrieveDataForInterestTransfer();
|
||||||
}
|
}
|
||||||
|
|||||||
+57
-3
@@ -26,7 +26,10 @@ import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext
|
|||||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||||
import org.mifosplatform.organisation.staff.data.StaffData;
|
import org.mifosplatform.organisation.staff.data.StaffData;
|
||||||
import org.mifosplatform.organisation.staff.service.StaffReadPlatformService;
|
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.data.AccountTransferData;
|
||||||
|
import org.mifosplatform.portfolio.account.domain.AccountTransferType;
|
||||||
import org.mifosplatform.portfolio.charge.data.ChargeData;
|
import org.mifosplatform.portfolio.charge.data.ChargeData;
|
||||||
import org.mifosplatform.portfolio.charge.service.ChargeReadPlatformService;
|
import org.mifosplatform.portfolio.charge.service.ChargeReadPlatformService;
|
||||||
import org.mifosplatform.portfolio.client.data.ClientData;
|
import org.mifosplatform.portfolio.client.data.ClientData;
|
||||||
@@ -464,6 +467,22 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<AccountTransferDTO> 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<DepositAccountData> {
|
private static abstract class DepositAccountMapper implements RowMapper<DepositAccountData> {
|
||||||
|
|
||||||
private final String selectFieldsSql;
|
private final String selectFieldsSql;
|
||||||
@@ -697,7 +716,8 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
|
|||||||
sqlBuilder.append("datp.maturity_date as maturityDate, ");
|
sqlBuilder.append("datp.maturity_date as maturityDate, ");
|
||||||
sqlBuilder.append("datp.deposit_period as depositPeriod, ");
|
sqlBuilder.append("datp.deposit_period as depositPeriod, ");
|
||||||
sqlBuilder.append("datp.deposit_period_frequency_enum as depositPeriodFrequencyTypeId, ");
|
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());
|
sqlBuilder.append(super.selectTablesSql());
|
||||||
|
|
||||||
@@ -750,12 +770,13 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
|
|||||||
final Integer onAccountClosureId = JdbcSupport.getInteger(rs, "onAccountClosureId");
|
final Integer onAccountClosureId = JdbcSupport.getInteger(rs, "onAccountClosureId");
|
||||||
final EnumOptionData onAccountClosureType = (onAccountClosureId == null) ? null : SavingsEnumerations
|
final EnumOptionData onAccountClosureType = (onAccountClosureId == null) ? null : SavingsEnumerations
|
||||||
.depositAccountOnClosureType(onAccountClosureId);
|
.depositAccountOnClosureType(onAccountClosureId);
|
||||||
|
final Boolean transferInterestToSavings = rs.getBoolean("transferInterestToSavings");
|
||||||
|
|
||||||
return FixedDepositAccountData.instance(depositAccountData, interestFreePeriodApplicable, interestFreeFromPeriod,
|
return FixedDepositAccountData.instance(depositAccountData, interestFreePeriodApplicable, interestFreeFromPeriod,
|
||||||
interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest,
|
interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest,
|
||||||
preClosurePenalInterestOnType, minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType,
|
preClosurePenalInterestOnType, minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType,
|
||||||
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate, depositPeriod,
|
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 Integer depositPeriod = null;
|
||||||
final EnumOptionData depositPeriodFrequencyType = null;
|
final EnumOptionData depositPeriodFrequencyType = null;
|
||||||
final EnumOptionData onAccountClosureType = null;
|
final EnumOptionData onAccountClosureType = null;
|
||||||
|
final Boolean transferInterestToSavings = false;
|
||||||
|
|
||||||
return FixedDepositAccountData.instance(depositAccountData, interestFreePeriodApplicable, interestFreeFromPeriod,
|
return FixedDepositAccountData.instance(depositAccountData, interestFreePeriodApplicable, interestFreeFromPeriod,
|
||||||
interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest,
|
interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest,
|
||||||
preClosurePenalInterestOnType, minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType,
|
preClosurePenalInterestOnType, minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType,
|
||||||
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate, depositPeriod,
|
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);
|
DateUtils.getLocalDateOfTenant(), currency, recurringDepositAmount, runningBalance, false, transfer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class AccountTransferMapper implements RowMapper<AccountTransferDTO> {
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+3
@@ -8,6 +8,7 @@ package org.mifosplatform.portfolio.savings.service;
|
|||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
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.office.domain.Office;
|
||||||
import org.mifosplatform.organisation.staff.domain.Staff;
|
import org.mifosplatform.organisation.staff.domain.Staff;
|
||||||
import org.mifosplatform.portfolio.savings.DepositAccountType;
|
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 applyChargeDue(final Long savingsAccountChargeId, final Long accountId, final DepositAccountType depositAccountType);
|
||||||
|
|
||||||
void updateMaturityDetails(final Long depositAccountId, final DepositAccountType depositAccountType);
|
void updateMaturityDetails(final Long depositAccountId, final DepositAccountType depositAccountType);
|
||||||
|
|
||||||
|
void transferInterestToSavings() throws JobExecutionException;
|
||||||
}
|
}
|
||||||
+51
-20
@@ -14,6 +14,7 @@ import java.math.BigDecimal;
|
|||||||
import java.math.MathContext;
|
import java.math.MathContext;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
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.PlatformApiDataValidationException;
|
||||||
import org.mifosplatform.infrastructure.core.exception.PlatformServiceUnavailableException;
|
import org.mifosplatform.infrastructure.core.exception.PlatformServiceUnavailableException;
|
||||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
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.infrastructure.security.service.PlatformSecurityContext;
|
||||||
import org.mifosplatform.organisation.holiday.service.HolidayWritePlatformService;
|
import org.mifosplatform.organisation.holiday.service.HolidayWritePlatformService;
|
||||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
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.SavingsAccountTransaction;
|
||||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccountTransactionRepository;
|
import org.mifosplatform.portfolio.savings.domain.SavingsAccountTransactionRepository;
|
||||||
import org.mifosplatform.portfolio.savings.exception.DepositAccountTransactionNotAllowedException;
|
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.SavingsAccountTransactionNotFoundException;
|
||||||
import org.mifosplatform.portfolio.savings.exception.TransactionUpdateNotAllowedException;
|
import org.mifosplatform.portfolio.savings.exception.TransactionUpdateNotAllowedException;
|
||||||
import org.mifosplatform.useradministration.domain.AppUser;
|
import org.mifosplatform.useradministration.domain.AppUser;
|
||||||
@@ -106,6 +111,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
|||||||
private final WorkingDaysWritePlatformService workingDaysWritePlatformService;
|
private final WorkingDaysWritePlatformService workingDaysWritePlatformService;
|
||||||
private final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService;
|
private final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService;
|
||||||
private final AccountTransfersWritePlatformService accountTransfersWritePlatformService;
|
private final AccountTransfersWritePlatformService accountTransfersWritePlatformService;
|
||||||
|
private final DepositAccountReadPlatformService depositAccountReadPlatformService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public DepositAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
public DepositAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||||
@@ -123,7 +129,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
|||||||
final HolidayWritePlatformService holidayWritePlatformService,
|
final HolidayWritePlatformService holidayWritePlatformService,
|
||||||
final WorkingDaysWritePlatformService workingDaysWritePlatformService,
|
final WorkingDaysWritePlatformService workingDaysWritePlatformService,
|
||||||
final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService,
|
final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService,
|
||||||
final AccountTransfersWritePlatformService accountTransfersWritePlatformService) {
|
final AccountTransfersWritePlatformService accountTransfersWritePlatformService,
|
||||||
|
final DepositAccountReadPlatformService depositAccountReadPlatformService) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.savingAccountRepository = savingAccountRepository;
|
this.savingAccountRepository = savingAccountRepository;
|
||||||
this.savingsAccountTransactionRepository = savingsAccountTransactionRepository;
|
this.savingsAccountTransactionRepository = savingsAccountTransactionRepository;
|
||||||
@@ -142,6 +149,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
|||||||
this.workingDaysWritePlatformService = workingDaysWritePlatformService;
|
this.workingDaysWritePlatformService = workingDaysWritePlatformService;
|
||||||
this.accountAssociationsReadPlatformService = accountAssociationsReadPlatformService;
|
this.accountAssociationsReadPlatformService = accountAssociationsReadPlatformService;
|
||||||
this.accountTransfersWritePlatformService = accountTransfersWritePlatformService;
|
this.accountTransfersWritePlatformService = accountTransfersWritePlatformService;
|
||||||
|
this.depositAccountReadPlatformService = depositAccountReadPlatformService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@@ -282,8 +290,9 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
|||||||
|
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
final MathContext mc = new MathContext(15, RoundingMode.HALF_EVEN);
|
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);
|
this.savingAccountRepository.save(account);
|
||||||
|
|
||||||
@@ -319,13 +328,33 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
|||||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
final MathContext mc = new MathContext(10, RoundingMode.HALF_EVEN);
|
final MathContext mc = new MathContext(10, RoundingMode.HALF_EVEN);
|
||||||
|
boolean isInterestTransfer = false;
|
||||||
account.postInterest(mc, today);
|
account.postInterest(mc, today, isInterestTransfer);
|
||||||
this.savingAccountRepository.save(account);
|
this.savingAccountRepository.save(account);
|
||||||
|
|
||||||
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
|
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@CronTarget(jobName = JobName.TRANSFER_INTEREST_TO_SAVINGS)
|
||||||
|
public void transferInterestToSavings() throws JobExecutionException {
|
||||||
|
Collection<AccountTransferDTO> 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
|
@Override
|
||||||
public CommandProcessingResult undoTransaction(final Long savingsId, final Long transactionId,
|
public CommandProcessingResult undoTransaction(final Long savingsId, final Long transactionId,
|
||||||
final boolean allowAccountTransferModification, final DepositAccountType depositAccountType) {
|
final boolean allowAccountTransferModification, final DepositAccountType depositAccountType) {
|
||||||
@@ -354,13 +383,13 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
|||||||
throwValidationForActiveStatus(SavingsApiConstants.undoTransactionAction);
|
throwValidationForActiveStatus(SavingsApiConstants.undoTransactionAction);
|
||||||
}
|
}
|
||||||
account.undoTransaction(transactionId);
|
account.undoTransaction(transactionId);
|
||||||
|
boolean isInterestTransfer = false;
|
||||||
checkClientOrGroupActive(account);
|
checkClientOrGroupActive(account);
|
||||||
if (savingsAccountTransaction.isPostInterestCalculationRequired()
|
if (savingsAccountTransaction.isPostInterestCalculationRequired()
|
||||||
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
|
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
|
||||||
account.postInterest(mc, today);
|
account.postInterest(mc, today, isInterestTransfer);
|
||||||
} else {
|
} else {
|
||||||
account.calculateInterestUsing(mc, today);
|
account.calculateInterestUsing(mc, today, isInterestTransfer);
|
||||||
}
|
}
|
||||||
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.undoTransactionAction);
|
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.undoTransactionAction);
|
||||||
account.activateAccountBasedOnBalance();
|
account.activateAccountBasedOnBalance();
|
||||||
@@ -425,12 +454,12 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
|||||||
transaction = account.withdraw(transactionDTO, true);
|
transaction = account.withdraw(transactionDTO, true);
|
||||||
}
|
}
|
||||||
final Long newtransactionId = saveTransactionToGenerateTransactionId(transaction);
|
final Long newtransactionId = saveTransactionToGenerateTransactionId(transaction);
|
||||||
|
boolean isInterestTransfer = false;
|
||||||
if (account.isBeforeLastPostingPeriod(transactionDate)
|
if (account.isBeforeLastPostingPeriod(transactionDate)
|
||||||
|| account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
|
|| account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
|
||||||
account.postInterest(mc, today);
|
account.postInterest(mc, today, isInterestTransfer);
|
||||||
} else {
|
} else {
|
||||||
account.calculateInterestUsing(mc, today);
|
account.calculateInterestUsing(mc, today, isInterestTransfer);
|
||||||
}
|
}
|
||||||
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.adjustTransactionAction);
|
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.adjustTransactionAction);
|
||||||
account.activateAccountBasedOnBalance();
|
account.activateAccountBasedOnBalance();
|
||||||
@@ -548,7 +577,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
|||||||
savingsAccount.getTransactions().add(newTransferTransaction);
|
savingsAccount.getTransactions().add(newTransferTransaction);
|
||||||
savingsAccount.setStatus(SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getValue());
|
savingsAccount.setStatus(SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getValue());
|
||||||
final MathContext mc = MathContext.DECIMAL64;
|
final MathContext mc = MathContext.DECIMAL64;
|
||||||
savingsAccount.calculateInterestUsing(mc, transferDate);
|
boolean isInterestTransfer = false;
|
||||||
|
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer);
|
||||||
|
|
||||||
this.savingsAccountTransactionRepository.save(newTransferTransaction);
|
this.savingsAccountTransactionRepository.save(newTransferTransaction);
|
||||||
this.savingAccountRepository.save(savingsAccount);
|
this.savingAccountRepository.save(savingsAccount);
|
||||||
@@ -572,7 +602,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
|||||||
savingsAccount.getTransactions().add(withdrawtransferTransaction);
|
savingsAccount.getTransactions().add(withdrawtransferTransaction);
|
||||||
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
|
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
|
||||||
final MathContext mc = MathContext.DECIMAL64;
|
final MathContext mc = MathContext.DECIMAL64;
|
||||||
savingsAccount.calculateInterestUsing(mc, transferDate);
|
boolean isInterestTransfer = false;
|
||||||
|
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer);
|
||||||
|
|
||||||
this.savingsAccountTransactionRepository.save(withdrawtransferTransaction);
|
this.savingsAccountTransactionRepository.save(withdrawtransferTransaction);
|
||||||
this.savingAccountRepository.save(savingsAccount);
|
this.savingAccountRepository.save(savingsAccount);
|
||||||
@@ -605,9 +636,9 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
|||||||
if (fieldOfficer != null) {
|
if (fieldOfficer != null) {
|
||||||
savingsAccount.update(fieldOfficer);
|
savingsAccount.update(fieldOfficer);
|
||||||
}
|
}
|
||||||
|
boolean isInterestTransfer = false;
|
||||||
final MathContext mc = MathContext.DECIMAL64;
|
final MathContext mc = MathContext.DECIMAL64;
|
||||||
savingsAccount.calculateInterestUsing(mc, transferDate);
|
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer);
|
||||||
|
|
||||||
this.savingsAccountTransactionRepository.save(acceptTransferTransaction);
|
this.savingsAccountTransactionRepository.save(acceptTransferTransaction);
|
||||||
this.savingAccountRepository.save(savingsAccount);
|
this.savingAccountRepository.save(savingsAccount);
|
||||||
@@ -745,14 +776,14 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
|||||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
|
||||||
account.waiveCharge(savingsAccountChargeId);
|
account.waiveCharge(savingsAccountChargeId);
|
||||||
|
boolean isInterestTransfer = false;
|
||||||
final MathContext mc = MathContext.DECIMAL64;
|
final MathContext mc = MathContext.DECIMAL64;
|
||||||
if (account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueLocalDate())) {
|
if (account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueLocalDate())) {
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
account.postInterest(mc, today);
|
account.postInterest(mc, today, isInterestTransfer);
|
||||||
} else {
|
} else {
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
account.calculateInterestUsing(mc, today);
|
account.calculateInterestUsing(mc, today, isInterestTransfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.waiveChargeTransactionAction);
|
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.waiveChargeTransactionAction);
|
||||||
@@ -863,14 +894,14 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
|||||||
final Set<Long> existingReversedTransactionIds = new HashSet<Long>();
|
final Set<Long> existingReversedTransactionIds = new HashSet<Long>();
|
||||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||||
account.payCharge(savingsAccountCharge, amountPaid, transactionDate, formatter);
|
account.payCharge(savingsAccountCharge, amountPaid, transactionDate, formatter);
|
||||||
|
boolean isInterestTransfer = false;
|
||||||
final MathContext mc = MathContext.DECIMAL64;
|
final MathContext mc = MathContext.DECIMAL64;
|
||||||
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
account.postInterest(mc, today);
|
account.postInterest(mc, today, isInterestTransfer);
|
||||||
} else {
|
} else {
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
account.calculateInterestUsing(mc, today);
|
account.calculateInterestUsing(mc, today, isInterestTransfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
account.validateAccountBalanceDoesNotBecomeNegative("." + SavingsAccountTransactionType.PAY_CHARGE.getCode());
|
account.validateAccountBalanceDoesNotBecomeNegative("." + SavingsAccountTransactionType.PAY_CHARGE.getCode());
|
||||||
|
|||||||
+11
-1
@@ -5,6 +5,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.portfolio.savings.service;
|
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.math.MathContext;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@@ -272,13 +275,15 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
|
|||||||
if (depositAccountType.isFixedDeposit()) {
|
if (depositAccountType.isFixedDeposit()) {
|
||||||
((FixedDepositAccount) account).updateMaturityDateAndAmountBeforeAccountActivation(mc);
|
((FixedDepositAccount) account).updateMaturityDateAndAmountBeforeAccountActivation(mc);
|
||||||
} else if (depositAccountType.isRecurringDeposit()) {
|
} else if (depositAccountType.isRecurringDeposit()) {
|
||||||
final LocalDate transactionStartDate = ((RecurringDepositAccount) account).depositStartDate();
|
final LocalDate transactionStartDate = ((RecurringDepositAccount) account).depositStartDate();
|
||||||
((RecurringDepositAccount) account).updateMaturityDateAndAmount(mc, transactionStartDate);
|
((RecurringDepositAccount) account).updateMaturityDateAndAmount(mc, transactionStartDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.savingAccountRepository.saveAndFlush(account);
|
this.savingAccountRepository.saveAndFlush(account);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isLinkedAccRequired = command.booleanPrimitiveValueOfParameterNamed(transferInterestToSavingsParamName);
|
||||||
|
|
||||||
// Save linked account information
|
// Save linked account information
|
||||||
final Long savingsAccountId = command.longValueOfParameterNamed(DepositsApiConstants.linkedAccountParamName);
|
final Long savingsAccountId = command.longValueOfParameterNamed(DepositsApiConstants.linkedAccountParamName);
|
||||||
AccountAssociations accountAssociations = this.accountAssociationsRepository.findBySavingsId(accountId);
|
AccountAssociations accountAssociations = this.accountAssociationsRepository.findBySavingsId(accountId);
|
||||||
@@ -287,7 +292,12 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
|
|||||||
if (this.fromJsonHelper.parameterExists(DepositsApiConstants.linkedAccountParamName, command.parsedJson())) {
|
if (this.fromJsonHelper.parameterExists(DepositsApiConstants.linkedAccountParamName, command.parsedJson())) {
|
||||||
this.accountAssociationsRepository.delete(accountAssociations);
|
this.accountAssociationsRepository.delete(accountAssociations);
|
||||||
changes.put(DepositsApiConstants.linkedAccountParamName, null);
|
changes.put(DepositsApiConstants.linkedAccountParamName, null);
|
||||||
|
if (isLinkedAccRequired) {
|
||||||
|
this.depositAccountDataValidator.throwLinkedAccountRequiredError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else if (isLinkedAccRequired) {
|
||||||
|
this.depositAccountDataValidator.throwLinkedAccountRequiredError();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
boolean isModified = false;
|
boolean isModified = false;
|
||||||
|
|||||||
+24
-20
@@ -234,9 +234,10 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
|
|
||||||
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
|
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
|
||||||
checkClientOrGroupActive(account);
|
checkClientOrGroupActive(account);
|
||||||
|
boolean isInterestTransfer = false;
|
||||||
|
|
||||||
final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(account, fmt, transactionDate,
|
final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(account, fmt, transactionDate,
|
||||||
transactionAmount, paymentDetail, true);
|
transactionAmount, paymentDetail, true, isInterestTransfer);
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withEntityId(withdrawal.getId()) //
|
.withEntityId(withdrawal.getId()) //
|
||||||
@@ -277,8 +278,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
|
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
final MathContext mc = new MathContext(15, RoundingMode.HALF_EVEN);
|
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);
|
this.savingAccountRepository.save(account);
|
||||||
|
|
||||||
@@ -315,8 +316,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
final MathContext mc = new MathContext(10, RoundingMode.HALF_EVEN);
|
final MathContext mc = new MathContext(10, RoundingMode.HALF_EVEN);
|
||||||
|
boolean isInterestTransfer = false;
|
||||||
account.postInterest(mc, today);
|
account.postInterest(mc, today, isInterestTransfer);
|
||||||
|
|
||||||
// for generating transaction id's
|
// for generating transaction id's
|
||||||
List<SavingsAccountTransaction> transactions = account.getTransactions();
|
List<SavingsAccountTransaction> transactions = account.getTransactions();
|
||||||
@@ -378,13 +379,13 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
account.undoTransaction(transactionId + 1);
|
account.undoTransaction(transactionId + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
boolean isInterestTransfer = false;
|
||||||
checkClientOrGroupActive(account);
|
checkClientOrGroupActive(account);
|
||||||
if (savingsAccountTransaction.isPostInterestCalculationRequired()
|
if (savingsAccountTransaction.isPostInterestCalculationRequired()
|
||||||
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
|
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
|
||||||
account.postInterest(mc, today);
|
account.postInterest(mc, today, isInterestTransfer);
|
||||||
} else {
|
} else {
|
||||||
account.calculateInterestUsing(mc, today);
|
account.calculateInterestUsing(mc, today, isInterestTransfer);
|
||||||
}
|
}
|
||||||
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.undoTransactionAction);
|
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.undoTransactionAction);
|
||||||
account.activateAccountBasedOnBalance();
|
account.activateAccountBasedOnBalance();
|
||||||
@@ -443,6 +444,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
}
|
}
|
||||||
|
|
||||||
SavingsAccountTransaction transaction = null;
|
SavingsAccountTransaction transaction = null;
|
||||||
|
boolean isInterestTransfer = false;
|
||||||
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
||||||
paymentDetail, savingsAccountTransaction.createdDate());
|
paymentDetail, savingsAccountTransaction.createdDate());
|
||||||
if (savingsAccountTransaction.isDeposit()) {
|
if (savingsAccountTransaction.isDeposit()) {
|
||||||
@@ -454,9 +456,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
|
|
||||||
if (account.isBeforeLastPostingPeriod(transactionDate)
|
if (account.isBeforeLastPostingPeriod(transactionDate)
|
||||||
|| account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
|
|| account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
|
||||||
account.postInterest(mc, today);
|
account.postInterest(mc, today, isInterestTransfer);
|
||||||
} else {
|
} else {
|
||||||
account.calculateInterestUsing(mc, today);
|
account.calculateInterestUsing(mc, today, isInterestTransfer);
|
||||||
}
|
}
|
||||||
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.adjustTransactionAction);
|
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.adjustTransactionAction);
|
||||||
account.activateAccountBasedOnBalance();
|
account.activateAccountBasedOnBalance();
|
||||||
@@ -541,7 +543,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
savingsAccount.getTransactions().add(newTransferTransaction);
|
savingsAccount.getTransactions().add(newTransferTransaction);
|
||||||
savingsAccount.setStatus(SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getValue());
|
savingsAccount.setStatus(SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getValue());
|
||||||
final MathContext mc = MathContext.DECIMAL64;
|
final MathContext mc = MathContext.DECIMAL64;
|
||||||
savingsAccount.calculateInterestUsing(mc, transferDate);
|
boolean isInterestTransfer = false;
|
||||||
|
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer);
|
||||||
|
|
||||||
this.savingsAccountTransactionRepository.save(newTransferTransaction);
|
this.savingsAccountTransactionRepository.save(newTransferTransaction);
|
||||||
this.savingAccountRepository.save(savingsAccount);
|
this.savingAccountRepository.save(savingsAccount);
|
||||||
@@ -564,7 +567,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
savingsAccount.getTransactions().add(withdrawtransferTransaction);
|
savingsAccount.getTransactions().add(withdrawtransferTransaction);
|
||||||
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
|
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
|
||||||
final MathContext mc = MathContext.DECIMAL64;
|
final MathContext mc = MathContext.DECIMAL64;
|
||||||
savingsAccount.calculateInterestUsing(mc, transferDate);
|
boolean isInterestTransfer = false;
|
||||||
|
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer);
|
||||||
|
|
||||||
this.savingsAccountTransactionRepository.save(withdrawtransferTransaction);
|
this.savingsAccountTransactionRepository.save(withdrawtransferTransaction);
|
||||||
this.savingAccountRepository.save(savingsAccount);
|
this.savingAccountRepository.save(savingsAccount);
|
||||||
@@ -597,9 +601,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
if (fieldOfficer != null) {
|
if (fieldOfficer != null) {
|
||||||
savingsAccount.update(fieldOfficer);
|
savingsAccount.update(fieldOfficer);
|
||||||
}
|
}
|
||||||
|
boolean isInterestTransfer = false;
|
||||||
final MathContext mc = MathContext.DECIMAL64;
|
final MathContext mc = MathContext.DECIMAL64;
|
||||||
savingsAccount.calculateInterestUsing(mc, transferDate);
|
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer);
|
||||||
|
|
||||||
this.savingsAccountTransactionRepository.save(acceptTransferTransaction);
|
this.savingsAccountTransactionRepository.save(acceptTransferTransaction);
|
||||||
this.savingAccountRepository.save(savingsAccount);
|
this.savingAccountRepository.save(savingsAccount);
|
||||||
@@ -736,14 +740,14 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
|
||||||
account.waiveCharge(savingsAccountChargeId);
|
account.waiveCharge(savingsAccountChargeId);
|
||||||
|
boolean isInterestTransfer = false;
|
||||||
final MathContext mc = MathContext.DECIMAL64;
|
final MathContext mc = MathContext.DECIMAL64;
|
||||||
if (account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueLocalDate())) {
|
if (account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueLocalDate())) {
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
account.postInterest(mc, today);
|
account.postInterest(mc, today, isInterestTransfer);
|
||||||
} else {
|
} else {
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
account.calculateInterestUsing(mc, today);
|
account.calculateInterestUsing(mc, today, isInterestTransfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.waiveChargeTransactionAction);
|
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.waiveChargeTransactionAction);
|
||||||
@@ -852,14 +856,14 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
final Set<Long> existingReversedTransactionIds = new HashSet<Long>();
|
final Set<Long> existingReversedTransactionIds = new HashSet<Long>();
|
||||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||||
account.payCharge(savingsAccountCharge, amountPaid, transactionDate, formatter);
|
account.payCharge(savingsAccountCharge, amountPaid, transactionDate, formatter);
|
||||||
|
boolean isInterestTransfer = false;
|
||||||
final MathContext mc = MathContext.DECIMAL64;
|
final MathContext mc = MathContext.DECIMAL64;
|
||||||
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
account.postInterest(mc, today);
|
account.postInterest(mc, today, isInterestTransfer);
|
||||||
} else {
|
} else {
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
account.calculateInterestUsing(mc, today);
|
account.calculateInterestUsing(mc, today, isInterestTransfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
account.validateAccountBalanceDoesNotBecomeNegative("." + SavingsAccountTransactionType.PAY_CHARGE.getCode());
|
account.validateAccountBalanceDoesNotBecomeNegative("." + SavingsAccountTransactionType.PAY_CHARGE.getCode());
|
||||||
|
|||||||
Reference in New Issue
Block a user