Merge pull request #313 from vishwasbabu/wuyanna-master
Apply annual fees for savings accounts
This commit is contained in:
+5
-6
@@ -897,11 +897,6 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***TODO Fixme: Annual fee seems to be added for all withdrawals?**/
|
|
||||||
final Money annualFee = Money.of(this.currency, this.annualFeeAmount);
|
|
||||||
SavingsAccountTransaction annualFeeTransaction = SavingsAccountTransaction.annualFee(this, transactionDate, annualFee);
|
|
||||||
this.transactions.add(annualFeeTransaction);
|
|
||||||
|
|
||||||
this.summary.updateSummary(this.currency, this.savingsAccountTransactionSummaryWrapper, this.transactions);
|
this.summary.updateSummary(this.currency, this.savingsAccountTransactionSummaryWrapper, this.transactions);
|
||||||
|
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
@@ -910,7 +905,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
return transaction;
|
return transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SavingsAccountTransaction addAnnualFee(final DateTimeFormatter formatter, final LocalDate transactionDate) {
|
public SavingsAccountTransaction addAnnualFee(final DateTimeFormatter formatter, final LocalDate transactionDate,
|
||||||
|
List<Long> existingTransactionIds, List<Long> existingReversedTransactionIds) {
|
||||||
|
|
||||||
if (isNotActive()) {
|
if (isNotActive()) {
|
||||||
|
|
||||||
@@ -961,6 +957,9 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
existingTransactionIds.addAll(findExistingTransactionIds());
|
||||||
|
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
||||||
|
|
||||||
final Money annualFee = Money.of(this.currency, this.annualFeeAmount);
|
final Money annualFee = Money.of(this.currency, this.annualFeeAmount);
|
||||||
SavingsAccountTransaction annualFeeTransaction = SavingsAccountTransaction.annualFee(this, transactionDate, annualFee);
|
SavingsAccountTransaction annualFeeTransaction = SavingsAccountTransaction.annualFee(this, transactionDate, annualFee);
|
||||||
this.transactions.add(annualFeeTransaction);
|
this.transactions.add(annualFeeTransaction);
|
||||||
|
|||||||
+2
@@ -21,6 +21,8 @@ public interface SavingsAccountWritePlatformService {
|
|||||||
CommandProcessingResult deposit(Long savingsId, JsonCommand command);
|
CommandProcessingResult deposit(Long savingsId, JsonCommand command);
|
||||||
|
|
||||||
CommandProcessingResult withdrawal(Long savingsId, JsonCommand command);
|
CommandProcessingResult withdrawal(Long savingsId, JsonCommand command);
|
||||||
|
|
||||||
|
CommandProcessingResult applyAnnualFee(Long savingsId);
|
||||||
|
|
||||||
CommandProcessingResult calculateInterest(Long savingsId, JsonCommand command);
|
CommandProcessingResult calculateInterest(Long savingsId, JsonCommand command);
|
||||||
|
|
||||||
|
|||||||
+29
@@ -359,6 +359,35 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public CommandProcessingResult applyAnnualFee(final Long savingsId) {
|
||||||
|
|
||||||
|
final SavingsAccount account = this.savingAccountRepository.findOneWithNotFoundDetection(savingsId);
|
||||||
|
|
||||||
|
final LocalDate transactionDate = LocalDate.now();
|
||||||
|
|
||||||
|
final DateTimeFormatter fmt = DateTimeFormat.forPattern("dd MM yyyy");
|
||||||
|
|
||||||
|
final List<Long> existingTransactionIds = new ArrayList<Long>();
|
||||||
|
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
|
||||||
|
|
||||||
|
final SavingsAccountTransaction annualFee = account.addAnnualFee(fmt, transactionDate, existingTransactionIds,
|
||||||
|
existingReversedTransactionIds);
|
||||||
|
final Long transactionId = saveTransactionToGenerateTransactionId(annualFee);
|
||||||
|
this.savingAccountRepository.save(account);
|
||||||
|
|
||||||
|
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
|
||||||
|
return new CommandProcessingResultBuilder() //
|
||||||
|
.withEntityId(transactionId) //
|
||||||
|
.withOfficeId(account.officeId()) //
|
||||||
|
.withClientId(account.clientId()) //
|
||||||
|
.withGroupId(account.groupId()) //
|
||||||
|
.withSavingsId(savingsId) //
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandProcessingResult calculateInterest(final Long savingsId, final JsonCommand command) {
|
public CommandProcessingResult calculateInterest(final Long savingsId, final JsonCommand command) {
|
||||||
this.context.authenticatedUser();
|
this.context.authenticatedUser();
|
||||||
|
|||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
package org.mifosplatform.scheduledjobs;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.mifosplatform.scheduledjobs.service.ScheduledJobRunnerService;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class ApplyAnnualFeeForSavingsScheduledJob {
|
||||||
|
|
||||||
|
private final static Logger logger = LoggerFactory.getLogger(ApplyAnnualFeeForSavingsScheduledJob.class);
|
||||||
|
|
||||||
|
private final ScheduledJobRunnerService scheduledJobRunnerService;
|
||||||
|
|
||||||
|
public ApplyAnnualFeeForSavingsScheduledJob(final ScheduledJobRunnerService scheduledJobRunnerService) {
|
||||||
|
this.scheduledJobRunnerService = scheduledJobRunnerService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void execute() {
|
||||||
|
logger.info("Running Job ApplyAnnualFeeForSavingsScheduledJob " + new Date());
|
||||||
|
|
||||||
|
this.scheduledJobRunnerService.applyAnnualFeeForSavings();
|
||||||
|
|
||||||
|
logger.info("Finishing Job ApplyAnnualFeeForSavingsScheduledJob " + new Date());
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -10,4 +10,6 @@ public interface ScheduledJobRunnerService {
|
|||||||
void updateLoanSummaryDetails();
|
void updateLoanSummaryDetails();
|
||||||
|
|
||||||
void updateLoanArrearsAgeingDetails();
|
void updateLoanArrearsAgeingDetails();
|
||||||
|
|
||||||
|
void applyAnnualFeeForSavings();
|
||||||
}
|
}
|
||||||
|
|||||||
+67
-26
@@ -5,10 +5,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.scheduledjobs.service;
|
package org.mifosplatform.scheduledjobs.service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenant;
|
import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenant;
|
||||||
import org.mifosplatform.infrastructure.core.service.DataSourcePerTenantService;
|
import org.mifosplatform.infrastructure.core.service.DataSourcePerTenantService;
|
||||||
import org.mifosplatform.infrastructure.core.service.ThreadLocalContextUtil;
|
import org.mifosplatform.infrastructure.core.service.ThreadLocalContextUtil;
|
||||||
import org.mifosplatform.infrastructure.security.service.TenantDetailsService;
|
import org.mifosplatform.infrastructure.security.service.TenantDetailsService;
|
||||||
|
import org.mifosplatform.portfolio.savings.service.SavingsAccountWritePlatformService;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -23,18 +26,20 @@ public class ScheduledJobRunnerServiceImpl implements ScheduledJobRunnerService
|
|||||||
|
|
||||||
private final TenantDetailsService tenantDetailsService;
|
private final TenantDetailsService tenantDetailsService;
|
||||||
private final DataSourcePerTenantService dataSourcePerTenantService;
|
private final DataSourcePerTenantService dataSourcePerTenantService;
|
||||||
|
private final SavingsAccountWritePlatformService savingsAccountWritePlatformService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ScheduledJobRunnerServiceImpl(final DataSourcePerTenantService dataSourcePerTenantService,
|
public ScheduledJobRunnerServiceImpl(final DataSourcePerTenantService dataSourcePerTenantService,
|
||||||
final TenantDetailsService tenantDetailsService) {
|
final TenantDetailsService tenantDetailsService, final SavingsAccountWritePlatformService savingsAccountWritePlatformService) {
|
||||||
this.dataSourcePerTenantService = dataSourcePerTenantService;
|
this.dataSourcePerTenantService = dataSourcePerTenantService;
|
||||||
this.tenantDetailsService = tenantDetailsService;
|
this.tenantDetailsService = tenantDetailsService;
|
||||||
|
this.savingsAccountWritePlatformService = savingsAccountWritePlatformService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
public void updateLoanSummaryDetails() {
|
public void updateLoanSummaryDetails() {
|
||||||
|
|
||||||
final MifosPlatformTenant tenant = this.tenantDetailsService.loadTenantById("default");
|
final MifosPlatformTenant tenant = this.tenantDetailsService.loadTenantById("default");
|
||||||
|
|
||||||
ThreadLocalContextUtil.setTenant(tenant);
|
ThreadLocalContextUtil.setTenant(tenant);
|
||||||
@@ -65,38 +70,51 @@ public class ScheduledJobRunnerServiceImpl implements ScheduledJobRunnerService
|
|||||||
updateSqlBuilder.append("WHERE ml.disbursedon_date is not null ");
|
updateSqlBuilder.append("WHERE ml.disbursedon_date is not null ");
|
||||||
updateSqlBuilder.append("GROUP BY ml.id ");
|
updateSqlBuilder.append("GROUP BY ml.id ");
|
||||||
updateSqlBuilder.append(") x on x.loanId = m_loan.id ");
|
updateSqlBuilder.append(") x on x.loanId = m_loan.id ");
|
||||||
|
|
||||||
updateSqlBuilder.append("SET m_loan.principal_disbursed_derived = x.principal_disbursed_derived,");
|
updateSqlBuilder.append("SET m_loan.principal_disbursed_derived = x.principal_disbursed_derived,");
|
||||||
updateSqlBuilder.append("m_loan.principal_repaid_derived = x.principal_repaid_derived,");
|
updateSqlBuilder.append("m_loan.principal_repaid_derived = x.principal_repaid_derived,");
|
||||||
updateSqlBuilder.append("m_loan.principal_writtenoff_derived = x.principal_writtenoff_derived,");
|
updateSqlBuilder.append("m_loan.principal_writtenoff_derived = x.principal_writtenoff_derived,");
|
||||||
updateSqlBuilder.append("m_loan.principal_outstanding_derived = (x.principal_disbursed_derived - (x.principal_repaid_derived + x.principal_writtenoff_derived)),");
|
updateSqlBuilder
|
||||||
|
.append("m_loan.principal_outstanding_derived = (x.principal_disbursed_derived - (x.principal_repaid_derived + x.principal_writtenoff_derived)),");
|
||||||
updateSqlBuilder.append("m_loan.interest_charged_derived = x.interest_charged_derived,");
|
updateSqlBuilder.append("m_loan.interest_charged_derived = x.interest_charged_derived,");
|
||||||
updateSqlBuilder.append("m_loan.interest_repaid_derived = x.interest_repaid_derived,");
|
updateSqlBuilder.append("m_loan.interest_repaid_derived = x.interest_repaid_derived,");
|
||||||
updateSqlBuilder.append("m_loan.interest_waived_derived = x.interest_waived_derived,");
|
updateSqlBuilder.append("m_loan.interest_waived_derived = x.interest_waived_derived,");
|
||||||
updateSqlBuilder.append("m_loan.interest_writtenoff_derived = x.interest_writtenoff_derived,");
|
updateSqlBuilder.append("m_loan.interest_writtenoff_derived = x.interest_writtenoff_derived,");
|
||||||
updateSqlBuilder.append("m_loan.interest_outstanding_derived = (x.interest_charged_derived - (x.interest_repaid_derived + x.interest_waived_derived + x.interest_writtenoff_derived)),");
|
updateSqlBuilder
|
||||||
|
.append("m_loan.interest_outstanding_derived = (x.interest_charged_derived - (x.interest_repaid_derived + x.interest_waived_derived + x.interest_writtenoff_derived)),");
|
||||||
updateSqlBuilder.append("m_loan.fee_charges_charged_derived = x.fee_charges_charged_derived,");
|
updateSqlBuilder.append("m_loan.fee_charges_charged_derived = x.fee_charges_charged_derived,");
|
||||||
updateSqlBuilder.append("m_loan.fee_charges_repaid_derived = x.fee_charges_repaid_derived,");
|
updateSqlBuilder.append("m_loan.fee_charges_repaid_derived = x.fee_charges_repaid_derived,");
|
||||||
updateSqlBuilder.append("m_loan.fee_charges_waived_derived = x.fee_charges_waived_derived,");
|
updateSqlBuilder.append("m_loan.fee_charges_waived_derived = x.fee_charges_waived_derived,");
|
||||||
updateSqlBuilder.append("m_loan.fee_charges_writtenoff_derived = x.fee_charges_writtenoff_derived,");
|
updateSqlBuilder.append("m_loan.fee_charges_writtenoff_derived = x.fee_charges_writtenoff_derived,");
|
||||||
updateSqlBuilder.append("m_loan.fee_charges_outstanding_derived = (x.fee_charges_charged_derived - (x.fee_charges_repaid_derived + x.fee_charges_waived_derived + x.fee_charges_writtenoff_derived)),");
|
updateSqlBuilder
|
||||||
|
.append("m_loan.fee_charges_outstanding_derived = (x.fee_charges_charged_derived - (x.fee_charges_repaid_derived + x.fee_charges_waived_derived + x.fee_charges_writtenoff_derived)),");
|
||||||
updateSqlBuilder.append("m_loan.penalty_charges_charged_derived = x.penalty_charges_charged_derived,");
|
updateSqlBuilder.append("m_loan.penalty_charges_charged_derived = x.penalty_charges_charged_derived,");
|
||||||
updateSqlBuilder.append("m_loan.penalty_charges_repaid_derived = x.penalty_charges_repaid_derived,");
|
updateSqlBuilder.append("m_loan.penalty_charges_repaid_derived = x.penalty_charges_repaid_derived,");
|
||||||
updateSqlBuilder.append("m_loan.penalty_charges_waived_derived = x.penalty_charges_waived_derived,");
|
updateSqlBuilder.append("m_loan.penalty_charges_waived_derived = x.penalty_charges_waived_derived,");
|
||||||
updateSqlBuilder.append("m_loan.penalty_charges_writtenoff_derived = x.penalty_charges_writtenoff_derived,");
|
updateSqlBuilder.append("m_loan.penalty_charges_writtenoff_derived = x.penalty_charges_writtenoff_derived,");
|
||||||
updateSqlBuilder.append("m_loan.penalty_charges_outstanding_derived = (x.penalty_charges_charged_derived - (x.penalty_charges_repaid_derived + x.penalty_charges_waived_derived + x.penalty_charges_writtenoff_derived)),");
|
updateSqlBuilder
|
||||||
updateSqlBuilder.append("m_loan.total_expected_repayment_derived = (x.principal_disbursed_derived + x.interest_charged_derived + x.fee_charges_charged_derived + x.penalty_charges_charged_derived),");
|
.append("m_loan.penalty_charges_outstanding_derived = (x.penalty_charges_charged_derived - (x.penalty_charges_repaid_derived + x.penalty_charges_waived_derived + x.penalty_charges_writtenoff_derived)),");
|
||||||
updateSqlBuilder.append("m_loan.total_repayment_derived = (x.principal_repaid_derived + x.interest_repaid_derived + x.fee_charges_repaid_derived + x.penalty_charges_repaid_derived),");
|
updateSqlBuilder
|
||||||
updateSqlBuilder.append("m_loan.total_expected_costofloan_derived = (x.interest_charged_derived + x.fee_charges_charged_derived + x.penalty_charges_charged_derived),");
|
.append("m_loan.total_expected_repayment_derived = (x.principal_disbursed_derived + x.interest_charged_derived + x.fee_charges_charged_derived + x.penalty_charges_charged_derived),");
|
||||||
updateSqlBuilder.append("m_loan.total_costofloan_derived = (x.interest_repaid_derived + x.fee_charges_repaid_derived + x.penalty_charges_repaid_derived),");
|
updateSqlBuilder
|
||||||
updateSqlBuilder.append("m_loan.total_waived_derived = (x.interest_waived_derived + x.fee_charges_waived_derived + x.penalty_charges_waived_derived),");
|
.append("m_loan.total_repayment_derived = (x.principal_repaid_derived + x.interest_repaid_derived + x.fee_charges_repaid_derived + x.penalty_charges_repaid_derived),");
|
||||||
updateSqlBuilder.append("m_loan.total_writtenoff_derived = (x.interest_writtenoff_derived + x.fee_charges_writtenoff_derived + x.penalty_charges_writtenoff_derived),");
|
updateSqlBuilder
|
||||||
|
.append("m_loan.total_expected_costofloan_derived = (x.interest_charged_derived + x.fee_charges_charged_derived + x.penalty_charges_charged_derived),");
|
||||||
|
updateSqlBuilder
|
||||||
|
.append("m_loan.total_costofloan_derived = (x.interest_repaid_derived + x.fee_charges_repaid_derived + x.penalty_charges_repaid_derived),");
|
||||||
|
updateSqlBuilder
|
||||||
|
.append("m_loan.total_waived_derived = (x.interest_waived_derived + x.fee_charges_waived_derived + x.penalty_charges_waived_derived),");
|
||||||
|
updateSqlBuilder
|
||||||
|
.append("m_loan.total_writtenoff_derived = (x.interest_writtenoff_derived + x.fee_charges_writtenoff_derived + x.penalty_charges_writtenoff_derived),");
|
||||||
updateSqlBuilder.append("m_loan.total_outstanding_derived=");
|
updateSqlBuilder.append("m_loan.total_outstanding_derived=");
|
||||||
updateSqlBuilder.append(" (x.principal_disbursed_derived - (x.principal_repaid_derived + x.principal_writtenoff_derived)) + ");
|
updateSqlBuilder.append(" (x.principal_disbursed_derived - (x.principal_repaid_derived + x.principal_writtenoff_derived)) + ");
|
||||||
updateSqlBuilder.append(" (x.interest_charged_derived - (x.interest_repaid_derived + x.interest_waived_derived + x.interest_writtenoff_derived)) +");
|
updateSqlBuilder
|
||||||
updateSqlBuilder.append(" (x.fee_charges_charged_derived - (x.fee_charges_repaid_derived + x.fee_charges_waived_derived + x.fee_charges_writtenoff_derived)) +");
|
.append(" (x.interest_charged_derived - (x.interest_repaid_derived + x.interest_waived_derived + x.interest_writtenoff_derived)) +");
|
||||||
updateSqlBuilder.append(" (x.penalty_charges_charged_derived - (x.penalty_charges_repaid_derived + x.penalty_charges_waived_derived + x.penalty_charges_writtenoff_derived))");
|
updateSqlBuilder
|
||||||
|
.append(" (x.fee_charges_charged_derived - (x.fee_charges_repaid_derived + x.fee_charges_waived_derived + x.fee_charges_writtenoff_derived)) +");
|
||||||
|
updateSqlBuilder
|
||||||
|
.append(" (x.penalty_charges_charged_derived - (x.penalty_charges_repaid_derived + x.penalty_charges_waived_derived + x.penalty_charges_writtenoff_derived))");
|
||||||
|
|
||||||
int result = jdbcTemplate.update(updateSqlBuilder.toString());
|
int result = jdbcTemplate.update(updateSqlBuilder.toString());
|
||||||
|
|
||||||
logger.info("Results affected by update: " + result);
|
logger.info("Results affected by update: " + result);
|
||||||
@@ -112,19 +130,24 @@ public class ScheduledJobRunnerServiceImpl implements ScheduledJobRunnerService
|
|||||||
|
|
||||||
jdbcTemplate.execute("truncate table m_loan_arrears_aging");
|
jdbcTemplate.execute("truncate table m_loan_arrears_aging");
|
||||||
|
|
||||||
|
|
||||||
StringBuilder updateSqlBuilder = new StringBuilder(900);
|
StringBuilder updateSqlBuilder = new StringBuilder(900);
|
||||||
|
|
||||||
updateSqlBuilder.append("INSERT INTO m_loan_arrears_aging(`loan_id`,`principal_overdue_derived`,`interest_overdue_derived`,`fee_charges_overdue_derived`,`penalty_charges_overdue_derived`,`total_overdue_derived`,`overdue_since_date_derived`)");
|
updateSqlBuilder
|
||||||
|
.append("INSERT INTO m_loan_arrears_aging(`loan_id`,`principal_overdue_derived`,`interest_overdue_derived`,`fee_charges_overdue_derived`,`penalty_charges_overdue_derived`,`total_overdue_derived`,`overdue_since_date_derived`)");
|
||||||
updateSqlBuilder.append("select ml.id as loanId,");
|
updateSqlBuilder.append("select ml.id as loanId,");
|
||||||
updateSqlBuilder.append("SUM((ifnull(mr.principal_amount,0) - ifnull(mr.principal_completed_derived, 0))) as principal_overdue_derived,");
|
updateSqlBuilder
|
||||||
updateSqlBuilder.append("SUM((ifnull(mr.interest_amount,0) - ifnull(mr.interest_completed_derived, 0))) as interest_overdue_derived,");
|
.append("SUM((ifnull(mr.principal_amount,0) - ifnull(mr.principal_completed_derived, 0))) as principal_overdue_derived,");
|
||||||
updateSqlBuilder.append("SUM((ifnull(mr.fee_charges_amount,0) - ifnull(mr.fee_charges_completed_derived, 0))) as fee_charges_overdue_derived,");
|
updateSqlBuilder
|
||||||
updateSqlBuilder.append("SUM((ifnull(mr.penalty_charges_amount,0) - ifnull(mr.penalty_charges_completed_derived, 0))) as penalty_charges_overdue_derived,");
|
.append("SUM((ifnull(mr.interest_amount,0) - ifnull(mr.interest_completed_derived, 0))) as interest_overdue_derived,");
|
||||||
|
updateSqlBuilder
|
||||||
|
.append("SUM((ifnull(mr.fee_charges_amount,0) - ifnull(mr.fee_charges_completed_derived, 0))) as fee_charges_overdue_derived,");
|
||||||
|
updateSqlBuilder
|
||||||
|
.append("SUM((ifnull(mr.penalty_charges_amount,0) - ifnull(mr.penalty_charges_completed_derived, 0))) as penalty_charges_overdue_derived,");
|
||||||
updateSqlBuilder.append("SUM((ifnull(mr.principal_amount,0) - ifnull(mr.principal_completed_derived, 0))) +");
|
updateSqlBuilder.append("SUM((ifnull(mr.principal_amount,0) - ifnull(mr.principal_completed_derived, 0))) +");
|
||||||
updateSqlBuilder.append("SUM((ifnull(mr.interest_amount,0) - ifnull(mr.interest_completed_derived, 0))) +");
|
updateSqlBuilder.append("SUM((ifnull(mr.interest_amount,0) - ifnull(mr.interest_completed_derived, 0))) +");
|
||||||
updateSqlBuilder.append("SUM((ifnull(mr.fee_charges_amount,0) - ifnull(mr.fee_charges_completed_derived, 0))) +");
|
updateSqlBuilder.append("SUM((ifnull(mr.fee_charges_amount,0) - ifnull(mr.fee_charges_completed_derived, 0))) +");
|
||||||
updateSqlBuilder.append("SUM((ifnull(mr.penalty_charges_amount,0) - ifnull(mr.penalty_charges_completed_derived, 0))) as total_overdue_derived,");
|
updateSqlBuilder
|
||||||
|
.append("SUM((ifnull(mr.penalty_charges_amount,0) - ifnull(mr.penalty_charges_completed_derived, 0))) as total_overdue_derived,");
|
||||||
updateSqlBuilder.append("MIN(mr.duedate) as overdue_since_date_derived ");
|
updateSqlBuilder.append("MIN(mr.duedate) as overdue_since_date_derived ");
|
||||||
updateSqlBuilder.append(" FROM m_loan ml ");
|
updateSqlBuilder.append(" FROM m_loan ml ");
|
||||||
updateSqlBuilder.append(" INNER JOIN m_loan_repayment_schedule mr on mr.loan_id = ml.id ");
|
updateSqlBuilder.append(" INNER JOIN m_loan_repayment_schedule mr on mr.loan_id = ml.id ");
|
||||||
@@ -132,9 +155,27 @@ public class ScheduledJobRunnerServiceImpl implements ScheduledJobRunnerService
|
|||||||
updateSqlBuilder.append(" and mr.completed_derived is false ");
|
updateSqlBuilder.append(" and mr.completed_derived is false ");
|
||||||
updateSqlBuilder.append(" and mr.duedate < CURDATE() ");
|
updateSqlBuilder.append(" and mr.duedate < CURDATE() ");
|
||||||
updateSqlBuilder.append(" GROUP BY ml.id");
|
updateSqlBuilder.append(" GROUP BY ml.id");
|
||||||
|
|
||||||
int result = jdbcTemplate.update(updateSqlBuilder.toString());
|
int result = jdbcTemplate.update(updateSqlBuilder.toString());
|
||||||
|
|
||||||
logger.info("Results affected by update: " + result);
|
logger.info("Results affected by update: " + result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyAnnualFeeForSavings() {
|
||||||
|
final MifosPlatformTenant tenant = this.tenantDetailsService.loadTenantById("default");
|
||||||
|
|
||||||
|
ThreadLocalContextUtil.setTenant(tenant);
|
||||||
|
|
||||||
|
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSourcePerTenantService.retrieveTenantAwareDataSource());
|
||||||
|
|
||||||
|
String sql = "SELECT ms.id as savingsAccountId FROM m_savings_account ms WHERE ms.annual_fee_next_due_date <= NOW() ";
|
||||||
|
List<Long> savingsIds = jdbcTemplate.queryForList(sql, Long.class);
|
||||||
|
|
||||||
|
for (Long savingsId : savingsIds) {
|
||||||
|
this.savingsAccountWritePlatformService.applyAnnualFee(savingsId);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("Results affected by update: " + savingsIds.size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,52 +1,74 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--
|
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
This Source Code Form is subject to the terms of the Mozilla Public
|
You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||||
License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
||||||
You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
-->
|
|
||||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||||
|
|
||||||
<bean id="updateLoanSummariesScheduledJob" class="org.mifosplatform.scheduledjobs.UpdateLoanSummariesScheduledJob">
|
<bean id="updateLoanSummariesScheduledJob"
|
||||||
<constructor-arg ref="scheduledJobRunnerService" />
|
class="org.mifosplatform.scheduledjobs.UpdateLoanSummariesScheduledJob">
|
||||||
</bean>
|
<constructor-arg ref="scheduledJobRunnerService" />
|
||||||
<bean id="updateLoanArrearsAgeingScheduledJob" class="org.mifosplatform.scheduledjobs.UpdateLoanArrearsAgeingScheduledJob">
|
</bean>
|
||||||
<constructor-arg ref="scheduledJobRunnerService" />
|
<bean id="updateLoanArrearsAgeingScheduledJob"
|
||||||
</bean>
|
class="org.mifosplatform.scheduledjobs.UpdateLoanArrearsAgeingScheduledJob">
|
||||||
|
<constructor-arg ref="scheduledJobRunnerService" />
|
||||||
|
</bean>
|
||||||
|
<bean id="applyAnnualFeeForSavingsScheduledJob"
|
||||||
|
class="org.mifosplatform.scheduledjobs.ApplyAnnualFeeForSavingsScheduledJob">
|
||||||
|
<constructor-arg ref="scheduledJobRunnerService" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
<bean id="updateLoanSummariesJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
|
<bean id="updateLoanSummariesJobDetail"
|
||||||
<property name="group" value="mifosJobs" />
|
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
|
||||||
<property name="targetObject" ref="updateLoanSummariesScheduledJob" />
|
<property name="group" value="mifosJobs" />
|
||||||
<property name="targetMethod" value="execute" />
|
<property name="targetObject" ref="updateLoanSummariesScheduledJob" />
|
||||||
<property name="concurrent" value="false" />
|
<property name="targetMethod" value="execute" />
|
||||||
</bean>
|
<property name="concurrent" value="false" />
|
||||||
|
</bean>
|
||||||
<bean id="UpdateLoanArrearsAgeingJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
|
|
||||||
<property name="group" value="mifosJobs" />
|
|
||||||
<property name="targetObject" ref="updateLoanArrearsAgeingScheduledJob" />
|
|
||||||
<property name="targetMethod" value="execute" />
|
|
||||||
<property name="concurrent" value="false" />
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="updateLoanSummariesJobCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
|
<bean id="updateLoanArrearsAgeingJobDetail"
|
||||||
<property name="jobDetail" ref="updateLoanSummariesJobDetail" />
|
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
|
||||||
<property name="cronExpression" value="0 0 22 1/1 * ? *" />
|
<property name="group" value="mifosJobs" />
|
||||||
</bean>
|
<property name="targetObject" ref="updateLoanArrearsAgeingScheduledJob" />
|
||||||
|
<property name="targetMethod" value="execute" />
|
||||||
<bean id="UpdateLoanArrearsAgeingJobDetailCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
|
<property name="concurrent" value="false" />
|
||||||
<property name="jobDetail" ref="UpdateLoanArrearsAgeingJobDetail" />
|
</bean>
|
||||||
<property name="cronExpression" value="0 10 22 1/1 * ? *" />
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean name="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
|
<bean id="applyAnnualFeeForSavingsJobDetail"
|
||||||
<property name="triggers">
|
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
|
||||||
<list>
|
<property name="group" value="mifosJobs" />
|
||||||
<ref bean="updateLoanSummariesJobCronTrigger" />
|
<property name="targetObject" ref="applyAnnualFeeForSavingsScheduledJob" />
|
||||||
<ref bean="UpdateLoanArrearsAgeingJobDetailCronTrigger" />
|
<property name="targetMethod" value="execute" />
|
||||||
</list>
|
<property name="concurrent" value="false" />
|
||||||
</property>
|
</bean>
|
||||||
</bean>
|
|
||||||
|
<bean id="updateLoanSummariesJobCronTrigger"
|
||||||
|
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
|
||||||
|
<property name="jobDetail" ref="updateLoanSummariesJobDetail" />
|
||||||
|
<property name="cronExpression" value="0 0 22 1/1 * ? *" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="updateLoanArrearsAgeingJobDetailCronTrigger"
|
||||||
|
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
|
||||||
|
<property name="jobDetail" ref="updateLoanArrearsAgeingJobDetail" />
|
||||||
|
<property name="cronExpression" value="0 10 22 1/1 * ? *" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="applyAnnualFeeForSavingsJobDetailCronTrigger"
|
||||||
|
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
|
||||||
|
<property name="jobDetail" ref="applyAnnualFeeForSavingsJobDetail" />
|
||||||
|
<property name="cronExpression" value="0 20 22 1/1 * ? *" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean name="schedulerFactory"
|
||||||
|
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
|
||||||
|
<property name="triggers">
|
||||||
|
<list>
|
||||||
|
<ref bean="updateLoanSummariesJobCronTrigger" />
|
||||||
|
<ref bean="updateLoanArrearsAgeingJobDetailCronTrigger" />
|
||||||
|
<ref bean="applyAnnualFeeForSavingsJobDetailCronTrigger" />
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
</beans>
|
</beans>
|
||||||
Reference in New Issue
Block a user