minor changes to batch jobs code

This commit is contained in:
Vishwas Babu A J
2013-07-13 20:03:29 +05:30
parent bb12ed1c45
commit aa8a6873e0
17 changed files with 354 additions and 293 deletions
@@ -0,0 +1,20 @@
RENAME TABLE `scheduled_jobs` TO `job`;
RENAME TABLE `scheduled_job_runhistory` TO `job_run_history`;
ALTER TABLE `job`
ALTER `job_name` DROP DEFAULT,
ALTER `job_display_name` DROP DEFAULT;
ALTER TABLE `job`
CHANGE COLUMN `job_name` `name` VARCHAR(50) NOT NULL,
CHANGE COLUMN `job_display_name` `display_name` VARCHAR(50) NOT NULL;
ALTER TABLE `job`
CHANGE COLUMN `job_initializing_errorlog` `initializing_errorlog` TEXT NULL;
ALTER TABLE `job_run_history`
ALTER `triggertype` DROP DEFAULT;
ALTER TABLE `job_run_history`
CHANGE COLUMN `errormessage` `error_message` VARCHAR(500) NULL DEFAULT NULL,
CHANGE COLUMN `triggertype` `trigger_type` VARCHAR(25) NOT NULL,
CHANGE COLUMN `errorlog` `error_log` TEXT NULL;
@@ -1,4 +1,4 @@
package org.mifosplatform.scheduledjobs.annotation;
package org.mifosplatform.infrastructure.jobs.annotation;
import java.io.IOException;
import java.lang.annotation.Annotation;
@@ -6,6 +6,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.mifosplatform.infrastructure.jobs.service.JobName;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
@@ -38,11 +39,11 @@ public class CronMethodParser {
public static final int METHOD_INDEX = 1;
public static String[] findTargetMethodDetails(String attriuteValue) throws IOException {
if (!targetMethosMap.containsKey(attriuteValue)) {
findAnnotationMethods(CronTargetMethod.class, CRON_ANNOTATION_ATTRIBUTE_NAME);
public static String[] findTargetMethodDetails(String attributeValue) throws IOException {
if (!targetMethosMap.containsKey(attributeValue)) {
findAnnotationMethods(CronTarget.class, CRON_ANNOTATION_ATTRIBUTE_NAME);
}
return targetMethosMap.get(attriuteValue);
return targetMethosMap.get(attributeValue);
}
/**
@@ -61,13 +62,20 @@ public class CronMethodParser {
if (metadataSet != null && metadataSet.size() > 0) {
for (MethodMetadata metadata : metadataSet) {
Map<String, Object> attributes = metadata.getAnnotationAttributes(annotationClass.getName());
String attributeValue = (String) attributes.get(attributeName);
JobName attributeValue = (JobName) attributes.get(attributeName);
String className = metadata.getDeclaringClassName();
if (attributeValue == null || attributeValue.trim().length() < 1) {
attributeValue = className.substring(className.lastIndexOf(".") + 1);
}
/**
* TODO: Vishwas, have commented out this piece of code,
* check its need with Pramod
**/
/**
* if (attributeValue == null ||
* attributeValue.trim().length() < 1) { attributeValue
* = className.substring(className.lastIndexOf(".") +
* 1); }
**/
String[] mapVal = { className, metadata.getMethodName() };
targetMethosMap.put(attributeValue, mapVal);
targetMethosMap.put(attributeValue.toString(), mapVal);
}
}
}
@@ -1,10 +1,12 @@
package org.mifosplatform.scheduledjobs.annotation;
package org.mifosplatform.infrastructure.jobs.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.mifosplatform.infrastructure.jobs.service.JobName;
/**
* Annotation that marks a method to be picked while scheduling a cron jobs.
*
@@ -12,7 +14,7 @@ import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CronTargetMethod {
public @interface CronTarget {
String jobName() default "";
JobName jobName();
}
@@ -1,4 +1,4 @@
package org.mifosplatform.scheduledjobs.domain;
package org.mifosplatform.infrastructure.jobs.domain;
import java.util.Date;
@@ -11,13 +11,13 @@ import javax.persistence.TemporalType;
import org.springframework.data.jpa.domain.AbstractPersistable;
@Entity
@Table(name = "scheduled_jobs")
public class ScheduledJobDetails extends AbstractPersistable<Long> {
@Table(name = "job")
public class ScheduledJobDetail extends AbstractPersistable<Long> {
@Column(name = "job_name")
@Column(name = "name")
private String jobName;
@Column(name = "job_display_name")
@Column(name = "display_name")
private String jobDisplayName;
@Column(name = "cron_expression")
@@ -44,17 +44,17 @@ public class ScheduledJobDetails extends AbstractPersistable<Long> {
@Column(name = "trigger_key")
private String triggerKey;
@Column(name = "job_initializing_errorlog")
@Column(name = "initializing_errorlog")
private String errorLog;
@Column(name = "is_active")
private boolean activeSchedular;
public ScheduledJobDetails() {
public ScheduledJobDetail() {
}
public ScheduledJobDetails(final String jobName, final String jobDisplayName, final String croneExpression, Date createTime,
public ScheduledJobDetail(final String jobName, final String jobDisplayName, final String croneExpression, Date createTime,
final Short taskPriority, final String groupName, final Date previousRunStartTime, final Date nextRunTime,
final String triggKey, final String errorLog, final boolean activeSchedular) {
this.jobName = jobName;
@@ -0,0 +1,14 @@
package org.mifosplatform.infrastructure.jobs.domain;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface ScheduledJobDetailRepository extends JpaRepository<ScheduledJobDetail, Long>,
JpaSpecificationExecutor<ScheduledJobDetail> {
@Query("from ScheduledJobDetail jobDetail where jobDetail.triggerKey = :triggerKey")
ScheduledJobDetail findByTriggerKey(@Param("triggerKey") String triggerKey);
}
@@ -1,4 +1,4 @@
package org.mifosplatform.scheduledjobs.domain;
package org.mifosplatform.infrastructure.jobs.domain;
import java.util.Date;
@@ -13,12 +13,12 @@ import javax.persistence.TemporalType;
import org.springframework.data.jpa.domain.AbstractPersistable;
@Entity
@Table(name = "scheduled_job_runhistory")
@Table(name = "job_run_history")
public class ScheduledJobRunHistory extends AbstractPersistable<Long> {
@ManyToOne
@JoinColumn(name = "job_id")
private ScheduledJobDetails scheduledJobDetails;
private ScheduledJobDetail scheduledJobDetail;
@Column(name = "version")
private Long version;
@@ -34,22 +34,22 @@ public class ScheduledJobRunHistory extends AbstractPersistable<Long> {
@Column(name = "status")
private String status;
@Column(name = "errormessage")
@Column(name = "error_message")
private String errorMessage;
@Column(name = "triggertype")
@Column(name = "trigger_type")
private String triggerType;
@Column(name = "errorlog")
@Column(name = "error_log")
private String errorLog;
public ScheduledJobRunHistory() {
}
public ScheduledJobRunHistory(final ScheduledJobDetails scheduledJobDetails, final Long version, final Date startTime,
public ScheduledJobRunHistory(final ScheduledJobDetail scheduledJobDetail, final Long version, final Date startTime,
final Date endTime, final String status, final String errorMessage, final String triggerType, final String errorLog) {
this.scheduledJobDetails = scheduledJobDetails;
this.scheduledJobDetail = scheduledJobDetail;
this.version = version;
this.startTime = startTime;
this.endTime = endTime;
@@ -1,4 +1,4 @@
package org.mifosplatform.scheduledjobs.domain;
package org.mifosplatform.infrastructure.jobs.domain;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
@@ -8,7 +8,7 @@ import org.springframework.data.repository.query.Param;
public interface ScheduledJobRunHistoryRepository extends JpaRepository<ScheduledJobRunHistory, Long>,
JpaSpecificationExecutor<ScheduledJobRunHistory> {
@Query("select max(sjrh.version) from ScheduledJobRunHistory sjrh where sjrh.scheduledJobDetails.triggerKey = :triggerKey")
@Query("select max(sjrh.version) from ScheduledJobRunHistory sjrh where sjrh.scheduledJobDetail.triggerKey = :triggerKey")
Long findMaxVersionByTriggerKey(@Param("triggerKey") String triggerKey);
}
@@ -0,0 +1,19 @@
package org.mifosplatform.infrastructure.jobs.service;
public enum JobName {
UPDATE_LOAN_SUMMARY("Update loan Summary"), UPDATE_LOAN_ARREARS_AGEING("Update Loan Arrears Ageing"), UPDATE_LOAN_PAID_IN_ADVANCE(
"Update Loan Paid In Advance"), APPLY_ANNUAL_FEE_FOR_SAVINGS("Apply Annual Fee For Savings"), APPLY_HOLIDAYS_TO_LOANS(
"Apply Holidays To Loans");
private final String name;
JobName(final String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
@@ -1,4 +1,4 @@
package org.mifosplatform.scheduledjobs.service;
package org.mifosplatform.infrastructure.jobs.service;
import java.util.List;
import java.util.TimeZone;
@@ -7,9 +7,9 @@ import javax.annotation.PostConstruct;
import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenant;
import org.mifosplatform.infrastructure.core.service.ThreadLocalContextUtil;
import org.mifosplatform.infrastructure.jobs.annotation.CronMethodParser;
import org.mifosplatform.infrastructure.jobs.domain.ScheduledJobDetail;
import org.mifosplatform.infrastructure.security.service.TenantDetailsService;
import org.mifosplatform.scheduledjobs.annotation.CronMethodParser;
import org.mifosplatform.scheduledjobs.domain.ScheduledJobDetails;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobKey;
@@ -54,8 +54,8 @@ public class JobRegisterService {
List<MifosPlatformTenant> allTenants = this.tenantDetailsService.findAllTenants();
for (MifosPlatformTenant tenant : allTenants) {
ThreadLocalContextUtil.setTenant(tenant);
List<ScheduledJobDetails> scheduledJobDetails = this.schedularService.getScheduledJobDetails();
for (ScheduledJobDetails jobDetails : scheduledJobDetails) {
List<ScheduledJobDetail> scheduledJobDetails = this.schedularService.getScheduledJobDetails();
for (ScheduledJobDetail jobDetails : scheduledJobDetails) {
if (jobDetails.isActiveSchedular()) {
scheduleJob(jobDetails);
this.schedularService.saveOrUpdate(jobDetails);
@@ -76,7 +76,7 @@ public class JobRegisterService {
}
public void rescheduleJob(ScheduledJobDetails scheduledJobDetails) {
public void rescheduleJob(ScheduledJobDetail scheduledJobDetails) {
try {
String triggerIdentity = scheduledJobDetails.getTriggerKey();
String[] triggerKeyIds = triggerIdentity.split(SchedularServiceConstants.TRIGGER_KEY_SEPERATOR);
@@ -95,7 +95,7 @@ public class JobRegisterService {
}
}
private void scheduleJob(ScheduledJobDetails scheduledJobDetails) {
private void scheduleJob(ScheduledJobDetail scheduledJobDetails) {
try {
JobDetail jobDetail = createJobDetail(scheduledJobDetails);
Trigger trigger = createTrigger(scheduledJobDetails, jobDetail);
@@ -109,7 +109,7 @@ public class JobRegisterService {
}
}
private JobDetail createJobDetail(ScheduledJobDetails scheduledJobDetails) throws Exception {
private JobDetail createJobDetail(ScheduledJobDetail scheduledJobDetails) throws Exception {
MifosPlatformTenant tenant = ThreadLocalContextUtil.getTenant();
String[] jobDetails = CronMethodParser.findTargetMethodDetails(scheduledJobDetails.getJobName());
String[] beanNames = this.applicationContext.getBeanNamesForType(Class.forName(jobDetails[CronMethodParser.CLASS_INDEX]));
@@ -134,7 +134,7 @@ public class JobRegisterService {
* @param scheduledJobDetails
* @return
*/
private Trigger createTrigger(ScheduledJobDetails scheduledJobDetails, JobDetail jobDetail) {
private Trigger createTrigger(ScheduledJobDetail scheduledJobDetails, JobDetail jobDetail) {
MifosPlatformTenant tenant = ThreadLocalContextUtil.getTenant();
CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
cronTriggerFactoryBean.setName(scheduledJobDetails.getJobName() + "Trigger-" + tenant.getId());
@@ -0,0 +1,20 @@
package org.mifosplatform.infrastructure.jobs.service;
import java.util.List;
import org.mifosplatform.infrastructure.jobs.domain.ScheduledJobDetail;
import org.mifosplatform.infrastructure.jobs.domain.ScheduledJobRunHistory;
public interface SchedularService {
public List<ScheduledJobDetail> getScheduledJobDetails();
public ScheduledJobDetail getByTriggerKey(String triggerKey);
public void saveOrUpdate(ScheduledJobDetail scheduledJobDetails);
public void saveOrUpdate(ScheduledJobDetail scheduledJobDetails, ScheduledJobRunHistory scheduledJobRunHistory);
public Long getMaxVersionBy(String triggerKey);
}
@@ -1,4 +1,4 @@
package org.mifosplatform.scheduledjobs.service;
package org.mifosplatform.infrastructure.jobs.service;
public interface SchedularServiceConstants {
@@ -1,11 +1,11 @@
package org.mifosplatform.scheduledjobs.service;
package org.mifosplatform.infrastructure.jobs.service;
import java.util.List;
import org.mifosplatform.scheduledjobs.domain.ScheduledJobDetails;
import org.mifosplatform.scheduledjobs.domain.ScheduledJobDetailsRepository;
import org.mifosplatform.scheduledjobs.domain.ScheduledJobRunHistory;
import org.mifosplatform.scheduledjobs.domain.ScheduledJobRunHistoryRepository;
import org.mifosplatform.infrastructure.jobs.domain.ScheduledJobDetail;
import org.mifosplatform.infrastructure.jobs.domain.ScheduledJobDetailRepository;
import org.mifosplatform.infrastructure.jobs.domain.ScheduledJobRunHistory;
import org.mifosplatform.infrastructure.jobs.domain.ScheduledJobRunHistoryRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -13,36 +13,36 @@ import org.springframework.transaction.annotation.Transactional;
@Service
public class SchedularServiceJpaRepositoryImpl implements SchedularService {
private final ScheduledJobDetailsRepository scheduledJobDetailsRepository;
private final ScheduledJobDetailRepository scheduledJobDetailsRepository;
private final ScheduledJobRunHistoryRepository scheduledJobRunHistoryRepository;
@Autowired
public SchedularServiceJpaRepositoryImpl(final ScheduledJobDetailsRepository scheduledJobDetailsRepository,
public SchedularServiceJpaRepositoryImpl(final ScheduledJobDetailRepository scheduledJobDetailsRepository,
final ScheduledJobRunHistoryRepository scheduledJobRunHistoryRepository) {
this.scheduledJobDetailsRepository = scheduledJobDetailsRepository;
this.scheduledJobRunHistoryRepository = scheduledJobRunHistoryRepository;
}
@Override
public List<ScheduledJobDetails> getScheduledJobDetails() {
public List<ScheduledJobDetail> getScheduledJobDetails() {
return scheduledJobDetailsRepository.findAll();
}
@Override
public ScheduledJobDetails getByTriggerKey(final String triggerKey) {
public ScheduledJobDetail getByTriggerKey(final String triggerKey) {
return scheduledJobDetailsRepository.findByTriggerKey(triggerKey);
}
@Transactional
@Override
public void saveOrUpdate(final ScheduledJobDetails scheduledJobDetails) {
public void saveOrUpdate(final ScheduledJobDetail scheduledJobDetails) {
this.scheduledJobDetailsRepository.save(scheduledJobDetails);
}
@Transactional
@Override
public void saveOrUpdate(final ScheduledJobDetails scheduledJobDetails, final ScheduledJobRunHistory scheduledJobRunHistory) {
public void saveOrUpdate(final ScheduledJobDetail scheduledJobDetails, final ScheduledJobRunHistory scheduledJobRunHistory) {
this.scheduledJobDetailsRepository.save(scheduledJobDetails);
this.scheduledJobRunHistoryRepository.save(scheduledJobRunHistory);
}
@@ -1,12 +1,12 @@
package org.mifosplatform.scheduledjobs.service;
package org.mifosplatform.infrastructure.jobs.service;
import java.util.Date;
import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenant;
import org.mifosplatform.infrastructure.core.service.ThreadLocalContextUtil;
import org.mifosplatform.infrastructure.jobs.domain.ScheduledJobDetail;
import org.mifosplatform.infrastructure.jobs.domain.ScheduledJobRunHistory;
import org.mifosplatform.infrastructure.security.service.TenantDetailsService;
import org.mifosplatform.scheduledjobs.domain.ScheduledJobDetails;
import org.mifosplatform.scheduledjobs.domain.ScheduledJobRunHistory;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;
@@ -60,7 +60,7 @@ public class SchedulerJobListener implements JobListener {
Trigger trigger = context.getTrigger();
TriggerKey key = trigger.getKey();
String triggerKey = key.getName() + SchedularServiceConstants.TRIGGER_KEY_SEPERATOR + key.getGroup();
final ScheduledJobDetails scheduledJobDetails = schedularService.getByTriggerKey(triggerKey);
final ScheduledJobDetail scheduledJobDetails = schedularService.getByTriggerKey(triggerKey);
Long version = schedularService.getMaxVersionBy(triggerKey) + 1;
String status = SchedularServiceConstants.STATUS_SUCCESS;
String errorMessage = null;
@@ -21,6 +21,8 @@ import org.mifosplatform.infrastructure.configuration.domain.ConfigurationDomain
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
import org.mifosplatform.infrastructure.jobs.annotation.CronTarget;
import org.mifosplatform.infrastructure.jobs.service.JobName;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.holiday.domain.Holiday;
import org.mifosplatform.organisation.holiday.domain.HolidayRepository;
@@ -75,7 +77,6 @@ import org.mifosplatform.portfolio.note.domain.Note;
import org.mifosplatform.portfolio.note.domain.NoteRepository;
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
import org.mifosplatform.portfolio.paymentdetail.service.PaymentDetailWritePlatformService;
import org.mifosplatform.scheduledjobs.annotation.CronTargetMethod;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -113,8 +114,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final JournalEntryWritePlatformService journalEntryWritePlatformService, final LoanSummaryWrapper loanSummaryWrapper,
final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory,
final LoanScheduleGeneratorFactory loanScheduleFactory, final CalendarInstanceRepository calendarInstanceRepository,
final PaymentDetailWritePlatformService paymentDetailWritePlatformService,
final HolidayRepository holidayRepository, final ConfigurationDomainService configurationDomainService) {
final PaymentDetailWritePlatformService paymentDetailWritePlatformService, final HolidayRepository holidayRepository,
final ConfigurationDomainService configurationDomainService) {
this.context = context;
this.loanEventApiJsonValidator = loanEventApiJsonValidator;
this.loanAssembler = loanAssembler;
@@ -172,7 +173,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final LocalDate actualDisbursementDate = command.localDateValueOfParameterNamed("actualDisbursementDate");
final LocalDate firstRepaymentMeetingDate = getFirstRepaymentMeetingDate(actualDisbursementDate, loan, calendarInstance);
final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), actualDisbursementDate.toDate());
final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(),
actualDisbursementDate.toDate());
updateLoanCounters(loan, actualDisbursementDate);
@@ -202,32 +204,26 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
.build();
}
private LocalDate getFirstRepaymentMeetingDate(
final LocalDate actualDisbursementDate, final Loan loan,
private LocalDate getFirstRepaymentMeetingDate(final LocalDate actualDisbursementDate, final Loan loan,
final CalendarInstance calendarInstance) {
final Calendar calendar = (calendarInstance == null) ? null
: calendarInstance.getCalendar();
final Calendar calendar = (calendarInstance == null) ? null : calendarInstance.getCalendar();
LocalDate firstRepaymentMeetingDate = null;
if (calendar != null) {// sync repayments
// TODO: AA - user provided first repayment date takes precedence over recalculated meeting date
// TODO: AA - user provided first repayment date takes precedence
// over recalculated meeting date
if (loan.getExpectedFirstRepaymentOnDate() == null) {
// FIXME: AA - Possibility of having next meeting date
// immediately after disbursement date,
// need to have minimum number of days gap between disbursement
// and first repayment date.
final LoanProductRelatedDetail repaymentScheduleDetails = loan
.repaymentScheduleDetail();
final LoanProductRelatedDetail repaymentScheduleDetails = loan.repaymentScheduleDetail();
if (repaymentScheduleDetails != null) {// Not expecting to be
// null
final Integer repayEvery = repaymentScheduleDetails
.getRepayEvery();
final String frequency = CalendarHelper
.getMeetingFrequencyFromPeriodFrequencyType(repaymentScheduleDetails
final Integer repayEvery = repaymentScheduleDetails.getRepayEvery();
final String frequency = CalendarHelper.getMeetingFrequencyFromPeriodFrequencyType(repaymentScheduleDetails
.getRepaymentPeriodFrequencyType());
firstRepaymentMeetingDate = CalendarHelper
.getFirstRepaymentMeetingDate(calendar,
actualDisbursementDate, repayEvery,
firstRepaymentMeetingDate = CalendarHelper.getFirstRepaymentMeetingDate(calendar, actualDisbursementDate, repayEvery,
frequency);
}
}
@@ -259,9 +255,12 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
PaymentDetail paymentDetail = paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
// Bulk disbursement should happen on meeting date (mostly from collection sheet).
//FIXME: AA - this should be first meeting date based on disbursement date and next available meeting dates
//assuming repayment schedule won't regenerate because expected disbursement and actual disbursement happens on same date
// Bulk disbursement should happen on meeting date (mostly from
// collection sheet).
// FIXME: AA - this should be first meeting date based on
// disbursement date and next available meeting dates
// assuming repayment schedule won't regenerate because expected
// disbursement and actual disbursement happens on same date
final LocalDate firstRepaymentOnDate = null;
final boolean isHolidayEnabled = false;
final List<Holiday> holidays = null;
@@ -359,13 +358,18 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final BigDecimal transactionAmount, final LocalDate transactionDate, final String noteText) {
final Loan loan = retrieveLoanBy(loanId);
//TODO: Is it required to validate transaction date with meeting dates if repayments is synced with meeting?
/*if(loan.isSyncDisbursementWithMeeting()){
// validate actual disbursement date against meeting date
CalendarInstance calendarInstance = this.calendarInstanceRepository.findCalendarInstaneByLoanId(loan.getId(),
CalendarEntityType.LOANS.getValue());
this.loanEventApiJsonValidator.validateRepaymentDateWithMeetingDate(transactionDate, calendarInstance);
}*/
// TODO: Is it required to validate transaction date with meeting dates
// if repayments is synced with meeting?
/*
* if(loan.isSyncDisbursementWithMeeting()){ // validate actual
* disbursement date against meeting date CalendarInstance
* calendarInstance =
* this.calendarInstanceRepository.findCalendarInstaneByLoanId
* (loan.getId(), CalendarEntityType.LOANS.getValue());
* this.loanEventApiJsonValidator
* .validateRepaymentDateWithMeetingDate(transactionDate,
* calendarInstance); }
*/
final List<Long> existingTransactionIds = new ArrayList<Long>();
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
@@ -1025,7 +1029,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
for (Loan loan : loans) {
if (loan != null) {
holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), loan.getDisbursementDate().toDate());
loan.updateLoanRepaymentScheduleDates(calendar.getStartDateLocalDate(), calendar.getRecurrence(), isHolidayEnabled, holidays);
loan.updateLoanRepaymentScheduleDates(calendar.getStartDateLocalDate(), calendar.getRecurrence(), isHolidayEnabled,
holidays);
this.loanRepository.save(loan);
}
}
@@ -1105,7 +1110,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final boolean includeInBorrowerCycle = loan.loanProduct().isIncludeInBorrowerCycle();
for (final Loan loanToUpdate : loansToUpdateForLoanCounter) {
//Update client loan counter if loan product includeInBorrowerCycle is true
// Update client loan counter if loan product includeInBorrowerCycle
// is true
if (includeInBorrowerCycle) {
Integer currentLoanCounter = loanToUpdate.getCurrentLoanCounter();
if (newLoanCounter > currentLoanCounter) {
@@ -1179,7 +1185,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
@Transactional
@Override
@CronTargetMethod(jobName="Apply Holidays To Loans")
@CronTarget(jobName = JobName.APPLY_HOLIDAYS_TO_LOANS)
public void applyHolidaysToLoans() {
final Collection<Integer> loanStatuses = new ArrayList<Integer>(Arrays.asList(LoanStatus.SUBMITTED_AND_PENDING_APPROVAL.getValue(),
@@ -1200,7 +1206,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
List<Loan> loans = new ArrayList<Loan>();
// get all individual and jlg loans
loans.addAll(this.loanRepository.findByClientOfficeIdsAndLoanStatus(officeIds, loanStatuses));
//FIXME: optimize to get all client and group loans belongs to a office id
// FIXME: optimize to get all client and group loans belongs to a
// office id
// get all group loans
loans.addAll(this.loanRepository.findByGroupOfficeIdsAndLoanStatus(officeIds, loanStatuses));
@@ -1,14 +0,0 @@
package org.mifosplatform.scheduledjobs.domain;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface ScheduledJobDetailsRepository extends JpaRepository<ScheduledJobDetails, Long>,
JpaSpecificationExecutor<ScheduledJobDetails> {
@Query("from ScheduledJobDetails jobDetails where jobDetails.triggerKey = :triggerKey")
ScheduledJobDetails findByTriggerKey(@Param("triggerKey") String triggerKey);
}
@@ -1,20 +0,0 @@
package org.mifosplatform.scheduledjobs.service;
import java.util.List;
import org.mifosplatform.scheduledjobs.domain.ScheduledJobDetails;
import org.mifosplatform.scheduledjobs.domain.ScheduledJobRunHistory;
public interface SchedularService {
public List<ScheduledJobDetails> getScheduledJobDetails();
public ScheduledJobDetails getByTriggerKey(String triggerKey);
public void saveOrUpdate(ScheduledJobDetails scheduledJobDetails);
public void saveOrUpdate(ScheduledJobDetails scheduledJobDetails, ScheduledJobRunHistory scheduledJobRunHistory);
public Long getMaxVersionBy(String triggerKey);
}
@@ -9,8 +9,9 @@ import java.util.List;
import org.mifosplatform.infrastructure.core.service.RoutingDataSourceServiceFactory;
import org.mifosplatform.infrastructure.core.service.ThreadLocalContextUtil;
import org.mifosplatform.infrastructure.jobs.annotation.CronTarget;
import org.mifosplatform.infrastructure.jobs.service.JobName;
import org.mifosplatform.portfolio.savings.service.SavingsAccountWritePlatformService;
import org.mifosplatform.scheduledjobs.annotation.CronTargetMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -34,7 +35,7 @@ public class ScheduledJobRunnerServiceImpl implements ScheduledJobRunnerService
@Transactional
@Override
@CronTargetMethod(jobName="Update loan Summary")
@CronTarget(jobName = JobName.UPDATE_LOAN_SUMMARY)
public void updateLoanSummaryDetails() {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSourceServiceFactory.determineDataSourceService().retrieveDataSource());
@@ -115,7 +116,7 @@ public class ScheduledJobRunnerServiceImpl implements ScheduledJobRunnerService
@Transactional
@Override
@CronTargetMethod(jobName="Update Loan Arrears Ageing")
@CronTarget(jobName = JobName.UPDATE_LOAN_ARREARS_AGEING)
public void updateLoanArrearsAgeingDetails() {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSourceServiceFactory.determineDataSourceService().retrieveDataSource());
@@ -155,7 +156,7 @@ public class ScheduledJobRunnerServiceImpl implements ScheduledJobRunnerService
@Transactional
@Override
@CronTargetMethod(jobName="Update Loan Paid In Advance")
@CronTarget(jobName = JobName.UPDATE_LOAN_PAID_IN_ADVANCE)
public void updateLoanPaidInAdvance() {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSourceServiceFactory.determineDataSourceService().retrieveDataSource());
@@ -164,20 +165,24 @@ public class ScheduledJobRunnerServiceImpl implements ScheduledJobRunnerService
StringBuilder updateSqlBuilder = new StringBuilder(900);
updateSqlBuilder.append("INSERT INTO m_loan_paid_in_advance(loan_id, principal_in_advance_derived, interest_in_advance_derived, fee_charges_in_advance_derived, penalty_charges_in_advance_derived, total_in_advance_derived)");
updateSqlBuilder
.append("INSERT INTO m_loan_paid_in_advance(loan_id, principal_in_advance_derived, interest_in_advance_derived, fee_charges_in_advance_derived, penalty_charges_in_advance_derived, total_in_advance_derived)");
updateSqlBuilder.append(" select ml.id as loanId,");
updateSqlBuilder.append(" SUM(ifnull(mr.principal_completed_derived, 0)) as principal_in_advance_derived,");
updateSqlBuilder.append(" SUM(ifnull(mr.interest_completed_derived, 0)) as interest_in_advance_derived,");
updateSqlBuilder.append(" SUM(ifnull(mr.fee_charges_completed_derived, 0)) as fee_charges_in_advance_derived,");
updateSqlBuilder.append(" SUM(ifnull(mr.penalty_charges_completed_derived, 0)) as penalty_charges_in_advance_derived,");
updateSqlBuilder.append(" (SUM(ifnull(mr.principal_completed_derived, 0)) + SUM(ifnull(mr.interest_completed_derived, 0)) + SUM(ifnull(mr.fee_charges_completed_derived, 0)) + SUM(ifnull(mr.penalty_charges_completed_derived, 0))) as total_in_advance_derived");
updateSqlBuilder
.append(" (SUM(ifnull(mr.principal_completed_derived, 0)) + SUM(ifnull(mr.interest_completed_derived, 0)) + SUM(ifnull(mr.fee_charges_completed_derived, 0)) + SUM(ifnull(mr.penalty_charges_completed_derived, 0))) as total_in_advance_derived");
updateSqlBuilder.append(" FROM m_loan ml ");
updateSqlBuilder.append(" INNER JOIN m_loan_repayment_schedule mr on mr.loan_id = ml.id ");
updateSqlBuilder.append(" WHERE ml.loan_status_id = 300 ");
updateSqlBuilder.append(" and mr.duedate >= CURDATE() ");
updateSqlBuilder.append(" GROUP BY ml.id");
updateSqlBuilder.append(" HAVING (SUM(ifnull(mr.principal_completed_derived, 0)) + SUM(ifnull(mr.interest_completed_derived, 0)) +");
updateSqlBuilder.append(" SUM(ifnull(mr.fee_charges_completed_derived, 0)) + SUM(ifnull(mr.penalty_charges_completed_derived, 0))) > 0.0");
updateSqlBuilder
.append(" HAVING (SUM(ifnull(mr.principal_completed_derived, 0)) + SUM(ifnull(mr.interest_completed_derived, 0)) +");
updateSqlBuilder
.append(" SUM(ifnull(mr.fee_charges_completed_derived, 0)) + SUM(ifnull(mr.penalty_charges_completed_derived, 0))) > 0.0");
int result = jdbcTemplate.update(updateSqlBuilder.toString());
@@ -186,7 +191,7 @@ public class ScheduledJobRunnerServiceImpl implements ScheduledJobRunnerService
@Transactional
@Override
@CronTargetMethod(jobName="Apply Annual Fee For Savings")
@CronTarget(jobName = JobName.APPLY_ANNUAL_FEE_FOR_SAVINGS)
public void applyAnnualFeeForSavings() {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSourceServiceFactory.determineDataSourceService().retrieveDataSource());