From bc85e81316dbf8e5756d0ce7e4321ec9a448237a Mon Sep 17 00:00:00 2001 From: ashok-conflux Date: Mon, 29 Apr 2013 16:17:44 +0530 Subject: [PATCH] fixed MIFOSX-301 issues and added loan type and template type to loan --- ...27__add-loan-type-column-to-loan-table.sql | 2 + .../AccountingScenarioIntegrationTest.java | 2 + .../loans/LoanApplicationTestBuilder.java | 6 + .../calendar/api/CalendarsApiResource.java | 36 +--- .../service/CalendarReadPlatformService.java | 6 + .../CalendarReadPlatformServiceImpl.java | 53 +++++ .../loanaccount/api/LoansApiResource.java | 182 ++++++++-------- .../loanaccount/data/LoanAccountData.java | 202 +++++++++++++++--- .../portfolio/loanaccount/domain/Loan.java | 72 ++++--- .../loanaccount/domain/LoanType.java | 81 +++++++ .../LoanTemplateTypeRequiredException.java | 18 ++ ...NotSupportedLoanTemplateTypeException.java | 18 ++ ...ateLoanScheduleQueryFromApiJsonHelper.java | 2 +- ...anApplicationCommandFromApiJsonHelper.java | 42 ++-- ...WritePlatformServiceJpaRepositoryImpl.java | 1 - .../loanaccount/service/LoanAssembler.java | 15 +- .../service/LoanReadPlatformService.java | 11 + .../service/LoanReadPlatformServiceImpl.java | 97 ++++++++- .../loanproduct/service/LoanEnumerations.java | 29 +++ 19 files changed, 669 insertions(+), 206 deletions(-) create mode 100644 mifosng-db/migrations/core_db/V27__add-loan-type-column-to-loan-table.sql create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanType.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/exception/LoanTemplateTypeRequiredException.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/exception/NotSupportedLoanTemplateTypeException.java diff --git a/mifosng-db/migrations/core_db/V27__add-loan-type-column-to-loan-table.sql b/mifosng-db/migrations/core_db/V27__add-loan-type-column-to-loan-table.sql new file mode 100644 index 000000000..fdc97c8d1 --- /dev/null +++ b/mifosng-db/migrations/core_db/V27__add-loan-type-column-to-loan-table.sql @@ -0,0 +1,2 @@ +ALTER TABLE `m_loan` + ADD COLUMN `loan_type_enum` SMALLINT(5) NOT NULL AFTER `loan_status_id`; \ No newline at end of file diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/AccountingScenarioIntegrationTest.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/AccountingScenarioIntegrationTest.java index fda9ed75f..2c94742c9 100644 --- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/AccountingScenarioIntegrationTest.java +++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/AccountingScenarioIntegrationTest.java @@ -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); } diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanApplicationTestBuilder.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanApplicationTestBuilder.java index 5bf85ef72..fbb1d8bee 100644 --- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanApplicationTestBuilder.java +++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanApplicationTestBuilder.java @@ -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; + } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/api/CalendarsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/api/CalendarsApiResource.java index dc36a824c..c3dc9ae90 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/api/CalendarsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/api/CalendarsApiResource.java @@ -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 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 recurringDates = CalendarHelper.getRecurringDates(rrule, seedDate, seedDate, endDate, -1); - final Collection nextTenRecurringDates = CalendarHelper.getRecurringDates(rrule, seedDate, endDate); - return new CalendarData(calendarData, recurringDates, nextTenRecurringDates); - } - - private Collection handleRecurringDates(final Collection calendarsData) { - Collection recuCalendarsData = new ArrayList(); - - for (CalendarData calendarData : calendarsData) { - recuCalendarsData.add(handleRecurringDate(calendarData)); - } - - return recuCalendarsData; - } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarReadPlatformService.java index 6eb205d94..dc75f2f9f 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarReadPlatformService.java @@ -20,4 +20,10 @@ public interface CalendarReadPlatformService { Collection retrieveAllCalendars(); CalendarData retrieveNewCalendarDetails(); + + CalendarData generateRecurringDate(final CalendarData calendarData); + + Collection generateRecurringDates(final Collection calendarsData); + + CalendarData retrieveLoanCalendar(final Long loanId); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarReadPlatformServiceImpl.java index 62cabeb6e..fe82f7991 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarReadPlatformServiceImpl.java @@ -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 recurringDates = CalendarHelper.getRecurringDates(rrule, seedDate, startDate, endDate, -1); + final Collection nextTenRecurringDates = CalendarHelper.getRecurringDates(rrule, seedDate, endDate); + return new CalendarData(calendarData, recurringDates, nextTenRecurringDates); + } + + @Override + public Collection generateRecurringDates(Collection calendarsData) { + Collection recuCalendarsData = new ArrayList(); + + 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 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 = ""; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/LoansApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/LoansApiResource.java index 2380f072f..bd3dcdf2d 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/LoansApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/LoansApiResource.java @@ -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 loanScheduleToApiJsonSerializer, final DefaultToApiJsonSerializer 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 productOptions = this.loanProductReadPlatformService.retrieveAllLoanProductsForLookup(); - // associations - final LoanScheduleData repaymentSchedule = null; - final Collection loanRepayments = null; - final Collection collateral = null; - final Collection guarantors = null; - // options - Collection loanTermFrequencyTypeOptions = null; - Collection repaymentFrequencyTypeOptions = null; - Collection interestRateFrequencyTypeOptions = null; - Collection amortizationTypeOptions = null; - Collection interestTypeOptions = null; - Collection interestCalculationPeriodTypeOptions = null; - Collection fundOptions = null; - Collection repaymentStrategyOptions = null; Collection allowedLoanOfficers = null; - Collection loanPurposeOptions = null; Collection loanCollateralOptions = null; - Collection 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 calendarOptions = null; LoanAccountData newLoanAccount = null; - if (clientId != null) { - LoanAccountData loanBasicDetails = this.loanReadPlatformService.retrieveTemplateWithClientAndProductDetails(clientId, - productId); - final Collection 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 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 charges = null; Collection guarantors = null; Collection collateral = null; - + CalendarData meeting = null; + final Set mandatoryResponseParameters = new HashSet(); final Set 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 productOptions = null; @@ -338,6 +312,7 @@ public class LoansApiResource { ChargeData chargeTemplate = null; Collection loanPurposeOptions = null; Collection loanCollateralOptions = null; + Collection 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); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanAccountData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanAccountData.java index eb11d45db..f2f017488 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanAccountData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanAccountData.java @@ -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 charges; private final Collection collateral; private final Collection guarantors; + private final CalendarData meeting; // template private final Collection productOptions; @@ -105,6 +108,7 @@ public class LoanAccountData { private final Collection transactionProcessingStrategyOptions; private final Collection chargeOptions; private final Collection loanCollateralOptions; + private final Collection 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 charges = null; final Collection collateral = null; final Collection guarantors = null; + final CalendarData calendarData = null; final Collection productOptions = null; final Collection termFrequencyTypeOptions = null; final Collection repaymentFrequencyTypeOptions = null; @@ -170,17 +176,18 @@ public class LoanAccountData { final ChargeData chargeTemplate = null; final Collection loanOfficerOptions = null; final Collection loanPurposeOptions = null; + final Collection 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 charges = null; final Collection collateral = null; final Collection guarantors = null; + final CalendarData calendarData = null; final Collection productOptions = null; final Collection termFrequencyTypeOptions = null; final Collection repaymentFrequencyTypeOptions = null; @@ -244,18 +253,35 @@ public class LoanAccountData { final Collection loanOfficerOptions = null; final Collection loanPurposeOptions = null; final Collection loanCollateralOptions = null; + final Collection 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 charges = null; final Collection collateral = null; final Collection guarantors = null; + final CalendarData calendarData = null; final Collection productOptions = null; final Collection termFrequencyTypeOptions = null; final Collection repaymentFrequencyTypeOptions = null; @@ -318,24 +346,117 @@ public class LoanAccountData { final Collection loanOfficerOptions = null; final Collection loanPurposeOptions = null; final Collection loanCollateralOptions = null; + final Collection 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 termFrequencyTypeOptions, final Collection repaymentFrequencyTypeOptions, + final Collection repaymentStrategyOptions, + final Collection interestRateFrequencyTypeOptions, final Collection amortizationTypeOptions, + final Collection interestTypeOptions, final Collection interestCalculationPeriodTypeOptions, + final Collection fundOptions, final Collection chargeOptions, + final Collection loanPurposeOptions, final Collection 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 transactions = null; + final Collection collateral = null; + final Collection guarantors = null; + final CalendarData calendarData = null; + final Collection productOptions = null; + final Collection calendarOptions = null; + final Collection loanOfficerOptions = null; + + final Integer termFrequency = product.getNumberOfRepayments() * product.getRepaymentEvery(); + final EnumOptionData termPeriodFrequencyType = product.getRepaymentFrequencyType(); + + final Collection charges = new ArrayList(); + 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 transactions = null; final Collection collateral = null; final Collection guarantors = null; + final CalendarData calendarData = null; final Collection productOptions = null; final Collection termFrequencyTypeOptions = null; final Collection repaymentFrequencyTypeOptions = null; @@ -350,7 +471,8 @@ public class LoanAccountData { final Collection loanOfficerOptions = null; final Collection loanPurposeOptions = null; final Collection loanCollateralOptions = null; - + final Collection 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 charges = null; final Collection collateral = null; final Collection guarantors = null; + final CalendarData calendarData = null; final Collection productOptions = null; final Collection termFrequencyTypeOptions = null; final Collection repaymentFrequencyTypeOptions = null; @@ -409,16 +532,17 @@ public class LoanAccountData { final Collection loanOfficerOptions = null; final Collection loanPurposeOptions = null; final Collection loanCollateralOptions = null; - - return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanProductId, + final Collection 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 transactions, final Collection charges, - final Collection collateral, final Collection guarantors, + final Collection collateral, final Collection guarantors, final CalendarData calendarData, final Collection productOptions, final Collection termFrequencyTypeOptions, final Collection repaymentFrequencyTypeOptions, final Collection transactionProcessingStrategyOptions, @@ -435,32 +559,41 @@ public class LoanAccountData { final Collection interestTypeOptions, final Collection interestCalculationPeriodTypeOptions, final Collection fundOptions, final Collection chargeOptions, final ChargeData chargeTemplate, final Collection loanOfficerOptions, final Collection loanPurposeOptions, - final Collection loanCollateralOptions) { + final Collection loanCollateralOptions, final Collection 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 productOptions, + Collection allowedLoanOfficers, final Collection 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 transactions, final Collection charges, - final Collection collateral, final Collection guarantors, + final Collection collateral, final Collection guarantors, final CalendarData meeting, final Collection productOptions, final Collection termFrequencyTypeOptions, final Collection repaymentFrequencyTypeOptions, final Collection transactionProcessingStrategyOptions, @@ -503,7 +637,7 @@ public class LoanAccountData { final Collection interestTypeOptions, final Collection interestCalculationPeriodTypeOptions, final Collection fundOptions, final Collection chargeOptions, final ChargeData chargeTemplate, final Collection loanOfficerOptions, final Collection loanPurposeOptions, - final Collection loanCollateralOptions) { + final Collection loanCollateralOptions, final Collection 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(); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java index ea39a792b..6c0ddd6bb 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java @@ -97,6 +97,10 @@ public class Loan extends AbstractPersistable { @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 { @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 loanCharges, final Set 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 loanCharges) { - final LoanStatus status = null; - final LoanProductRelatedDetail loanRepaymentScheduleDetail = loanSchedule.loanProductRelatedDetail(); - final CodeValue loanPurpose = null; - final Set 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 loanCharges) { @@ -288,7 +282,20 @@ public class Loan extends AbstractPersistable { final LoanProductRelatedDetail loanRepaymentScheduleDetail = loanSchedule.loanProductRelatedDetail(); final CodeValue loanPurpose = null; final Set 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 loanCharges) { + final LoanStatus status = null; + final LoanProductRelatedDetail loanRepaymentScheduleDetail = loanSchedule.loanProductRelatedDetail(); + final CodeValue loanPurpose = null; + final Set 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 { // } - 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 loanCharges, final Set collateral) { @@ -308,6 +315,7 @@ public class Loan extends AbstractPersistable { } 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 { 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 { actualChanges.put(collateralParamName, listOfLoanCollateralData(possiblyModifedLoanCollateralItems)); } } - + return actualChanges; } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanType.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanType.java new file mode 100644 index 000000000..9a51a5cc6 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanType.java @@ -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()); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/exception/LoanTemplateTypeRequiredException.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/exception/LoanTemplateTypeRequiredException.java new file mode 100644 index 000000000..2456018fa --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/exception/LoanTemplateTypeRequiredException.java @@ -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); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/exception/NotSupportedLoanTemplateTypeException.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/exception/NotSupportedLoanTemplateTypeException.java new file mode 100644 index 000000000..70ebd3966 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/exception/NotSupportedLoanTemplateTypeException.java @@ -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); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/CalculateLoanScheduleQueryFromApiJsonHelper.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/CalculateLoanScheduleQueryFromApiJsonHelper.java index cc9713af5..4c7135105 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/CalculateLoanScheduleQueryFromApiJsonHelper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/CalculateLoanScheduleQueryFromApiJsonHelper.java @@ -36,7 +36,7 @@ public final class CalculateLoanScheduleQueryFromApiJsonHelper { /** * The parameters supported for this command. */ - final Set supportedParameters = new HashSet(Arrays.asList("id", "clientId", "groupId", "calendarId", "productId", "accountNo", + final Set supportedParameters = new HashSet(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", diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java index 3b281a933..7548530a4 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java @@ -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 supportedParameters = new HashSet(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; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java index 7ed175398..4b793dc5b 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java @@ -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); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAssembler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAssembler.java index e4c519dc1..a403fb8c0 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAssembler.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAssembler.java @@ -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); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformService.java index 36a647297..334eef348 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformService.java @@ -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 retrieveCalendars(Long groupId); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java index 42db1cf39..2d53cecd3 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java @@ -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 loanTermFrequencyTypeOptions = loanDropdownReadPlatformService.retrieveLoanTermFrequencyTypeOptions(); + final Collection repaymentFrequencyTypeOptions = loanDropdownReadPlatformService.retrieveRepaymentFrequencyTypeOptions(); + final Collection interestRateFrequencyTypeOptions = loanDropdownReadPlatformService.retrieveInterestRateFrequencyTypeOptions(); + final Collection amortizationTypeOptions = loanDropdownReadPlatformService.retrieveLoanAmortizationTypeOptions(); + final Collection interestTypeOptions = loanDropdownReadPlatformService.retrieveLoanInterestTypeOptions(); + final Collection interestCalculationPeriodTypeOptions = loanDropdownReadPlatformService.retrieveLoanInterestRateCalculatedInPeriodOptions(); + final Collection fundOptions = this.fundReadPlatformService.retrieveAllFunds(); + final Collection repaymentStrategyOptions = this.loanDropdownReadPlatformService.retreiveTransactionProcessingStrategies(); + final Collection loanPurposeOptions = this.codeValueReadPlatformService.retrieveCodeValuesByCode("LoanPurpose"); + final Collection loanCollateralOptions = this.codeValueReadPlatformService.retrieveCodeValuesByCode("LoanCollateral"); + final boolean feeChargesOnly = false; + final Collection 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 membersOfGroup = this.clientReadPlatformService.retrieveClientMembersOfGroup(groupId); + if (!CollectionUtils.isEmpty(membersOfGroup)) { + groupAccount = GroupGeneralData.withAssocations(groupAccount, membersOfGroup); + } + + return LoanAccountData.groupDefaults(groupAccount, expectedDisbursementDate); + } + + @Override + public Collection retrieveCalendars(Long groupId) { + Collection calendarsData = new ArrayList(); + 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; + } + + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/service/LoanEnumerations.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/service/LoanEnumerations.java index 612556005..f5729019f 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/service/LoanEnumerations.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/service/LoanEnumerations.java @@ -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; + } } \ No newline at end of file