fixed MIFOSX-301 issues and added loan type and template type to loan

This commit is contained in:
ashok-conflux
2013-04-29 17:46:11 +05:30
parent 1f7cd4d293
commit bc85e81316
19 changed files with 669 additions and 206 deletions
@@ -0,0 +1,2 @@
ALTER TABLE `m_loan`
ADD COLUMN `loan_type_enum` SMALLINT(5) NOT NULL AFTER `loan_status_id`;
@@ -36,6 +36,7 @@ public class AccountingScenarioIntegrationTest {
private final String EXPECTED_DISBURSAL_DATE="04 March 2011";
private final String LOAN_APPLICATION_SUBMISSION_DATE= "3 March 2011";
private final String LOAN_TERM_FREQUENCY= "10";
private final String INDIVIDUAL_LOAN = "individual";
private final String REPAYMENT_DATE[]={"","04 May 2011","04 July 2011","04 September 2011","04 November 2011","04 January 2012"};
private final Float REPAYMENT_AMOUNT [] = {.0f,2200.0f,3000.0f,900.0f,2000.0f,2500.0f};
@@ -187,6 +188,7 @@ public class AccountingScenarioIntegrationTest {
.withRepaymentFrequencyTypeAsMonths().withInterestRatePerPeriod(LP_INTEREST_RATE).withInterestTypeAsFlatBalance()
.withAmortizationTypeAsEqualPrincipalPayments().withInterestCalculationPeriodTypeSameAsRepaymentPeriod()
.withExpectedDisbursementDate(EXPECTED_DISBURSAL_DATE).withSubmittedOnDate(LOAN_APPLICATION_SUBMISSION_DATE)
.withLoanType(INDIVIDUAL_LOAN)
.build(clientID.toString(), loanProductID.toString());
return loanTransactionHelper.getLoanId(loanApplicationJSON);
}
@@ -31,6 +31,7 @@ public class LoanApplicationTestBuilder {
private final String transactionProcessingID = MIFOS_STANDARD_STRATEGY;
private String expectedDisbursmentDate = "";
private String submittedOnDate = "";
private String loanType = "individual"; //default it to individual
public String build(final String clientID, final String loanProductId) {
@@ -52,6 +53,7 @@ public class LoanApplicationTestBuilder {
map.put("transactionProcessingStrategyId", transactionProcessingID);
map.put("expectedDisbursementDate", expectedDisbursmentDate);
map.put("submittedOnDate", submittedOnDate);
map.put("loanType", "individual");
return new Gson().toJson(map);
}
@@ -155,5 +157,9 @@ public class LoanApplicationTestBuilder {
return this;
}
public LoanApplicationTestBuilder withLoanType(final String loanType){
this.loanType = loanType;
return this;
}
}
@@ -24,7 +24,6 @@ import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandWrapper;
import org.mifosplatform.commands.service.CommandWrapperBuilder;
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
@@ -34,14 +33,12 @@ import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.core.service.DateUtils;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.calendar.data.CalendarData;
import org.mifosplatform.portfolio.calendar.domain.Calendar;
import org.mifosplatform.portfolio.calendar.domain.CalendarEntityType;
import org.mifosplatform.portfolio.calendar.service.CalendarDropdownReadPlatformService;
import org.mifosplatform.portfolio.calendar.service.CalendarReadPlatformService;
import org.mifosplatform.portfolio.calendar.service.CalendarHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -92,7 +89,7 @@ public class CalendarsApiResource {
CalendarData calendarData = this.readPlatformService.retrieveCalendar(calendarId, entityId, entityTypeId);
// Include recurring date details
calendarData = handleRecurringDate(calendarData);
calendarData = this.readPlatformService.generateRecurringDate(calendarData);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
if (settings.isTemplate()) {
@@ -124,7 +121,7 @@ public class CalendarsApiResource {
CalendarEntityType.valueOf(entityType.toUpperCase()).getValue()));
// Add recurring dates
calendarsData = handleRecurringDates(calendarsData);
calendarsData = this.readPlatformService.generateRecurringDates(calendarsData);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, calendarsData, this.RESPONSE_DATA_PARAMETERS);
@@ -195,33 +192,4 @@ public class CalendarsApiResource {
final List<EnumOptionData> remindByOptions = this.dropdownReadPlatformService.retrieveCalendarRemindByOptions();
return new CalendarData(calendarData, entityTypeOptions, calendarTypeOptions, remindByOptions);
}
private CalendarData handleRecurringDate(final CalendarData calendarData){
if(!calendarData.isRepeating()) return calendarData;
final String rrule = calendarData.getRecurrence();
final LocalDate currentDate = DateUtils.getLocalDateOfTenant();
LocalDate seedDate = calendarData.getStartDate();
LocalDate endDate = calendarData.getEndDate();
if(seedDate.isBefore(currentDate.minusYears(1))){
seedDate = currentDate.minusYears(1);
}
if(endDate == null || endDate.isAfter(currentDate.plusYears(1))){
endDate = currentDate.plusYears(1);
}
final Collection<LocalDate> recurringDates = CalendarHelper.getRecurringDates(rrule, seedDate, seedDate, endDate, -1);
final Collection<LocalDate> nextTenRecurringDates = CalendarHelper.getRecurringDates(rrule, seedDate, endDate);
return new CalendarData(calendarData, recurringDates, nextTenRecurringDates);
}
private Collection<CalendarData> handleRecurringDates(final Collection<CalendarData> calendarsData) {
Collection<CalendarData> recuCalendarsData = new ArrayList<CalendarData>();
for (CalendarData calendarData : calendarsData) {
recuCalendarsData.add(handleRecurringDate(calendarData));
}
return recuCalendarsData;
}
}
@@ -20,4 +20,10 @@ public interface CalendarReadPlatformService {
Collection<CalendarData> retrieveAllCalendars();
CalendarData retrieveNewCalendarDetails();
CalendarData generateRecurringDate(final CalendarData calendarData);
Collection<CalendarData> generateRecurringDates(final Collection<CalendarData> calendarsData);
CalendarData retrieveLoanCalendar(final Long loanId);
}
@@ -7,11 +7,13 @@ package org.mifosplatform.portfolio.calendar.service;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
import org.mifosplatform.infrastructure.core.service.DateUtils;
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
import org.mifosplatform.portfolio.calendar.data.CalendarData;
import org.mifosplatform.portfolio.calendar.domain.CalendarEntityType;
@@ -21,6 +23,7 @@ import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
@Service
public class CalendarReadPlatformServiceImpl implements CalendarReadPlatformService {
@@ -130,6 +133,56 @@ public class CalendarReadPlatformServiceImpl implements CalendarReadPlatformServ
return CalendarData.sensibleDefaultsForNewCalendarCreation();
}
@Override
public CalendarData generateRecurringDate(CalendarData calendarData) {
if(!calendarData.isRepeating()) return calendarData;
final String rrule = calendarData.getRecurrence();
final LocalDate currentDate = DateUtils.getLocalDateOfTenant();
LocalDate seedDate = calendarData.getStartDate();
LocalDate endDate = calendarData.getEndDate();
LocalDate startDate = calendarData.getStartDate();
if(seedDate.isBefore(currentDate.minusYears(1))){
startDate = currentDate.minusYears(1);
}
if(endDate == null || endDate.isAfter(currentDate.plusYears(1))){
endDate = currentDate.plusYears(1);
}
final Collection<LocalDate> recurringDates = CalendarHelper.getRecurringDates(rrule, seedDate, startDate, endDate, -1);
final Collection<LocalDate> nextTenRecurringDates = CalendarHelper.getRecurringDates(rrule, seedDate, endDate);
return new CalendarData(calendarData, recurringDates, nextTenRecurringDates);
}
@Override
public Collection<CalendarData> generateRecurringDates(Collection<CalendarData> calendarsData) {
Collection<CalendarData> recuCalendarsData = new ArrayList<CalendarData>();
for (CalendarData calendarData : calendarsData) {
recuCalendarsData.add(generateRecurringDate(calendarData));
}
return recuCalendarsData;
}
@Override
public CalendarData retrieveLoanCalendar(Long loanId) {
final CalendarDataMapper rm = new CalendarDataMapper();
final String sql = rm.schema() + " and ci.entity_id = ? and ci.entity_type_enum = ? order by c.start_date ";
CalendarData calendarData = null;
final Collection<CalendarData> calendars = this.jdbcTemplate.query(sql, rm, new Object[] { loanId, CalendarEntityType.LOANS.getValue() });
if(!CollectionUtils.isEmpty(calendars)){
for (CalendarData calendar : calendars) {
calendarData = calendar;
break;//Loans are associated with only one calendar
}
}
return calendarData;
}
public static String getParentHierarchyCondition(final CalendarEntityType calendarEntityType) {
String conditionSql = "";
@@ -43,6 +43,8 @@ import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext
import org.mifosplatform.organisation.staff.data.BulkTransferLoanOfficerData;
import org.mifosplatform.organisation.staff.data.StaffData;
import org.mifosplatform.organisation.staff.service.StaffReadPlatformService;
import org.mifosplatform.portfolio.calendar.data.CalendarData;
import org.mifosplatform.portfolio.calendar.service.CalendarReadPlatformService;
import org.mifosplatform.portfolio.charge.data.ChargeData;
import org.mifosplatform.portfolio.charge.service.ChargeReadPlatformService;
import org.mifosplatform.portfolio.collateral.data.CollateralData;
@@ -55,6 +57,8 @@ import org.mifosplatform.portfolio.loanaccount.data.LoanAccountData;
import org.mifosplatform.portfolio.loanaccount.data.LoanChargeData;
import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionData;
import org.mifosplatform.portfolio.loanaccount.data.RepaymentScheduleRelatedLoanData;
import org.mifosplatform.portfolio.loanaccount.exception.LoanTemplateTypeRequiredException;
import org.mifosplatform.portfolio.loanaccount.exception.NotSupportedLoanTemplateTypeException;
import org.mifosplatform.portfolio.loanaccount.guarantor.data.GuarantorData;
import org.mifosplatform.portfolio.loanaccount.guarantor.service.GuarantorReadPlatformService;
import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanScheduleData;
@@ -63,8 +67,6 @@ import org.mifosplatform.portfolio.loanaccount.service.LoanChargeReadPlatformSer
import org.mifosplatform.portfolio.loanaccount.service.LoanReadPlatformService;
import org.mifosplatform.portfolio.loanproduct.data.LoanProductData;
import org.mifosplatform.portfolio.loanproduct.data.TransactionProcessingStrategyData;
import org.mifosplatform.portfolio.loanproduct.domain.LendingStrategy;
import org.mifosplatform.portfolio.loanproduct.exception.InvalidLendingStrategy;
import org.mifosplatform.portfolio.loanproduct.service.LoanDropdownReadPlatformService;
import org.mifosplatform.portfolio.loanproduct.service.LoanProductReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -85,11 +87,11 @@ public class LoansApiResource {
"termPeriodFrequencyType", "numberOfRepayments", "repaymentEvery", "interestRatePerPeriod", "annualInterestRate",
"repaymentFrequencyType", "transactionProcessingStrategyId", "interestRateFrequencyType", "amortizationType", "interestType",
"interestCalculationPeriodType", "expectedFirstRepaymentOnDate", "interestChargedFromDate", "timeline",
"totalFeeChargesAtDisbursement", "summary", "repaymentSchedule", "transactions", "charges", "collateral", "guarantors",
"totalFeeChargesAtDisbursement", "summary", "repaymentSchedule", "transactions", "charges", "collateral", "guarantors","meeting",
"productOptions", "amortizationTypeOptions", "interestTypeOptions", "interestCalculationPeriodTypeOptions",
"repaymentFrequencyTypeOptions", "termFrequencyTypeOptions", "interestRateFrequencyTypeOptions", "fundOptions",
"repaymentStrategyOptions", "chargeOptions", "loanOfficerOptions", "loanPurposeOptions", "loanCollateralOptions",
"chargeTemplate"));
"chargeTemplate","calendarOptions"));
private final String resourceNameForPermissions = "LOAN";
@@ -112,6 +114,7 @@ public class LoansApiResource {
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final FromJsonHelper fromJsonHelper;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
private final CalendarReadPlatformService calendarReadPlatformService;
@Autowired
public LoansApiResource(final PlatformSecurityContext context, final LoanReadPlatformService loanReadPlatformService,
@@ -127,7 +130,8 @@ public class LoansApiResource {
final DefaultToApiJsonSerializer<LoanScheduleData> loanScheduleToApiJsonSerializer,
final DefaultToApiJsonSerializer<BulkTransferLoanOfficerData> loanOfficeTransferToApiJsonSerializer,
final ApiRequestParameterHelper apiRequestParameterHelper, final FromJsonHelper fromJsonHelper,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
final CalendarReadPlatformService calendarReadPlatformService) {
this.context = context;
this.loanReadPlatformService = loanReadPlatformService;
this.loanProductReadPlatformService = loanProductReadPlatformService;
@@ -147,6 +151,7 @@ public class LoansApiResource {
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.fromJsonHelper = fromJsonHelper;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
this.calendarReadPlatformService = calendarReadPlatformService;
}
@GET
@@ -154,108 +159,71 @@ public class LoansApiResource {
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String template(@QueryParam("clientId") final Long clientId, @QueryParam("groupId") final Long groupId,
@QueryParam("productId") final Long productId, @QueryParam("lendingStrategy") final Integer lendingStrategy, @Context final UriInfo uriInfo) {
@QueryParam("productId") final Long productId, @QueryParam("templateType") final String templateType, @Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
// template
final Collection<LoanProductData> productOptions = this.loanProductReadPlatformService.retrieveAllLoanProductsForLookup();
// associations
final LoanScheduleData repaymentSchedule = null;
final Collection<LoanTransactionData> loanRepayments = null;
final Collection<CollateralData> collateral = null;
final Collection<GuarantorData> guarantors = null;
// options
Collection<EnumOptionData> loanTermFrequencyTypeOptions = null;
Collection<EnumOptionData> repaymentFrequencyTypeOptions = null;
Collection<EnumOptionData> interestRateFrequencyTypeOptions = null;
Collection<EnumOptionData> amortizationTypeOptions = null;
Collection<EnumOptionData> interestTypeOptions = null;
Collection<EnumOptionData> interestCalculationPeriodTypeOptions = null;
Collection<FundData> fundOptions = null;
Collection<TransactionProcessingStrategyData> repaymentStrategyOptions = null;
Collection<StaffData> allowedLoanOfficers = null;
Collection<CodeValueData> loanPurposeOptions = null;
Collection<CodeValueData> loanCollateralOptions = null;
Collection<ChargeData> chargeOptions = null;
ChargeData chargeTemplate = null;
if (productId != null) {
loanTermFrequencyTypeOptions = dropdownReadPlatformService.retrieveLoanTermFrequencyTypeOptions();
repaymentFrequencyTypeOptions = dropdownReadPlatformService.retrieveRepaymentFrequencyTypeOptions();
interestRateFrequencyTypeOptions = dropdownReadPlatformService.retrieveInterestRateFrequencyTypeOptions();
amortizationTypeOptions = dropdownReadPlatformService.retrieveLoanAmortizationTypeOptions();
interestTypeOptions = dropdownReadPlatformService.retrieveLoanInterestTypeOptions();
interestCalculationPeriodTypeOptions = dropdownReadPlatformService.retrieveLoanInterestRateCalculatedInPeriodOptions();
fundOptions = this.fundReadPlatformService.retrieveAllFunds();
repaymentStrategyOptions = this.dropdownReadPlatformService.retreiveTransactionProcessingStrategies();
loanPurposeOptions = this.codeValueReadPlatformService.retrieveCodeValuesByCode("LoanPurpose");
loanCollateralOptions = this.codeValueReadPlatformService.retrieveCodeValuesByCode("LoanCollateral");
final boolean feeChargesOnly = false;
chargeOptions = this.chargeReadPlatformService.retrieveLoanApplicableCharges(feeChargesOnly);
}
Collection<CalendarData> calendarOptions = null;
LoanAccountData newLoanAccount = null;
if (clientId != null) {
LoanAccountData loanBasicDetails = this.loanReadPlatformService.retrieveTemplateWithClientAndProductDetails(clientId,
productId);
final Collection<LoanChargeData> charges = loanBasicDetails.charges();
if (productId != null) {
final Long officeId = loanBasicDetails.officeId();
allowedLoanOfficers = this.staffReadPlatformService.retrieveAllLoanOfficersByOffice(officeId);
}
//If JLG loan then attach group
if(groupId != null){
final GroupGeneralData group = this.groupReadPlatformService.retrieveOne(groupId);
loanBasicDetails = LoanAccountData.associateGroup(loanBasicDetails, group);
}
newLoanAccount = LoanAccountData.associationsAndTemplate(loanBasicDetails, repaymentSchedule, loanRepayments, charges,
collateral, guarantors, productOptions, loanTermFrequencyTypeOptions, repaymentFrequencyTypeOptions,
repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions,
interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, allowedLoanOfficers,
loanPurposeOptions, loanCollateralOptions);
} else if (groupId != null ) {
LoanAccountData loanBasicDetails = null;
if (LendingStrategy.JOINT_LIABILITY_LOAN.getId().equals(lendingStrategy)){
loanBasicDetails = this.loanReadPlatformService.retrieveTemplateWithCompleteGroupAndProductDetails(groupId,
productId);
}
else if( LendingStrategy.GROUP_LOAN.getId().equals(lendingStrategy)){
loanBasicDetails = this.loanReadPlatformService.retrieveTemplateWithGroupAndProductDetails(groupId,
productId);
}else{
throw new InvalidLendingStrategy(lendingStrategy);
}
final Collection<LoanChargeData> charges = loanBasicDetails.charges();
if (productId != null) {
final Long officeId = loanBasicDetails.groupOfficeId();
if(officeId != null) allowedLoanOfficers = this.staffReadPlatformService.retrieveAllLoanOfficersByOffice(officeId);
}
newLoanAccount = LoanAccountData.associationsAndTemplate(loanBasicDetails, repaymentSchedule, loanRepayments, charges,
collateral, guarantors, productOptions, loanTermFrequencyTypeOptions, repaymentFrequencyTypeOptions,
repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions,
interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, allowedLoanOfficers,
loanPurposeOptions, loanCollateralOptions);
Long officeId = null;
if (productId != null) {
newLoanAccount = this.loanReadPlatformService.retrieveLoanProductDetailsTemplate(productId);
}
else {
if(templateType == null){
final String errorMsg = "Loan template type must be provided";
throw new LoanTemplateTypeRequiredException(errorMsg);
}else if (templateType.equals("collateral")) {
newLoanAccount = LoanAccountData.collateralTemplate(loanCollateralOptions);
}
} else {
//for JLG loan both client and group details are required
if (templateType.equals("individual") || templateType.equals("jlg")) {
LoanAccountData loanAccountClientDetails = this.loanReadPlatformService.retrieveClientDetailsTemplate(clientId);
officeId = loanAccountClientDetails.officeId();
newLoanAccount = (newLoanAccount == null) ? loanAccountClientDetails : LoanAccountData.populateClientDefaults(
newLoanAccount, loanAccountClientDetails);
// if it's JLG loan add group details
if (templateType.equals("jlg")) {
final GroupGeneralData group = this.groupReadPlatformService.retrieveOne(groupId);
newLoanAccount = LoanAccountData.associateGroup(newLoanAccount, group);
calendarOptions = this.loanReadPlatformService.retrieveCalendars(groupId);
}
} else if (templateType.equals("group")) {
final LoanAccountData loanAccountGroupData = this.loanReadPlatformService.retrieveGroupDetailsTemplate(groupId);
officeId = loanAccountGroupData.groupOfficeId();
calendarOptions = this.loanReadPlatformService.retrieveCalendars(groupId);
newLoanAccount = (newLoanAccount == null) ? loanAccountGroupData : LoanAccountData.populateGroupDefaults(newLoanAccount,
loanAccountGroupData);
} else if (templateType.equals("jlgbulk")) {
//get group details along with members in that group
final LoanAccountData loanAccountGroupData = this.loanReadPlatformService.retrieveGroupAndMembersDetailsTemplate(groupId);
officeId = loanAccountGroupData.groupOfficeId();
calendarOptions = this.loanReadPlatformService.retrieveCalendars(groupId);
newLoanAccount = (newLoanAccount == null) ? loanAccountGroupData : LoanAccountData.populateGroupDefaults(newLoanAccount,
loanAccountGroupData);
} else {
final String errorMsg = "Loan template type '" + templateType + "' is not supported";
throw new NotSupportedLoanTemplateTypeException(errorMsg, templateType);
}
if (officeId != null) allowedLoanOfficers = this.staffReadPlatformService.retrieveAllLoanOfficersByOffice(officeId);
// add product options, allowed loan officers and calendar options (calendar options will be null in individual loan)
newLoanAccount = LoanAccountData.associationsAndTemplate(newLoanAccount, productOptions, allowedLoanOfficers, calendarOptions);
}
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, newLoanAccount, LOAN_DATA_PARAMETERS);
}
@@ -275,7 +243,8 @@ public class LoansApiResource {
Collection<LoanChargeData> charges = null;
Collection<GuarantorData> guarantors = null;
Collection<CollateralData> collateral = null;
CalendarData meeting = null;
final Set<String> mandatoryResponseParameters = new HashSet<String>();
final Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
if (!associationParameters.isEmpty()) {
@@ -322,6 +291,11 @@ public class LoansApiResource {
collateral = null;
}
}
if (associationParameters.contains("meeting")) {
mandatoryResponseParameters.add("meeting");
meeting = this.calendarReadPlatformService.retrieveLoanCalendar(loanId);
}
}
Collection<LoanProductData> productOptions = null;
@@ -338,6 +312,7 @@ public class LoansApiResource {
ChargeData chargeTemplate = null;
Collection<CodeValueData> loanPurposeOptions = null;
Collection<CodeValueData> loanCollateralOptions = null;
Collection<CalendarData> calendarOptions = null;
final boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters());
if (template) {
@@ -355,16 +330,27 @@ public class LoansApiResource {
final boolean feeChargesOnly = false;
chargeOptions = this.chargeReadPlatformService.retrieveLoanApplicableCharges(feeChargesOnly);
chargeTemplate = this.loanChargeReadPlatformService.retrieveLoanChargeTemplate();
allowedLoanOfficers = this.staffReadPlatformService.retrieveAllLoanOfficersByOffice(loanBasicDetails.officeId());
if(loanBasicDetails.officeId() != null){
allowedLoanOfficers = this.staffReadPlatformService.retrieveAllLoanOfficersByOffice(loanBasicDetails.officeId());
}else if(loanBasicDetails.groupOfficeId() != null){
allowedLoanOfficers = this.staffReadPlatformService.retrieveAllLoanOfficersByOffice(loanBasicDetails.groupOfficeId());
}
loanPurposeOptions = this.codeValueReadPlatformService.retrieveCodeValuesByCode("LoanPurpose");
loanCollateralOptions = this.codeValueReadPlatformService.retrieveCodeValuesByCode("LoanCollateral");
if(loanBasicDetails.groupId() != null){
calendarOptions = this.loanReadPlatformService.retrieveCalendars(loanBasicDetails.groupId());
}
}
final LoanAccountData loanAccount = LoanAccountData.associationsAndTemplate(loanBasicDetails, repaymentSchedule, loanRepayments,
charges, collateral, guarantors, productOptions, loanTermFrequencyTypeOptions, repaymentFrequencyTypeOptions,
charges, collateral, guarantors, meeting, productOptions, loanTermFrequencyTypeOptions, repaymentFrequencyTypeOptions,
repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions,
interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, allowedLoanOfficers, loanPurposeOptions,
loanCollateralOptions);
loanCollateralOptions, calendarOptions);
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters(),
mandatoryResponseParameters);
@@ -16,6 +16,7 @@ import org.mifosplatform.infrastructure.codes.data.CodeValueData;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.organisation.monetary.data.CurrencyData;
import org.mifosplatform.organisation.staff.data.StaffData;
import org.mifosplatform.portfolio.calendar.data.CalendarData;
import org.mifosplatform.portfolio.charge.data.ChargeData;
import org.mifosplatform.portfolio.collateral.data.CollateralData;
import org.mifosplatform.portfolio.fund.data.FundData;
@@ -56,6 +57,7 @@ public class LoanAccountData {
private final String loanPurposeName;
private final Long loanOfficerId;
private final String loanOfficerName;
private final EnumOptionData loanType;
// terms
private final CurrencyData currency;
@@ -90,6 +92,7 @@ public class LoanAccountData {
private final Collection<LoanChargeData> charges;
private final Collection<CollateralData> collateral;
private final Collection<GuarantorData> guarantors;
private final CalendarData meeting;
// template
private final Collection<LoanProductData> productOptions;
@@ -105,6 +108,7 @@ public class LoanAccountData {
private final Collection<TransactionProcessingStrategyData> transactionProcessingStrategyOptions;
private final Collection<ChargeData> chargeOptions;
private final Collection<CodeValueData> loanCollateralOptions;
private final Collection<CalendarData> calendarOptions;
@Transient
private final BigDecimal feeChargesAtDisbursementCharged;
@@ -122,6 +126,7 @@ public class LoanAccountData {
final String clientName = null;
final Long clientOfficeId = null;
final GroupGeneralData group = null;
final EnumOptionData loanType = null;
final Long loanProductId = null;
final String loanProductName = null;
final String loanProductDescription = null;
@@ -157,6 +162,7 @@ public class LoanAccountData {
final Collection<LoanChargeData> charges = null;
final Collection<CollateralData> collateral = null;
final Collection<GuarantorData> guarantors = null;
final CalendarData calendarData = null;
final Collection<LoanProductData> productOptions = null;
final Collection<EnumOptionData> termFrequencyTypeOptions = null;
final Collection<EnumOptionData> repaymentFrequencyTypeOptions = null;
@@ -170,17 +176,18 @@ public class LoanAccountData {
final ChargeData chargeTemplate = null;
final Collection<StaffData> loanOfficerOptions = null;
final Collection<CodeValueData> loanPurposeOptions = null;
final Collection<CalendarData> calendarOptions = null;
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanProductId,
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanType, loanProductId,
loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
currencyData, principal, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments, repaymentEvery,
repaymentFrequencyType, transactionProcessingStrategyId, amortizationType, interestRatePerPeriod,
interestRateFrequencyType, annualInterestRate, interestType, interestCalculationPeriodType, expectedFirstRepaymentOnDate,
interestChargedFromDate, timeline, summary, feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges,
collateral, guarantors, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions,
collateral, guarantors, calendarData, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions,
transactionProcessingStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions,
interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions,
loanCollateralOptions);
loanCollateralOptions, calendarOptions);
}
/**
@@ -194,6 +201,7 @@ public class LoanAccountData {
final LoanStatusEnumData status = null;
final String externalId = null;
final GroupGeneralData group = null;
final EnumOptionData loanType = null;
final String groupName = null;
final Long loanProductId = null;
final String loanProductName = null;
@@ -230,6 +238,7 @@ public class LoanAccountData {
final Collection<LoanChargeData> charges = null;
final Collection<CollateralData> collateral = null;
final Collection<GuarantorData> guarantors = null;
final CalendarData calendarData = null;
final Collection<LoanProductData> productOptions = null;
final Collection<EnumOptionData> termFrequencyTypeOptions = null;
final Collection<EnumOptionData> repaymentFrequencyTypeOptions = null;
@@ -244,18 +253,35 @@ public class LoanAccountData {
final Collection<StaffData> loanOfficerOptions = null;
final Collection<CodeValueData> loanPurposeOptions = null;
final Collection<CodeValueData> loanCollateralOptions = null;
final Collection<CalendarData> calendarOptions = null;
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanProductId,
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanType, loanProductId,
loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
currencyData, principal, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments, repaymentEvery,
repaymentFrequencyType, transactionProcessingStrategyId, amortizationType, interestRatePerPeriod,
interestRateFrequencyType, annualInterestRate, interestType, interestCalculationPeriodType, expectedFirstRepaymentOnDate,
interestChargedFromDate, timeline, summary, feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges,
collateral, guarantors, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions,
collateral, guarantors, calendarData, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions,
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions);
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions);
}
public static LoanAccountData populateClientDefaults(final LoanAccountData acc, final LoanAccountData clientAcc) {
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, clientAcc.clientId, clientAcc.clientName,
clientAcc.clientOfficeId, acc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.fundId,
acc.fundName, acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, acc.currency, acc.principal,
acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery,
acc.repaymentFrequencyType, acc.transactionProcessingStrategyId, acc.amortizationType, acc.interestRatePerPeriod,
acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType, acc.interestCalculationPeriodType,
acc.expectedFirstRepaymentOnDate, acc.interestChargedFromDate, clientAcc.timeline, acc.summary,
acc.feeChargesAtDisbursementCharged, acc.repaymentSchedule, acc.transactions, acc.charges, acc.collateral, acc.guarantors, acc.meeting,
acc.productOptions, acc.termFrequencyTypeOptions, acc.repaymentFrequencyTypeOptions,
acc.transactionProcessingStrategyOptions, acc.interestRateFrequencyTypeOptions, acc.amortizationTypeOptions,
acc.interestTypeOptions, acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null,
acc.loanOfficerOptions, acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions);
}
/**
* Used to produce a {@link LoanAccountData} with only group information
* defaulted.
@@ -269,6 +295,7 @@ public class LoanAccountData {
final Long clientId = null;
final String clientName = null;
final Long clientOfficeId = null;
final EnumOptionData loanType = null;
final Long loanProductId = null;
final String loanProductName = null;
final String loanProductDescription = null;
@@ -304,6 +331,7 @@ public class LoanAccountData {
final Collection<LoanChargeData> charges = null;
final Collection<CollateralData> collateral = null;
final Collection<GuarantorData> guarantors = null;
final CalendarData calendarData = null;
final Collection<LoanProductData> productOptions = null;
final Collection<EnumOptionData> termFrequencyTypeOptions = null;
final Collection<EnumOptionData> repaymentFrequencyTypeOptions = null;
@@ -318,24 +346,117 @@ public class LoanAccountData {
final Collection<StaffData> loanOfficerOptions = null;
final Collection<CodeValueData> loanPurposeOptions = null;
final Collection<CodeValueData> loanCollateralOptions = null;
final Collection<CalendarData> calendarOptions = null;
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanProductId,
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanType, loanProductId,
loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
currencyData, principal, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments, repaymentEvery,
repaymentFrequencyType, transactionProcessingStrategyId, amortizationType, interestRatePerPeriod,
interestRateFrequencyType, annualInterestRate, interestType, interestCalculationPeriodType, expectedFirstRepaymentOnDate,
interestChargedFromDate, timeline, summary, feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges,
collateral, guarantors, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions,
collateral, guarantors, calendarData, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions,
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions);
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions);
}
public static LoanAccountData populateGroupDefaults(final LoanAccountData acc, final LoanAccountData groupAcc) {
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientName,
acc.clientOfficeId, groupAcc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.fundId,
acc.fundName, acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, acc.currency, acc.principal,
acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery,
acc.repaymentFrequencyType, acc.transactionProcessingStrategyId, acc.amortizationType, acc.interestRatePerPeriod,
acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType, acc.interestCalculationPeriodType,
acc.expectedFirstRepaymentOnDate, acc.interestChargedFromDate, groupAcc.timeline, acc.summary,
acc.feeChargesAtDisbursementCharged, acc.repaymentSchedule, acc.transactions, acc.charges, acc.collateral, acc.guarantors, acc.meeting,
acc.productOptions, acc.termFrequencyTypeOptions, acc.repaymentFrequencyTypeOptions,
acc.transactionProcessingStrategyOptions, acc.interestRateFrequencyTypeOptions, acc.amortizationTypeOptions,
acc.interestTypeOptions, acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null,
acc.loanOfficerOptions, acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions);
}
public static LoanAccountData loanProductWithTemplateDefaults(final LoanProductData product,
final Collection<EnumOptionData> termFrequencyTypeOptions, final Collection<EnumOptionData> repaymentFrequencyTypeOptions,
final Collection<TransactionProcessingStrategyData> repaymentStrategyOptions,
final Collection<EnumOptionData> interestRateFrequencyTypeOptions, final Collection<EnumOptionData> amortizationTypeOptions,
final Collection<EnumOptionData> interestTypeOptions, final Collection<EnumOptionData> interestCalculationPeriodTypeOptions,
final Collection<FundData> fundOptions, final Collection<ChargeData> chargeOptions,
final Collection<CodeValueData> loanPurposeOptions, final Collection<CodeValueData> loanCollateralOptions) {
final Long id = null;
final String accountNo = null;
final LoanStatusEnumData status = null;
final String externalId = null;
final Long clientId = null;
final String clientName = null;
final Long clientOfficeId = null;
final GroupGeneralData group = null;
final EnumOptionData loanType = null;
final String groupName = null;
final Long fundId = null;
final String fundName = null;
final Long loanPurposeId = null;
final String loanPurposeName = null;
final Long loanOfficerId = null;
final String loanOfficerName = null;
final CurrencyData currencyData = null;
final BigDecimal principal = null;
final BigDecimal inArrearsTolerance = null;
final Integer numberOfRepayments = null;
final Integer repaymentEvery = null;
final EnumOptionData repaymentFrequencyType = null;
final Long transactionProcessingStrategyId = null;
final EnumOptionData amortizationType = null;
final BigDecimal interestRatePerPeriod = null;
final EnumOptionData interestRateFrequencyType = null;
final BigDecimal annualInterestRate = null;
final EnumOptionData interestType = null;
final EnumOptionData interestCalculationPeriodType = null;
final LocalDate expectedFirstRepaymentOnDate = null;
final LocalDate interestChargedFromDate = null;
final LoanApplicationTimelineData timeline = null;
final LoanSummaryData summary = null;
final BigDecimal feeChargesDueAtDisbursementCharged = null;
final ChargeData chargeTemplate = null;
final LoanScheduleData repaymentSchedule = null;
final Collection<LoanTransactionData> transactions = null;
final Collection<CollateralData> collateral = null;
final Collection<GuarantorData> guarantors = null;
final CalendarData calendarData = null;
final Collection<LoanProductData> productOptions = null;
final Collection<CalendarData> calendarOptions = null;
final Collection<StaffData> loanOfficerOptions = null;
final Integer termFrequency = product.getNumberOfRepayments() * product.getRepaymentEvery();
final EnumOptionData termPeriodFrequencyType = product.getRepaymentFrequencyType();
final Collection<LoanChargeData> charges = new ArrayList<LoanChargeData>();
for (ChargeData charge : product.charges()) {
charges.add(charge.toLoanChargeData());
}
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId,
group, loanType, product.getId(), product.getName(), product.getDescription(), product.getFundId(), product.getFundName(),
loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, product.getCurrency(),
product.getPrincipal(), product.getInArrearsTolerance(), termFrequency, termPeriodFrequencyType,
product.getNumberOfRepayments(), product.getRepaymentEvery(), product.getRepaymentFrequencyType(),
product.getTransactionProcessingStrategyId(), product.getAmortizationType(), product.getInterestRatePerPeriod(),
product.getInterestRateFrequencyType(), product.getAnnualInterestRate(), product.getInterestType(),
product.getInterestCalculationPeriodType(), expectedFirstRepaymentOnDate, interestChargedFromDate, timeline,
summary, feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors, calendarData,
productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions,
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions);
}
public static LoanAccountData populateLoanProductDefaults(final LoanAccountData acc, final LoanProductData product) {
final LoanScheduleData repaymentSchedule = null;
final Collection<LoanTransactionData> transactions = null;
final Collection<CollateralData> collateral = null;
final Collection<GuarantorData> guarantors = null;
final CalendarData calendarData = null;
final Collection<LoanProductData> productOptions = null;
final Collection<EnumOptionData> termFrequencyTypeOptions = null;
final Collection<EnumOptionData> repaymentFrequencyTypeOptions = null;
@@ -350,7 +471,8 @@ public class LoanAccountData {
final Collection<StaffData> loanOfficerOptions = null;
final Collection<CodeValueData> loanPurposeOptions = null;
final Collection<CodeValueData> loanCollateralOptions = null;
final Collection<CalendarData> calendarOptions = null;
final Integer termFrequency = product.getNumberOfRepayments() * product.getRepaymentEvery();
final EnumOptionData termPeriodFrequencyType = product.getRepaymentFrequencyType();
@@ -360,17 +482,17 @@ public class LoanAccountData {
}
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientName, acc.clientOfficeId,
acc.group, product.getId(), product.getName(), product.getDescription(), product.getFundId(), product.getFundName(),
acc.group, acc.loanType, product.getId(), product.getName(), product.getDescription(), product.getFundId(), product.getFundName(),
acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, product.getCurrency(),
product.getPrincipal(), product.getInArrearsTolerance(), termFrequency, termPeriodFrequencyType,
product.getNumberOfRepayments(), product.getRepaymentEvery(), product.getRepaymentFrequencyType(),
product.getTransactionProcessingStrategyId(), product.getAmortizationType(), product.getInterestRatePerPeriod(),
product.getInterestRateFrequencyType(), product.getAnnualInterestRate(), product.getInterestType(),
product.getInterestCalculationPeriodType(), acc.expectedFirstRepaymentOnDate, acc.interestChargedFromDate, acc.timeline,
acc.summary, acc.feeChargesAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors,
acc.summary, acc.feeChargesAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors, calendarData,
productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions,
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions);
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions);
}
/*
@@ -379,7 +501,7 @@ public class LoanAccountData {
*/
public static LoanAccountData basicLoanDetails(final Long id, final String accountNo, final LoanStatusEnumData status,
final String externalId, final Long clientId, final String clientName, final Long clientOfficeId, final GroupGeneralData group,
final Long loanProductId, final String loanProductName, final String loanProductDescription, final Long fundId,
final EnumOptionData loanType, final Long loanProductId, final String loanProductName, final String loanProductDescription, final Long fundId,
final String fundName, final Long loanPurposeId, final String loanPurposeName, final Long loanOfficerId,
final String loanOfficerName, final CurrencyData currencyData, final BigDecimal principal, final BigDecimal inArrearsTolerance,
final Integer termFrequency, final EnumOptionData termPeriodFrequencyType, final Integer numberOfRepayments,
@@ -395,6 +517,7 @@ public class LoanAccountData {
final Collection<LoanChargeData> charges = null;
final Collection<CollateralData> collateral = null;
final Collection<GuarantorData> guarantors = null;
final CalendarData calendarData = null;
final Collection<LoanProductData> productOptions = null;
final Collection<EnumOptionData> termFrequencyTypeOptions = null;
final Collection<EnumOptionData> repaymentFrequencyTypeOptions = null;
@@ -409,16 +532,17 @@ public class LoanAccountData {
final Collection<StaffData> loanOfficerOptions = null;
final Collection<CodeValueData> loanPurposeOptions = null;
final Collection<CodeValueData> loanCollateralOptions = null;
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanProductId,
final Collection<CalendarData> calendarOptions = null;
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanType, loanProductId,
loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
currencyData, principal, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments, repaymentEvery,
repaymentFrequencyType, transactionStrategyId, amortizationType, interestRatePerPeriod, interestRateFrequencyType,
annualInterestRate, interestType, interestCalculationPeriodType, expectedFirstRepaymentOnDate, interestChargedFromDate,
timeline, loanSummary, feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral,
guarantors, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions,
guarantors, calendarData, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions,
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions);
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions);
}
/*
@@ -427,7 +551,7 @@ public class LoanAccountData {
*/
public static LoanAccountData associationsAndTemplate(final LoanAccountData acc, final LoanScheduleData repaymentSchedule,
final Collection<LoanTransactionData> transactions, final Collection<LoanChargeData> charges,
final Collection<CollateralData> collateral, final Collection<GuarantorData> guarantors,
final Collection<CollateralData> collateral, final Collection<GuarantorData> guarantors, final CalendarData calendarData,
final Collection<LoanProductData> productOptions, final Collection<EnumOptionData> termFrequencyTypeOptions,
final Collection<EnumOptionData> repaymentFrequencyTypeOptions,
final Collection<TransactionProcessingStrategyData> transactionProcessingStrategyOptions,
@@ -435,32 +559,41 @@ public class LoanAccountData {
final Collection<EnumOptionData> interestTypeOptions, final Collection<EnumOptionData> interestCalculationPeriodTypeOptions,
final Collection<FundData> fundOptions, final Collection<ChargeData> chargeOptions, final ChargeData chargeTemplate,
final Collection<StaffData> loanOfficerOptions, final Collection<CodeValueData> loanPurposeOptions,
final Collection<CodeValueData> loanCollateralOptions) {
final Collection<CodeValueData> loanCollateralOptions, final Collection<CalendarData> calendarOptions) {
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientName, acc.clientOfficeId,
acc.group, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.fundId, acc.fundName, acc.loanPurposeId,
acc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.fundId, acc.fundName, acc.loanPurposeId,
acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, acc.currency, acc.principal, acc.inArrearsTolerance,
acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery, acc.repaymentFrequencyType,
acc.transactionProcessingStrategyId, acc.amortizationType, acc.interestRatePerPeriod, acc.interestRateFrequencyType,
acc.annualInterestRate, acc.interestType, acc.interestCalculationPeriodType, acc.expectedFirstRepaymentOnDate,
acc.interestChargedFromDate, acc.timeline, acc.summary, acc.feeChargesAtDisbursementCharged, repaymentSchedule,
transactions, charges, collateral, guarantors, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions,
transactions, charges, collateral, guarantors, calendarData, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions,
transactionProcessingStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions,
interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions,
loanCollateralOptions);
loanCollateralOptions, calendarOptions);
}
public static LoanAccountData associationsAndTemplate(LoanAccountData acc, Collection<LoanProductData> productOptions,
Collection<StaffData> allowedLoanOfficers, final Collection<CalendarData> calendarOptions) {
return associationsAndTemplate(acc, acc.repaymentSchedule, acc.transactions, acc.charges, acc.collateral, acc.guarantors, acc.meeting,
productOptions, acc.termFrequencyTypeOptions, acc.repaymentFrequencyTypeOptions, acc.transactionProcessingStrategyOptions,
acc.interestRateFrequencyTypeOptions, acc.amortizationTypeOptions, acc.interestTypeOptions,
acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null, allowedLoanOfficers,
acc.loanPurposeOptions, acc.loanCollateralOptions, calendarOptions);
}
public static LoanAccountData associateGroup(final LoanAccountData acc, final GroupGeneralData group) {
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientName, acc.clientOfficeId,
group, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.fundId, acc.fundName, acc.loanPurposeId,
group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.fundId, acc.fundName, acc.loanPurposeId,
acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, acc.currency, acc.principal, acc.inArrearsTolerance,
acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery, acc.repaymentFrequencyType,
acc.transactionProcessingStrategyId, acc.amortizationType, acc.interestRatePerPeriod, acc.interestRateFrequencyType,
acc.annualInterestRate, acc.interestType, acc.interestCalculationPeriodType, acc.expectedFirstRepaymentOnDate,
acc.interestChargedFromDate, acc.timeline, acc.summary, acc.feeChargesAtDisbursementCharged, acc.repaymentSchedule,
acc.transactions, acc.charges, acc.collateral, acc.guarantors, acc.productOptions, acc.termFrequencyTypeOptions, acc.repaymentFrequencyTypeOptions,
acc.transactions, acc.charges, acc.collateral, acc.guarantors, acc.meeting, acc.productOptions, acc.termFrequencyTypeOptions, acc.repaymentFrequencyTypeOptions,
acc.transactionProcessingStrategyOptions, acc.interestRateFrequencyTypeOptions, acc.amortizationTypeOptions, acc.interestTypeOptions,
acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null, acc.loanOfficerOptions, acc.loanPurposeOptions,
acc.loanCollateralOptions);
acc.loanCollateralOptions, acc.calendarOptions);
}
private LoanAccountData(
@@ -472,6 +605,7 @@ public class LoanAccountData {
final String clientName,
final Long clientOfficeId, //
final GroupGeneralData group,
final EnumOptionData loanType,
final Long loanProductId,
final String loanProductName,
final String loanProductDescription, //
@@ -495,7 +629,7 @@ public class LoanAccountData {
final LocalDate interestChargedFromDate, final LoanApplicationTimelineData timeline, final LoanSummaryData summary,
final BigDecimal feeChargesDueAtDisbursementCharged, final LoanScheduleData repaymentSchedule,
final Collection<LoanTransactionData> transactions, final Collection<LoanChargeData> charges,
final Collection<CollateralData> collateral, final Collection<GuarantorData> guarantors,
final Collection<CollateralData> collateral, final Collection<GuarantorData> guarantors, final CalendarData meeting,
final Collection<LoanProductData> productOptions, final Collection<EnumOptionData> termFrequencyTypeOptions,
final Collection<EnumOptionData> repaymentFrequencyTypeOptions,
final Collection<TransactionProcessingStrategyData> transactionProcessingStrategyOptions,
@@ -503,7 +637,7 @@ public class LoanAccountData {
final Collection<EnumOptionData> interestTypeOptions, final Collection<EnumOptionData> interestCalculationPeriodTypeOptions,
final Collection<FundData> fundOptions, final Collection<ChargeData> chargeOptions, final ChargeData chargeTemplate,
final Collection<StaffData> loanOfficerOptions, final Collection<CodeValueData> loanPurposeOptions,
final Collection<CodeValueData> loanCollateralOptions) {
final Collection<CodeValueData> loanCollateralOptions, final Collection<CalendarData> calendarOptions) {
this.id = id;
this.accountNo = accountNo;
this.status = status;
@@ -512,6 +646,7 @@ public class LoanAccountData {
this.clientName = clientName;
this.clientOfficeId = clientOfficeId;
this.group = group;
this.loanType = loanType;
this.loanProductId = loanProductId;
this.loanProductName = loanProductName;
this.loanProductDescription = loanProductDescription;
@@ -550,6 +685,7 @@ public class LoanAccountData {
this.charges = charges;
this.collateral = collateral;
this.guarantors = guarantors;
this.meeting = meeting;
// template
this.productOptions = productOptions;
@@ -595,6 +731,12 @@ public class LoanAccountData {
} else {
this.loanCollateralOptions = loanCollateralOptions;
}
if (CollectionUtils.isEmpty(calendarOptions)) {
this.calendarOptions = null;
} else {
this.calendarOptions = calendarOptions;
}
}
public RepaymentScheduleRelatedLoanData repaymentScheduleRelatedData() {
@@ -617,4 +759,8 @@ public class LoanAccountData {
public Long groupOfficeId(){
return group == null? null : group.officeId();
}
public Long groupId(){
return group == null? null : group.getId();
}
}
@@ -97,6 +97,10 @@ public class Loan extends AbstractPersistable<Long> {
@JoinColumn(name = "group_id", nullable = true)
private Group group;
@SuppressWarnings("unused")
@Column(name = "loan_type_enum", nullable = false)
private Integer loanType;
@ManyToOne
@JoinColumn(name = "product_id", nullable = false)
private LoanProduct loanProduct;
@@ -259,28 +263,18 @@ public class Loan extends AbstractPersistable<Long> {
@Transient
private LoanSummaryWrapper loanSummaryWrapper;
public static Loan newIndividualLoanApplication(final String accountNo, final Client client, final LoanProduct loanProduct,
public static Loan newIndividualLoanApplication(final String accountNo, final Client client, final Integer loanType, final LoanProduct loanProduct,
final Fund fund, final Staff officer, final CodeValue loanPurpose,
final LoanTransactionProcessingStrategy transactionProcessingStrategy, final LoanSchedule loanSchedule,
final Set<LoanCharge> loanCharges, final Set<LoanCollateral> collateral) {
final LoanStatus status = null;
final Group group = null;
LoanProductRelatedDetail loanRepaymentScheduleDetail = loanSchedule.loanProductRelatedDetail();
return new Loan(accountNo, client, null, fund, officer, loanPurpose, transactionProcessingStrategy, loanProduct,
return new Loan(accountNo, client, group, loanType, fund, officer, loanPurpose, transactionProcessingStrategy, loanProduct,
loanRepaymentScheduleDetail, status, loanCharges, collateral);
}
public static Loan newGroupLoanApplication(final String accountNo, final Group group, final LoanProduct loanProduct, final Fund fund,
final Staff officer, final LoanTransactionProcessingStrategy transactionProcessingStrategy, final LoanSchedule loanSchedule,
final Set<LoanCharge> loanCharges) {
final LoanStatus status = null;
final LoanProductRelatedDetail loanRepaymentScheduleDetail = loanSchedule.loanProductRelatedDetail();
final CodeValue loanPurpose = null;
final Set<LoanCollateral> collateral = null;
return new Loan(accountNo, null, group, fund, officer, loanPurpose, transactionProcessingStrategy, loanProduct,
loanRepaymentScheduleDetail, status, loanCharges, collateral);
}
public static Loan newIndividualLoanApplicationFromGroup(final String accountNo, final Client client, final Group group,
public static Loan newGroupLoanApplication(final String accountNo, final Group group, final Integer loanType,
final LoanProduct loanProduct, final Fund fund, final Staff officer,
final LoanTransactionProcessingStrategy transactionProcessingStrategy, final LoanSchedule loanSchedule,
final Set<LoanCharge> loanCharges) {
@@ -288,7 +282,20 @@ public class Loan extends AbstractPersistable<Long> {
final LoanProductRelatedDetail loanRepaymentScheduleDetail = loanSchedule.loanProductRelatedDetail();
final CodeValue loanPurpose = null;
final Set<LoanCollateral> collateral = null;
return new Loan(accountNo, client, group, fund, officer, loanPurpose, transactionProcessingStrategy, loanProduct,
final Client client = null;
return new Loan(accountNo, client, group, loanType, fund, officer, loanPurpose, transactionProcessingStrategy, loanProduct,
loanRepaymentScheduleDetail, status, loanCharges, collateral);
}
public static Loan newIndividualLoanApplicationFromGroup(final String accountNo, final Client client, final Group group,
final Integer loanType, final LoanProduct loanProduct, final Fund fund, final Staff officer,
final LoanTransactionProcessingStrategy transactionProcessingStrategy, final LoanSchedule loanSchedule,
final Set<LoanCharge> loanCharges) {
final LoanStatus status = null;
final LoanProductRelatedDetail loanRepaymentScheduleDetail = loanSchedule.loanProductRelatedDetail();
final CodeValue loanPurpose = null;
final Set<LoanCollateral> collateral = null;
return new Loan(accountNo, client, group, loanType, fund, officer, loanPurpose, transactionProcessingStrategy, loanProduct,
loanRepaymentScheduleDetail, status, loanCharges, collateral);
}
@@ -296,7 +303,7 @@ public class Loan extends AbstractPersistable<Long> {
//
}
private Loan(final String accountNo, final Client client, final Group group, final Fund fund, final Staff loanOfficer,
private Loan(final String accountNo, final Client client, final Group group, final Integer loanType, final Fund fund, final Staff loanOfficer,
final CodeValue loanPurpose, final LoanTransactionProcessingStrategy transactionProcessingStrategy,
final LoanProduct loanProduct, final LoanProductRelatedDetail loanRepaymentScheduleDetail, final LoanStatus loanStatus,
final Set<LoanCharge> loanCharges, final Set<LoanCollateral> collateral) {
@@ -308,6 +315,7 @@ public class Loan extends AbstractPersistable<Long> {
}
this.client = client;
this.group = group;
this.loanType = loanType;
this.fund = fund;
this.loanOfficer = loanOfficer;
this.loanPurpose = loanPurpose;
@@ -813,15 +821,31 @@ public class Loan extends AbstractPersistable<Long> {
this.externalId = StringUtils.defaultIfEmpty(newValue, null);
}
//add clientId, groupId and loanType changes to actual changes
//FIXME: AA - We may require separate api command to move loan from one client to another
final String clientIdParamName = "clientId";
// FIXME AA : Client is null for group loans. Group loan modifications
// require group validation.
if (this.client != null) {
if (command.isChangeInLongParameterNamed(clientIdParamName, this.client.getId())) {
final Long newValue = command.longValueOfParameterNamed(clientIdParamName);
actualChanges.put(clientIdParamName, newValue);
}
final Long clientId = this.client == null ? null : this.client.getId();
if (command.isChangeInLongParameterNamed(clientIdParamName, clientId)) {
final Long newValue = command.longValueOfParameterNamed(clientIdParamName);
actualChanges.put(clientIdParamName, newValue);
}
//FIXME: AA - We may require separate api command to move loan from one group to another
final String groupIdParamName = "groupId";
final Long groupId = this.group == null ? null : this.group.getId();
if (command.isChangeInLongParameterNamed(clientIdParamName, groupId)) {
final Long newValue = command.longValueOfParameterNamed(groupIdParamName);
actualChanges.put(groupIdParamName, newValue);
}
//Do not support loan type modification
/*final String loanTypeParamName = "loanType";
final String loanTypeStr = LoanType.fromInt(this.loanType).getName();
if (command.isChangeInStringParameterNamed(loanTypeParamName, loanTypeStr)) {
final String newValue = command.stringValueOfParameterNamed(loanTypeParamName);
actualChanges.put(loanTypeParamName, newValue);
this.loanType = LoanType.fromName(newValue).getValue();
}*/
final String productIdParamName = "productId";
if (command.isChangeInLongParameterNamed(productIdParamName, this.loanProduct.getId())) {
@@ -959,7 +983,7 @@ public class Loan extends AbstractPersistable<Long> {
actualChanges.put(collateralParamName, listOfLoanCollateralData(possiblyModifedLoanCollateralItems));
}
}
return actualChanges;
}
@@ -0,0 +1,81 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.loanaccount.domain;
/**
* Enum representation of loan types .
*/
public enum LoanType {
INVALID(0, "loanType.invalid"), //
INDIVIDUAL(1, "loanType.individual"), //
GROUP(2, "loanType.group"), //
JLG(3, "loanType.jlg");//JLG loans given in group context
private final Integer value;
private final String code;
private LoanType(final Integer value, final String code) {
this.value = value;
this.code = code;
}
public static LoanType fromInt(final Integer loanTypeValue) {
LoanType enumeration = LoanType.INVALID;
switch (loanTypeValue) {
case 1:
enumeration = LoanType.INDIVIDUAL;
break;
case 2:
enumeration = LoanType.GROUP;
break;
case 3:
enumeration = LoanType.JLG;
break;
}
return enumeration;
}
public static LoanType fromName(final String name){
LoanType loanType = LoanType.INVALID;
for (LoanType type : LoanType.values()) {
if(type.getName().equals(name)) {
loanType = type;
break;
}
}
return loanType;
}
public Integer getValue() {
return this.value;
}
public String getCode() {
return code;
}
public String getName(){
return name().toLowerCase();
}
public boolean isInvalid(){
return this.value.equals(LoanType.INVALID.getValue());
}
public boolean isIndividualLoan(){
return this.value.equals(LoanType.INDIVIDUAL.getValue());
}
public boolean isGroupLoan(){
return this.value.equals(LoanType.GROUP.getValue());
}
public boolean isJLGLoan(){
return this.value.equals(LoanType.JLG.getValue());
}
}
@@ -0,0 +1,18 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.loanaccount.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
/**
* {@link AbstractPlatformDomainRuleException} thrown when not supported loan template type is sent.
*/
public class LoanTemplateTypeRequiredException extends AbstractPlatformDomainRuleException {
public LoanTemplateTypeRequiredException(String defaultUserMessage) {
super("error.msg.loan.template.type.required", defaultUserMessage);
}
}
@@ -0,0 +1,18 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.loanaccount.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
/**
* {@link AbstractPlatformDomainRuleException} thrown when not supported loan template type is sent.
*/
public class NotSupportedLoanTemplateTypeException extends AbstractPlatformDomainRuleException {
public NotSupportedLoanTemplateTypeException(String defaultUserMessage, Object... defaultUserMessageArgs) {
super("error.msg.loan.template.type.not.supported", defaultUserMessage, defaultUserMessageArgs);
}
}
@@ -36,7 +36,7 @@ public final class CalculateLoanScheduleQueryFromApiJsonHelper {
/**
* The parameters supported for this command.
*/
final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("id", "clientId", "groupId", "calendarId", "productId", "accountNo",
final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("id", "clientId", "groupId", "loanType", "calendarId", "productId", "accountNo",
"externalId", "fundId", "loanOfficerId", "loanPurposeId", "transactionProcessingStrategyId", "principal", "inArrearsTolerance",
"interestRatePerPeriod", "repaymentEvery", "numberOfRepayments", "loanTermFrequency", "loanTermFrequencyType",
"repaymentFrequencyType", "interestRateFrequencyType", "amortizationType", "interestType", "interestCalculationPeriodType",
@@ -22,6 +22,7 @@ import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.portfolio.loanaccount.domain.LoanType;
import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct;
import org.mifosplatform.portfolio.loanproduct.serialization.LoanProductCommandFromApiJsonDeserializer;
import org.springframework.beans.factory.annotation.Autowired;
@@ -39,7 +40,7 @@ public final class LoanApplicationCommandFromApiJsonHelper {
* The parameters supported for this command.
*/
final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("dateFormat", "locale", "id", "clientId", "groupId",
"productId", "principal", "loanTermFrequency", "loanTermFrequencyType", "numberOfRepayments", "repaymentEvery",
"loanType", "productId", "principal", "loanTermFrequency", "loanTermFrequencyType", "numberOfRepayments", "repaymentEvery",
"repaymentFrequencyType", "interestRatePerPeriod", "amortizationType", "interestType",
"interestCalculationPeriodType", "expectedDisbursementDate", "repaymentsStartingFromDate", "interestChargedFromDate",
"submittedOnDate", "submittedOnNote", //
@@ -69,20 +70,35 @@ public final class LoanApplicationCommandFromApiJsonHelper {
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan");
final JsonElement element = fromApiJsonHelper.parse(json);
final Long clientId = fromApiJsonHelper.extractLongNamed("clientId", element);
if (clientId != null) {
baseDataValidator.reset().parameter("clientId").value(clientId).longGreaterThanZero();
}
final Long groupId = fromApiJsonHelper.extractLongNamed("groupId", element);
if (groupId != null) {
baseDataValidator.reset().parameter("groupId").value(groupId).longGreaterThanZero();
}
final String loanTypeParameterName = "loanType";
final String loanTypeStr = fromApiJsonHelper.extractStringNamed(loanTypeParameterName, element);
baseDataValidator.reset().parameter(loanTypeParameterName).value(loanTypeStr).notNull();
if(!StringUtils.isBlank(loanTypeStr)){
final LoanType loanType = LoanType.fromName(loanTypeStr);
baseDataValidator.reset().parameter(loanTypeParameterName).value(loanType.getValue()).inMinMaxRange(1, 3);
final Long clientId = fromApiJsonHelper.extractLongNamed("clientId", element);
final Long groupId = fromApiJsonHelper.extractLongNamed("groupId", element);
if(loanType.isIndividualLoan()){
baseDataValidator.reset().parameter("clientId").value(clientId).notNull().longGreaterThanZero();
baseDataValidator.reset().parameter("groupId").value(groupId).mustBeBlankWhenParameterProvided("clientId", clientId);
}
if (clientId == null && groupId == null) {
baseDataValidator.reset().parameter("clientId").value(clientId).notNull().integerGreaterThanZero();
}
if (loanType.isGroupLoan()) {
baseDataValidator.reset().parameter("groupId").value(groupId).notNull().longGreaterThanZero();
baseDataValidator.reset().parameter("clientId").value(clientId).mustBeBlankWhenParameterProvided("groupId", groupId);
}
if (loanType.isJLGLoan()) {
baseDataValidator.reset().parameter("clientId").value(clientId).notNull().integerGreaterThanZero();
baseDataValidator.reset().parameter("groupId").value(groupId).notNull().longGreaterThanZero();
}
}
final Long productId = fromApiJsonHelper.extractLongNamed("productId", element);
baseDataValidator.reset().parameter("productId").value(productId).notNull().integerGreaterThanZero();
@@ -295,7 +311,7 @@ public final class LoanApplicationCommandFromApiJsonHelper {
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan");
final JsonElement element = fromApiJsonHelper.parse(json);
boolean atLeastOneParameterPassedForUpdate = false;
final String clientIdParameterName = "clientId";
if (fromApiJsonHelper.parameterExists(clientIdParameterName, element)) {
atLeastOneParameterPassedForUpdate = true;
@@ -136,7 +136,6 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
AppUser currentUser = context.authenticatedUser();
final Long productId = fromJsonHelper.extractLongNamed("productId", command.parsedJson());
final LoanProduct loanProduct = this.loanProductRepository.findOne(productId);
if (loanProduct == null) { throw new LoanProductNotFoundException(productId); }
@@ -14,6 +14,7 @@ import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.codes.domain.CodeValue;
import org.mifosplatform.infrastructure.codes.domain.CodeValueRepositoryWrapper;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.organisation.staff.domain.Staff;
import org.mifosplatform.organisation.staff.domain.StaffRepository;
@@ -45,6 +46,7 @@ import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct;
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRepository;
import org.mifosplatform.portfolio.loanproduct.domain.LoanTransactionProcessingStrategy;
import org.mifosplatform.portfolio.loanproduct.exception.LoanProductNotFoundException;
import org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -128,18 +130,23 @@ public class LoanAssembler {
Loan loanApplication = null;
Client client = null;
Group group = null;
final String loanTypeParameterName = "loanType";
final String loanTypeStr = fromApiJsonHelper.extractStringNamed(loanTypeParameterName, element);
final EnumOptionData loanType = LoanEnumerations.loanType(loanTypeStr);
if (clientId != null) {
client = this.clientRepository.findOneWithNotFoundDetection(clientId);
loanApplication = Loan.newIndividualLoanApplication(accountNo, client, loanProduct, fund, loanOfficer, loanPurpose,
loanTransactionProcessingStrategy, loanSchedule, loanCharges, collateral);
loanApplication = Loan.newIndividualLoanApplication(accountNo, client, loanType.getId().intValue(), loanProduct, fund,
loanOfficer, loanPurpose, loanTransactionProcessingStrategy, loanSchedule, loanCharges, collateral);
}
if (groupId != null) {
group = this.groupRepository.findOne(groupId);
if (group == null) { throw new GroupNotFoundException(groupId); }
loanApplication = Loan.newGroupLoanApplication(accountNo, group, loanProduct, fund, loanOfficer,
loanApplication = Loan.newGroupLoanApplication(accountNo, group, loanType.getId().intValue(), loanProduct, fund, loanOfficer,
loanTransactionProcessingStrategy, loanSchedule, loanCharges);
}
@@ -147,7 +154,7 @@ public class LoanAssembler {
if (!group.hasClientAsMember(client)) { throw new ClientNotInGroupException(clientId, groupId); }
loanApplication = Loan.newIndividualLoanApplicationFromGroup(accountNo, client, group, loanProduct, fund, loanOfficer,
loanApplication = Loan.newIndividualLoanApplicationFromGroup(accountNo, client, group, loanType.getId().intValue(), loanProduct, fund, loanOfficer,
loanTransactionProcessingStrategy, loanSchedule, loanCharges);
}
@@ -7,6 +7,7 @@ package org.mifosplatform.portfolio.loanaccount.service;
import java.util.Collection;
import org.mifosplatform.portfolio.calendar.data.CalendarData;
import org.mifosplatform.portfolio.loanaccount.data.LoanAccountData;
import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionData;
import org.mifosplatform.portfolio.loanaccount.data.RepaymentScheduleRelatedLoanData;
@@ -35,4 +36,14 @@ public interface LoanReadPlatformService {
LoanTransactionData retrieveDisbursalTemplate(Long loanId);
LoanAccountData retrieveTemplateWithCompleteGroupAndProductDetails(Long groupId, Long productId);
LoanAccountData retrieveLoanProductDetailsTemplate(Long productId);
LoanAccountData retrieveClientDetailsTemplate(Long clientId);
LoanAccountData retrieveGroupDetailsTemplate(Long groupId);
LoanAccountData retrieveGroupAndMembersDetailsTemplate(Long groupId);
Collection<CalendarData> retrieveCalendars(Long groupId);
}
@@ -14,6 +14,8 @@ import java.util.List;
import org.joda.time.Days;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.codes.data.CodeValueData;
import org.mifosplatform.infrastructure.codes.service.CodeValueReadPlatformService;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
import org.mifosplatform.infrastructure.core.service.DateUtils;
@@ -24,9 +26,16 @@ import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.portfolio.calendar.data.CalendarData;
import org.mifosplatform.portfolio.calendar.domain.CalendarEntityType;
import org.mifosplatform.portfolio.calendar.service.CalendarReadPlatformService;
import org.mifosplatform.portfolio.charge.data.ChargeData;
import org.mifosplatform.portfolio.charge.service.ChargeReadPlatformService;
import org.mifosplatform.portfolio.client.data.ClientData;
import org.mifosplatform.portfolio.client.domain.ClientEnumerations;
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
import org.mifosplatform.portfolio.fund.data.FundData;
import org.mifosplatform.portfolio.fund.service.FundReadPlatformService;
import org.mifosplatform.portfolio.group.data.GroupGeneralData;
import org.mifosplatform.portfolio.group.service.GroupReadPlatformService;
import org.mifosplatform.portfolio.loanaccount.data.DisbursementData;
@@ -48,6 +57,7 @@ import org.mifosplatform.portfolio.loanaccount.exception.LoanTransactionNotFound
import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanScheduleData;
import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanSchedulePeriodData;
import org.mifosplatform.portfolio.loanproduct.data.LoanProductData;
import org.mifosplatform.portfolio.loanproduct.data.TransactionProcessingStrategyData;
import org.mifosplatform.portfolio.loanproduct.service.LoanDropdownReadPlatformService;
import org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations;
import org.mifosplatform.portfolio.loanproduct.service.LoanProductReadPlatformService;
@@ -72,6 +82,11 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
private final GroupReadPlatformService groupReadPlatformService;
private final LoanTransactionRepository loanTransactionRepository;
private final LoanDropdownReadPlatformService loanDropdownReadPlatformService;
private final FundReadPlatformService fundReadPlatformService;
private final ChargeReadPlatformService chargeReadPlatformService;
private final CodeValueReadPlatformService codeValueReadPlatformService;
private final CalendarReadPlatformService calendarReadPlatformService;
@Autowired
public LoanReadPlatformServiceImpl(final PlatformSecurityContext context, final LoanRepository loanRepository,
@@ -79,7 +94,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository,
final LoanProductReadPlatformService loanProductReadPlatformService, final ClientReadPlatformService clientReadPlatformService,
final GroupReadPlatformService groupReadPlatformService, final LoanDropdownReadPlatformService loanDropdownReadPlatformService,
final TenantAwareRoutingDataSource dataSource) {
final FundReadPlatformService fundReadPlatformService, final ChargeReadPlatformService chargeReadPlatformService,
final CodeValueReadPlatformService codeValueReadPlatformService, final TenantAwareRoutingDataSource dataSource, final CalendarReadPlatformService calendarReadPlatformService) {
this.context = context;
this.loanRepository = loanRepository;
this.loanTransactionRepository = loanTransactionRepository;
@@ -88,6 +104,10 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
this.clientReadPlatformService = clientReadPlatformService;
this.groupReadPlatformService = groupReadPlatformService;
this.loanDropdownReadPlatformService = loanDropdownReadPlatformService;
this.fundReadPlatformService = fundReadPlatformService;
this.chargeReadPlatformService = chargeReadPlatformService;
this.codeValueReadPlatformService = codeValueReadPlatformService;
this.calendarReadPlatformService = calendarReadPlatformService;
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@@ -294,7 +314,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
public String loanSchema() {
return "l.id as id, l.account_no as accountNo, l.external_id as externalId, l.fund_id as fundId, f.name as fundName,"
+ " l.loanpurpose_cv_id as loanPurposeId, cv.code_value as loanPurposeName,"
+ " l.loan_type_enum as loanType, l.loanpurpose_cv_id as loanPurposeId, cv.code_value as loanPurposeName,"
+ " lp.id as loanProductId, lp.name as loanProductName, lp.description as loanProductDescription,"
+ " c.id as clientId, c.display_name as clientName, c.office_id as clientOfficeId,"
+ " g.id as groupId, g.display_name as groupName,"
@@ -393,6 +413,9 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
final Long groupParentId = JdbcSupport.getLong(rs, "groupParentId");
final String groupHierarchy = rs.getString("groupHierarchy");
final Integer loanTypeId = JdbcSupport.getInteger(rs, "loanType");
final EnumOptionData loanType = LoanEnumerations.loanType(loanTypeId);
final Long fundId = JdbcSupport.getLong(rs, "fundId");
final String fundName = rs.getString("fundName");
@@ -545,7 +568,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
}
return LoanAccountData.basicLoanDetails(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, groupData,
loanProductId, loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName,
loanType, loanProductId, loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName,
loanOfficerId, loanOfficerName, currencyData, principal, inArrearsTolerance, termFrequency, termPeriodFrequencyType,
numberOfRepayments, repaymentEvery, repaymentFrequencyType, transactionStrategyId, amortizationType,
interestRatePerPeriod, interestRateFrequencyType, annualInterestRate, interestType, interestCalculationPeriodType,
@@ -763,4 +786,72 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
}
}
@Override
public LoanAccountData retrieveLoanProductDetailsTemplate(Long productId) {
context.authenticatedUser();
final LoanProductData loanProduct = this.loanProductReadPlatformService.retrieveLoanProduct(productId);
final Collection<EnumOptionData> loanTermFrequencyTypeOptions = loanDropdownReadPlatformService.retrieveLoanTermFrequencyTypeOptions();
final Collection<EnumOptionData> repaymentFrequencyTypeOptions = loanDropdownReadPlatformService.retrieveRepaymentFrequencyTypeOptions();
final Collection<EnumOptionData> interestRateFrequencyTypeOptions = loanDropdownReadPlatformService.retrieveInterestRateFrequencyTypeOptions();
final Collection<EnumOptionData> amortizationTypeOptions = loanDropdownReadPlatformService.retrieveLoanAmortizationTypeOptions();
final Collection<EnumOptionData> interestTypeOptions = loanDropdownReadPlatformService.retrieveLoanInterestTypeOptions();
final Collection<EnumOptionData> interestCalculationPeriodTypeOptions = loanDropdownReadPlatformService.retrieveLoanInterestRateCalculatedInPeriodOptions();
final Collection<FundData> fundOptions = this.fundReadPlatformService.retrieveAllFunds();
final Collection<TransactionProcessingStrategyData> repaymentStrategyOptions = this.loanDropdownReadPlatformService.retreiveTransactionProcessingStrategies();
final Collection<CodeValueData> loanPurposeOptions = this.codeValueReadPlatformService.retrieveCodeValuesByCode("LoanPurpose");
final Collection<CodeValueData> loanCollateralOptions = this.codeValueReadPlatformService.retrieveCodeValuesByCode("LoanCollateral");
final boolean feeChargesOnly = false;
final Collection<ChargeData> chargeOptions = this.chargeReadPlatformService.retrieveLoanApplicableCharges(feeChargesOnly);
return LoanAccountData.loanProductWithTemplateDefaults(loanProduct, loanTermFrequencyTypeOptions, repaymentFrequencyTypeOptions,
repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions,
interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, loanPurposeOptions, loanCollateralOptions);
}
@Override
public LoanAccountData retrieveClientDetailsTemplate(Long clientId) {
context.authenticatedUser();
final ClientData clientAccount = this.clientReadPlatformService.retrieveOne(clientId);
final LocalDate expectedDisbursementDate = DateUtils.getLocalDateOfTenant();
return LoanAccountData.clientDefaults(clientAccount.id(), clientAccount.displayName(), clientAccount.officeId(),
expectedDisbursementDate);
}
@Override
public LoanAccountData retrieveGroupDetailsTemplate(Long groupId) {
context.authenticatedUser();
final GroupGeneralData groupAccount = this.groupReadPlatformService.retrieveOne(groupId);
final LocalDate expectedDisbursementDate = DateUtils.getLocalDateOfTenant();
return LoanAccountData.groupDefaults(groupAccount, expectedDisbursementDate);
}
@Override
public LoanAccountData retrieveGroupAndMembersDetailsTemplate(Long groupId) {
GroupGeneralData groupAccount = this.groupReadPlatformService.retrieveOne(groupId);
final LocalDate expectedDisbursementDate = DateUtils.getLocalDateOfTenant();
// get group associations
Collection<ClientData> membersOfGroup = this.clientReadPlatformService.retrieveClientMembersOfGroup(groupId);
if (!CollectionUtils.isEmpty(membersOfGroup)) {
groupAccount = GroupGeneralData.withAssocations(groupAccount, membersOfGroup);
}
return LoanAccountData.groupDefaults(groupAccount, expectedDisbursementDate);
}
@Override
public Collection<CalendarData> retrieveCalendars(Long groupId) {
Collection<CalendarData> calendarsData = new ArrayList<CalendarData>();
calendarsData.addAll(this.calendarReadPlatformService.retrieveParentCalendarsByEntity(groupId,CalendarEntityType.GROUPS.getValue()));
calendarsData.addAll(this.calendarReadPlatformService.retrieveCalendarsByEntity(groupId,CalendarEntityType.GROUPS.getValue()));
calendarsData = this.calendarReadPlatformService.generateRecurringDates(calendarsData);
return calendarsData;
}
}
@@ -13,6 +13,7 @@ import org.mifosplatform.portfolio.loanaccount.data.LoanStatusEnumData;
import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionEnumData;
import org.mifosplatform.portfolio.loanaccount.domain.LoanStatus;
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionType;
import org.mifosplatform.portfolio.loanaccount.domain.LoanType;
import org.mifosplatform.portfolio.loanaccount.domain.PaymentType;
import org.mifosplatform.portfolio.loanproduct.domain.AccountingRuleType;
import org.mifosplatform.portfolio.loanproduct.domain.AmortizationMethod;
@@ -337,4 +338,32 @@ public class LoanEnumerations {
EnumOptionData optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), type.toString());
return optionData;
}
public static EnumOptionData loanType(final Integer loanTypeId) {
return loanType(LoanType.fromInt(loanTypeId));
}
public static EnumOptionData loanType(final String name) {
return loanType(LoanType.fromName(name));
}
public static EnumOptionData loanType(final LoanType type) {
EnumOptionData optionData = new EnumOptionData(LoanType.INVALID.getValue().longValue(), LoanType.INVALID.getCode(), "Invalid");
switch (type) {
case INVALID:
optionData = new EnumOptionData(LoanType.INVALID.getValue().longValue(), LoanType.INVALID.getCode(), "Invalid");
break;
case INDIVIDUAL:
optionData = new EnumOptionData(LoanType.INDIVIDUAL.getValue().longValue(), LoanType.INDIVIDUAL.getCode(), "Individual");
break;
case GROUP:
optionData = new EnumOptionData(LoanType.GROUP.getValue().longValue(), LoanType.GROUP.getCode(), "Group");
break;
case JLG:
optionData = new EnumOptionData(LoanType.JLG.getValue().longValue(), LoanType.JLG.getCode(), "JLG");
break;
}
return optionData;
}
}