Merge pull request #313 from vishwasbabu/wuyanna-master

Apply annual fees for savings accounts
This commit is contained in:
Vishwas Babu A J
2013-05-27 09:20:51 -07:00
7 changed files with 203 additions and 77 deletions
@@ -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);
@@ -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);
@@ -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();
@@ -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());
}
}
@@ -10,4 +10,6 @@ public interface ScheduledJobRunnerService {
void updateLoanSummaryDetails(); void updateLoanSummaryDetails();
void updateLoanArrearsAgeingDetails(); void updateLoanArrearsAgeingDetails();
void applyAnnualFeeForSavings();
} }
@@ -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>