update api docs for charges, update validation of charges.
This commit is contained in:
@@ -261,6 +261,21 @@ function getBaseURL(docURL)
|
||||
<td><a href="#staff_update">Update a Staff Member</a></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="alt">
|
||||
<td><a href="#charges">CHARGES</a></td><td>charges</td>
|
||||
<td><a href="#charges_create">Create a Charge</a></td>
|
||||
<td><a href="#charges_list">List Charges</a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="alt">
|
||||
<td></td>
|
||||
<td>charges/{chargeId}</td>
|
||||
<td></td>
|
||||
<td><a href="#charges_retrieve">Retrieve a Charge</a></td>
|
||||
<td><a href="#charges_update">Update a Charge</a></td>
|
||||
<td><a href="#charges_delete">Delete a Charge</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2703,6 +2718,207 @@ Request Body:
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<a id="charges" name="charges" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h3>Charges</h3>
|
||||
<p>Its typical for MFIs to add extra costs to their financial products. There are typically <b>Fees</b> or <b>Penalites</b>.</p>
|
||||
<p>Charges is what we use to model both fees and penalities. For now charges can only be associated with loan products / loans.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="charges_create" name="staff_create" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Create/Define a Charge</h4>
|
||||
<p>Define a new charge that can later be associated with loan products or loans.</p>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">POST https://Domain Name/api/v1/charges</code>
|
||||
<code class="method-request">POST charges
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
"name": "Loan service fee",
|
||||
"chargeAppliesTo": 1,
|
||||
"currencyCode": "USD",
|
||||
"locale": "en",
|
||||
"amount": "230.56",
|
||||
"chargeTimeType": "1",
|
||||
"chargeCalculationType": "1"
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"resourceId": 2
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="charges_list" name="charges_list" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Retrieve Charges</h4>
|
||||
<p>Returns the list of defined charges.</p>
|
||||
<p>Example Requests: </p>
|
||||
<div class=apiClick>charges</div>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/charges</code>
|
||||
<code class="method-response">[
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Loan service fee",
|
||||
"active": false,
|
||||
"penalty": false,
|
||||
"currency": {
|
||||
"code": "USD",
|
||||
"name": "US Dollar",
|
||||
"decimalPlaces": 2,
|
||||
"displaySymbol": "$",
|
||||
"nameCode": "currency.USD",
|
||||
"displayLabel": "US Dollar ($)"
|
||||
},
|
||||
"amount": 230.56,
|
||||
"chargeTimeType": {
|
||||
"id": 1,
|
||||
"code": "chargeTimeType.disbursement",
|
||||
"value": "Disbursement"
|
||||
},
|
||||
"chargeAppliesTo": {
|
||||
"id": 1,
|
||||
"code": "chargeAppliesTo.loan",
|
||||
"value": "Loan"
|
||||
},
|
||||
"chargeCalculationType": {
|
||||
"id": 1,
|
||||
"code": "chargeCalculationType.flat",
|
||||
"value": "Flat"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "newcharge",
|
||||
"active": true,
|
||||
"penalty": false,
|
||||
"currency": {
|
||||
"code": "USD",
|
||||
"name": "US Dollar",
|
||||
"decimalPlaces": 2,
|
||||
"displaySymbol": "$",
|
||||
"nameCode": "currency.USD",
|
||||
"displayLabel": "US Dollar ($)"
|
||||
},
|
||||
"amount": 456,
|
||||
"chargeTimeType": {
|
||||
"id": 1,
|
||||
"code": "chargeTimeType.disbursement",
|
||||
"value": "Disbursement"
|
||||
},
|
||||
"chargeAppliesTo": {
|
||||
"id": 1,
|
||||
"code": "chargeAppliesTo.loan",
|
||||
"value": "Loan"
|
||||
},
|
||||
"chargeCalculationType": {
|
||||
"id": 1,
|
||||
"code": "chargeCalculationType.flat",
|
||||
"value": "Flat"
|
||||
}
|
||||
}
|
||||
]
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="charges_retrieve" name="charges_retrieve" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Retrieve a Charge</h4>
|
||||
<p>Returns the details of a defined Charge.</p>
|
||||
<p>Example Requests: </p>
|
||||
<div class=apiClick>charges/2</div>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/charges/2</code>
|
||||
<code class="method-response">{
|
||||
"id": 2,
|
||||
"name": "Loan service fee",
|
||||
"active": false,
|
||||
"penalty": false,
|
||||
"currency": {
|
||||
"code": "USD",
|
||||
"name": "US Dollar",
|
||||
"decimalPlaces": 2,
|
||||
"displaySymbol": "$",
|
||||
"nameCode": "currency.USD",
|
||||
"displayLabel": "US Dollar ($)"
|
||||
},
|
||||
"amount": 230.56,
|
||||
"chargeTimeType": {
|
||||
"id": 1,
|
||||
"code": "chargeTimeType.disbursement",
|
||||
"value": "Disbursement"
|
||||
},
|
||||
"chargeAppliesTo": {
|
||||
"id": 1,
|
||||
"code": "chargeAppliesTo.loan",
|
||||
"value": "Loan"
|
||||
},
|
||||
"chargeCalculationType": {
|
||||
"id": 1,
|
||||
"code": "chargeCalculationType.flat",
|
||||
"value": "Flat"
|
||||
}
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="charges_update" name="charges_update" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Update a Charge</h4>
|
||||
<p>Updates the details of a Charge.</p>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">PUT https://Domain Name/api/v1/charges/1</code>
|
||||
<code class="method-request">PUT charges/1
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
"name": "Loan service fee(changed)"
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"resourceId": 2,
|
||||
"changes": {
|
||||
"name": "Loan service fee(changed)"
|
||||
}
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="charges_delete" name="charges_delete" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Delete a Charge</h4>
|
||||
<p>Deletes a Charge.</p>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">DELETE https://Domain Name/api/v1/charges/2</code>
|
||||
<code class="method-request">DELETE charges/2
|
||||
Content-Type: application/json
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"resourceId": 2
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- start of datatables api docs -->
|
||||
<a id="datatables" name="datatables" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
@@ -3839,6 +4055,21 @@ Request body:
|
||||
<td><a href="#staff_update">Update a Staff Member</a></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="alt">
|
||||
<td><a href="#charges">CHARGES</a></td><td>charges</td>
|
||||
<td><a href="#charges_create">Create a Charge</a></td>
|
||||
<td><a href="#charges_list">List Charges</a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="alt">
|
||||
<td></td>
|
||||
<td>charges/{chargeId}</td>
|
||||
<td></td>
|
||||
<td><a href="#charges_retrieve">Retrieve a Charge</a></td>
|
||||
<td><a href="#charges_update">Update a Charge</a></td>
|
||||
<td><a href="#charges_delete">Delete a Charge</a></td>
|
||||
</tr>
|
||||
<tr><td><a href="#datatables">DATA TABLE</a></td><td>datatables</td><td></td><td><a href="#datatables_list">List Data Tables</a></td><td></td><td></td></tr>
|
||||
<tr class="alt"><td></td><td>datatables/register/{datatable}/{apptable}</td><td><a href="#datatables_register">Register Data Table</a></td><td></td><td></td><td></td></tr>
|
||||
<tr><td></td><td>datatables/deregister/{datatable}</td><td><a href="#datatables_deregister">Deregister Data Table</a></td><td></td><td></td><td></td></tr>
|
||||
|
||||
-111
@@ -1,111 +0,0 @@
|
||||
package org.mifosplatform.portfolio.charge.command;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
|
||||
/**
|
||||
* Immutable data object for creating and modifying defined charges.
|
||||
*/
|
||||
public class ChargeDefinitionCommand {
|
||||
|
||||
private final String name;
|
||||
private final BigDecimal amount;
|
||||
private final String currencyCode;
|
||||
private final Integer chargeTimeType;
|
||||
private final Integer chargeAppliesTo;
|
||||
private final Integer chargeCalculationType;
|
||||
private final Boolean penalty;
|
||||
private final Boolean active;
|
||||
|
||||
public ChargeDefinitionCommand(final String name, final BigDecimal amount, final String currencyCode, final Integer chargeTimeType,
|
||||
final Integer chargeAppliesTo, final Integer chargeCalculationType, final Boolean penalty, final Boolean active) {
|
||||
this.name = name;
|
||||
this.amount = amount;
|
||||
this.currencyCode = currencyCode;
|
||||
this.chargeTimeType = chargeTimeType;
|
||||
this.chargeAppliesTo = chargeAppliesTo;
|
||||
this.chargeCalculationType = chargeCalculationType;
|
||||
this.penalty = penalty;
|
||||
this.active = active;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public String getCurrencyCode() {
|
||||
return currencyCode;
|
||||
}
|
||||
|
||||
public Integer getChargeCalculationType() {
|
||||
return chargeCalculationType;
|
||||
}
|
||||
|
||||
public Integer getChargeAppliesTo() {
|
||||
return chargeAppliesTo;
|
||||
}
|
||||
|
||||
public Integer getChargeTimeType() {
|
||||
return chargeTimeType;
|
||||
}
|
||||
|
||||
public boolean isPenalty() {
|
||||
return penalty;
|
||||
}
|
||||
|
||||
public boolean isFee() {
|
||||
return !penalty;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
public void validateForCreate() {
|
||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
|
||||
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("charge");
|
||||
|
||||
baseDataValidator.reset().parameter("name").value(this.name).notBlank().notExceedingLengthOf(100);
|
||||
baseDataValidator.reset().parameter("amount").value(this.amount).notNull().positiveAmount();
|
||||
baseDataValidator.reset().parameter("currencyCode").value(this.currencyCode).notBlank();
|
||||
baseDataValidator.reset().parameter("chargeAppliesTo").value(this.chargeAppliesTo).notNull().inMinMaxRange(1, 1);
|
||||
baseDataValidator.reset().parameter("chargeTimeType").value(this.chargeTimeType).notNull().inMinMaxRange(1, 2);
|
||||
baseDataValidator.reset().parameter("chargeCalculationType").value(this.chargeCalculationType).notNull().inMinMaxRange(1, 4);
|
||||
|
||||
if (this.penalty && this.chargeTimeType.equals(Integer.valueOf(1))) {
|
||||
// FIXME - KW - cannot have penalty charge at time of disbursement
|
||||
}
|
||||
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
|
||||
public void validateForUpdate() {
|
||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
|
||||
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("charge");
|
||||
|
||||
baseDataValidator.reset().parameter("name").value(this.name).ignoreIfNull().notBlank().notExceedingLengthOf(100);
|
||||
baseDataValidator.reset().parameter("amount").value(this.amount).ignoreIfNull().positiveAmount();
|
||||
baseDataValidator.reset().parameter("currencyCode").value(this.currencyCode).ignoreIfNull().notBlank();
|
||||
|
||||
// FIXME - kw - need to check if parameter exists in update and if so that its not null
|
||||
baseDataValidator.reset().parameter("chargeAppliesTo").value(this.chargeAppliesTo).ignoreIfNull().notNull().inMinMaxRange(1, 1);
|
||||
baseDataValidator.reset().parameter("chargeTimeType").value(this.chargeTimeType).ignoreIfNull().notNull().inMinMaxRange(1, 2);
|
||||
baseDataValidator.reset().parameter("chargeCalculationType").value(this.chargeCalculationType).ignoreIfNull().notNull()
|
||||
.inMinMaxRange(1, 4);
|
||||
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import javax.persistence.Table;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.portfolio.charge.exception.ChargeDueAtDisbursementCannotBePenaltyException;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
@Entity
|
||||
@@ -74,6 +75,7 @@ public class Charge extends AbstractPersistable<Long> {
|
||||
this.chargeCalculation = chargeCalculationType.getValue();
|
||||
this.penalty = penalty;
|
||||
this.active = active;
|
||||
if (penalty && chargeTime.isTimeOfDisbursement()) { throw new ChargeDueAtDisbursementCannotBePenaltyException(name); }
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
@@ -173,6 +175,8 @@ public class Charge extends AbstractPersistable<Long> {
|
||||
actualChanges.put(activeParamName, newValue);
|
||||
this.active = newValue;
|
||||
}
|
||||
|
||||
if (this.penalty && ChargeTimeType.fromInt(this.chargeTime).isTimeOfDisbursement()) { throw new ChargeDueAtDisbursementCannotBePenaltyException(name); }
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
+11
-7
@@ -1,9 +1,9 @@
|
||||
package org.mifosplatform.portfolio.charge.domain;
|
||||
|
||||
public enum ChargeTimeType {
|
||||
|
||||
INVALID(0, "chargeTimeType.invalid"),
|
||||
DISBURSEMENT(1, "chargeTimeType.disbursement"),
|
||||
|
||||
INVALID(0, "chargeTimeType.invalid"), //
|
||||
DISBURSEMENT(1, "chargeTimeType.disbursement"), //
|
||||
SPECIFIED_DUE_DATE(2, "chargeTimeType.specifiedDueDate");
|
||||
|
||||
private final Integer value;
|
||||
@@ -24,17 +24,21 @@ public enum ChargeTimeType {
|
||||
|
||||
public static ChargeTimeType fromInt(final Integer chargeTime) {
|
||||
ChargeTimeType chargeTimeType = ChargeTimeType.INVALID;
|
||||
switch(chargeTime){
|
||||
switch (chargeTime) {
|
||||
case 1:
|
||||
chargeTimeType = DISBURSEMENT;
|
||||
break;
|
||||
break;
|
||||
case 2:
|
||||
chargeTimeType = SPECIFIED_DUE_DATE;
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
chargeTimeType = INVALID;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
return chargeTimeType;
|
||||
}
|
||||
|
||||
public boolean isTimeOfDisbursement() {
|
||||
return ChargeTimeType.DISBURSEMENT.getValue().equals(this.value);
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package org.mifosplatform.portfolio.charge.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
/**
|
||||
* {@link AbstractPlatformDomainRuleException} thrown when attempting to crate
|
||||
* charge of type penalty due at disbursement .
|
||||
*/
|
||||
public class ChargeDueAtDisbursementCannotBePenaltyException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
public ChargeDueAtDisbursementCannotBePenaltyException(final String name) {
|
||||
super("error.msg.charge.due.at.disbursement.cannot.be.penalty", "Charge '" + name + "' is invalid.", name, name);
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -7,7 +7,7 @@ import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRul
|
||||
*/
|
||||
public class ChargeIsNotActiveException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
public ChargeIsNotActiveException(final Long id, final String name) {
|
||||
super("error.msg.charge.is.not.active", "Charge '" + name + "' with identifier " + id + " is not active", name, id);
|
||||
}
|
||||
public ChargeIsNotActiveException(final Long id, final String name) {
|
||||
super("error.msg.charge.is.not.active", "Charge '" + name + "' with identifier " + id + " is not active", name, id);
|
||||
}
|
||||
}
|
||||
+93
-12
@@ -2,16 +2,20 @@ package org.mifosplatform.portfolio.charge.serialization;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.mifosplatform.portfolio.charge.command.ChargeDefinitionCommand;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -19,7 +23,7 @@ import com.google.gson.JsonElement;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
@Component
|
||||
public final class ChargeDefinitionCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer<ChargeDefinitionCommand> {
|
||||
public final class ChargeDefinitionCommandFromApiJsonDeserializer {
|
||||
|
||||
/**
|
||||
* The parameters supported for this command.
|
||||
@@ -35,27 +39,104 @@ public final class ChargeDefinitionCommandFromApiJsonDeserializer extends Abstra
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChargeDefinitionCommand commandFromApiJson(final String json) {
|
||||
public void validateForCreate(final String json) {
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("charge");
|
||||
|
||||
final JsonElement element = fromApiJsonHelper.parse(json);
|
||||
|
||||
final String name = fromApiJsonHelper.extractStringNamed("name", element);
|
||||
baseDataValidator.reset().parameter("name").value(name).notBlank().notExceedingLengthOf(100);
|
||||
|
||||
final String currencyCode = fromApiJsonHelper.extractStringNamed("currencyCode", element);
|
||||
baseDataValidator.reset().parameter("currencyCode").value(currencyCode).notBlank().notExceedingLengthOf(3);
|
||||
|
||||
final BigDecimal amount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("amount", element.getAsJsonObject());
|
||||
baseDataValidator.reset().parameter("amount").value(amount).notNull().positiveAmount();
|
||||
|
||||
final Integer chargeTimeType = fromApiJsonHelper.extractIntegerWithLocaleNamed("chargeTimeType", element);
|
||||
final Integer chargeAppliesTo = fromApiJsonHelper.extractIntegerWithLocaleNamed("chargeAppliesTo", element);
|
||||
final Integer chargeCalculationType = fromApiJsonHelper.extractIntegerWithLocaleNamed("chargeCalculationType", element);
|
||||
final Integer chargeAppliesTo = fromApiJsonHelper.extractIntegerNamed("chargeAppliesTo", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("chargeAppliesTo").value(chargeAppliesTo).notNull().inMinMaxRange(1, 1);
|
||||
|
||||
final Boolean penalty = fromApiJsonHelper.extractBooleanNamed("penalty", element);
|
||||
final Boolean active = fromApiJsonHelper.extractBooleanNamed("active", element);
|
||||
final Integer chargeTimeType = fromApiJsonHelper.extractIntegerNamed("chargeTimeType", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("chargeTimeType").value(chargeTimeType).notNull().inMinMaxRange(1, 2);
|
||||
|
||||
return new ChargeDefinitionCommand(name, amount, currencyCode, chargeTimeType, chargeAppliesTo, chargeCalculationType, penalty,
|
||||
active);
|
||||
final Integer chargeCalculationType = fromApiJsonHelper.extractIntegerNamed("chargeCalculationType", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("chargeCalculationType").value(chargeCalculationType).notNull().inMinMaxRange(1, 4);
|
||||
|
||||
if (fromApiJsonHelper.parameterExists("penalty", element)) {
|
||||
final Boolean penalty = fromApiJsonHelper.extractBooleanNamed("penalty", element);
|
||||
baseDataValidator.reset().parameter("penalty").value(penalty).notNull();
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists("active", element)) {
|
||||
final Boolean active = fromApiJsonHelper.extractBooleanNamed("active", element);
|
||||
baseDataValidator.reset().parameter("active").value(active).notNull();
|
||||
}
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
public void validateForUpdate(final String json) {
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("charge");
|
||||
|
||||
final JsonElement element = fromApiJsonHelper.parse(json);
|
||||
if (fromApiJsonHelper.parameterExists("name", element)) {
|
||||
final String name = fromApiJsonHelper.extractStringNamed("name", element);
|
||||
baseDataValidator.reset().parameter("name").value(name).notBlank().notExceedingLengthOf(100);
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists("currencyCode", element)) {
|
||||
final String currencyCode = fromApiJsonHelper.extractStringNamed("currencyCode", element);
|
||||
baseDataValidator.reset().parameter("currencyCode").value(currencyCode).notBlank().notExceedingLengthOf(3);
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists("amount", element)) {
|
||||
final BigDecimal amount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("amount", element.getAsJsonObject());
|
||||
baseDataValidator.reset().parameter("amount").value(amount).notNull().positiveAmount();
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists("chargeAppliesTo", element)) {
|
||||
final Integer chargeAppliesTo = fromApiJsonHelper.extractIntegerNamed("chargeAppliesTo", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("chargeAppliesTo").value(chargeAppliesTo).notNull().inMinMaxRange(1, 1);
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists("chargeTimeType", element)) {
|
||||
final Integer chargeTimeType = fromApiJsonHelper.extractIntegerNamed("chargeTimeType", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("chargeTimeType").value(chargeTimeType).notNull().inMinMaxRange(1, 2);
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists("chargeCalculationType", element)) {
|
||||
final Integer chargeCalculationType = fromApiJsonHelper.extractIntegerNamed("chargeCalculationType", element,
|
||||
Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("chargeCalculationType").value(chargeCalculationType).notNull().inMinMaxRange(1, 4);
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists("penalty", element)) {
|
||||
final Boolean penalty = fromApiJsonHelper.extractBooleanNamed("penalty", element);
|
||||
baseDataValidator.reset().parameter("penalty").value(penalty).notNull();
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists("active", element)) {
|
||||
final Boolean active = fromApiJsonHelper.extractBooleanNamed("active", element);
|
||||
baseDataValidator.reset().parameter("active").value(active).notNull();
|
||||
}
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
}
|
||||
-8
@@ -3,9 +3,7 @@ package org.mifosplatform.portfolio.charge.service;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mifosplatform.portfolio.charge.data.ChargeData;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.LoanChargeData;
|
||||
|
||||
// FIXME - KW - break out methods that belong to product charges and loan charges
|
||||
public interface ChargeReadPlatformService {
|
||||
|
||||
Collection<ChargeData> retrieveAllCharges();
|
||||
@@ -17,10 +15,4 @@ public interface ChargeReadPlatformService {
|
||||
Collection<ChargeData> retrieveLoanApplicableCharges(boolean feeChargesOnly);
|
||||
|
||||
Collection<ChargeData> retrieveLoanProductCharges(Long loanProductId);
|
||||
|
||||
Collection<LoanChargeData> retrieveLoanCharges(Long loanId);
|
||||
|
||||
LoanChargeData retrieveLoanChargeDetails(Long loanChargeId, Long loanId);
|
||||
|
||||
ChargeData retrieveLoanChargeTemplate();
|
||||
}
|
||||
|
||||
+2
-91
@@ -6,7 +6,6 @@ import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
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.TenantAwareRoutingDataSource;
|
||||
@@ -16,7 +15,6 @@ import org.mifosplatform.organisation.monetary.service.CurrencyReadPlatformServi
|
||||
import org.mifosplatform.portfolio.charge.data.ChargeData;
|
||||
import org.mifosplatform.portfolio.charge.domain.ChargeAppliesTo;
|
||||
import org.mifosplatform.portfolio.charge.exception.ChargeNotFoundException;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.LoanChargeData;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.EmptyResultDataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
@@ -93,31 +91,6 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] { loanProductId });
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<LoanChargeData> retrieveLoanCharges(final Long loanId) {
|
||||
this.context.authenticatedUser();
|
||||
|
||||
final LoanChargeMapper rm = new LoanChargeMapper();
|
||||
|
||||
// TODO - KW - check to see if its important that 'c.is_deleted=0' is
|
||||
// required here?
|
||||
final String sql = "select " + rm.loanChargeSchema() + " where c.is_deleted=0 and lc.loan_id=? "
|
||||
+ " order by lc.charge_time_enum ASC, lc.due_for_collection_as_of_date ASC, lc.is_penalty ASC";
|
||||
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] { loanId });
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoanChargeData retrieveLoanChargeDetails(final Long id, final Long loanId) {
|
||||
this.context.authenticatedUser();
|
||||
|
||||
final LoanChargeMapper rm = new LoanChargeMapper();
|
||||
|
||||
final String sql = "select " + rm.loanChargeSchema() + " where lc.id=? and lc.loan_id=?";
|
||||
|
||||
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { id, loanId });
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ChargeData> retrieveLoanApplicableCharges(final boolean feeChargesOnly) {
|
||||
this.context.authenticatedUser();
|
||||
@@ -134,16 +107,6 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] { ChargeAppliesTo.LOAN.getValue() });
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChargeData retrieveLoanChargeTemplate() {
|
||||
this.context.authenticatedUser();
|
||||
|
||||
final List<EnumOptionData> allowedChargeCalculationTypeOptions = this.chargeDropdownReadPlatformService.retrieveCalculationTypes();
|
||||
final List<EnumOptionData> allowedChargeTimeOptions = this.chargeDropdownReadPlatformService.retrieveCollectionTimeTypes();
|
||||
|
||||
return ChargeData.template(null, allowedChargeCalculationTypeOptions, null, allowedChargeTimeOptions);
|
||||
}
|
||||
|
||||
private static final class ChargeMapper implements RowMapper<ChargeData> {
|
||||
|
||||
public String chargeSchema() {
|
||||
@@ -185,60 +148,8 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService
|
||||
final boolean penalty = rs.getBoolean("penalty");
|
||||
final boolean active = rs.getBoolean("active");
|
||||
|
||||
return ChargeData.instance(id, name, amount, currency, chargeTimeType, chargeAppliesToType, chargeCalculationType, penalty, active);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class LoanChargeMapper implements RowMapper<LoanChargeData> {
|
||||
|
||||
public String loanChargeSchema() {
|
||||
return "lc.id as id, c.id as chargeId, c.name as name, " + "lc.amount as amountDue, "
|
||||
+ "lc.amount_paid_derived as amountPaid, " + "lc.amount_waived_derived as amountWaived, "
|
||||
+ "lc.amount_writtenoff_derived as amountWrittenOff, " + "lc.amount_outstanding_derived as amountOutstanding, "
|
||||
+ "lc.calculation_percentage as percentageOf, lc.calculation_on_amount as amountPercentageAppliedTo, "
|
||||
+ "lc.charge_time_enum as chargeTime, " + "lc.is_penalty as penalty, "
|
||||
+ "lc.due_for_collection_as_of_date as dueAsOfDate, " + "lc.charge_calculation_enum as chargeCalculation, "
|
||||
+ "c.currency_code as currencyCode, oc.name as currencyName, "
|
||||
+ "oc.decimal_places as currencyDecimalPlaces, oc.display_symbol as currencyDisplaySymbol, "
|
||||
+ "oc.internationalized_name_code as currencyNameCode from m_charge c "
|
||||
+ "join m_organisation_currency oc on c.currency_code = oc.code " + "join m_loan_charge lc on lc.charge_id = c.id ";
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoanChargeData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
|
||||
final Long id = rs.getLong("id");
|
||||
final Long chargeId = rs.getLong("chargeId");
|
||||
final String name = rs.getString("name");
|
||||
final BigDecimal amount = rs.getBigDecimal("amountDue");
|
||||
final BigDecimal amountPaid = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amountPaid");
|
||||
final BigDecimal amountWaived = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amountWaived");
|
||||
final BigDecimal amountWrittenOff = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amountWrittenOff");
|
||||
final BigDecimal amountOutstanding = rs.getBigDecimal("amountOutstanding");
|
||||
|
||||
final BigDecimal percentageOf = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "percentageOf");
|
||||
final BigDecimal amountPercentageAppliedTo = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amountPercentageAppliedTo");
|
||||
|
||||
final String currencyCode = rs.getString("currencyCode");
|
||||
final String currencyName = rs.getString("currencyName");
|
||||
final String currencyNameCode = rs.getString("currencyNameCode");
|
||||
final String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
|
||||
final Integer currencyDecimalPlaces = JdbcSupport.getInteger(rs, "currencyDecimalPlaces");
|
||||
|
||||
final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDecimalPlaces, currencyDisplaySymbol,
|
||||
currencyNameCode);
|
||||
|
||||
final int chargeTime = rs.getInt("chargeTime");
|
||||
final EnumOptionData chargeTimeType = ChargeEnumerations.chargeTimeType(chargeTime);
|
||||
|
||||
final LocalDate dueAsOfDate = JdbcSupport.getLocalDate(rs, "dueAsOfDate");
|
||||
|
||||
final int chargeCalculation = rs.getInt("chargeCalculation");
|
||||
final EnumOptionData chargeCalculationType = ChargeEnumerations.chargeCalculationType(chargeCalculation);
|
||||
final boolean penalty = rs.getBoolean("penalty");
|
||||
|
||||
return new LoanChargeData(id, chargeId, name, currency, amount, amountPaid, amountWaived, amountWrittenOff, amountOutstanding,
|
||||
chargeTimeType, dueAsOfDate, chargeCalculationType, percentageOf, amountPercentageAppliedTo, penalty);
|
||||
return ChargeData.instance(id, name, amount, currency, chargeTimeType, chargeAppliesToType, chargeCalculationType, penalty,
|
||||
active);
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-5
@@ -7,7 +7,6 @@ import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.portfolio.charge.command.ChargeDefinitionCommand;
|
||||
import org.mifosplatform.portfolio.charge.domain.Charge;
|
||||
import org.mifosplatform.portfolio.charge.domain.ChargeRepository;
|
||||
import org.mifosplatform.portfolio.charge.exception.ChargeNotFoundException;
|
||||
@@ -42,8 +41,7 @@ public class ChargeWritePlatformServiceJpaRepositoryImpl implements ChargeWriteP
|
||||
try {
|
||||
this.context.authenticatedUser();
|
||||
|
||||
final ChargeDefinitionCommand chargeDefinitionCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
|
||||
chargeDefinitionCommand.validateForCreate();
|
||||
this.fromApiJsonDeserializer.validateForCreate(command.json());
|
||||
|
||||
final Charge charge = Charge.fromJson(command);
|
||||
this.chargeRepository.save(charge);
|
||||
@@ -62,8 +60,7 @@ public class ChargeWritePlatformServiceJpaRepositoryImpl implements ChargeWriteP
|
||||
try {
|
||||
this.context.authenticatedUser();
|
||||
|
||||
final ChargeDefinitionCommand chargeDefinitionCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
|
||||
chargeDefinitionCommand.validateForUpdate();
|
||||
this.fromApiJsonDeserializer.validateForUpdate(command.json());
|
||||
|
||||
final Charge chargeForUpdate = this.chargeRepository.findOne(chargeId);
|
||||
if (chargeForUpdate == null) { throw new ChargeNotFoundException(chargeId); }
|
||||
|
||||
+5
-1
@@ -31,6 +31,7 @@ import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext
|
||||
import org.mifosplatform.portfolio.charge.data.ChargeData;
|
||||
import org.mifosplatform.portfolio.charge.service.ChargeReadPlatformService;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.LoanChargeData;
|
||||
import org.mifosplatform.portfolio.loanaccount.service.LoanChargeReadPlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -48,17 +49,20 @@ public class LoanChargesApiResource {
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final ChargeReadPlatformService chargeReadPlatformService;
|
||||
private final LoanChargeReadPlatformService loanChargeReadPlatformService;
|
||||
private final DefaultToApiJsonSerializer<LoanChargeData> toApiJsonSerializer;
|
||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public LoanChargesApiResource(final PlatformSecurityContext context, final ChargeReadPlatformService chargeReadPlatformService,
|
||||
final LoanChargeReadPlatformService loanChargeReadPlatformService,
|
||||
final DefaultToApiJsonSerializer<LoanChargeData> toApiJsonSerializer,
|
||||
final ApiRequestParameterHelper apiRequestParameterHelper,
|
||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
|
||||
this.context = context;
|
||||
this.chargeReadPlatformService = chargeReadPlatformService;
|
||||
this.loanChargeReadPlatformService = loanChargeReadPlatformService;
|
||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||
@@ -93,7 +97,7 @@ public class LoanChargesApiResource {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
|
||||
|
||||
final LoanChargeData loanCharge = this.chargeReadPlatformService.retrieveLoanChargeDetails(loanChargeId, loanId);
|
||||
final LoanChargeData loanCharge = this.loanChargeReadPlatformService.retrieveLoanChargeDetails(loanChargeId, loanId);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.toApiJsonSerializer.serialize(settings, loanCharge, RESPONSE_DATA_PARAMETERS);
|
||||
|
||||
+7
-4
@@ -52,6 +52,7 @@ import org.mifosplatform.portfolio.loanaccount.gaurantor.data.GuarantorData;
|
||||
import org.mifosplatform.portfolio.loanaccount.gaurantor.service.GuarantorReadPlatformService;
|
||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanScheduleData;
|
||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.service.LoanScheduleCalculationPlatformService;
|
||||
import org.mifosplatform.portfolio.loanaccount.service.LoanChargeReadPlatformService;
|
||||
import org.mifosplatform.portfolio.loanaccount.service.LoanReadPlatformService;
|
||||
import org.mifosplatform.portfolio.loanproduct.data.LoanProductData;
|
||||
import org.mifosplatform.portfolio.loanproduct.data.TransactionProcessingStrategyData;
|
||||
@@ -88,6 +89,7 @@ public class LoansApiResource {
|
||||
private final LoanDropdownReadPlatformService dropdownReadPlatformService;
|
||||
private final FundReadPlatformService fundReadPlatformService;
|
||||
private final ChargeReadPlatformService chargeReadPlatformService;
|
||||
private final LoanChargeReadPlatformService loanChargeReadPlatformService;
|
||||
private final LoanScheduleCalculationPlatformService calculationPlatformService;
|
||||
private final StaffReadPlatformService staffReadPlatformService;
|
||||
private final GuarantorReadPlatformService guarantorReadPlatformService;
|
||||
@@ -102,7 +104,7 @@ public class LoansApiResource {
|
||||
public LoansApiResource(final PlatformSecurityContext context, final LoanReadPlatformService loanReadPlatformService,
|
||||
final LoanProductReadPlatformService loanProductReadPlatformService,
|
||||
final LoanDropdownReadPlatformService dropdownReadPlatformService, final FundReadPlatformService fundReadPlatformService,
|
||||
final ChargeReadPlatformService chargeReadPlatformService,
|
||||
final ChargeReadPlatformService chargeReadPlatformService, final LoanChargeReadPlatformService loanChargeReadPlatformService,
|
||||
final LoanScheduleCalculationPlatformService calculationPlatformService,
|
||||
final StaffReadPlatformService staffReadPlatformService, final GuarantorReadPlatformService guarantorReadPlatformService,
|
||||
final DefaultToApiJsonSerializer<LoanAccountData> toApiJsonSerializer,
|
||||
@@ -116,6 +118,7 @@ public class LoansApiResource {
|
||||
this.dropdownReadPlatformService = dropdownReadPlatformService;
|
||||
this.fundReadPlatformService = fundReadPlatformService;
|
||||
this.chargeReadPlatformService = chargeReadPlatformService;
|
||||
this.loanChargeReadPlatformService = loanChargeReadPlatformService;
|
||||
this.calculationPlatformService = calculationPlatformService;
|
||||
this.staffReadPlatformService = staffReadPlatformService;
|
||||
this.guarantorReadPlatformService = guarantorReadPlatformService;
|
||||
@@ -154,7 +157,7 @@ public class LoansApiResource {
|
||||
|
||||
final boolean feeChargesOnly = false;
|
||||
Collection<ChargeData> chargeOptions = this.chargeReadPlatformService.retrieveLoanApplicableCharges(feeChargesOnly);
|
||||
ChargeData chargeTemplate = this.chargeReadPlatformService.retrieveLoanChargeTemplate();
|
||||
ChargeData chargeTemplate = this.loanChargeReadPlatformService.retrieveLoanChargeTemplate();
|
||||
|
||||
LoanBasicDetailsData loanBasicDetails;
|
||||
Long officeId;
|
||||
@@ -258,7 +261,7 @@ public class LoansApiResource {
|
||||
}
|
||||
|
||||
if (associationParameters.contains("charges")) {
|
||||
charges = this.chargeReadPlatformService.retrieveLoanCharges(loanId);
|
||||
charges = this.loanChargeReadPlatformService.retrieveLoanCharges(loanId);
|
||||
if (CollectionUtils.isEmpty(charges)) {
|
||||
charges = null; // set back to null so doesnt appear in JSON
|
||||
// is no charges exist.
|
||||
@@ -293,7 +296,7 @@ public class LoansApiResource {
|
||||
repaymentStrategyOptions = this.dropdownReadPlatformService.retreiveTransactionProcessingStrategies();
|
||||
final boolean feeChargesOnly = false;
|
||||
chargeOptions = this.chargeReadPlatformService.retrieveLoanApplicableCharges(feeChargesOnly);
|
||||
chargeTemplate = this.chargeReadPlatformService.retrieveLoanChargeTemplate();
|
||||
chargeTemplate = this.loanChargeReadPlatformService.retrieveLoanChargeTemplate();
|
||||
}
|
||||
|
||||
final LoanAccountData loanAccount = new LoanAccountData(loanBasicDetails, convenienceDataRequired, repaymentSchedule,
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package org.mifosplatform.portfolio.loanaccount.service;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mifosplatform.portfolio.charge.data.ChargeData;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.LoanChargeData;
|
||||
|
||||
public interface LoanChargeReadPlatformService {
|
||||
|
||||
ChargeData retrieveLoanChargeTemplate();
|
||||
|
||||
Collection<LoanChargeData> retrieveLoanCharges(Long loanId);
|
||||
|
||||
LoanChargeData retrieveLoanChargeDetails(Long loanChargeId, Long loanId);
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
package org.mifosplatform.portfolio.loanaccount.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
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.TenantAwareRoutingDataSource;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
import org.mifosplatform.portfolio.charge.data.ChargeData;
|
||||
import org.mifosplatform.portfolio.charge.service.ChargeDropdownReadPlatformService;
|
||||
import org.mifosplatform.portfolio.charge.service.ChargeEnumerations;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.LoanChargeData;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatformService {
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final PlatformSecurityContext context;
|
||||
private final ChargeDropdownReadPlatformService chargeDropdownReadPlatformService;
|
||||
|
||||
@Autowired
|
||||
public LoanChargeReadPlatformServiceImpl(final PlatformSecurityContext context,
|
||||
final ChargeDropdownReadPlatformService chargeDropdownReadPlatformService, final TenantAwareRoutingDataSource dataSource) {
|
||||
this.context = context;
|
||||
this.chargeDropdownReadPlatformService = chargeDropdownReadPlatformService;
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
}
|
||||
|
||||
private static final class LoanChargeMapper implements RowMapper<LoanChargeData> {
|
||||
|
||||
public String schema() {
|
||||
return "lc.id as id, c.id as chargeId, c.name as name, " + "lc.amount as amountDue, "
|
||||
+ "lc.amount_paid_derived as amountPaid, " + "lc.amount_waived_derived as amountWaived, "
|
||||
+ "lc.amount_writtenoff_derived as amountWrittenOff, " + "lc.amount_outstanding_derived as amountOutstanding, "
|
||||
+ "lc.calculation_percentage as percentageOf, lc.calculation_on_amount as amountPercentageAppliedTo, "
|
||||
+ "lc.charge_time_enum as chargeTime, " + "lc.is_penalty as penalty, "
|
||||
+ "lc.due_for_collection_as_of_date as dueAsOfDate, " + "lc.charge_calculation_enum as chargeCalculation, "
|
||||
+ "c.currency_code as currencyCode, oc.name as currencyName, "
|
||||
+ "oc.decimal_places as currencyDecimalPlaces, oc.display_symbol as currencyDisplaySymbol, "
|
||||
+ "oc.internationalized_name_code as currencyNameCode from m_charge c "
|
||||
+ "join m_organisation_currency oc on c.currency_code = oc.code " + "join m_loan_charge lc on lc.charge_id = c.id ";
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoanChargeData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
|
||||
final Long id = rs.getLong("id");
|
||||
final Long chargeId = rs.getLong("chargeId");
|
||||
final String name = rs.getString("name");
|
||||
final BigDecimal amount = rs.getBigDecimal("amountDue");
|
||||
final BigDecimal amountPaid = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amountPaid");
|
||||
final BigDecimal amountWaived = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amountWaived");
|
||||
final BigDecimal amountWrittenOff = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amountWrittenOff");
|
||||
final BigDecimal amountOutstanding = rs.getBigDecimal("amountOutstanding");
|
||||
|
||||
final BigDecimal percentageOf = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "percentageOf");
|
||||
final BigDecimal amountPercentageAppliedTo = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amountPercentageAppliedTo");
|
||||
|
||||
final String currencyCode = rs.getString("currencyCode");
|
||||
final String currencyName = rs.getString("currencyName");
|
||||
final String currencyNameCode = rs.getString("currencyNameCode");
|
||||
final String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
|
||||
final Integer currencyDecimalPlaces = JdbcSupport.getInteger(rs, "currencyDecimalPlaces");
|
||||
|
||||
final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDecimalPlaces, currencyDisplaySymbol,
|
||||
currencyNameCode);
|
||||
|
||||
final int chargeTime = rs.getInt("chargeTime");
|
||||
final EnumOptionData chargeTimeType = ChargeEnumerations.chargeTimeType(chargeTime);
|
||||
|
||||
final LocalDate dueAsOfDate = JdbcSupport.getLocalDate(rs, "dueAsOfDate");
|
||||
|
||||
final int chargeCalculation = rs.getInt("chargeCalculation");
|
||||
final EnumOptionData chargeCalculationType = ChargeEnumerations.chargeCalculationType(chargeCalculation);
|
||||
final boolean penalty = rs.getBoolean("penalty");
|
||||
|
||||
return new LoanChargeData(id, chargeId, name, currency, amount, amountPaid, amountWaived, amountWrittenOff, amountOutstanding,
|
||||
chargeTimeType, dueAsOfDate, chargeCalculationType, percentageOf, amountPercentageAppliedTo, penalty);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChargeData retrieveLoanChargeTemplate() {
|
||||
this.context.authenticatedUser();
|
||||
|
||||
final List<EnumOptionData> allowedChargeCalculationTypeOptions = this.chargeDropdownReadPlatformService.retrieveCalculationTypes();
|
||||
final List<EnumOptionData> allowedChargeTimeOptions = this.chargeDropdownReadPlatformService.retrieveCollectionTimeTypes();
|
||||
|
||||
return ChargeData.template(null, allowedChargeCalculationTypeOptions, null, allowedChargeTimeOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoanChargeData retrieveLoanChargeDetails(final Long id, final Long loanId) {
|
||||
this.context.authenticatedUser();
|
||||
|
||||
final LoanChargeMapper rm = new LoanChargeMapper();
|
||||
|
||||
final String sql = "select " + rm.schema() + " where lc.id=? and lc.loan_id=?";
|
||||
|
||||
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { id, loanId });
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<LoanChargeData> retrieveLoanCharges(final Long loanId) {
|
||||
this.context.authenticatedUser();
|
||||
|
||||
final LoanChargeMapper rm = new LoanChargeMapper();
|
||||
|
||||
// TODO - KW - check to see if its important that 'c.is_deleted=0' is
|
||||
// required here?
|
||||
final String sql = "select " + rm.schema() + " where c.is_deleted=0 and lc.loan_id=? "
|
||||
+ " order by lc.charge_time_enum ASC, lc.due_for_collection_as_of_date ASC, lc.is_penalty ASC";
|
||||
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] { loanId });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user