Merge pull request #1502 from nazeer1100126/Mifosx_1523_-_Loan_Rescheduling

Mifosx 1523   loan rescheduling
This commit is contained in:
pramod
2015-09-15 13:20:36 +05:30
7 changed files with 386 additions and 331 deletions
@@ -306,5 +306,4 @@ public class CommandWrapper {
return this.actionName.equalsIgnoreCase("UPDATE") && this.entityName.equalsIgnoreCase("DISBURSEMENTDETAIL") return this.actionName.equalsIgnoreCase("UPDATE") && this.entityName.equalsIgnoreCase("DISBURSEMENTDETAIL")
&& this.entityId == null; && this.entityId == null;
} }
} }
@@ -2457,5 +2457,4 @@ public class CommandWrapperBuilder {
this.href = "/clients/" + clientId + "/transactions/" + transactionId + "?command=undo"; this.href = "/clients/" + clientId + "/transactions/" + transactionId + "?command=undo";
return this; return this;
} }
} }
@@ -13,6 +13,8 @@ public class RescheduleLoansApiConstants {
public final static String ENTITY_NAME = "RESCHEDULELOAN"; public final static String ENTITY_NAME = "RESCHEDULELOAN";
public static final String LOAN_RESCHEDULE_REASON = "LoanRescheduleReason";
// general // general
public static final String localeParamName = "locale"; public static final String localeParamName = "locale";
public static final String dateFormatParamName = "dateFormat"; public static final String dateFormatParamName = "dateFormat";
@@ -69,23 +69,39 @@ public class RescheduleLoansApiResource {
} }
@GET @GET
@Path("{requestId}") @Path("template")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String readLoanRescheduleRequest(@Context final UriInfo uriInfo, @PathParam("requestId") final Long requestId, public String retrieveTemplate(@Context final UriInfo uriInfo) {
this.platformSecurityContext.authenticatedUser().validateHasReadPermission(RescheduleLoansApiConstants.ENTITY_NAME);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
LoanRescheduleRequestData loanRescheduleReasons = null;
loanRescheduleReasons = this.loanRescheduleRequestReadPlatformService
.retrieveAllRescheduleReasons(RescheduleLoansApiConstants.LOAN_RESCHEDULE_REASON);
return this.loanRescheduleRequestToApiJsonSerializer.serialize(settings, loanRescheduleReasons);
}
@GET
@Path("{scheduleId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String readLoanRescheduleRequest(@Context final UriInfo uriInfo, @PathParam("scheduleId") final Long scheduleId,
@QueryParam("command") final String command) { @QueryParam("command") final String command) {
this.platformSecurityContext.authenticatedUser().validateHasReadPermission(RescheduleLoansApiConstants.ENTITY_NAME); this.platformSecurityContext.authenticatedUser().validateHasReadPermission(RescheduleLoansApiConstants.ENTITY_NAME);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
if (compareIgnoreCase(command, "previewLoanReschedule")) { if (compareIgnoreCase(command, "previewLoanReschedule")) {
final LoanRescheduleModel loanRescheduleModel = this.loanReschedulePreviewPlatformService.previewLoanReschedule(requestId); final LoanRescheduleModel loanRescheduleModel = this.loanReschedulePreviewPlatformService.previewLoanReschedule(scheduleId);
return this.loanRescheduleToApiJsonSerializer.serialize(settings, loanRescheduleModel.toData(), new HashSet<String>()); return this.loanRescheduleToApiJsonSerializer.serialize(settings, loanRescheduleModel.toData(), new HashSet<String>());
} }
final LoanRescheduleRequestData loanRescheduleRequestData = this.loanRescheduleRequestReadPlatformService final LoanRescheduleRequestData loanRescheduleRequestData = this.loanRescheduleRequestReadPlatformService
.readLoanRescheduleRequest(requestId); .readLoanRescheduleRequest(scheduleId);
return this.loanRescheduleRequestToApiJsonSerializer.serialize(settings, loanRescheduleRequestData); return this.loanRescheduleRequestToApiJsonSerializer.serialize(settings, loanRescheduleRequestData);
} }
@@ -103,20 +119,20 @@ public class RescheduleLoansApiResource {
} }
@POST @POST
@Path("{requestId}") @Path("{scheduleId}")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String updateLoanRescheduleRequest(@PathParam("requestId") final Long requestId, @QueryParam("command") final String command, public String updateLoanRescheduleRequest(@PathParam("scheduleId") final Long scheduleId, @QueryParam("command") final String command,
final String apiRequestBodyAsJson) { final String apiRequestBodyAsJson) {
CommandWrapper commandWrapper = null; CommandWrapper commandWrapper = null;
if (compareIgnoreCase(command, "approve")) { if (compareIgnoreCase(command, "approve")) {
commandWrapper = new CommandWrapperBuilder().approveLoanRescheduleRequest(RescheduleLoansApiConstants.ENTITY_NAME, requestId) commandWrapper = new CommandWrapperBuilder().approveLoanRescheduleRequest(RescheduleLoansApiConstants.ENTITY_NAME, scheduleId)
.withJson(apiRequestBodyAsJson).build(); .withJson(apiRequestBodyAsJson).build();
} }
else if (compareIgnoreCase(command, "reject")) { else if (compareIgnoreCase(command, "reject")) {
commandWrapper = new CommandWrapperBuilder().rejectLoanRescheduleRequest(RescheduleLoansApiConstants.ENTITY_NAME, requestId) commandWrapper = new CommandWrapperBuilder().rejectLoanRescheduleRequest(RescheduleLoansApiConstants.ENTITY_NAME, scheduleId)
.withJson(apiRequestBodyAsJson).build(); .withJson(apiRequestBodyAsJson).build();
} }
@@ -6,6 +6,7 @@
package org.mifosplatform.portfolio.loanaccount.rescheduleloan.data; package org.mifosplatform.portfolio.loanaccount.rescheduleloan.data;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Collection;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.codes.data.CodeValueData; import org.mifosplatform.infrastructure.codes.data.CodeValueData;
@@ -32,15 +33,16 @@ public class LoanRescheduleRequestData {
private final LoanRescheduleRequestTimelineData timeline; private final LoanRescheduleRequestTimelineData timeline;
private final String rescheduleReasonComment; private final String rescheduleReasonComment;
private final LocalDate adjustedDueDate; private final LocalDate adjustedDueDate;
private final Collection<CodeValueData> rescheduleReasons;
/** /**
* LoanRescheduleRequestData constructor * LoanRescheduleRequestData constructor
**/ **/
private LoanRescheduleRequestData(Long id, Long loanId, LoanRescheduleRequestStatusEnumData statusEnum, private LoanRescheduleRequestData(Long id, Long loanId, LoanRescheduleRequestStatusEnumData statusEnum,
Integer rescheduleFromInstallment, Integer graceOnPrincipal, Integer graceOnInterest, Integer rescheduleFromInstallment, Integer graceOnPrincipal, Integer graceOnInterest, LocalDate rescheduleFromDate,
LocalDate rescheduleFromDate, LocalDate adjustedDueDate, Integer extraTerms, BigDecimal interestRate, LocalDate adjustedDueDate, Integer extraTerms, BigDecimal interestRate, CodeValueData rescheduleReasonCodeValue,
CodeValueData rescheduleReasonCodeValue, String rescheduleReasonComment, LoanRescheduleRequestTimelineData timeline, String rescheduleReasonComment, LoanRescheduleRequestTimelineData timeline, final String clientName,
final String clientName, final String loanAccountNumber, final Long clientId, final Boolean recalculateInterest) { final String loanAccountNumber, final Long clientId, final Boolean recalculateInterest, Collection<CodeValueData> rescheduleReasons) {
this.id = id; this.id = id;
this.loanId = loanId; this.loanId = loanId;
@@ -59,20 +61,21 @@ public class LoanRescheduleRequestData {
this.loanAccountNumber = loanAccountNumber; this.loanAccountNumber = loanAccountNumber;
this.clientId = clientId; this.clientId = clientId;
this.recalculateInterest = recalculateInterest; this.recalculateInterest = recalculateInterest;
this.rescheduleReasons = rescheduleReasons ;
} }
/** /**
* @return an instance of the LoanRescheduleRequestData class * @return an instance of the LoanRescheduleRequestData class
**/ **/
public static LoanRescheduleRequestData instance(Long id, Long loanId, LoanRescheduleRequestStatusEnumData statusEnum, public static LoanRescheduleRequestData instance(Long id, Long loanId, LoanRescheduleRequestStatusEnumData statusEnum,
Integer rescheduleFromInstallment, Integer graceOnPrincipal, Integer graceOnInterest, Integer rescheduleFromInstallment, Integer graceOnPrincipal, Integer graceOnInterest, LocalDate rescheduleFromDate,
LocalDate rescheduleFromDate, LocalDate adjustedDueDate, Integer extraTerms, BigDecimal interestRate, LocalDate adjustedDueDate, Integer extraTerms, BigDecimal interestRate, CodeValueData rescheduleReasonCodeValue,
CodeValueData rescheduleReasonCodeValue, String rescheduleReasonComment, LoanRescheduleRequestTimelineData timeline, String rescheduleReasonComment, LoanRescheduleRequestTimelineData timeline, final String clientName,
final String clientName, final String loanAccountNumber, final Long clientId, final Boolean recalculateInterest) { final String loanAccountNumber, final Long clientId, final Boolean recalculateInterest, Collection<CodeValueData> rescheduleReasons) {
return new LoanRescheduleRequestData(id, loanId, statusEnum, rescheduleFromInstallment, graceOnPrincipal, graceOnInterest, return new LoanRescheduleRequestData(id, loanId, statusEnum, rescheduleFromInstallment, graceOnPrincipal, graceOnInterest,
rescheduleFromDate, adjustedDueDate, extraTerms, interestRate, rescheduleReasonCodeValue, rescheduleReasonComment, rescheduleFromDate, adjustedDueDate, extraTerms, interestRate, rescheduleReasonCodeValue, rescheduleReasonComment,
timeline, clientName, loanAccountNumber, clientId, recalculateInterest); timeline, clientName, loanAccountNumber, clientId, recalculateInterest, rescheduleReasons);
} }
/** /**
@@ -193,7 +196,7 @@ public class LoanRescheduleRequestData {
public Boolean getRecalculateInterest() { public Boolean getRecalculateInterest() {
boolean value = false; boolean value = false;
if(recalculateInterest != null) { if (recalculateInterest != null) {
value = recalculateInterest; value = recalculateInterest;
} }
@@ -14,7 +14,8 @@ public interface LoanRescheduleRequestReadPlatformService {
/** /**
* get all loan reschedule requests by loan ID * get all loan reschedule requests by loan ID
* *
* @param loanId the loan identifier * @param loanId
* the loan identifier
* @return list of LoanRescheduleRequestData objects * @return list of LoanRescheduleRequestData objects
**/ **/
public List<LoanRescheduleRequestData> readLoanRescheduleRequests(Long loanId); public List<LoanRescheduleRequestData> readLoanRescheduleRequests(Long loanId);
@@ -22,7 +23,8 @@ public interface LoanRescheduleRequestReadPlatformService {
/** /**
* get a single loan reschedule request by ID (primary key) * get a single loan reschedule request by ID (primary key)
* *
* @param requestId the loan reschedule request identifier * @param requestId
* the loan reschedule request identifier
* @return a LoanRescheduleRequestData object * @return a LoanRescheduleRequestData object
**/ **/
public LoanRescheduleRequestData readLoanRescheduleRequest(Long requestId); public LoanRescheduleRequestData readLoanRescheduleRequest(Long requestId);
@@ -30,8 +32,18 @@ public interface LoanRescheduleRequestReadPlatformService {
/** /**
* get all loan reschedule requests filter by loan ID and status enum * get all loan reschedule requests filter by loan ID and status enum
* *
* @param loanId the loan identifier * @param loanId
* the loan identifier
* @return list of LoanRescheduleRequestData objects * @return list of LoanRescheduleRequestData objects
**/ **/
public List<LoanRescheduleRequestData> readLoanRescheduleRequests(Long loanId, Integer statusEnum); public List<LoanRescheduleRequestData> readLoanRescheduleRequests(Long loanId, Integer statusEnum);
/**
* get all loan reschedule reasons
*
* @param loanRescheduleReason
* the loan reschedule reason
* @return list of LoanRescheduleRequestData objects
**/
public LoanRescheduleRequestData retrieveAllRescheduleReasons(String loanRescheduleReason);
} }
@@ -8,10 +8,13 @@ package org.mifosplatform.portfolio.loanaccount.rescheduleloan.service;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.codes.data.CodeValueData; import org.mifosplatform.infrastructure.codes.data.CodeValueData;
import org.mifosplatform.infrastructure.codes.service.CodeValueReadPlatformService;
import org.mifosplatform.infrastructure.core.domain.JdbcSupport; import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
import org.mifosplatform.infrastructure.core.service.RoutingDataSource; import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
import org.mifosplatform.portfolio.loanaccount.domain.Loan; import org.mifosplatform.portfolio.loanaccount.domain.Loan;
@@ -33,12 +36,14 @@ public class LoanRescheduleRequestReadPlatformServiceImpl implements LoanResched
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private final LoanRepository loanRepository; private final LoanRepository loanRepository;
private final LoanRescheduleRequestRowMapper loanRescheduleRequestRowMapper = new LoanRescheduleRequestRowMapper(); private final LoanRescheduleRequestRowMapper loanRescheduleRequestRowMapper = new LoanRescheduleRequestRowMapper();
private final CodeValueReadPlatformService codeValueReadPlatformService;
@Autowired @Autowired
public LoanRescheduleRequestReadPlatformServiceImpl(final RoutingDataSource dataSource, public LoanRescheduleRequestReadPlatformServiceImpl(final RoutingDataSource dataSource, LoanRepository loanRepository,
LoanRepository loanRepository) { final CodeValueReadPlatformService codeValueReadPlatformService) {
this.jdbcTemplate = new JdbcTemplate(dataSource); this.jdbcTemplate = new JdbcTemplate(dataSource);
this.loanRepository = loanRepository; this.loanRepository = loanRepository;
this.codeValueReadPlatformService = codeValueReadPlatformService;
} }
private static final class LoanRescheduleRequestRowMapper implements RowMapper<LoanRescheduleRequestData> { private static final class LoanRescheduleRequestRowMapper implements RowMapper<LoanRescheduleRequestData> {
@@ -104,8 +109,7 @@ public class LoanRescheduleRequestReadPlatformServiceImpl implements LoanResched
final Long id = rs.getLong("id"); final Long id = rs.getLong("id");
final Long loanId = rs.getLong("loanId"); final Long loanId = rs.getLong("loanId");
final Integer statusEnumId = JdbcSupport.getInteger(rs, "statusEnum"); final Integer statusEnumId = JdbcSupport.getInteger(rs, "statusEnum");
final LoanRescheduleRequestStatusEnumData statusEnum = LoanRescheduleRequestEnumerations final LoanRescheduleRequestStatusEnumData statusEnum = LoanRescheduleRequestEnumerations.status(statusEnumId);
.status(statusEnumId);
final String clientName = rs.getString("clientName"); final String clientName = rs.getString("clientName");
final String loanAccountNumber = rs.getString("loanAccountNumber"); final String loanAccountNumber = rs.getString("loanAccountNumber");
final Long clientId = rs.getLong("clientId"); final Long clientId = rs.getLong("clientId");
@@ -118,8 +122,7 @@ public class LoanRescheduleRequestReadPlatformServiceImpl implements LoanResched
final BigDecimal interestRate = rs.getBigDecimal("interestRate"); final BigDecimal interestRate = rs.getBigDecimal("interestRate");
final Long rescheduleReasonCvId = JdbcSupport.getLong(rs, "rescheduleReasonCvId"); final Long rescheduleReasonCvId = JdbcSupport.getLong(rs, "rescheduleReasonCvId");
final String rescheduleReasonCvValue = rs.getString("rescheduleReasonCvValue"); final String rescheduleReasonCvValue = rs.getString("rescheduleReasonCvValue");
final CodeValueData rescheduleReasonCodeValue = CodeValueData final CodeValueData rescheduleReasonCodeValue = CodeValueData.instance(rescheduleReasonCvId, rescheduleReasonCvValue);
.instance(rescheduleReasonCvId, rescheduleReasonCvValue);
final String rescheduleReasonComment = rs.getString("rescheduleReasonComment"); final String rescheduleReasonComment = rs.getString("rescheduleReasonComment");
final Boolean recalculateInterest = rs.getBoolean("recalculateInterest"); final Boolean recalculateInterest = rs.getBoolean("recalculateInterest");
@@ -137,15 +140,14 @@ public class LoanRescheduleRequestReadPlatformServiceImpl implements LoanResched
final String rejectedByUsername = rs.getString("rejectedByUsername"); final String rejectedByUsername = rs.getString("rejectedByUsername");
final String rejectedByFirstname = rs.getString("rejectedByFirstname"); final String rejectedByFirstname = rs.getString("rejectedByFirstname");
final String rejectedByLastname = rs.getString("rejectedByLastname"); final String rejectedByLastname = rs.getString("rejectedByLastname");
final Collection<CodeValueData> rescheduleReasons = null;
final LoanRescheduleRequestTimelineData timeline = new LoanRescheduleRequestTimelineData(submittedOnDate, submittedByUsername,
submittedByFirstname, submittedByLastname, approvedOnDate, approvedByUsername, approvedByFirstname, approvedByLastname,
rejectedOnDate, rejectedByUsername, rejectedByFirstname, rejectedByLastname);
final LoanRescheduleRequestTimelineData timeline = new LoanRescheduleRequestTimelineData(submittedOnDate, return LoanRescheduleRequestData.instance(id, loanId, statusEnum, rescheduleFromInstallment, graceOnPrincipal, graceOnInterest,
submittedByUsername, submittedByFirstname, submittedByLastname, approvedOnDate, approvedByUsername, rescheduleFromDate, adjustedDueDate, extraTerms, interestRate, rescheduleReasonCodeValue, rescheduleReasonComment,
approvedByFirstname, approvedByLastname, rejectedOnDate, rejectedByUsername, rejectedByFirstname, timeline, clientName, loanAccountNumber, clientId, recalculateInterest, rescheduleReasons);
rejectedByLastname);
return LoanRescheduleRequestData.instance(id, loanId, statusEnum, rescheduleFromInstallment, graceOnPrincipal,
graceOnInterest, rescheduleFromDate, adjustedDueDate, extraTerms, interestRate, rescheduleReasonCodeValue,
rescheduleReasonComment, timeline, clientName, loanAccountNumber, clientId, recalculateInterest);
} }
} }
@@ -154,9 +156,7 @@ public class LoanRescheduleRequestReadPlatformServiceImpl implements LoanResched
public List<LoanRescheduleRequestData> readLoanRescheduleRequests(Long loanId) { public List<LoanRescheduleRequestData> readLoanRescheduleRequests(Long loanId) {
final Loan loan = this.loanRepository.findOne(loanId); final Loan loan = this.loanRepository.findOne(loanId);
if(loan == null) { if (loan == null) { throw new LoanNotFoundException(loanId); }
throw new LoanNotFoundException(loanId);
}
final String sql = "select " + this.loanRescheduleRequestRowMapper.schema() + " where lr.loan_id = ?"; final String sql = "select " + this.loanRescheduleRequestRowMapper.schema() + " where lr.loan_id = ?";
@@ -172,7 +172,7 @@ public class LoanRescheduleRequestReadPlatformServiceImpl implements LoanResched
return this.jdbcTemplate.queryForObject(sql, this.loanRescheduleRequestRowMapper, new Object[] { requestId }); return this.jdbcTemplate.queryForObject(sql, this.loanRescheduleRequestRowMapper, new Object[] { requestId });
} }
catch(final EmptyResultDataAccessException e) { catch (final EmptyResultDataAccessException e) {
return null; return null;
} }
} }
@@ -181,13 +181,37 @@ public class LoanRescheduleRequestReadPlatformServiceImpl implements LoanResched
public List<LoanRescheduleRequestData> readLoanRescheduleRequests(Long loanId, Integer statusEnum) { public List<LoanRescheduleRequestData> readLoanRescheduleRequests(Long loanId, Integer statusEnum) {
final Loan loan = this.loanRepository.findOne(loanId); final Loan loan = this.loanRepository.findOne(loanId);
if(loan == null) { if (loan == null) { throw new LoanNotFoundException(loanId); }
throw new LoanNotFoundException(loanId);
}
final String sql = "select " + this.loanRescheduleRequestRowMapper.schema() + " where lr.loan_id = ?" final String sql = "select " + this.loanRescheduleRequestRowMapper.schema() + " where lr.loan_id = ?" + " and lr.status_enum = ?";
+ " and lr.status_enum = ?";
return this.jdbcTemplate.query(sql, this.loanRescheduleRequestRowMapper, new Object[] { loanId, statusEnum }); return this.jdbcTemplate.query(sql, this.loanRescheduleRequestRowMapper, new Object[] { loanId, statusEnum });
} }
@Override
public LoanRescheduleRequestData retrieveAllRescheduleReasons(String loanRescheduleReason) {
final List<CodeValueData> rescheduleReasons = new ArrayList<>(
this.codeValueReadPlatformService.retrieveCodeValuesByCode(loanRescheduleReason));
final Long id = null;
final Long loanId = null;
final LoanRescheduleRequestStatusEnumData statusEnum = null;
final Integer rescheduleFromInstallment = null;
final Integer graceOnPrincipal = null;
final Integer graceOnInterest = null;
final LocalDate rescheduleFromDate = null;
final LocalDate adjustedDueDate = null;
final Integer extraTerms = null;
final BigDecimal interestRate = null;
final CodeValueData rescheduleReasonCodeValue = null;
final String rescheduleReasonComment = null;
final LoanRescheduleRequestTimelineData timeline = null;
final String clientName = null;
final String loanAccountNumber = null;
final Long clientId = null;
final Boolean recalculateInterest = null;
return LoanRescheduleRequestData.instance(id, loanId, statusEnum, rescheduleFromInstallment, graceOnPrincipal, graceOnInterest,
rescheduleFromDate, adjustedDueDate, extraTerms, interestRate, rescheduleReasonCodeValue, rescheduleReasonComment,
timeline, clientName, loanAccountNumber, clientId, recalculateInterest, rescheduleReasons);
}
} }