MIFOSX-746: musoni specific approach to auto penalties on late installments.
This commit is contained in:
+3
-12
@@ -34,6 +34,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@Path("/jobs")
|
@Path("/jobs")
|
||||||
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
@Component
|
@Component
|
||||||
public class SchedulerJobApiResource {
|
public class SchedulerJobApiResource {
|
||||||
|
|
||||||
@@ -59,8 +61,6 @@ public class SchedulerJobApiResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
|
||||||
public String retrieveAll(@Context final UriInfo uriInfo) {
|
public String retrieveAll(@Context final UriInfo uriInfo) {
|
||||||
final List<JobDetailData> jobDetailDatas = this.schedulerJobRunnerReadService.findAllJobDeatils();
|
final List<JobDetailData> jobDetailDatas = this.schedulerJobRunnerReadService.findAllJobDeatils();
|
||||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||||
@@ -69,8 +69,6 @@ public class SchedulerJobApiResource {
|
|||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("{" + SchedulerJobApiConstants.JOB_ID + "}")
|
@Path("{" + SchedulerJobApiConstants.JOB_ID + "}")
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
|
||||||
public String retrieveOne(@PathParam(SchedulerJobApiConstants.JOB_ID) final Long jobId, @Context final UriInfo uriInfo) {
|
public String retrieveOne(@PathParam(SchedulerJobApiConstants.JOB_ID) final Long jobId, @Context final UriInfo uriInfo) {
|
||||||
final JobDetailData jobDetailData = this.schedulerJobRunnerReadService.retrieveOne(jobId);
|
final JobDetailData jobDetailData = this.schedulerJobRunnerReadService.retrieveOne(jobId);
|
||||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||||
@@ -79,8 +77,6 @@ public class SchedulerJobApiResource {
|
|||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("{" + SchedulerJobApiConstants.JOB_ID + "}/" + SchedulerJobApiConstants.JOB_RUN_HISTORY)
|
@Path("{" + SchedulerJobApiConstants.JOB_ID + "}/" + SchedulerJobApiConstants.JOB_RUN_HISTORY)
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
|
||||||
public String retrieveHistory(@Context final UriInfo uriInfo, @PathParam(SchedulerJobApiConstants.JOB_ID) final Long jobId,
|
public String retrieveHistory(@Context final UriInfo uriInfo, @PathParam(SchedulerJobApiConstants.JOB_ID) final Long jobId,
|
||||||
@QueryParam("offset") final Integer offset, @QueryParam("limit") final Integer limit,
|
@QueryParam("offset") final Integer offset, @QueryParam("limit") final Integer limit,
|
||||||
@QueryParam("orderBy") final String orderBy, @QueryParam("sortOrder") final String sortOrder) {
|
@QueryParam("orderBy") final String orderBy, @QueryParam("sortOrder") final String sortOrder) {
|
||||||
@@ -94,8 +90,6 @@ public class SchedulerJobApiResource {
|
|||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Path("{" + SchedulerJobApiConstants.JOB_ID + "}")
|
@Path("{" + SchedulerJobApiConstants.JOB_ID + "}")
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
|
||||||
public Response executeJob(@PathParam(SchedulerJobApiConstants.JOB_ID) final Long jobId,
|
public Response executeJob(@PathParam(SchedulerJobApiConstants.JOB_ID) final Long jobId,
|
||||||
@QueryParam(SchedulerJobApiConstants.COMMAND) final String commandParam) {
|
@QueryParam(SchedulerJobApiConstants.COMMAND) final String commandParam) {
|
||||||
Response response = Response.status(400).build();
|
Response response = Response.status(400).build();
|
||||||
@@ -110,8 +104,6 @@ public class SchedulerJobApiResource {
|
|||||||
|
|
||||||
@PUT
|
@PUT
|
||||||
@Path("{" + SchedulerJobApiConstants.JOB_ID + "}")
|
@Path("{" + SchedulerJobApiConstants.JOB_ID + "}")
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
|
||||||
public String updateJobDetail(@PathParam(SchedulerJobApiConstants.JOB_ID) final Long jobId, final String jsonRequestBody) {
|
public String updateJobDetail(@PathParam(SchedulerJobApiConstants.JOB_ID) final Long jobId, final String jsonRequestBody) {
|
||||||
|
|
||||||
final CommandWrapper commandRequest = new CommandWrapperBuilder() //
|
final CommandWrapper commandRequest = new CommandWrapperBuilder() //
|
||||||
@@ -130,5 +122,4 @@ public class SchedulerJobApiResource {
|
|||||||
private boolean is(final String commandParam, final String commandValue) {
|
private boolean is(final String commandParam, final String commandValue) {
|
||||||
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
|
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
+12
-7
@@ -2,15 +2,20 @@ package org.mifosplatform.infrastructure.jobs.service;
|
|||||||
|
|
||||||
public enum JobName {
|
public enum JobName {
|
||||||
|
|
||||||
UPDATE_LOAN_SUMMARY("Update loan Summary"), UPDATE_LOAN_ARREARS_AGEING("Update Loan Arrears Ageing"), UPDATE_LOAN_PAID_IN_ADVANCE(
|
UPDATE_LOAN_SUMMARY("Update loan Summary"), //
|
||||||
"Update Loan Paid In Advance"), APPLY_ANNUAL_FEE_FOR_SAVINGS("Apply Annual Fee For Savings"), APPLY_HOLIDAYS_TO_LOANS(
|
UPDATE_LOAN_ARREARS_AGEING("Update Loan Arrears Ageing"), //
|
||||||
"Apply Holidays To Loans"), POST_INTEREST_FOR_SAVINGS("Post Interest For Savings"), TRANSFER_FEE_CHARGE_FOR_LOANS(
|
UPDATE_LOAN_PAID_IN_ADVANCE("Update Loan Paid In Advance"), //
|
||||||
"Transfer Fee For Loans From Savings"), ACCOUNTING_RUNNING_BALANCE_UPDATE("Update Accounting Running Balances"), PAY_DUE_SAVINGS_CHARGES(
|
APPLY_ANNUAL_FEE_FOR_SAVINGS("Apply Annual Fee For Savings"), //
|
||||||
"Pay Due Savings Charges"),APPLY_CHARGE_TO_OVERDUE_LOAN_INSTALLMENT("Apply penalty to overdue loans");
|
APPLY_HOLIDAYS_TO_LOANS("Apply Holidays To Loans"), //
|
||||||
|
POST_INTEREST_FOR_SAVINGS("Post Interest For Savings"), //
|
||||||
|
TRANSFER_FEE_CHARGE_FOR_LOANS("Transfer Fee For Loans From Savings"), //
|
||||||
|
ACCOUNTING_RUNNING_BALANCE_UPDATE("Update Accounting Running Balances"), //
|
||||||
|
PAY_DUE_SAVINGS_CHARGES("Pay Due Savings Charges"), //
|
||||||
|
APPLY_CHARGE_TO_OVERDUE_LOAN_INSTALLMENT("Apply penalty to overdue loans");
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
JobName(final String name) {
|
private JobName(final String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,4 +23,4 @@ public enum JobName {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-5
@@ -38,7 +38,7 @@ import org.springframework.stereotype.Service;
|
|||||||
* Service class to create and load batch jobs to Scheduler using
|
* Service class to create and load batch jobs to Scheduler using
|
||||||
* {@link SchedulerFactoryBean} ,{@link MethodInvokingJobDetailFactoryBean} and
|
* {@link SchedulerFactoryBean} ,{@link MethodInvokingJobDetailFactoryBean} and
|
||||||
* {@link CronTriggerFactoryBean}
|
* {@link CronTriggerFactoryBean}
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class JobRegisterServiceImpl implements JobRegisterService {
|
public class JobRegisterServiceImpl implements JobRegisterService {
|
||||||
@@ -351,10 +351,6 @@ public class JobRegisterServiceImpl implements JobRegisterService {
|
|||||||
return cronTriggerFactoryBean.getObject();
|
return cronTriggerFactoryBean.getObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param throwable
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private String getStackTraceAsString(final Throwable throwable) {
|
private String getStackTraceAsString(final Throwable throwable) {
|
||||||
final StackTraceElement[] stackTraceElements = throwable.getStackTrace();
|
final StackTraceElement[] stackTraceElements = throwable.getStackTrace();
|
||||||
final StringBuffer sb = new StringBuffer(throwable.toString());
|
final StringBuffer sb = new StringBuffer(throwable.toString());
|
||||||
|
|||||||
+5
-17
@@ -2,14 +2,8 @@ package org.mifosplatform.portfolio.loanaccount.loanschedule.data;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
/**
|
|
||||||
* Created with IntelliJ IDEA.
|
|
||||||
* User: andrew
|
|
||||||
* Date: 13-11-13
|
|
||||||
* Time: 11:53
|
|
||||||
* To change this template use File | Settings | File Templates.
|
|
||||||
*/
|
|
||||||
public class OverdueLoanScheduleData {
|
public class OverdueLoanScheduleData {
|
||||||
|
|
||||||
private final Long loanId;
|
private final Long loanId;
|
||||||
private final Long chargeId;
|
private final Long chargeId;
|
||||||
private final String locale;
|
private final String locale;
|
||||||
@@ -17,9 +11,8 @@ public class OverdueLoanScheduleData {
|
|||||||
private final String dateFormat;
|
private final String dateFormat;
|
||||||
private final String dueDate;
|
private final String dueDate;
|
||||||
|
|
||||||
|
public OverdueLoanScheduleData(final Long loanId, final Long chargeId, final String dueDate, final BigDecimal amount,
|
||||||
|
final String dateFormat, final String locale) {
|
||||||
public OverdueLoanScheduleData(Long loanId, Long chargeId, String dueDate, BigDecimal amount, String dateFormat, String locale) {
|
|
||||||
this.loanId = loanId;
|
this.loanId = loanId;
|
||||||
this.chargeId = chargeId;
|
this.chargeId = chargeId;
|
||||||
this.dueDate = dueDate;
|
this.dueDate = dueDate;
|
||||||
@@ -54,12 +47,7 @@ public class OverdueLoanScheduleData {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "{" +
|
return "{" + "chargeId:" + this.chargeId + ", locale:'" + this.locale + '\'' + ", amount:" + this.amount + ", dateFormat:'"
|
||||||
"chargeId:" + chargeId +
|
+ this.dateFormat + '\'' + ", dueDate:'" + this.dueDate + '\'' + '}';
|
||||||
", locale:'" + locale + '\'' +
|
|
||||||
", amount:" + amount +
|
|
||||||
", dateFormat:'" + dateFormat + '\'' +
|
|
||||||
", dueDate:'" + dueDate + '\'' +
|
|
||||||
'}';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-3
@@ -5,6 +5,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.portfolio.loanaccount.service;
|
package org.mifosplatform.portfolio.loanaccount.service;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.mifosplatform.infrastructure.core.service.Page;
|
import org.mifosplatform.infrastructure.core.service.Page;
|
||||||
import org.mifosplatform.organisation.staff.data.StaffData;
|
import org.mifosplatform.organisation.staff.data.StaffData;
|
||||||
import org.mifosplatform.portfolio.calendar.data.CalendarData;
|
import org.mifosplatform.portfolio.calendar.data.CalendarData;
|
||||||
@@ -15,8 +17,6 @@ import org.mifosplatform.portfolio.loanaccount.data.RepaymentScheduleRelatedLoan
|
|||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanScheduleData;
|
import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanScheduleData;
|
||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.data.OverdueLoanScheduleData;
|
import org.mifosplatform.portfolio.loanaccount.loanschedule.data.OverdueLoanScheduleData;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
public interface LoanReadPlatformService {
|
public interface LoanReadPlatformService {
|
||||||
|
|
||||||
LoanAccountData retrieveOne(Long loanId);
|
LoanAccountData retrieveOne(Long loanId);
|
||||||
@@ -55,5 +55,10 @@ public interface LoanReadPlatformService {
|
|||||||
|
|
||||||
Collection<StaffData> retrieveAllowedLoanOfficers(Long selectedOfficeId, boolean staffInSelectedOfficeOnly);
|
Collection<StaffData> retrieveAllowedLoanOfficers(Long selectedOfficeId, boolean staffInSelectedOfficeOnly);
|
||||||
|
|
||||||
Collection<OverdueLoanScheduleData> retrieveAllOverdueLoans();
|
/*
|
||||||
|
* musoni-specific at present - will find overdue scheduled installments that have a special 'overdue charge' associated with the loan product.
|
||||||
|
*
|
||||||
|
* The 'overdue-charge' is only ever applied once to an installment and as a result overdue installments with this charge already applied are not returned.
|
||||||
|
*/
|
||||||
|
Collection<OverdueLoanScheduleData> retrieveAllLoansWithOverdueInstallmentsNotAlreadyPenalized();
|
||||||
}
|
}
|
||||||
+38
-26
@@ -5,6 +5,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.portfolio.loanaccount.service;
|
package org.mifosplatform.portfolio.loanaccount.service;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.joda.time.Days;
|
import org.joda.time.Days;
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
@@ -40,8 +47,19 @@ import org.mifosplatform.portfolio.group.data.GroupGeneralData;
|
|||||||
import org.mifosplatform.portfolio.group.data.GroupRoleData;
|
import org.mifosplatform.portfolio.group.data.GroupRoleData;
|
||||||
import org.mifosplatform.portfolio.group.service.GroupReadPlatformService;
|
import org.mifosplatform.portfolio.group.service.GroupReadPlatformService;
|
||||||
import org.mifosplatform.portfolio.group.service.SearchParameters;
|
import org.mifosplatform.portfolio.group.service.SearchParameters;
|
||||||
import org.mifosplatform.portfolio.loanaccount.data.*;
|
import org.mifosplatform.portfolio.loanaccount.data.DisbursementData;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.*;
|
import org.mifosplatform.portfolio.loanaccount.data.LoanAccountData;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.data.LoanApplicationTimelineData;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.data.LoanStatusEnumData;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.data.LoanSummaryData;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionData;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionEnumData;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.data.RepaymentScheduleRelatedLoanData;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepository;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionRepository;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionType;
|
||||||
import org.mifosplatform.portfolio.loanaccount.exception.LoanNotFoundException;
|
import org.mifosplatform.portfolio.loanaccount.exception.LoanNotFoundException;
|
||||||
import org.mifosplatform.portfolio.loanaccount.exception.LoanTransactionNotFoundException;
|
import org.mifosplatform.portfolio.loanaccount.exception.LoanTransactionNotFoundException;
|
||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanScheduleData;
|
import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanScheduleData;
|
||||||
@@ -64,13 +82,6 @@ import org.springframework.jdbc.core.RowMapper;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||||
|
|
||||||
@@ -662,7 +673,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
final EnumOptionData groupStatus = ClientEnumerations.status(groupStatusEnum);
|
final EnumOptionData groupStatus = ClientEnumerations.status(groupStatusEnum);
|
||||||
final LocalDate activationDate = JdbcSupport.getLocalDate(rs, "activationDate");
|
final LocalDate activationDate = JdbcSupport.getLocalDate(rs, "activationDate");
|
||||||
groupData = GroupGeneralData.instance(groupId, groupName, groupExternalId, groupStatus, activationDate, groupOfficeId,
|
groupData = GroupGeneralData.instance(groupId, groupName, groupExternalId, groupStatus, activationDate, groupOfficeId,
|
||||||
null, groupParentId, null, groupStaffId, null, groupHierarchy,null);
|
null, groupParentId, null, groupStaffId, null, groupHierarchy, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Integer loanCounter = JdbcSupport.getInteger(rs, "loanCounter");
|
final Integer loanCounter = JdbcSupport.getInteger(rs, "loanCounter");
|
||||||
@@ -678,9 +689,10 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
feeChargesDueAtDisbursementCharged, syncDisbursementWithMeeting, loanCounter, loanProductCounter);
|
feeChargesDueAtDisbursementCharged, syncDisbursementWithMeeting, loanCounter, loanProductCounter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static final class OverdueLoanSchedule implements RowMapper<OverdueLoanScheduleData>{
|
|
||||||
|
|
||||||
public String schema(){
|
private static final class MusoniOverdueLoanScheduleMapper implements RowMapper<OverdueLoanScheduleData> {
|
||||||
|
|
||||||
|
public String schema() {
|
||||||
return " ls.loan_id as loanId, ls.installment as period, ls.fromdate as fromDate, ls.duedate as dueDate, ls.obligations_met_on_date as obligationsMetOnDate, ls.completed_derived as complete,"
|
return " ls.loan_id as loanId, ls.installment as period, ls.fromdate as fromDate, ls.duedate as dueDate, ls.obligations_met_on_date as obligationsMetOnDate, ls.completed_derived as complete,"
|
||||||
+ " ls.principal_amount as principalDue, ls.principal_completed_derived as principalPaid, ls.principal_writtenoff_derived as principalWrittenOff, "
|
+ " ls.principal_amount as principalDue, ls.principal_completed_derived as principalPaid, ls.principal_writtenoff_derived as principalWrittenOff, "
|
||||||
+ " ls.interest_amount as interestDue, ls.interest_completed_derived as interestPaid, ls.interest_waived_derived as interestWaived, ls.interest_writtenoff_derived as interestWrittenOff, "
|
+ " ls.interest_amount as interestDue, ls.interest_completed_derived as interestPaid, ls.interest_waived_derived as interestWaived, ls.interest_writtenoff_derived as interestWrittenOff, "
|
||||||
@@ -696,17 +708,16 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OverdueLoanScheduleData mapRow(ResultSet rs, int rowNum) throws SQLException {
|
public OverdueLoanScheduleData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||||
final Long chargeId = rs.getLong("chargeId");
|
final Long chargeId = rs.getLong("chargeId");
|
||||||
final Long loanId = rs.getLong("loanId");
|
final Long loanId = rs.getLong("loanId");
|
||||||
final BigDecimal amount = rs.getBigDecimal("amount");
|
final BigDecimal amount = rs.getBigDecimal("amount");
|
||||||
final String dateFormat = "yyyy-MM-dd";
|
final String dateFormat = "yyyy-MM-dd";
|
||||||
final String dueDate = rs.getString("dueDate");
|
final String dueDate = rs.getString("dueDate");
|
||||||
final String locale = "en_GB";
|
final String locale = "en_GB";
|
||||||
|
|
||||||
|
final OverdueLoanScheduleData overdueLoanScheduleData = new OverdueLoanScheduleData(loanId, chargeId, dueDate, amount,
|
||||||
OverdueLoanScheduleData overdueLoanScheduleData = new OverdueLoanScheduleData(loanId,chargeId,dueDate,
|
dateFormat, locale);
|
||||||
amount,dateFormat,locale) ;
|
|
||||||
|
|
||||||
return overdueLoanScheduleData;
|
return overdueLoanScheduleData;
|
||||||
}
|
}
|
||||||
@@ -1129,13 +1140,14 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<OverdueLoanScheduleData> retrieveAllOverdueLoans() {
|
public Collection<OverdueLoanScheduleData> retrieveAllLoansWithOverdueInstallmentsNotAlreadyPenalized() {
|
||||||
final OverdueLoanSchedule rm = new OverdueLoanSchedule();
|
final MusoniOverdueLoanScheduleMapper rm = new MusoniOverdueLoanScheduleMapper();
|
||||||
final String sql = "select " + rm.schema() +
|
final String sql = "select "
|
||||||
" where CURDATE() > ls.duedate "+
|
+ rm.schema()
|
||||||
" and ls.completed_derived <> 1 and mc.charge_applies_to_enum =1 "+
|
+ " where CURDATE() > ls.duedate "
|
||||||
" and mc.charge_time_enum = 9 and ml.loan_status_id = 300 "+
|
+ " and ls.completed_derived <> 1 and mc.charge_applies_to_enum =1 "
|
||||||
" and plc.charge_id not in (SELECT charge_id from m_loan_charge as mlc where mlc.loan_id = ml.id and mlc.charge_id = plc.charge_id and mlc.due_for_collection_as_of_date > fromdate AND mlc.due_for_collection_as_of_date <= duedate) ";
|
+ " and mc.charge_time_enum = 9 and ml.loan_status_id = 300 "
|
||||||
return this.jdbcTemplate.query(sql,rm,new Object[] {});
|
+ " and plc.charge_id not in (SELECT charge_id from m_loan_charge as mlc where mlc.loan_id = ml.id and mlc.charge_id = plc.charge_id and mlc.due_for_collection_as_of_date > fromdate AND mlc.due_for_collection_as_of_date <= duedate) ";
|
||||||
|
return this.jdbcTemplate.query(sql, rm, new Object[] {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+95
-80
@@ -5,7 +5,17 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.portfolio.loanaccount.service;
|
package org.mifosplatform.portfolio.loanaccount.service;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.joda.time.format.DateTimeFormat;
|
import org.joda.time.format.DateTimeFormat;
|
||||||
@@ -49,11 +59,15 @@ import org.mifosplatform.portfolio.calendar.service.CalendarUtils;
|
|||||||
import org.mifosplatform.portfolio.charge.domain.Charge;
|
import org.mifosplatform.portfolio.charge.domain.Charge;
|
||||||
import org.mifosplatform.portfolio.charge.domain.ChargePaymentMode;
|
import org.mifosplatform.portfolio.charge.domain.ChargePaymentMode;
|
||||||
import org.mifosplatform.portfolio.charge.domain.ChargeRepositoryWrapper;
|
import org.mifosplatform.portfolio.charge.domain.ChargeRepositoryWrapper;
|
||||||
import org.mifosplatform.portfolio.charge.exception.*;
|
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeDeletedException;
|
||||||
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeDeletedException.LOAN_CHARGE_CANNOT_BE_DELETED_REASON;
|
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeDeletedException.LOAN_CHARGE_CANNOT_BE_DELETED_REASON;
|
||||||
|
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBePayedException;
|
||||||
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBePayedException.LOAN_CHARGE_CANNOT_BE_PAYED_REASON;
|
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBePayedException.LOAN_CHARGE_CANNOT_BE_PAYED_REASON;
|
||||||
|
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeUpdatedException;
|
||||||
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeUpdatedException.LOAN_CHARGE_CANNOT_BE_UPDATED_REASON;
|
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeUpdatedException.LOAN_CHARGE_CANNOT_BE_UPDATED_REASON;
|
||||||
|
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeWaivedException;
|
||||||
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeWaivedException.LOAN_CHARGE_CANNOT_BE_WAIVED_REASON;
|
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeWaivedException.LOAN_CHARGE_CANNOT_BE_WAIVED_REASON;
|
||||||
|
import org.mifosplatform.portfolio.charge.exception.LoanChargeNotFoundException;
|
||||||
import org.mifosplatform.portfolio.client.domain.Client;
|
import org.mifosplatform.portfolio.client.domain.Client;
|
||||||
import org.mifosplatform.portfolio.client.exception.ClientNotActiveException;
|
import org.mifosplatform.portfolio.client.exception.ClientNotActiveException;
|
||||||
import org.mifosplatform.portfolio.collectionsheet.command.CollectionSheetBulkDisbursalCommand;
|
import org.mifosplatform.portfolio.collectionsheet.command.CollectionSheetBulkDisbursalCommand;
|
||||||
@@ -65,7 +79,19 @@ import org.mifosplatform.portfolio.group.exception.GroupNotActiveException;
|
|||||||
import org.mifosplatform.portfolio.loanaccount.command.LoanUpdateCommand;
|
import org.mifosplatform.portfolio.loanaccount.command.LoanUpdateCommand;
|
||||||
import org.mifosplatform.portfolio.loanaccount.data.LoanChargeData;
|
import org.mifosplatform.portfolio.loanaccount.data.LoanChargeData;
|
||||||
import org.mifosplatform.portfolio.loanaccount.data.LoanInstallmentChargeData;
|
import org.mifosplatform.portfolio.loanaccount.data.LoanInstallmentChargeData;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.*;
|
import org.mifosplatform.portfolio.loanaccount.domain.ChangedTransactionDetail;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanAccountDomainService;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanCharge;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanChargeRepository;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanInstallmentCharge;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanLifecycleStateMachine;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepository;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanStatus;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionRepository;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionType;
|
||||||
import org.mifosplatform.portfolio.loanaccount.exception.LoanDisbursalException;
|
import org.mifosplatform.portfolio.loanaccount.exception.LoanDisbursalException;
|
||||||
import org.mifosplatform.portfolio.loanaccount.exception.LoanOfficerAssignmentException;
|
import org.mifosplatform.portfolio.loanaccount.exception.LoanOfficerAssignmentException;
|
||||||
import org.mifosplatform.portfolio.loanaccount.exception.LoanOfficerUnassignmentException;
|
import org.mifosplatform.portfolio.loanaccount.exception.LoanOfficerUnassignmentException;
|
||||||
@@ -93,16 +119,13 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import com.google.gson.JsonElement;
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatformService {
|
public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatformService {
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger(LoanWritePlatformServiceJpaRepositoryImpl.class);
|
private final static Logger logger = LoggerFactory.getLogger(LoanWritePlatformServiceJpaRepositoryImpl.class);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private final PlatformSecurityContext context;
|
private final PlatformSecurityContext context;
|
||||||
private final LoanEventApiJsonValidator loanEventApiJsonValidator;
|
private final LoanEventApiJsonValidator loanEventApiJsonValidator;
|
||||||
private final LoanUpdateCommandFromApiJsonDeserializer loanUpdateCommandFromApiJsonDeserializer;
|
private final LoanUpdateCommandFromApiJsonDeserializer loanUpdateCommandFromApiJsonDeserializer;
|
||||||
@@ -129,7 +152,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
private final LoanReadPlatformService loanReadPlatformService;
|
private final LoanReadPlatformService loanReadPlatformService;
|
||||||
private final FromJsonHelper fromApiJsonHelper;
|
private final FromJsonHelper fromApiJsonHelper;
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||||
final LoanEventApiJsonValidator loanEventApiJsonValidator,
|
final LoanEventApiJsonValidator loanEventApiJsonValidator,
|
||||||
@@ -146,8 +168,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
final AccountTransfersWritePlatformService accountTransfersWritePlatformService,
|
final AccountTransfersWritePlatformService accountTransfersWritePlatformService,
|
||||||
final AccountTransfersReadPlatformService accountTransfersReadPlatformService,
|
final AccountTransfersReadPlatformService accountTransfersReadPlatformService,
|
||||||
final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService,
|
final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService,
|
||||||
final LoanChargeReadPlatformService loanChargeReadPlatformService,final LoanReadPlatformService loanReadPlatformService,
|
final LoanChargeReadPlatformService loanChargeReadPlatformService, final LoanReadPlatformService loanReadPlatformService,
|
||||||
final FromJsonHelper fromApiJsonHelper ) {
|
final FromJsonHelper fromApiJsonHelper) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.loanEventApiJsonValidator = loanEventApiJsonValidator;
|
this.loanEventApiJsonValidator = loanEventApiJsonValidator;
|
||||||
this.loanAssembler = loanAssembler;
|
this.loanAssembler = loanAssembler;
|
||||||
@@ -257,8 +279,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
for (final LoanCharge loanCharge : loanCharges) {
|
for (final LoanCharge loanCharge : loanCharges) {
|
||||||
if (loanCharge.isDueAtDisbursement() && loanCharge.getChargePaymentMode().isPaymentModeAccountTransfer()) {
|
if (loanCharge.isDueAtDisbursement() && loanCharge.getChargePaymentMode().isPaymentModeAccountTransfer()) {
|
||||||
disBuLoanCharges.put(loanCharge.getId(), loanCharge.amount());
|
disBuLoanCharges.put(loanCharge.getId(), loanCharge.amount());
|
||||||
}else if(loanCharge.isInstalmentFee() && loanCharge.hasNoLoanInstallmentCharges()){
|
} else if (loanCharge.isInstalmentFee() && loanCharge.hasNoLoanInstallmentCharges()) {
|
||||||
Set<LoanInstallmentCharge> chargePerInstallments = loan.generateInstallmentLoanCharges(loanCharge);
|
final Set<LoanInstallmentCharge> chargePerInstallments = loan.generateInstallmentLoanCharges(loanCharge);
|
||||||
loanCharge.addLoanInstallmentCharges(chargePerInstallments);
|
loanCharge.addLoanInstallmentCharges(chargePerInstallments);
|
||||||
this.loanChargeRepository.save(loanCharge);
|
this.loanChargeRepository.save(loanCharge);
|
||||||
}
|
}
|
||||||
@@ -384,8 +406,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
for (final LoanCharge loanCharge : loanCharges) {
|
for (final LoanCharge loanCharge : loanCharges) {
|
||||||
if (loanCharge.isDueAtDisbursement() && loanCharge.getChargePaymentMode().isPaymentModeAccountTransfer()) {
|
if (loanCharge.isDueAtDisbursement() && loanCharge.getChargePaymentMode().isPaymentModeAccountTransfer()) {
|
||||||
disBuLoanCharges.put(loanCharge.getId(), loanCharge.amount());
|
disBuLoanCharges.put(loanCharge.getId(), loanCharge.amount());
|
||||||
}else if(loanCharge.isInstalmentFee() && loanCharge.hasNoLoanInstallmentCharges()){
|
} else if (loanCharge.isInstalmentFee() && loanCharge.hasNoLoanInstallmentCharges()) {
|
||||||
Set<LoanInstallmentCharge> chargePerInstallments = loan.generateInstallmentLoanCharges(loanCharge);
|
final Set<LoanInstallmentCharge> chargePerInstallments = loan.generateInstallmentLoanCharges(loanCharge);
|
||||||
loanCharge.addLoanInstallmentCharges(chargePerInstallments);
|
loanCharge.addLoanInstallmentCharges(chargePerInstallments);
|
||||||
this.loanChargeRepository.save(loanCharge);
|
this.loanChargeRepository.save(loanCharge);
|
||||||
}
|
}
|
||||||
@@ -393,10 +415,12 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
final Locale locale = command.extractLocale();
|
final Locale locale = command.extractLocale();
|
||||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||||
for (final Map.Entry<Long, BigDecimal> entrySet : disBuLoanCharges.entrySet()) {
|
for (final Map.Entry<Long, BigDecimal> entrySet : disBuLoanCharges.entrySet()) {
|
||||||
final PortfolioAccountData savingAccountData = this.accountAssociationsReadPlatformService.retriveLoanAssociation(loan.getId());
|
final PortfolioAccountData savingAccountData = this.accountAssociationsReadPlatformService.retriveLoanAssociation(loan
|
||||||
|
.getId());
|
||||||
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(actualDisbursementDate, entrySet.getValue(),
|
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(actualDisbursementDate, entrySet.getValue(),
|
||||||
PortfolioAccountType.SAVINGS, PortfolioAccountType.LOAN, savingAccountData.accountId(), loan.getId(), "Loan Charge Payment",
|
PortfolioAccountType.SAVINGS, PortfolioAccountType.LOAN, savingAccountData.accountId(), loan.getId(),
|
||||||
locale, fmt, null, null, LoanTransactionType.REPAYMENT_AT_DISBURSEMENT.getValue(), entrySet.getKey(), null);
|
"Loan Charge Payment", locale, fmt, null, null, LoanTransactionType.REPAYMENT_AT_DISBURSEMENT.getValue(),
|
||||||
|
entrySet.getKey(), null);
|
||||||
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
|
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -576,7 +600,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
final String noteText = command.stringValueOfParameterNamed("note");
|
final String noteText = command.stringValueOfParameterNamed("note");
|
||||||
if (StringUtils.isNotBlank(noteText)) {
|
if (StringUtils.isNotBlank(noteText)) {
|
||||||
changes.put("note", noteText);
|
changes.put("note", noteText);
|
||||||
@@ -653,8 +676,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
final String noteText = command.stringValueOfParameterNamed("note");
|
final String noteText = command.stringValueOfParameterNamed("note");
|
||||||
if (StringUtils.isNotBlank(noteText)) {
|
if (StringUtils.isNotBlank(noteText)) {
|
||||||
changes.put("note", noteText);
|
changes.put("note", noteText);
|
||||||
@@ -876,7 +897,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// we post Journal entries only for loans in active status
|
// we post Journal entries only for loans in active status
|
||||||
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
||||||
}
|
}
|
||||||
@@ -943,28 +963,26 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
if (loanCharge.isWaived()) {
|
if (loanCharge.isWaived()) {
|
||||||
throw new LoanChargeCannotBeWaivedException(LOAN_CHARGE_CANNOT_BE_WAIVED_REASON.ALREADY_WAIVED, loanCharge.getId());
|
throw new LoanChargeCannotBeWaivedException(LOAN_CHARGE_CANNOT_BE_WAIVED_REASON.ALREADY_WAIVED, loanCharge.getId());
|
||||||
} else if (loanCharge.isPaid()) { throw new LoanChargeCannotBeWaivedException(LOAN_CHARGE_CANNOT_BE_WAIVED_REASON.ALREADY_PAID,
|
} else if (loanCharge.isPaid()) { throw new LoanChargeCannotBeWaivedException(LOAN_CHARGE_CANNOT_BE_WAIVED_REASON.ALREADY_PAID,
|
||||||
loanCharge.getId());
|
loanCharge.getId()); }
|
||||||
}
|
Integer loanInstallmentNumber = null;
|
||||||
Integer loanInstallmentNumber = null;
|
if (loanCharge.isInstalmentFee()) {
|
||||||
if (loanCharge.isInstalmentFee()){
|
|
||||||
LoanInstallmentCharge chargePerInstallment = null;
|
LoanInstallmentCharge chargePerInstallment = null;
|
||||||
if(!StringUtils.isBlank(command.json())){
|
if (!StringUtils.isBlank(command.json())) {
|
||||||
final LocalDate dueDate = command.localDateValueOfParameterNamed("dueDate");
|
final LocalDate dueDate = command.localDateValueOfParameterNamed("dueDate");
|
||||||
final Integer installmentNumber = command.integerValueOfParameterNamed("installmentNumber");
|
final Integer installmentNumber = command.integerValueOfParameterNamed("installmentNumber");
|
||||||
if(dueDate !=null){
|
if (dueDate != null) {
|
||||||
chargePerInstallment = loanCharge.getInstallmentLoanCharge(dueDate);
|
chargePerInstallment = loanCharge.getInstallmentLoanCharge(dueDate);
|
||||||
}else if(installmentNumber!=null){
|
} else if (installmentNumber != null) {
|
||||||
chargePerInstallment = loanCharge.getInstallmentLoanCharge(installmentNumber);
|
chargePerInstallment = loanCharge.getInstallmentLoanCharge(installmentNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(chargePerInstallment == null){
|
if (chargePerInstallment == null) {
|
||||||
chargePerInstallment = loanCharge.getUnpaidInstallmentLoanCharge();
|
chargePerInstallment = loanCharge.getUnpaidInstallmentLoanCharge();
|
||||||
}
|
}
|
||||||
if(chargePerInstallment.isWaived()){
|
if (chargePerInstallment.isWaived()) {
|
||||||
throw new LoanChargeCannotBePayedException(LOAN_CHARGE_CANNOT_BE_PAYED_REASON.ALREADY_WAIVED, loanCharge.getId());
|
throw new LoanChargeCannotBePayedException(LOAN_CHARGE_CANNOT_BE_PAYED_REASON.ALREADY_WAIVED, loanCharge.getId());
|
||||||
}else if(chargePerInstallment.isPaid()){
|
} else if (chargePerInstallment.isPaid()) { throw new LoanChargeCannotBePayedException(
|
||||||
throw new LoanChargeCannotBePayedException(LOAN_CHARGE_CANNOT_BE_PAYED_REASON.ALREADY_PAID, loanCharge.getId());
|
LOAN_CHARGE_CANNOT_BE_PAYED_REASON.ALREADY_PAID, loanCharge.getId()); }
|
||||||
}
|
|
||||||
loanInstallmentNumber = chargePerInstallment.getRepaymentInstallment().getInstallmentNumber();
|
loanInstallmentNumber = chargePerInstallment.getRepaymentInstallment().getInstallmentNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1042,8 +1060,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
if (loanCharge.isWaived()) {
|
if (loanCharge.isWaived()) {
|
||||||
throw new LoanChargeCannotBePayedException(LOAN_CHARGE_CANNOT_BE_PAYED_REASON.ALREADY_WAIVED, loanCharge.getId());
|
throw new LoanChargeCannotBePayedException(LOAN_CHARGE_CANNOT_BE_PAYED_REASON.ALREADY_WAIVED, loanCharge.getId());
|
||||||
} else if (loanCharge.isPaid()) { throw new LoanChargeCannotBePayedException(LOAN_CHARGE_CANNOT_BE_PAYED_REASON.ALREADY_PAID,
|
} else if (loanCharge.isPaid()) { throw new LoanChargeCannotBePayedException(LOAN_CHARGE_CANNOT_BE_PAYED_REASON.ALREADY_PAID,
|
||||||
loanCharge.getId());
|
loanCharge.getId()); }
|
||||||
}
|
|
||||||
|
|
||||||
if (!loanCharge.getChargePaymentMode().isPaymentModeAccountTransfer()) { throw new LoanChargeCannotBePayedException(
|
if (!loanCharge.getChargePaymentMode().isPaymentModeAccountTransfer()) { throw new LoanChargeCannotBePayedException(
|
||||||
LOAN_CHARGE_CANNOT_BE_PAYED_REASON.CHARGE_NOT_ACCOUNT_TRANSFER, loanCharge.getId()); }
|
LOAN_CHARGE_CANNOT_BE_PAYED_REASON.CHARGE_NOT_ACCOUNT_TRANSFER, loanCharge.getId()); }
|
||||||
@@ -1052,37 +1069,36 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
|
|
||||||
final Locale locale = command.extractLocale();
|
final Locale locale = command.extractLocale();
|
||||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||||
Integer loanInstallmentNumber = null;
|
Integer loanInstallmentNumber = null;
|
||||||
BigDecimal amount = loanCharge.amountOutstanding();
|
BigDecimal amount = loanCharge.amountOutstanding();
|
||||||
if (loanCharge.isInstalmentFee()){
|
if (loanCharge.isInstalmentFee()) {
|
||||||
LoanInstallmentCharge chargePerInstallment = null;
|
LoanInstallmentCharge chargePerInstallment = null;
|
||||||
final LocalDate dueDate = command.localDateValueOfParameterNamed("dueDate");
|
final LocalDate dueDate = command.localDateValueOfParameterNamed("dueDate");
|
||||||
final Integer installmentNumber = command.integerValueOfParameterNamed("installmentNumber");
|
final Integer installmentNumber = command.integerValueOfParameterNamed("installmentNumber");
|
||||||
if(dueDate !=null){
|
if (dueDate != null) {
|
||||||
chargePerInstallment = loanCharge.getInstallmentLoanCharge(dueDate);
|
chargePerInstallment = loanCharge.getInstallmentLoanCharge(dueDate);
|
||||||
}else if(installmentNumber!=null){
|
} else if (installmentNumber != null) {
|
||||||
chargePerInstallment = loanCharge.getInstallmentLoanCharge(installmentNumber);
|
chargePerInstallment = loanCharge.getInstallmentLoanCharge(installmentNumber);
|
||||||
}
|
}
|
||||||
if(chargePerInstallment == null){
|
if (chargePerInstallment == null) {
|
||||||
chargePerInstallment = loanCharge.getUnpaidInstallmentLoanCharge();
|
chargePerInstallment = loanCharge.getUnpaidInstallmentLoanCharge();
|
||||||
}
|
}
|
||||||
if(chargePerInstallment.isWaived()){
|
if (chargePerInstallment.isWaived()) {
|
||||||
throw new LoanChargeCannotBePayedException(LOAN_CHARGE_CANNOT_BE_PAYED_REASON.ALREADY_WAIVED, loanCharge.getId());
|
throw new LoanChargeCannotBePayedException(LOAN_CHARGE_CANNOT_BE_PAYED_REASON.ALREADY_WAIVED, loanCharge.getId());
|
||||||
}else if(chargePerInstallment.isPaid()){
|
} else if (chargePerInstallment.isPaid()) { throw new LoanChargeCannotBePayedException(
|
||||||
throw new LoanChargeCannotBePayedException(LOAN_CHARGE_CANNOT_BE_PAYED_REASON.ALREADY_PAID, loanCharge.getId());
|
LOAN_CHARGE_CANNOT_BE_PAYED_REASON.ALREADY_PAID, loanCharge.getId()); }
|
||||||
}
|
|
||||||
loanInstallmentNumber = chargePerInstallment.getRepaymentInstallment().getInstallmentNumber();
|
loanInstallmentNumber = chargePerInstallment.getRepaymentInstallment().getInstallmentNumber();
|
||||||
amount= chargePerInstallment.getAmountOutstanding();
|
amount = chargePerInstallment.getAmountOutstanding();
|
||||||
}
|
}
|
||||||
|
|
||||||
final PortfolioAccountData portfolioAccountData = this.accountAssociationsReadPlatformService.retriveLoanAssociation(loanId);
|
final PortfolioAccountData portfolioAccountData = this.accountAssociationsReadPlatformService.retriveLoanAssociation(loanId);
|
||||||
if (portfolioAccountData == null) {
|
if (portfolioAccountData == null) {
|
||||||
final String errorMessage = "Charge with id:" + loanChargeId + " requires linked savings account for payment";
|
final String errorMessage = "Charge with id:" + loanChargeId + " requires linked savings account for payment";
|
||||||
throw new LinkedAccountRequiredException("loanCharge.pay", errorMessage, loanChargeId);
|
throw new LinkedAccountRequiredException("loanCharge.pay", errorMessage, loanChargeId);
|
||||||
}
|
}
|
||||||
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(transactionDate, amount,
|
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(transactionDate, amount, PortfolioAccountType.SAVINGS,
|
||||||
PortfolioAccountType.SAVINGS, PortfolioAccountType.LOAN, portfolioAccountData.accountId(), loanId, "Loan Charge Payment",
|
PortfolioAccountType.LOAN, portfolioAccountData.accountId(), loanId, "Loan Charge Payment", locale, fmt, null, null,
|
||||||
locale, fmt, null, null, LoanTransactionType.CHARGE_PAYMENT.getValue(), loanChargeId, loanInstallmentNumber);
|
LoanTransactionType.CHARGE_PAYMENT.getValue(), loanChargeId, loanInstallmentNumber);
|
||||||
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
|
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
@@ -1103,23 +1119,25 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
if (chargeDatas != null) {
|
if (chargeDatas != null) {
|
||||||
for (final LoanChargeData chargeData : chargeDatas) {
|
for (final LoanChargeData chargeData : chargeDatas) {
|
||||||
if(chargeData.isInstallmentFee()){
|
if (chargeData.isInstallmentFee()) {
|
||||||
Collection<LoanInstallmentChargeData> chargePerInstallments = this.LoanChargeReadPlatformService.retrieveInstallmentLoanCharges(chargeData.getId(), true);
|
final Collection<LoanInstallmentChargeData> chargePerInstallments = this.LoanChargeReadPlatformService
|
||||||
|
.retrieveInstallmentLoanCharges(chargeData.getId(), true);
|
||||||
PortfolioAccountData portfolioAccountData = null;
|
PortfolioAccountData portfolioAccountData = null;
|
||||||
for(LoanInstallmentChargeData installmentChargeData : chargePerInstallments){
|
for (final LoanInstallmentChargeData installmentChargeData : chargePerInstallments) {
|
||||||
if(!installmentChargeData.getDueDate().isAfter(new LocalDate())){
|
if (!installmentChargeData.getDueDate().isAfter(new LocalDate())) {
|
||||||
if(portfolioAccountData == null){
|
if (portfolioAccountData == null) {
|
||||||
portfolioAccountData = this.accountAssociationsReadPlatformService
|
portfolioAccountData = this.accountAssociationsReadPlatformService.retriveLoanAssociation(chargeData
|
||||||
.retriveLoanAssociation(chargeData.getLoanId());
|
.getLoanId());
|
||||||
}
|
}
|
||||||
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(new LocalDate(),
|
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(new LocalDate(),
|
||||||
installmentChargeData.getAmountOutstanding(), PortfolioAccountType.SAVINGS, PortfolioAccountType.LOAN,
|
installmentChargeData.getAmountOutstanding(), PortfolioAccountType.SAVINGS, PortfolioAccountType.LOAN,
|
||||||
portfolioAccountData.accountId(), chargeData.getLoanId(), "Loan Charge Payment", null, null, null, null,
|
portfolioAccountData.accountId(), chargeData.getLoanId(), "Loan Charge Payment", null, null, null,
|
||||||
LoanTransactionType.CHARGE_PAYMENT.getValue(), chargeData.getId(), installmentChargeData.getInstallmentNumber());
|
null, LoanTransactionType.CHARGE_PAYMENT.getValue(), chargeData.getId(),
|
||||||
|
installmentChargeData.getInstallmentNumber());
|
||||||
transferFeeCharge(sb, accountTransferDTO);
|
transferFeeCharge(sb, accountTransferDTO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else if (chargeData.getDueDate() != null && !chargeData.getDueDate().isAfter(new LocalDate())) {
|
} else if (chargeData.getDueDate() != null && !chargeData.getDueDate().isAfter(new LocalDate())) {
|
||||||
final PortfolioAccountData portfolioAccountData = this.accountAssociationsReadPlatformService
|
final PortfolioAccountData portfolioAccountData = this.accountAssociationsReadPlatformService
|
||||||
.retriveLoanAssociation(chargeData.getLoanId());
|
.retriveLoanAssociation(chargeData.getLoanId());
|
||||||
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(new LocalDate(),
|
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(new LocalDate(),
|
||||||
@@ -1601,22 +1619,25 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
@Override
|
@Override
|
||||||
@CronTarget(jobName = JobName.APPLY_CHARGE_TO_OVERDUE_LOAN_INSTALLMENT)
|
@CronTarget(jobName = JobName.APPLY_CHARGE_TO_OVERDUE_LOAN_INSTALLMENT)
|
||||||
public void applyChargeForOverdueLoans() throws JobExecutionException {
|
public void applyChargeForOverdueLoans() throws JobExecutionException {
|
||||||
final Collection<OverdueLoanScheduleData> overdueLoanScheduleData = this.loanReadPlatformService.retrieveAllOverdueLoans();
|
|
||||||
if(!overdueLoanScheduleData.isEmpty()) {
|
|
||||||
for(OverdueLoanScheduleData overdueLoanScheduleData1 : overdueLoanScheduleData){
|
|
||||||
try{
|
|
||||||
|
|
||||||
final JsonElement parsedCommand = fromApiJsonHelper.parse(overdueLoanScheduleData1.toString());
|
final Collection<OverdueLoanScheduleData> overdueLoanScheduledInstallments = this.loanReadPlatformService.retrieveAllLoansWithOverdueInstallmentsNotAlreadyPenalized();
|
||||||
|
|
||||||
final JsonCommand command = JsonCommand.from(overdueLoanScheduleData1.toString(),parsedCommand,this.fromApiJsonHelper,null,null,
|
if (!overdueLoanScheduledInstallments.isEmpty()) {
|
||||||
null,null,null,overdueLoanScheduleData1.getLoanId(),null,null,null,null,null,null,null);
|
for (final OverdueLoanScheduleData overdueInstallment : overdueLoanScheduledInstallments) {
|
||||||
this.applyChargeToOverdueLoanInstallment(overdueLoanScheduleData1.getLoanId(),overdueLoanScheduleData1.getChargeId(),command);
|
try {
|
||||||
|
|
||||||
}catch(final PlatformApiDataValidationException e){
|
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(overdueInstallment.toString());
|
||||||
|
|
||||||
|
final JsonCommand command = JsonCommand.from(overdueInstallment.toString(), parsedCommand, this.fromApiJsonHelper,
|
||||||
|
null, null, null, null, null, overdueInstallment.getLoanId(), null, null, null, null, null, null, null);
|
||||||
|
|
||||||
|
applyChargeToOverdueLoanInstallment(overdueInstallment.getLoanId(), overdueInstallment.getChargeId(), command);
|
||||||
|
|
||||||
|
} catch (final PlatformApiDataValidationException e) {
|
||||||
final List<ApiParameterError> errors = e.getErrors();
|
final List<ApiParameterError> errors = e.getErrors();
|
||||||
for (final ApiParameterError error : errors) {
|
for (final ApiParameterError error : errors) {
|
||||||
logger.error("Apply Charges due for overdue loans failed for account:" + overdueLoanScheduleData1.getLoanId() + " with message "
|
logger.error("Apply Charges due for overdue loans failed for account:" + overdueInstallment.getLoanId()
|
||||||
+ error.getDeveloperMessage());
|
+ " with message " + error.getDeveloperMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1624,7 +1645,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public void applyChargeToOverdueLoanInstallment(Long loanId, Long loanChargeId,JsonCommand command) {
|
public void applyChargeToOverdueLoanInstallment(final Long loanId, final Long loanChargeId, final JsonCommand command) {
|
||||||
|
|
||||||
final Loan loan = this.loanAssembler.assembleFrom(loanId);
|
final Loan loan = this.loanAssembler.assembleFrom(loanId);
|
||||||
checkClientOrGroupActive(loan);
|
checkClientOrGroupActive(loan);
|
||||||
|
|
||||||
@@ -1636,6 +1658,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
final String errorMessage = "Charge and Loan must have the same currency.";
|
final String errorMessage = "Charge and Loan must have the same currency.";
|
||||||
throw new InvalidCurrencyException("loanCharge", "attach.to.loan", errorMessage);
|
throw new InvalidCurrencyException("loanCharge", "attach.to.loan", errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loanCharge.getChargePaymentMode().isPaymentModeAccountTransfer()) {
|
if (loanCharge.getChargePaymentMode().isPaymentModeAccountTransfer()) {
|
||||||
final PortfolioAccountData portfolioAccountData = this.accountAssociationsReadPlatformService.retriveLoanAssociation(loanId);
|
final PortfolioAccountData portfolioAccountData = this.accountAssociationsReadPlatformService.retriveLoanAssociation(loanId);
|
||||||
if (portfolioAccountData == null) {
|
if (portfolioAccountData == null) {
|
||||||
@@ -1656,13 +1679,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
if (loan.status().isActive()) {
|
if (loan.status().isActive()) {
|
||||||
final LoanTransaction applyLoanChargeTransaction = loan.handleChargeAppliedTransaction(loanCharge, null);
|
final LoanTransaction applyLoanChargeTransaction = loan.handleChargeAppliedTransaction(loanCharge, null);
|
||||||
this.loanTransactionRepository.save(applyLoanChargeTransaction);
|
this.loanTransactionRepository.save(applyLoanChargeTransaction);
|
||||||
/***
|
|
||||||
* TODO Vishwas Batch save is giving me a
|
|
||||||
* HibernateOptimisticLockingFailureException, looping and saving
|
|
||||||
* for the time being, not a major issue for now as this loop is
|
|
||||||
* entered only in edge cases (when a payment is made before the
|
|
||||||
* latest payment recorded against the loan)
|
|
||||||
***/
|
|
||||||
this.loanRepository.saveAndFlush(loan);
|
this.loanRepository.saveAndFlush(loan);
|
||||||
if (changedTransactionDetail != null) {
|
if (changedTransactionDetail != null) {
|
||||||
for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
|
for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
|
||||||
@@ -1671,7 +1687,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// we post Journal entries only for loans in active status
|
// we post Journal entries only for loans in active status
|
||||||
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-4
@@ -37,7 +37,6 @@ import org.mifosplatform.portfolio.calendar.domain.Calendar;
|
|||||||
import org.mifosplatform.portfolio.calendar.domain.CalendarEntityType;
|
import org.mifosplatform.portfolio.calendar.domain.CalendarEntityType;
|
||||||
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
|
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
|
||||||
import org.mifosplatform.portfolio.calendar.exception.NotValidRecurringDateException;
|
import org.mifosplatform.portfolio.calendar.exception.NotValidRecurringDateException;
|
||||||
import org.mifosplatform.portfolio.calendar.service.CalendarUtils;
|
|
||||||
import org.mifosplatform.portfolio.meeting.attendance.domain.ClientAttendance;
|
import org.mifosplatform.portfolio.meeting.attendance.domain.ClientAttendance;
|
||||||
import org.mifosplatform.portfolio.meeting.exception.MeetingDateException;
|
import org.mifosplatform.portfolio.meeting.exception.MeetingDateException;
|
||||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||||
@@ -163,7 +162,7 @@ public class Meeting extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isMeetingDateBefore(final LocalDate newStartDate) {
|
public boolean isMeetingDateBefore(final LocalDate newStartDate) {
|
||||||
return (this.meetingDate != null && newStartDate != null && getMeetingDateLocalDate().isBefore(newStartDate)) ? true : false;
|
return this.meetingDate != null && newStartDate != null && getMeetingDateLocalDate().isBefore(newStartDate) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isValidMeetingDate(final CalendarInstance calendarInstance, final Date meetingDate) {
|
private static boolean isValidMeetingDate(final CalendarInstance calendarInstance, final Date meetingDate) {
|
||||||
@@ -173,8 +172,7 @@ public class Meeting extends AbstractPersistable<Long> {
|
|||||||
meetingDateLocalDate = LocalDate.fromDateFields(meetingDate);
|
meetingDateLocalDate = LocalDate.fromDateFields(meetingDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (meetingDateLocalDate == null
|
if (meetingDateLocalDate == null || !calendar.isValidRecurringDate(meetingDateLocalDate)) { return false; }
|
||||||
|| !calendar.isValidRecurringDate(meetingDateLocalDate)) { return false; }
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user