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