FINERACT-737: Updated Api Docs to include loan charges paid by
FINERACT-736: Api Docs were updated to include rates documentation FINERACT-735: Integration test were created for rates creation, retrieval and update Missing permission READ_RATE
This commit is contained in:
committed by
Michael Vorburger ⛑️
parent
a7d4c83e92
commit
c342f5b43d
+223
-4
@@ -2546,6 +2546,24 @@
|
|||||||
<td></td>
|
<td></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><a href="#rates">Rates</a></td>
|
||||||
|
<td>rates</td>
|
||||||
|
<td><a href="#create_rate">Create Rate</a></td>
|
||||||
|
<td><a href="#rate_list">List Rates</a></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>rates/{rateId}</td>
|
||||||
|
<td></td>
|
||||||
|
<td><a href="#retrieve_rate">Retrieve Rate</a></td>
|
||||||
|
<td><a href="#update_rate">Update Rate</a></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -12142,7 +12160,17 @@ GET https://DomainName/api/v1/loans/{loanId}/transactions/{transactionId}
|
|||||||
"displayLabel": "US Dollar ($)"
|
"displayLabel": "US Dollar ($)"
|
||||||
},
|
},
|
||||||
"amount": 559.88,
|
"amount": 559.88,
|
||||||
"interestPortion": 559.88
|
"interestPortion": 559.88,
|
||||||
|
"loanChargePaidByList": [
|
||||||
|
{
|
||||||
|
"id": 29,
|
||||||
|
"amount": 138.700000,
|
||||||
|
"installmentNumber": 0,
|
||||||
|
"chargeId": 7,
|
||||||
|
"transactionId": 35,
|
||||||
|
"name": "Late Penalty Charge"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
@@ -16174,7 +16202,7 @@ GET https://DomainName/api/v1/loanproducts/{productId}
|
|||||||
numberOfRepaymentVariationsForBorrowerCycle,
|
numberOfRepaymentVariationsForBorrowerCycle,
|
||||||
interestRateVariationsForBorrowerCycle,
|
interestRateVariationsForBorrowerCycle,
|
||||||
multiDisburseLoan,maxTrancheCount,
|
multiDisburseLoan,maxTrancheCount,
|
||||||
outstandingLoanBalance,overdueDaysForNPA,holdGuaranteeFunds, principalThresholdForLastInstalment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount, installmentAmountInMultiplesOf, allowAttributeOverrides, allowPartialPeriodInterestCalcualtion
|
outstandingLoanBalance,overdueDaysForNPA,holdGuaranteeFunds, principalThresholdForLastInstalment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount, installmentAmountInMultiplesOf, allowAttributeOverrides, allowPartialPeriodInterestCalcualtion, rates
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@@ -43279,7 +43307,198 @@ No Request Body:
|
|||||||
</div>
|
</div>
|
||||||
<!-- End of Tax Group -->
|
<!-- End of Tax Group -->
|
||||||
|
|
||||||
<!-- start of clients api docs -->
|
<!-- Start of Rates-->
|
||||||
|
<a id="rates" name="rates" class="old-syle-anchor"> </a>
|
||||||
|
<div class="method-section">
|
||||||
|
<div class="method-description">
|
||||||
|
<h3>Rates</h3>
|
||||||
|
<p>This defines the Rates</p>
|
||||||
|
<table class=matrixHeading>
|
||||||
|
<tr class="matrixHeadingBG">
|
||||||
|
<td>
|
||||||
|
<div class="fineractHeading2">Field Descriptions</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class=alt>
|
||||||
|
<td>name</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class=fielddesc>Name of Rate
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class=alt>
|
||||||
|
<td>productApply</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class=fielddesc>
|
||||||
|
Enum value that defines to which entity the rate will be applicable.
|
||||||
|
Available options are:
|
||||||
|
1=Loans
|
||||||
|
|
||||||
|
Once a rate definition is created, this attribute cannot be changed at any point
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class=alt>
|
||||||
|
<td>Active</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class=fielddesc>
|
||||||
|
Flag indicating if the rate is currently active
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a id="create_rate" name="create_rate"
|
||||||
|
class="old-syle-anchor"> </a>
|
||||||
|
<div class="method-section">
|
||||||
|
<div class="method-description">
|
||||||
|
<h4>Create a new Rate</h4>
|
||||||
|
<p>Creates a new Rate</p>
|
||||||
|
<table class=matrixHeading>
|
||||||
|
<tr class="matrixHeadingBG">
|
||||||
|
<td>
|
||||||
|
<div class="fineractHeading2">Mandatory Fields</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class=alt>
|
||||||
|
<td>name</td>
|
||||||
|
</tr>
|
||||||
|
<tr class=alt>
|
||||||
|
<td>percentage</td>
|
||||||
|
</tr>
|
||||||
|
<tr class=alt>
|
||||||
|
<td>productApply</td>
|
||||||
|
</tr>
|
||||||
|
<tr class=alt>
|
||||||
|
<td>active</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="method-example">
|
||||||
|
<code class="method-declaration">
|
||||||
|
POST https://DomainName/api/v1/rates
|
||||||
|
</code>
|
||||||
|
<code class="method-request">
|
||||||
|
POST rates
|
||||||
|
Content-Type: application/json
|
||||||
|
Request Body:
|
||||||
|
{
|
||||||
|
"productApply":1,
|
||||||
|
"name":"Loan rate",
|
||||||
|
"percentage":"12",
|
||||||
|
"active":true,
|
||||||
|
"locale":"en"
|
||||||
|
}
|
||||||
|
</code>
|
||||||
|
<code class="method-response">
|
||||||
|
{
|
||||||
|
"resourceId": 1
|
||||||
|
}
|
||||||
|
</code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a id="rate_list" name="rate_list"
|
||||||
|
class="old-syle-anchor"> </a>
|
||||||
|
<div class="method-section">
|
||||||
|
<div class="method-description">
|
||||||
|
<h4>List Rates</h4>
|
||||||
|
<p>List Rates</p>
|
||||||
|
</div>
|
||||||
|
<div class="method-example">
|
||||||
|
<code class="method-declaration">
|
||||||
|
GET https://DomainName/api/v1/rates
|
||||||
|
</code>
|
||||||
|
<code class="method-request">
|
||||||
|
GET rates
|
||||||
|
Content-Type: application/json
|
||||||
|
</code>
|
||||||
|
<code class="method-response">
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id":1,
|
||||||
|
"name":"Loan Rate",
|
||||||
|
"percentage":12.00,
|
||||||
|
"productApply":1,
|
||||||
|
"active":true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":2,
|
||||||
|
"name":"Public Rate",
|
||||||
|
"percentage":30.00,
|
||||||
|
"productApply":1,
|
||||||
|
"active":true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":3,
|
||||||
|
"name":"Private Rate",
|
||||||
|
"percentage":14.00,
|
||||||
|
"productApply":1,
|
||||||
|
"active":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
</code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a id="retrieve_rate" name="retrieve_rate"
|
||||||
|
class="old-syle-anchor"> </a>
|
||||||
|
<div class="method-section">
|
||||||
|
<div class="method-description">
|
||||||
|
<h4>Retrieve a Rate</h4>
|
||||||
|
<p>Return the details of an existing Rate</p>
|
||||||
|
</div>
|
||||||
|
<div class="method-example">
|
||||||
|
<code class="method-declaration">
|
||||||
|
GET https://DomainName/api/v1/rates/{rateId}
|
||||||
|
</code>
|
||||||
|
<code class="method-request">
|
||||||
|
GET rates/1
|
||||||
|
Content-Type: application/json
|
||||||
|
</code>
|
||||||
|
<code class="method-response">
|
||||||
|
{
|
||||||
|
"id":1,
|
||||||
|
"name":"Loan Rate",
|
||||||
|
"percentage":12.00,
|
||||||
|
"productApply":1,
|
||||||
|
"active":true
|
||||||
|
}
|
||||||
|
</code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a id="update_rate" name="update_rate"
|
||||||
|
class="old-syle-anchor"> </a>
|
||||||
|
<div class="method-section">
|
||||||
|
<div class="method-description">
|
||||||
|
<h4>Update a Rate</h4>
|
||||||
|
<p>Updates an existing Rate</p>
|
||||||
|
</div>
|
||||||
|
<div class="method-example">
|
||||||
|
<code class="method-declaration">
|
||||||
|
POST https://DomainName/api/v1/rates/{rateId}
|
||||||
|
</code>
|
||||||
|
<code class="method-request">
|
||||||
|
POST rates/3
|
||||||
|
Content-Type: application/json
|
||||||
|
Request Body:
|
||||||
|
{
|
||||||
|
"percentage":"17",
|
||||||
|
}
|
||||||
|
</code>
|
||||||
|
<code class="method-response">
|
||||||
|
{
|
||||||
|
"resourceId":3,
|
||||||
|
"changes":
|
||||||
|
{
|
||||||
|
"percentage":17
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- End of Rates -->
|
||||||
|
|
||||||
|
<!-- start of clients api docs -->
|
||||||
<a id="templates" name="clients" class="old-syle-anchor"> </a>
|
<a id="templates" name="clients" class="old-syle-anchor"> </a>
|
||||||
<div class="method-section">
|
<div class="method-section">
|
||||||
<div class="method-description">
|
<div class="method-description">
|
||||||
@@ -46751,7 +46970,7 @@ GET https://DomainName/api/v1/self/loans/{loanId}/transactions/{transactionId}
|
|||||||
},
|
},
|
||||||
"amount": 559.88,
|
"amount": 559.88,
|
||||||
"interestPortion": 559.88
|
"interestPortion": 559.88
|
||||||
}
|
}
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+71
@@ -0,0 +1,71 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.integrationtests;
|
||||||
|
|
||||||
|
import com.jayway.restassured.builder.RequestSpecBuilder;
|
||||||
|
import com.jayway.restassured.builder.ResponseSpecBuilder;
|
||||||
|
import com.jayway.restassured.http.ContentType;
|
||||||
|
import com.jayway.restassured.specification.RequestSpecification;
|
||||||
|
import com.jayway.restassured.specification.ResponseSpecification;
|
||||||
|
import org.apache.fineract.integrationtests.common.Utils;
|
||||||
|
import org.apache.fineract.integrationtests.common.rates.RatesHelper;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
@SuppressWarnings({"rawtypes"})
|
||||||
|
public class RatesTest {
|
||||||
|
|
||||||
|
private ResponseSpecification responseSpec;
|
||||||
|
private RequestSpecification requestSpec;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
Utils.initializeRESTAssured();
|
||||||
|
this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
||||||
|
this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
|
||||||
|
this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRatesForLoans() {
|
||||||
|
|
||||||
|
// Retrieving all Rates
|
||||||
|
ArrayList<HashMap> allRatesData = RatesHelper.getRates(this.requestSpec, this.responseSpec);
|
||||||
|
Assert.assertNotNull(allRatesData);
|
||||||
|
|
||||||
|
// Testing Creation and Update of Loan Rate
|
||||||
|
final Integer loanRateId = RatesHelper.createRates(this.requestSpec, this.responseSpec,
|
||||||
|
RatesHelper.getLoanRateJSON());
|
||||||
|
Assert.assertNotNull(loanRateId);
|
||||||
|
|
||||||
|
//Update Rate percentage
|
||||||
|
HashMap changes = RatesHelper.updateRates(this.requestSpec, this.responseSpec, loanRateId,
|
||||||
|
RatesHelper.getModifyRateJSON());
|
||||||
|
|
||||||
|
HashMap rateDataAfterChanges = RatesHelper.getRateById(this.requestSpec, this.responseSpec, loanRateId);
|
||||||
|
Assert.assertEquals("Verifying Rate after modification", rateDataAfterChanges.get("percentage"), changes.get("percentage"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+91
@@ -0,0 +1,91 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.integrationtests.common.rates;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.jayway.restassured.specification.RequestSpecification;
|
||||||
|
import com.jayway.restassured.specification.ResponseSpecification;
|
||||||
|
import org.apache.fineract.integrationtests.common.CommonConstants;
|
||||||
|
import org.apache.fineract.integrationtests.common.Utils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
|
public class RatesHelper {
|
||||||
|
|
||||||
|
private static final String RATES_URL = "/fineract-provider/api/v1/rates";
|
||||||
|
private static final String CREATE_RATES_URL = RATES_URL + "?" + Utils.TENANT_IDENTIFIER;
|
||||||
|
private final static String PERCENTAGE = "10";
|
||||||
|
private final static Integer PRODUCT_APPLY_LOAN = 1;
|
||||||
|
private final static Boolean ACTIVE = true;
|
||||||
|
|
||||||
|
public static ArrayList<HashMap> getRates(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) {
|
||||||
|
return (ArrayList) Utils.performServerGet(requestSpec, responseSpec, RATES_URL + "?" + Utils.TENANT_IDENTIFIER, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Integer createRates(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||||
|
final String request) {
|
||||||
|
return Utils.performServerPost(requestSpec, responseSpec, CREATE_RATES_URL, request, "resourceId");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HashMap getRateById(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||||
|
final Integer rateId) {
|
||||||
|
return Utils.performServerGet(requestSpec, responseSpec, RATES_URL + "/" + rateId + "?" + Utils.TENANT_IDENTIFIER, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HashMap updateRates(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||||
|
final Integer rateId, final String request) {
|
||||||
|
return Utils.performServerPut(requestSpec, responseSpec, RATES_URL + "/" + rateId + "?" + Utils.TENANT_IDENTIFIER, request,
|
||||||
|
CommonConstants.RESPONSE_CHANGES);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getLoanRateJSON() {
|
||||||
|
return getLoanRateJSON(RatesHelper.PRODUCT_APPLY_LOAN, RatesHelper.PERCENTAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getLoanRateJSON(final Integer productApply, final String percentage) {
|
||||||
|
final HashMap<String, Object> map = populateDefaultsForLoan();
|
||||||
|
map.put("percentage", percentage);
|
||||||
|
map.put("productApply", productApply);
|
||||||
|
String crateRateJSON = new Gson().toJson(map);
|
||||||
|
return crateRateJSON;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HashMap<String, Object> populateDefaultsForLoan() {
|
||||||
|
final HashMap<String, Object> map = new HashMap<>();
|
||||||
|
map.put("active", RatesHelper.ACTIVE);
|
||||||
|
map.put("percentage", RatesHelper.PERCENTAGE);
|
||||||
|
map.put("locale", "en");
|
||||||
|
map.put("productApply", RatesHelper.PRODUCT_APPLY_LOAN);
|
||||||
|
map.put("name", Utils.randomNameGenerator("Rate_Loans_", 6));
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getModifyRateJSON() {
|
||||||
|
final HashMap<String, Object> map = new HashMap<>();
|
||||||
|
map.put("percentage", "15.0");
|
||||||
|
map.put("locale", "en");
|
||||||
|
String json = new Gson().toJson(map);
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
+5
-3
@@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
package org.apache.fineract.portfolio.rate.data;
|
package org.apache.fineract.portfolio.rate.data;
|
||||||
|
|
||||||
|
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
@@ -33,17 +35,17 @@ public class RateData implements Serializable {
|
|||||||
|
|
||||||
private BigDecimal percentage;
|
private BigDecimal percentage;
|
||||||
|
|
||||||
private String productApply;
|
private EnumOptionData productApply;
|
||||||
|
|
||||||
private boolean active;
|
private boolean active;
|
||||||
|
|
||||||
public static RateData instance(final Long id, final String name, final BigDecimal percentage,
|
public static RateData instance(final Long id, final String name, final BigDecimal percentage,
|
||||||
final String productApply, final boolean active) {
|
final EnumOptionData productApply, final boolean active) {
|
||||||
return new RateData(id, name, percentage, productApply, active);
|
return new RateData(id, name, percentage, productApply, active);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RateData(final Long id, final String name, final BigDecimal percentage,
|
private RateData(final Long id, final String name, final BigDecimal percentage,
|
||||||
final String productApply, final boolean active) {
|
final EnumOptionData productApply, final boolean active) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.percentage = percentage;
|
this.percentage = percentage;
|
||||||
|
|||||||
+21
-15
@@ -19,11 +19,18 @@
|
|||||||
|
|
||||||
package org.apache.fineract.portfolio.rate.domain;
|
package org.apache.fineract.portfolio.rate.domain;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||||
|
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||||
|
import org.apache.fineract.portfolio.charge.exception.ChargeParameterUpdateNotSupportedException;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
|
import org.apache.fineract.portfolio.rate.domain.RateAppliesTo;
|
||||||
|
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
@@ -45,7 +52,7 @@ public class Rate extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
private BigDecimal percentage;
|
private BigDecimal percentage;
|
||||||
|
|
||||||
@Column(name = "product_apply", length = 100)
|
@Column(name = "product_apply", length = 100)
|
||||||
private String productApply;
|
private Integer productApply;
|
||||||
|
|
||||||
@Column(name = "active", nullable = false)
|
@Column(name = "active", nullable = false)
|
||||||
private boolean active;
|
private boolean active;
|
||||||
@@ -59,19 +66,19 @@ public class Rate extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Rate(String name, BigDecimal percentage, String productApply, boolean active,
|
public Rate(String name, BigDecimal percentage, RateAppliesTo productApply, boolean active,
|
||||||
AppUser approveUser) {
|
AppUser approveUser) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.percentage = percentage;
|
this.percentage = percentage;
|
||||||
this.productApply = productApply;
|
this.productApply = productApply.getValue();
|
||||||
this.active = active;
|
this.active = active;
|
||||||
this.approveUser = approveUser;
|
this.approveUser = approveUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Rate(String name, BigDecimal percentage, String productApply, boolean active) {
|
public Rate(String name, BigDecimal percentage, RateAppliesTo productApply, boolean active) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.percentage = percentage;
|
this.percentage = percentage;
|
||||||
this.productApply = productApply;
|
this.productApply = productApply.getValue();
|
||||||
this.active = active;
|
this.active = active;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,11 +114,11 @@ public class Rate extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
this.approveUser = approveUser;
|
this.approveUser = approveUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getProductApply() {
|
public Integer getProductApply() {
|
||||||
return productApply;
|
return productApply;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProductApply(String productApply) {
|
public void setProductApply(Integer productApply) {
|
||||||
this.productApply = productApply;
|
this.productApply = productApply;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,7 +133,7 @@ public class Rate extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Rate from(String name, BigDecimal percentage, String productApply, Boolean active) {
|
public static Rate from(String name, BigDecimal percentage, RateAppliesTo productApply, Boolean active) {
|
||||||
return new Rate(name, percentage, productApply, active);
|
return new Rate(name, percentage, productApply, active);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,8 +143,8 @@ public class Rate extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
|
|
||||||
final BigDecimal percentage = command.bigDecimalValueOfParameterNamed("percentage");
|
final BigDecimal percentage = command.bigDecimalValueOfParameterNamed("percentage");
|
||||||
|
|
||||||
final String productApply = command.stringValueOfParameterNamed("productApply");
|
final RateAppliesTo productApply = RateAppliesTo.fromInt(command.integerValueOfParameterNamed("productApply"));
|
||||||
|
|
||||||
final boolean active = command.booleanPrimitiveValueOfParameterNamed("active");
|
final boolean active = command.booleanPrimitiveValueOfParameterNamed("active");
|
||||||
|
|
||||||
return new Rate(name, percentage, productApply, active, user);
|
return new Rate(name, percentage, productApply, active, user);
|
||||||
@@ -162,10 +169,9 @@ public class Rate extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final String productApplyParamName = "productApply";
|
final String productApplyParamName = "productApply";
|
||||||
if (command.isChangeInStringParameterNamed(productApplyParamName, this.productApply)) {
|
if (command.isChangeInIntegerParameterNamed(productApplyParamName, this.productApply)) {
|
||||||
final String newValue = command.stringValueOfParameterNamed(productApplyParamName);
|
final String errorMessage = "Update of Rate applies to is not supported";
|
||||||
actualChanges.put(productApplyParamName, newValue);
|
throw new ChargeParameterUpdateNotSupportedException("rate.applies.to", errorMessage);
|
||||||
this.productApply = StringUtils.defaultIfEmpty(newValue, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final String activeParamName = "active";
|
final String activeParamName = "active";
|
||||||
@@ -192,7 +198,7 @@ public class Rate extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
return approveUserId;
|
return approveUserId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void assembleFrom(String name, BigDecimal percentage, String productApply, boolean active){
|
public void assembleFrom(String name, BigDecimal percentage, Integer productApply, boolean active){
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.percentage = percentage;
|
this.percentage = percentage;
|
||||||
this.productApply = productApply;
|
this.productApply = productApply;
|
||||||
|
|||||||
+66
@@ -0,0 +1,66 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.fineract.portfolio.rate.domain;
|
||||||
|
|
||||||
|
public enum RateAppliesTo {
|
||||||
|
|
||||||
|
INVALID(0, "rateAppliesTo.invalid"),
|
||||||
|
LOAN(1, "rateAppliesTo.loan");
|
||||||
|
|
||||||
|
private final Integer value;
|
||||||
|
private final String code;
|
||||||
|
|
||||||
|
private RateAppliesTo(final Integer value, final String code) {
|
||||||
|
this.value = value;
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getValue() {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return this.code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RateAppliesTo fromInt(final Integer rateAppliesTo) {
|
||||||
|
RateAppliesTo rateAppliesToType = RateAppliesTo.INVALID;
|
||||||
|
|
||||||
|
if (rateAppliesTo != null) {
|
||||||
|
switch (rateAppliesTo) {
|
||||||
|
case 1:
|
||||||
|
rateAppliesToType = LOAN;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rateAppliesToType = INVALID;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rateAppliesToType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLoanRate() {
|
||||||
|
return this.value.equals(RateAppliesTo.LOAN.getValue());
|
||||||
|
}
|
||||||
|
public static Object[] validValues() {
|
||||||
|
return new Object[] { RateAppliesTo.LOAN.getValue() };
|
||||||
|
}
|
||||||
|
}
|
||||||
+47
@@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.fineract.portfolio.rate.service;
|
||||||
|
|
||||||
|
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||||
|
import org.apache.fineract.portfolio.rate.domain.RateAppliesTo;
|
||||||
|
|
||||||
|
public class RateEnumerations {
|
||||||
|
|
||||||
|
public static EnumOptionData rateAppliesTo(final int id) {
|
||||||
|
return rateAppliesTo(RateAppliesTo.fromInt(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EnumOptionData rateAppliesTo(final RateAppliesTo type) {
|
||||||
|
EnumOptionData optionData = null;
|
||||||
|
switch (type) {
|
||||||
|
case LOAN:
|
||||||
|
optionData = new EnumOptionData(RateAppliesTo.LOAN.getValue().longValue(), RateAppliesTo.LOAN.getCode(), "Loan");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
optionData = new EnumOptionData(RateAppliesTo.INVALID.getValue().longValue(), RateAppliesTo.INVALID.getCode(),
|
||||||
|
"Invalid");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return optionData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+8
-4
@@ -19,8 +19,11 @@
|
|||||||
|
|
||||||
package org.apache.fineract.portfolio.rate.service;
|
package org.apache.fineract.portfolio.rate.service;
|
||||||
|
|
||||||
|
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||||
import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
|
import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
|
||||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||||
|
import org.apache.fineract.portfolio.charge.service.ChargeEnumerations;
|
||||||
|
import org.apache.fineract.portfolio.rate.domain.RateAppliesTo;
|
||||||
import org.apache.fineract.portfolio.rate.exception.RateNotFoundException;
|
import org.apache.fineract.portfolio.rate.exception.RateNotFoundException;
|
||||||
import org.apache.fineract.portfolio.rate.domain.Rate;
|
import org.apache.fineract.portfolio.rate.domain.Rate;
|
||||||
import org.apache.fineract.portfolio.rate.data.RateData;
|
import org.apache.fineract.portfolio.rate.data.RateData;
|
||||||
@@ -92,7 +95,7 @@ public class RateReadServiceImpl implements RateReadService {
|
|||||||
this.context.authenticatedUser();
|
this.context.authenticatedUser();
|
||||||
final RateMapper rm = new RateMapper();
|
final RateMapper rm = new RateMapper();
|
||||||
final String sql = "select " + rm.rateSchema() + " where r.active = ? and product_apply=?";
|
final String sql = "select " + rm.rateSchema() + " where r.active = ? and product_apply=?";
|
||||||
return this.jdbcTemplate.query(sql, rm, new Object[]{true, "m_loan"});
|
return this.jdbcTemplate.query(sql, rm, new Object[]{true, RateAppliesTo.LOAN.getValue() });
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -133,16 +136,17 @@ public class RateReadServiceImpl implements RateReadService {
|
|||||||
final Long id = resultSet.getLong("id");
|
final Long id = resultSet.getLong("id");
|
||||||
final String name = resultSet.getString("name");
|
final String name = resultSet.getString("name");
|
||||||
final BigDecimal percentage = resultSet.getBigDecimal("percentage");
|
final BigDecimal percentage = resultSet.getBigDecimal("percentage");
|
||||||
final String productApply = resultSet.getString("productApply");
|
final Integer productApply = resultSet.getInt("productApply");
|
||||||
|
final EnumOptionData productAppliesTo = RateEnumerations.rateAppliesTo(productApply);
|
||||||
final boolean active = resultSet.getBoolean("active");
|
final boolean active = resultSet.getBoolean("active");
|
||||||
return RateData.instance(id, name, percentage, productApply, active);
|
return RateData.instance(id, name, percentage, productAppliesTo, active);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RateData mapRow(Rate rateResponse, int i) {
|
public RateData mapRow(Rate rateResponse, int i) {
|
||||||
final Long id = rateResponse.getId();
|
final Long id = rateResponse.getId();
|
||||||
final String name = rateResponse.getName();
|
final String name = rateResponse.getName();
|
||||||
final BigDecimal percentage = rateResponse.getPercentage();
|
final BigDecimal percentage = rateResponse.getPercentage();
|
||||||
final String productApply = rateResponse.getProductApply();
|
final EnumOptionData productApply = RateEnumerations.rateAppliesTo(rateResponse.getProductApply());;
|
||||||
final boolean active = rateResponse.isActive();
|
final boolean active = rateResponse.isActive();
|
||||||
return RateData.instance(id, name, percentage, productApply, active);
|
return RateData.instance(id, name, percentage, productApply, active);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ CREATE TABLE IF NOT EXISTS `m_rate` (
|
|||||||
`name` varchar(250) NOT NULL,
|
`name` varchar(250) NOT NULL,
|
||||||
`percentage` decimal(10,2) NOT NULL,
|
`percentage` decimal(10,2) NOT NULL,
|
||||||
`active` tinyint(1) DEFAULT '0',
|
`active` tinyint(1) DEFAULT '0',
|
||||||
`product_apply` varchar(100) NOT NULL,
|
`product_apply` smallint(5) NOT NULL,
|
||||||
`created_date` datetime NULL DEFAULT NULL,
|
`created_date` datetime NULL DEFAULT NULL,
|
||||||
`createdby_id` bigint(20) NOT NULL,
|
`createdby_id` bigint(20) NOT NULL,
|
||||||
`lastmodifiedby_id` bigint(20) NOT NULL,
|
`lastmodifiedby_id` bigint(20) NOT NULL,
|
||||||
@@ -58,10 +58,10 @@ CREATE TABLE IF NOT EXISTS `m_product_loan_rate` (
|
|||||||
|
|
||||||
INSERT INTO `m_permission`
|
INSERT INTO `m_permission`
|
||||||
(`grouping`,`code`,`entity_name`,`action_name`,`can_maker_checker`) VALUES
|
(`grouping`,`code`,`entity_name`,`action_name`,`can_maker_checker`) VALUES
|
||||||
|
('organisation', 'READ_RATE', 'RATE', 'CREATE', '1'),
|
||||||
('organisation', 'CREATE_RATE', 'RATE', 'CREATE', '1'),
|
('organisation', 'CREATE_RATE', 'RATE', 'CREATE', '1'),
|
||||||
('organisation', 'UPDATE_RATE', 'RATE', 'UPDATE', '1');
|
('organisation', 'UPDATE_RATE', 'RATE', 'UPDATE', '1');
|
||||||
|
|
||||||
INSERT INTO `c_configuration`
|
INSERT INTO `c_configuration`
|
||||||
(`name`, `value`, `enabled`, `is_trap_door`, `description`) VALUES
|
(`name`, `value`, `enabled`, `is_trap_door`, `description`) VALUES
|
||||||
('vat-tax', 12, 0, 0, 'VAT tax'),
|
('sub-rates', 0, 0, 0, 'Enable Rates Module');
|
||||||
('sub-rates', 12, 0, 0, 'Enable Rates Module');;
|
|
||||||
|
|||||||
Reference in New Issue
Block a user