diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm index b5b18b1f3..8de5d816e 100644 --- a/api-docs/apiLive.htm +++ b/api-docs/apiLive.htm @@ -292,7 +292,7 @@ loans Submit a new Loan Application - + List Loans/Loan Applications @@ -4413,6 +4413,247 @@ GET https://DomainName/api/v1/loans/{loanId} +   +
+
+

List Loans

+

The list capability of loans can support pagination and sorting.

+
Optional Arguments
+
+
offset
+
+ Integer optional, defaults to 0 +
+
Indicates from what result to start from.
+ +
limit
+
+ Integer optional, defaults to 200 +
+
Restricts the size of results returned. To override the default and return all entries you must explicitly pass a non-positive integer value for limit e.g. limit=0, or limit=-1
+ +
orderBy
+
+ String optional, one of displayName, accountNo, officeId, officeName +
+
Orders the results by the field indicated.
+ +
sortBy
+
+ String optional, one of ASC, DESC +
+
Indicates what way to order results if orderBy is used.
+ +
officeId
+
+ Integer optional +
+
Provides ability to restrict list of loans returned based on the office there associated with.
+ +
underHierarchy
+
+ String optional +
+
Use the office hierarchy string to return all loans under a given hierarchy.
+ +
accountNo
+
+ String optional +
+
Use account no. of loans to restrict results.
+ +
externalId
+
+ String optional +
+
Use externalId of loan to restrict results.
+ +
sqlSearch
+
+ String optional +
+
Use an sql fragment valid for the underlying loan schema to filter results. e.g. display_name like %K%
+
+

Example Requests:

+
loans
+
+
loans?fields=accountNo
+
+
loans?offset=10&limit=50
+
+
loans?orderBy=accountNo,sortOrder=DESC
+
+
+ +GET https://DomainName/mifosng-provider/api/v1/loans + + +{ + "totalFilteredRecords": 1, + "pageItems": [ + { + "id": 1, + "accountNo": "000000001", + "status": { + "id": 300, + "code": "loanStatusType.active", + "value": "Active", + "pendingApproval": false, + "waitingForDisbursal": false, + "active": true, + "closedObligationsMet": false, + "closedWrittenOff": false, + "closedRescheduled": false, + "closed": false, + "overpaid": false + }, + "clientId": 1, + "clientName": "Change To IndividualName", + "clientOfficeId": 1, + "loanProductId": 1, + "loanProductName": "AgriCredit", + "loanProductDescription": "test", + "loanType": { + "id": 1, + "code": "loanType.individual", + "value": "Individual" + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "principal": 10000, + "termFrequency": 12, + "termPeriodFrequencyType": { + "id": 2, + "code": "termFrequency.periodFrequencyType.months", + "value": "Months" + }, + "numberOfRepayments": 12, + "repaymentEvery": 1, + "repaymentFrequencyType": { + "id": 2, + "code": "repaymentFrequency.periodFrequencyType.months", + "value": "Months" + }, + "interestRatePerPeriod": 2, + "interestRateFrequencyType": { + "id": 2, + "code": "interestRateFrequency.periodFrequencyType.months", + "value": "Per month" + }, + "annualInterestRate": 24, + "amortizationType": { + "id": 1, + "code": "amortizationType.equal.installments", + "value": "Equal installments" + }, + "interestType": { + "id": 0, + "code": "interestType.declining.balance", + "value": "Declining Balance" + }, + "interestCalculationPeriodType": { + "id": 1, + "code": "interestCalculationPeriodType.same.as.repayment.period", + "value": "Same as repayment period" + }, + "transactionProcessingStrategyId": 2, + "timeline": { + "submittedOnDate": [ + 2012, + 6, + 1 + ], + "submittedByUsername": "mifos", + "submittedByFirstname": "App", + "submittedByLastname": "Administrator", + "approvedOnDate": [ + 2012, + 6, + 1 + ], + "approvedByUsername": "mifos", + "approvedByFirstname": "App", + "approvedByLastname": "Administrator", + "expectedDisbursementDate": [ + 2012, + 6, + 1 + ], + "actualDisbursementDate": [ + 2012, + 6, + 1 + ], + "disbursedByUsername": "mifos", + "disbursedByFirstname": "App", + "disbursedByLastname": "Administrator", + "expectedMaturityDate": [ + 2013, + 6, + 1 + ] + }, + "summary": { + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "principalDisbursed": 10000, + "principalPaid": 3073.07, + "principalWrittenOff": 0, + "principalOutstanding": 6926.93, + "principalOverdue": 5999.92, + "interestCharged": 1347.15, + "interestPaid": 709.33, + "interestWaived": 0, + "interestWrittenOff": 0, + "interestOutstanding": 637.82, + "interestOverdue": 619.28, + "feeChargesCharged": 0, + "feeChargesDueAtDisbursementCharged": 0, + "feeChargesPaid": 0, + "feeChargesWaived": 0, + "feeChargesWrittenOff": 0, + "feeChargesOutstanding": 0, + "feeChargesOverdue": 0, + "penaltyChargesCharged": 0, + "penaltyChargesPaid": 0, + "penaltyChargesWaived": 0, + "penaltyChargesWrittenOff": 0, + "penaltyChargesOutstanding": 0, + "penaltyChargesOverdue": 0, + "totalExpectedRepayment": 11347.15, + "totalRepayment": 3782.4, + "totalExpectedCostOfLoan": 1347.15, + "totalCostOfLoan": 709.33, + "totalWaived": 0, + "totalWrittenOff": 0, + "totalOutstanding": 7564.75, + "totalOverdue": 6619.2, + "overdueSinceDate": [ + 2012, + 11, + 1 + ] + }, + "feeChargesAtDisbursementCharged": 0 + } + ] +} + +
+
+  
@@ -13611,7 +13852,7 @@ GET https://DomainName/api/v1/search?query=000000111 loans Submit a new Loan Application - + List Loans/Loan Applications 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 7c6306194..8d1d8724f 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 @@ -238,7 +238,7 @@ public class LoansApiResource { context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); - final LoanAccountData loanBasicDetails = this.loanReadPlatformService.retrieveLoanAccountDetails(loanId); + final LoanAccountData loanBasicDetails = this.loanReadPlatformService.retrieveOne(loanId); Collection loanRepayments = null; LoanScheduleData repaymentSchedule = null; @@ -486,7 +486,7 @@ public class LoansApiResource { // normal // template method to avoid 'assign' on api. and avoid needing to query // for officeId and loanOfficerId in current way! - final LoanAccountData loanBasicDetails = this.loanReadPlatformService.retrieveLoanAccountDetails(loanId); + final LoanAccountData loanBasicDetails = this.loanReadPlatformService.retrieveOne(loanId); final Collection allowedLoanOfficers = this.staffReadPlatformService.retrieveAllLoanOfficersByOffice(loanBasicDetails .officeId()); 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 288665b90..d4f1c55f3 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 @@ -17,7 +17,7 @@ import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanScheduleDat public interface LoanReadPlatformService { - LoanAccountData retrieveLoanAccountDetails(Long loanId); + LoanAccountData retrieveOne(Long loanId); LoanScheduleData retrieveRepaymentSchedule(Long loanId, RepaymentScheduleRelatedLoanData repaymentScheduleRelatedData); 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 29f5b3d17..573c37e3b 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 @@ -66,6 +66,7 @@ import org.mifosplatform.portfolio.loanproduct.data.TransactionProcessingStrateg import org.mifosplatform.portfolio.loanproduct.service.LoanDropdownReadPlatformService; import org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations; import org.mifosplatform.portfolio.loanproduct.service.LoanProductReadPlatformService; +import org.mifosplatform.useradministration.domain.AppUser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.dao.EmptyResultDataAccessException; @@ -120,16 +121,22 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { } @Override - public LoanAccountData retrieveLoanAccountDetails(final Long loanId) { + public LoanAccountData retrieveOne(final Long loanId) { try { - context.authenticatedUser(); + final AppUser currentUser = context.authenticatedUser(); + final String hierarchy = currentUser.getOffice().getHierarchy(); + final String hierarchySearchString = hierarchy + "%"; LoanMapper rm = new LoanMapper(); - String sql = "select " + rm.loanSchema() + " where l.id = ?"; + StringBuilder sqlBuilder = new StringBuilder(); + sqlBuilder.append("select "); + sqlBuilder.append(rm.loanSchema()); + sqlBuilder.append(" join m_office o on o.id = c.office_id"); + sqlBuilder.append(" where l.id=? and o.hierarchy like ?"); - return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { loanId }); + return this.jdbcTemplate.queryForObject(sqlBuilder.toString(), rm, new Object[] { loanId, hierarchySearchString }); } catch (EmptyResultDataAccessException e) { throw new LoanNotFoundException(loanId); } @@ -176,12 +183,25 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { @Override public Page retrieveAll(final SearchParameters searchParameters) { + final AppUser currentUser = context.authenticatedUser(); + final String hierarchy = currentUser.getOffice().getHierarchy(); + final String hierarchySearchString = hierarchy + "%"; + StringBuilder sqlBuilder = new StringBuilder(200); sqlBuilder.append("select SQL_CALC_FOUND_ROWS "); sqlBuilder.append(loaanLoanMapper.loanSchema()); - final Object[] objectArray = new Object[1]; - int arrayPos = 0; + // TODO - for time being this will data scope list of loans returned to + // only loans that have a client associated. + // to support senario where loan has group_id only OR client_id will + // probably require a UNION query + // but that at present is an edge case + sqlBuilder.append(" join m_office o on o.id = c.office_id"); + sqlBuilder.append(" where o.hierarchy like ?"); + + final Object[] objectArray = new Object[2]; + objectArray[0] = hierarchySearchString; + int arrayPos = 1; String sqlQueryCriteria = searchParameters.getSqlSearch(); if (StringUtils.isNotBlank(sqlQueryCriteria)) {