Client fees and MIFOSX-2169

This commit is contained in:
Vishwas Babu A J
2015-09-05 01:49:11 +05:30
parent 670b6eef19
commit 66ce3b4873
31 changed files with 533 additions and 951 deletions
+72 -430
View File
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
@@ -35623,52 +35623,40 @@ Request Body:
<a id="client_charge" name="client_charge" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h3>Client Charge</h3>
<p>Client Charge is a type of charge which is directlly applied on client.One client can have more than one client charge and client charge is created with charge time type as specified due date and calculation type as flat.
<h3>Client Charges</h3>
<p>It is typical for MFI's to directly associate charges with an implicit Client account. These
can be either fees or penalties</p>
<p>Client Charges are client specific instances of <a href="#charges">Charges</a>. Refer <a href="#charges">Charges</a> for documentation of the various properties of a charge, Only additional properties (
specific to the context of a Charge being associated with a Client account) are
described here</p>
</p>
<table class=matrixHeading>
<tr class="matrixHeadingBG">
<td><div class="mifosXHeading2">Field Descriptions</div></td>
</tr>
<tr class=alt>
<td>chargeId</td>
</tr>
<tr>
<td class=fielddesc>This ia an unique Id associate with client charge.
</td>
</tr>
<tr class=alt>
<td>name</td>
</tr>
<tr>
<td class=fielddesc>Name given to the client charge.</td>
</tr>
<tr class=alt>
<td>active</td>
</tr>
<tr>
<td class=fielddesc>Indicates whether this charge is to be created as active</b>. If active=true, then <b>activationDate</b> must be provided. If active=false, then the charge is created as <b>pending</b>.
</td>
</tr>
<tr class=alt>
<td>amountPaid</td>
</tr>
<tr>
<td class=fielddesc>amount paid as client charge</b>.
</td>
<td class=fielddesc>The total amount which has been paid for this Charge
</td>
</tr>
<tr class=alt>
<td>amountWaived</td>
</tr>
<tr>
<td class=fielddesc>amount waive from client charge</td>
<td class=fielddesc>The total amount that has been waived for this Charge
</td>
</tr>
<tr class=alt>
<td>amountOutstanding</td>
</tr>
<tr>
<td class=fielddesc>The left over amount to pay .</td>
<td class=fielddesc>The Total outstanding amount for this Charge
</td>
</tr>
<tr class=alt>
<td>dueDate</td>
</tr>
@@ -35684,51 +35672,51 @@ Request Body:
<div class="method-section">
<div class="method-description">
<h3>Client Transaction</h3>
<p>Client Charge transactions are get created when a client pays/waives off client charge.this client charge transaction shows
<br>the unit of amount paid as client charge.
<p>Client Transactions refer to transactions made directly againt a Client's internal account. Currently, these transactions are only created as a result of charge payments/waivers. You are allowed to undo a transaction, however you cannot explicitly create one.
</p>
<table class=matrixHeading>
<tr class="matrixHeadingBG">
<td><div class="mifosXHeading2">Field Descriptions</div></td>
</tr>
<tr class=alt>
<td>transactionId</td>
<td>id</td>
</tr>
<tr>
<td class=fielddesc>This ia an unique Id associate with client charge Transaction.
<td class=fielddesc>This ia an unique Id associate with a Transaction.
</td>
</tr>
<tr class=alt>
<td>clientId</td>
<td>officeId</td>
</tr>
<tr>
<td class=fielddesc>clientId on which client transaction got created</td>
<td class=fielddesc>Identifier of the office in which the transaction was made</td>
</tr>
<tr class=alt>
<td>isReverse</td>
<td>reversed</td>
</tr>
<tr>
<td class=fielddesc>Indicates whether this client charge transaction is reversed or not.
<td class=fielddesc>Boolean Flag that indicates if this transaction is reversed.
</td>
</tr>
<tr class=alt>
<td>amountPaid</td>
<td>amount</td>
</tr>
<tr>
<td class=fielddesc>amount paid as client charge</b>.
<td class=fielddesc>Transaction amount</b>.
</td>
</tr>
<tr class=alt>
<td>currency code</td>
<td>currency</td>
</tr>
<tr>
<td class=fielddesc>currency type</td>
<td class=fielddesc>Details of the currency involved with the Transaction. Currently defaults
to the currency of the Client Charge this transaction pays </td>
</tr>
<tr class=alt>
<td>transaction date</td>
<td>date</td>
</tr>
<tr>
<td class=fielddesc>date on which transaction happened</td>
<td class=fielddesc>Effective date of the transaction</td>
</tr>
</table>
@@ -35737,8 +35725,8 @@ Request Body:
<a id="list_clientTransactions" name="list_clientTransactions" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>List client Transactions</h4>
<p>The <i>list</i> capability of client charge transaction can support <b>pagination</b> and <b>sorting</b>.</p>
<h4>List Client Transactions</h4>
<p>The <i>list</i> capability of client transaction can support <b>pagination</b> and <b>sorting</b>.</p>
<h5>Mandatory Arguments</h5>
<dl class="argument-list">
<dt>offset</dt>
@@ -35752,8 +35740,7 @@ Request Body:
Integer <span>Mandatory</span>, defaults to 200
</dd>
<dd>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</dd>
</dl>
</dl>
</dl>
<p>Example Requests:</p>
<div class=apiClick>clients/189/transactions</div>
<div class=apiClick>clients/189/transactions?offset=10&limit=50</div>
@@ -35765,11 +35752,8 @@ GET https://DomainName/api/v1/clients/{clientId}/transactions?limit=5&offset=0
<code class="method-request">
GET clients/226/transactions?limit=5&offset=0
Content-Type: application/json
Request Body:
{
chargeId="226"
}
No Request Body:
</code>
<code class="method-response">
{
@@ -35804,126 +35788,6 @@ Request Body:
2
],
"reversed": false
},
{
"id": 208,
"officeId": 1,
"officeName": "Head Office",
"type": {
"id": 1,
"code": "clientTransactionType.payCharge",
"value": "PAY_CHARGE"
},
"date": [
2015,
8,
28
],
"currency": {
"code": "USD",
"name": "US Dollar",
"decimalPlaces": 2,
"displaySymbol": "$",
"nameCode": "currency.USD",
"displayLabel": "US Dollar ($)"
},
"amount": 3,
"submittedOnDate": [
2015,
8,
28
],
"reversed": false
},
{
"id": 207,
"officeId": 1,
"officeName": "Head Office",
"type": {
"id": 1,
"code": "clientTransactionType.payCharge",
"value": "PAY_CHARGE"
},
"date": [
2015,
8,
28
],
"currency": {
"code": "USD",
"name": "US Dollar",
"decimalPlaces": 2,
"displaySymbol": "$",
"nameCode": "currency.USD",
"displayLabel": "US Dollar ($)"
},
"amount": 5,
"submittedOnDate": [
2015,
8,
28
],
"reversed": false
},
{
"id": 206,
"officeId": 1,
"officeName": "Head Office",
"type": {
"id": 1,
"code": "clientTransactionType.payCharge",
"value": "PAY_CHARGE"
},
"date": [
2015,
8,
28
],
"currency": {
"code": "USD",
"name": "US Dollar",
"decimalPlaces": 2,
"displaySymbol": "$",
"nameCode": "currency.USD",
"displayLabel": "US Dollar ($)"
},
"amount": 5,
"submittedOnDate": [
2015,
8,
28
],
"reversed": false
},
{
"id": 205,
"officeId": 1,
"officeName": "Head Office",
"type": {
"id": 1,
"code": "clientTransactionType.payCharge",
"value": "PAY_CHARGE"
},
"date": [
2015,
8,
28
],
"currency": {
"code": "USD",
"name": "US Dollar",
"decimalPlaces": 2,
"displaySymbol": "$",
"nameCode": "currency.USD",
"displayLabel": "US Dollar ($)"
},
"amount": 5,
"submittedOnDate": [
2015,
8,
28
],
"reversed": false
}
]
}
@@ -35935,23 +35799,22 @@ Request Body:
<div class="method-description">
<h4>Add Client Charge</h4>
<p>
It is one among the charges.It is created chargeTime type as specified due date and calculation type as flat and it can only be applied client.This API enables to add client charge to client.
This API associates a Client charge with an implicit Client account
</p>
<table class=matrixHeading>
<tr class="matrixHeadingBG">
<td><div class="mifosXHeading2">Mandatory Fields</div></td>
</tr>
<tr class=alt>
<td>clientId,chargeId and activationDate </td>
<td>chargeId and dueDate </td>
</tr>
</table>
<br />
<table class=matrixHeading>
<tr class="matrixHeadingBG">
<td><div class="mifosXHeading2">Optional Fields</div></td>
</tr>
<tr class=alt>
<td>externalId, accountNo,genderId, clientTypeId, clientClassificationId</td>
<td>amount</td>
</tr>
</table>
</div>
@@ -35964,11 +35827,11 @@ POST clients/226/charges
Content-Type: application/json
Request Body:
{
"amount"="100"
chargeId="226"
dateFormat="dd MMMM yyyy"
dueDate="01 September 2015"
locale="en"
"amount" : "100",
"chargeId" : "226",
"dateFormat" : "dd MMMM yyyy",
"dueDate" : "01 September 2015",
"locale" : "en"
}
</code>
<code class="method-response">
@@ -35999,8 +35862,13 @@ Request Body:
Integer <span>Mandatory</span>, defaults to 200
</dd>
<dd>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</dd>
</dl>
</dl>
<dt>pendingPayment</dt>
<dd>
String <span>optional</span>
</dd>
<dd>Only returns those charges which are pending payment (neither paid or waived).</dd>
</dl>
<p>Example Requests:</p>
<div class=apiClick>clients/189/charges</div>
<div class=apiClick>clients/189/charges?offset=0&limit=5</div>
@@ -36018,119 +35886,9 @@ Request Body:
{
"clientId":189
}
</code>
<code class="method-response">
{
"id": 151,
"clientId": 182,
"chargeId": 228,
"name": "Charge_client_1WA4XRZ1",
"chargeTimeType": {
"id": 2,
"code": "chargeTimeType.specifiedDueDate",
"value": "Specified due date"
},
"dueDate": [
2011,
10,
29
],
"chargeCalculationType": {
"id": 1,
"code": "chargeCalculationType.flat",
"value": "Flat"
},
"currency": {
"code": "USD",
"name": "US Dollar",
"decimalPlaces": 2,
"displaySymbol": "$",
"nameCode": "currency.USD",
"displayLabel": "US Dollar ($)"
},
"amount": 200,
"amountPaid": 183,
"amountWaived": 0,
"amountWrittenOff": 0,
"amountOutstanding": 17,
"penalty": false,
"isActive": true,
"isPaid": false
},
{
"id": 160,
"clientId": 182,
"chargeId": 239,
"name": "Charge_client_09UC3HYL",
"chargeTimeType": {
"id": 2,
"code": "chargeTimeType.specifiedDueDate",
"value": "Specified due date"
},
"dueDate": [
2015,
8,
14
],
"chargeCalculationType": {
"id": 1,
"code": "chargeCalculationType.flat",
"value": "Flat"
},
"currency": {
"code": "USD",
"name": "US Dollar",
"decimalPlaces": 2,
"displaySymbol": "$",
"nameCode": "currency.USD",
"displayLabel": "US Dollar ($)"
},
"amount": 100,
"amountPaid": 0,
"amountWaived": 0,
"amountWrittenOff": 0,
"amountOutstanding": 100,
"penalty": false,
"isActive": true,
"isPaid": false
},
{
"id": 163,
"clientId": 182,
"chargeId": 161,
"name": "Charge_client_12J3LSPO",
"chargeTimeType": {
"id": 2,
"code": "chargeTimeType.specifiedDueDate",
"value": "Specified due date"
},
"dueDate": [
2015,
9,
1
],
"chargeCalculationType": {
"id": 1,
"code": "chargeCalculationType.flat",
"value": "Flat"
},
"currency": {
"code": "USD",
"name": "US Dollar",
"decimalPlaces": 2,
"displaySymbol": "$",
"nameCode": "currency.USD",
"displayLabel": "US Dollar ($)"
},
"amount": 100,
"amountPaid": 0,
"amountWaived": 0,
"amountWrittenOff": 0,
"amountOutstanding": 100,
"penalty": false,
"isActive": true,
"isPaid": false
}
</code>
<code class="method-response">
</code>
</div>
</div>
@@ -36141,23 +35899,14 @@ Request Body:
<div class="method-description">
<h4>Delete Client Charge</h4>
<p>
<br>A client can be associated with more than one client charge and this API enables to delete a charge from client.
</p>
<table class=matrixHeading>
<tr class="matrixHeadingBG">
<td><div class="mifosXHeading2">Mandatory Fields</div></td>
</tr>
<tr class=alt>
<td>chargeId
</td>
</tr>
</table>
Deletes a Client Charge on which no transactions have taken place (either payments or waivers). </p>
</div>
<div class="method-example">
<code class="method-declaration">
DELETE https://localhost:8443/mifosng-provider/api/v1/clients/189/charges?command=delete
POST clients/189/charges/164?command=delete
DELETE https://localhost:8443/mifosng-provider/api/v1/clients/{clientId}/charges/{chargeId}
</code>
<code class="method-request">
POST clients/189/charges/164
Content-Type: application/json
No Request Body
</code>
@@ -36178,7 +35927,7 @@ No Request Body
<div class="method-description">
<h4>Pay Client Charge</h4>
<p>
<br>Total or Some amount of the client charge can be paid by specifying transaction date and which should not be below or above the specifed due date.
<br>Pay either a part of or the entire due amount for a charge.
</p>
<table class=matrixHeading>
<tr class="matrixHeadingBG">
@@ -36194,10 +35943,10 @@ No Request Body
</div>
<div class="method-example">
<code class="method-declaration">
POST https://localhost:8443/mifosng-provider/api/v1/clients/189/charges/157?command=paycharge
POST https://localhost:8443/mifosng-provider/api/v1/clients/{clientId}/charges/{chargeId}?command=paycharge
</code>
<code class="method-request">
POST clients/189/charges/157?command=paycharge
POST clients/189/charges/157?command=payCharge
Content-Type: application/json
Request Body:
{
@@ -36206,7 +35955,6 @@ Request Body:
"locale":"en",
"dateFormat":"dd MMMM yyyy",
"transactionDate":"01 September 2015"
}
</code>
<code class="method-response">
@@ -36225,38 +35973,24 @@ Request Body:
<div class="method-description">
<h4>Waive Client Charge</h4>
<p>
<br>This API provieds the facility of waiving off the client charge of a client.
<br>This API provides the facility of waiving off the remaining amount on a client charge
</p>
<table class=matrixHeading>
<tr class="matrixHeadingBG">
<td><div class="mifosXHeading2">Mandatory Fields</div></td>
</tr>
<tr class=alt>
<td>clientId and chargeId
</td>
</tr>
</table>
<br />
</div>
<div class="method-example">
<code class="method-declaration">
POST https://localhost:8443/mifosng-provider/api/v1/clients/189/charges/157?command=waive
POST https://localhost:8443/mifosng-provider/api/v1/clients/{clientId}/charges/{chargeId}?command=waive
</code>
<code class="method-request">
POST clients/189/charges/157?command=waive
Content-Type: application/json
Request Body:
{
"clientId"="189"
"resourceType"="164"
}
No Request Body
</code>
<code class="method-response">
{
"clientId":"189",
"resourceType":"164"
"resourceId":157
}
</code>
</div>
@@ -36265,120 +35999,28 @@ Request Body:
<a id="revert_clientCharge" name="revert_clientCharge" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Revert Client Charge Transaction</h4>
<p>
<br>This API exists to revert the client transactions which have got created after paying the client charge
<br>or after waiving off the client charge.
</p>
<table class=matrixHeading>
<tr class="matrixHeadingBG">
<td><div class="mifosXHeading2">Mandatory Fields</div></td>
</tr>
<tr class=alt>
<td>clientId ,chargeId and transactionId
</td>
</tr>
</table>
<br />
<h4>Undo Client Transaction</h4>
</div>
<div class="method-example">
<code class="method-declaration">
POST https://localhost:8443/mifosng-provider/api/v1/clients/189/charges/157?command=undo
POST https://localhost:8443/mifosng-provider/api/v1/clients/{clientId}/transactions/{transactionId?command=undo
</code>
<code class="method-request">
POST clients/189/transactions/222
POST clients/189/transactions/222?command=undo
Content-Type: application/json
Request Body:
{
clientId="189"
transactionId=222
}
</code>
<code class="method-response">
No Request Body
</code>
<code class="method-response">
{
"officeId":1,
"clientId":189,
"resourceId":222
}
GET https://localhost:8443/mifosng-provider/api/v1/clients/189/charges/164?associations=all
Content-Type: application/json
Resonse Body:
{
"id": 164,
"clientId": 189,
"chargeId": 226,
"name": "Charge_client_0RC9TLF4",
"chargeTimeType": {
"id": 2,
"code": "chargeTimeType.specifiedDueDate",
"value": "Specified due date"
},
"dueDate": [
2015,
9,
1
],
"chargeCalculationType": {
"id": 1,
"code": "chargeCalculationType.flat",
"value": "Flat"
},
"currency": {
"code": "USD",
"name": "US Dollar",
"decimalPlaces": 2,
"displaySymbol": "$",
"nameCode": "currency.USD",
"displayLabel": "US Dollar ($)"
},
"amount": 100,
"amountPaid": 0,
"amountWaived": 0,
"amountWrittenOff": 0,
"amountOutstanding": 100,
"penalty": false,
"isActive": true,
"isPaid": false,
"clientTransactionDatas": [
{
"id": 222,
"officeId": 1,
"officeName": "Head Office",
"type": {
"id": 2,
"code": "clientTransactionType.waiveCharge",
"value": "WAIVE_CHARGE"
},
"date": [
2015,
9,
1
],
"currency": {
"code": "USD",
"name": "US Dollar",
"decimalPlaces": 2,
"displaySymbol": "$",
"nameCode": "currency.USD",
"displayLabel": "US Dollar ($)"
},
"amount": 100,
"submittedOnDate": [
2015,
9,
1
],
"reversed": true
}
]
}
</code>
</div>
</div>
<!-- End of Client Transactions -->
<a id="resources_deletetemplate" name="resources_deletetemplate"
class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
@@ -62,9 +62,9 @@ import com.google.gson.JsonObject;
public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
private final static Logger logger = LoggerFactory.getLogger(AuditReadPlatformServiceImpl.class);
private final static Set<String> supportedOrderByValues = new HashSet<>(Arrays.asList("id", "actionName", "entityName", "resourceId",
"subresourceId", "madeOnDate", "checkedOnDate", "officeName", "groupName", "clientName", "loanAccountNo", "savingsAccountNo",
"clientId", "loanId"));
private final static Set<String> supportedOrderByValues = new HashSet<>(
Arrays.asList("id", "actionName", "entityName", "resourceId", "subresourceId", "madeOnDate", "checkedOnDate", "officeName",
"groupName", "clientName", "loanAccountNo", "savingsAccountNo", "clientId", "loanId"));
private final JdbcTemplate jdbcTemplate;
private final PlatformSecurityContext context;
@@ -250,8 +250,7 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
if (isLimitedChecker) {
sql += " join m_permission p on REPLACE(p.action_name, '_CHECKER', '') = aud.action_name and p.entity_name = aud.entity_name and p.code like '%\\_CHECKER'"
+ " join m_role_permission rp on rp.permission_id = p.id"
+ " join m_role r on r.id = rp.role_id "
+ " join m_role_permission rp on rp.permission_id = p.id" + " join m_role r on r.id = rp.role_id "
+ " join m_appuser_role ur on ur.role_id = r.id and ur.appuser_id = " + currentUser.getId();
}
sql += extraCriteria;
@@ -328,12 +327,12 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
final SavingsProductData savingProduct = this.savingsProductReadPlatformService.retrieveOne(productId);
commandAsJsonMap.put("productName", savingProduct.getName());
} else if (auditResult.getEntityName().equalsIgnoreCase("RECURRINGDEPOSITACCOUNT")) {
final DepositProductData depositProduct = this.depositProductReadPlatformService.retrieveOne(
DepositAccountType.RECURRING_DEPOSIT, productId);
final DepositProductData depositProduct = this.depositProductReadPlatformService
.retrieveOne(DepositAccountType.RECURRING_DEPOSIT, productId);
commandAsJsonMap.put("productName", depositProduct.getName());
} else if (auditResult.getEntityName().equalsIgnoreCase("FIXEDDEPOSITACCOUNT")) {
final DepositProductData depositProduct = this.depositProductReadPlatformService.retrieveOne(
DepositAccountType.FIXED_DEPOSIT, productId);
final DepositProductData depositProduct = this.depositProductReadPlatformService
.retrieveOne(DepositAccountType.FIXED_DEPOSIT, productId);
commandAsJsonMap.put("productName", depositProduct.getName());
} else {
commandAsJsonMap.put("productName", "");
@@ -386,11 +385,9 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
commandAsJsonMap.remove(typeName);
final Integer enumTypeId = auditObject.get(typeName).getAsInt();
if (enumTypeId != null) {
final String code = LoanEnumerations.loanEnumueration(typeName, enumTypeId).getValue();
if (code != null) {
commandAsJsonMap.put(typeName, code);
}
final String code = LoanEnumerations.loanEnumueration(typeName, enumTypeId).getValue();
if (code != null) {
commandAsJsonMap.put(typeName, code);
}
}
}
@@ -409,18 +406,17 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
commandAsJsonMap.remove(typeName);
final Integer enumTypeId = auditObject.get(typeName).getAsInt();
if (enumTypeId != null) {
final String code = SavingsEnumerations.savingEnumueration(typeName, enumTypeId).getValue();
if (code != null) {
commandAsJsonMap.put(typeName, code);
}
final String code = SavingsEnumerations.savingEnumueration(typeName, enumTypeId).getValue();
if (code != null) {
commandAsJsonMap.put(typeName, code);
}
}
}
}
}
private void replaceStaffIdWithStaffName(final String staffIdStr, final String staffNameParamName, Map<String, Object> commandAsJsonMap) {
private void replaceStaffIdWithStaffName(final String staffIdStr, final String staffNameParamName,
Map<String, Object> commandAsJsonMap) {
Long staffId = null;
if (StringUtils.isNotBlank(staffIdStr)) {
@@ -20,16 +20,13 @@ import javax.ws.rs.core.UriInfo;
import org.mifosplatform.commands.domain.CommandWrapper;
import org.mifosplatform.commands.service.CommandWrapperBuilder;
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
import org.mifosplatform.infrastructure.configuration.data.ExternalServicesData;
import org.mifosplatform.infrastructure.configuration.data.ExternalServicesPropertiesData;
import org.mifosplatform.infrastructure.configuration.service.ExternalServicesPropertiesReadPlatformService;
import org.mifosplatform.infrastructure.configuration.service.ExternalServicesReadPlatformService;
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -41,7 +38,6 @@ public class ExternalServicesConfigurationApiResource {
private final PlatformSecurityContext context;
private final ExternalServicesPropertiesReadPlatformService externalServicePropertiesReadPlatformService;
private final ExternalServicesReadPlatformService externalServiceReadPlatformService;
private final ToApiJsonSerializer<ExternalServicesPropertiesData> toApiJsonSerializer;
// private final ToApiJsonSerializer<S3CredentialsData>
// s3ToApiJsonSerializer;
@@ -51,14 +47,12 @@ public class ExternalServicesConfigurationApiResource {
@Autowired
public ExternalServicesConfigurationApiResource(final PlatformSecurityContext context,
final ExternalServicesPropertiesReadPlatformService readPlatformService,
final ExternalServicesReadPlatformService externalServicesReadPlatformService,
final ToApiJsonSerializer<ExternalServicesPropertiesData> toApiJsonSerializer,
final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
this.context = context;
this.externalServicePropertiesReadPlatformService = readPlatformService;
this.toApiJsonSerializer = toApiJsonSerializer;
this.externalServiceReadPlatformService = externalServicesReadPlatformService;
// this.s3ToApiJsonSerializer = s3ToApiJsonSerializer;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
@@ -180,6 +180,7 @@ public class ConfigurationDomainServiceJpa implements ConfigurationDomainService
return property.isEnabled();
}
@Override
public int getRoundingMode() {
final String propertyName = "rounding-mode";
int defaultValue = 6; // 6 Stands for HALF-EVEN
@@ -1,11 +1,5 @@
package org.mifosplatform.infrastructure.configuration.domain;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import javax.persistence.CascadeType;
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
@@ -14,12 +8,9 @@ import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.springframework.data.jpa.domain.AbstractPersistable;
@@ -9,10 +9,6 @@ import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import org.springframework.data.annotation.Id;
@Embeddable
public class ExternalServicePropertiesPK implements Serializable {
@@ -9,12 +9,8 @@ import java.util.LinkedHashMap;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Embedded;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.apache.commons.lang.StringUtils;
@@ -22,7 +18,6 @@ import org.mifosplatform.infrastructure.configuration.data.ExternalServicesPrope
import org.mifosplatform.infrastructure.configuration.service.ExternalServicesConstants.EXTERNALSERVICEPROPERTIES_JSON_INPUT_PARAMS;
import org.mifosplatform.infrastructure.configuration.service.ExternalServicesConstants.SMTP_JSON_INPUT_PARAMS;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.springframework.data.annotation.Id;
@Entity
@Table(name = "c_external_service_properties")
@@ -13,7 +13,6 @@ import javax.persistence.Entity;
import javax.persistence.Table;
import org.mifosplatform.infrastructure.configuration.exception.GlobalConfigurationPropertyCannotBeModfied;
import org.mifosplatform.infrastructure.configuration.exception.GlobalConfigurationPropertyNotFoundException;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.security.exception.ForcePasswordResetException;
import org.springframework.data.jpa.domain.AbstractPersistable;
@@ -6,7 +6,6 @@
package org.mifosplatform.infrastructure.configuration.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
public class GlobalConfigurationPropertyCannotBeModfied extends AbstractPlatformDomainRuleException{
@@ -6,31 +6,23 @@
package org.mifosplatform.infrastructure.configuration.serialization;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.infrastructure.configuration.exception.ExternalServiceConfigurationNotFoundException;
import org.mifosplatform.infrastructure.configuration.service.ExternalServicesConstants;
import org.mifosplatform.infrastructure.configuration.service.ExternalServicesConstants.EXTERNALSERVICEPROPERTIES_JSON_INPUT_PARAMS;
import org.mifosplatform.infrastructure.configuration.service.ExternalServicesConstants.S3_JSON_INPUT_PARAMS;
import org.mifosplatform.infrastructure.configuration.service.ExternalServicesConstants.SMTP_JSON_INPUT_PARAMS;
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.FromJsonHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.google.gson.JsonElement;
import com.google.gson.reflect.TypeToken;
@Component
public class ExternalServicesPropertiesCommandFromApiJsonDeserializer {
private final Set<String> supportedParameters = EXTERNALSERVICEPROPERTIES_JSON_INPUT_PARAMS.getAllValues();
private final Set<String> S3SupportedParameters = S3_JSON_INPUT_PARAMS.getAllValues();
private final Set<String> SMTPSupportedParameters = SMTP_JSON_INPUT_PARAMS.getAllValues();
private final FromJsonHelper fromApiJsonHelper;
@@ -57,10 +49,6 @@ public class ExternalServicesPropertiesCommandFromApiJsonDeserializer {
throw new ExternalServiceConfigurationNotFoundException(externalServiceName);
}
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("external.service");
final JsonElement element = this.fromApiJsonHelper.parse(json);
}
public Set<String> getNameKeys(final String json) {
@@ -28,6 +28,7 @@ import org.springframework.transaction.annotation.Transactional;
@Service
public class ExternalServiceWritePlatformServiceJpaRepositoryImpl implements ExternalServiceWritePlatformService {
@SuppressWarnings("unused")
private final static Logger logger = LoggerFactory.getLogger(ExternalServiceWritePlatformServiceJpaRepositoryImpl.class);
private final PlatformSecurityContext context;
@@ -8,8 +8,6 @@ package org.mifosplatform.infrastructure.configuration.service;
import java.util.HashSet;
import java.util.Set;
import org.mifosplatform.infrastructure.codes.CodeConstants.CODEVALUE_JSON_INPUT_PARAMS;
public class ExternalServicesConstants {
public static final String S3_SERVICE_NAME = "S3";
@@ -14,7 +14,6 @@ import org.mifosplatform.infrastructure.configuration.data.S3CredentialsData;
import org.mifosplatform.infrastructure.configuration.data.SMTPCredentialsData;
import org.mifosplatform.infrastructure.configuration.exception.ExternalServiceConfigurationNotFoundException;
import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
import org.mifosplatform.infrastructure.documentmanagement.data.DocumentData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
@@ -82,7 +81,7 @@ public class ExternalServicesPropertiesReadPlatformServiceImpl implements Extern
private static final class ExternalServiceMapper implements RowMapper<ExternalServicesPropertiesData> {
@Override
public ExternalServicesPropertiesData mapRow(ResultSet rs, int rowNum) throws SQLException {
public ExternalServicesPropertiesData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException {
// TODO Auto-generated method stub
final String name = rs.getString("name");
String value = rs.getString("value");
@@ -114,6 +113,7 @@ public class ExternalServicesPropertiesReadPlatformServiceImpl implements Extern
return smtpCredentialsData;
}
@Override
public Collection<ExternalServicesPropertiesData> retrieveOne(String serviceName) {
String serviceNameToUse = null;
switch (serviceName) {
@@ -9,7 +9,6 @@ import org.apache.commons.mail.DefaultAuthenticator;
import org.apache.commons.mail.Email;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.SimpleEmail;
import org.mifosplatform.infrastructure.configuration.data.S3CredentialsData;
import org.mifosplatform.infrastructure.configuration.data.SMTPCredentialsData;
import org.mifosplatform.infrastructure.configuration.service.ExternalServicesPropertiesReadPlatformService;
import org.mifosplatform.infrastructure.core.domain.EmailDetail;
@@ -254,16 +254,18 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
final Throwable realCause = cve.getCause();
// even if duplicate is only due to permission duplicate, okay to
// show duplicate datatable error msg
if (realCause.getMessage().contains("Duplicate entry")) { throw new PlatformDataIntegrityException(
"error.msg.datatable.registered", "Datatable `" + dataTableName
+ "` is already registered against an application table.", "dataTableName", dataTableName); }
if (realCause.getMessage()
.contains("Duplicate entry")) { throw new PlatformDataIntegrityException("error.msg.datatable.registered",
"Datatable `" + dataTableName + "` is already registered against an application table.", "dataTableName",
dataTableName); }
} catch (final DataIntegrityViolationException dve) {
final Throwable realCause = dve.getMostSpecificCause();
// even if duplicate is only due to permission duplicate, okay to
// show duplicate datatable error msg
if (realCause.getMessage().contains("Duplicate entry")) { throw new PlatformDataIntegrityException(
"error.msg.datatable.registered", "Datatable `" + dataTableName
+ "` is already registered against an application table.", "dataTableName", dataTableName); }
if (realCause.getMessage()
.contains("Duplicate entry")) { throw new PlatformDataIntegrityException("error.msg.datatable.registered",
"Datatable `" + dataTableName + "` is already registered against an application table.", "dataTableName",
dataTableName); }
logAsErrorUnexpectedDataIntegrityException(dve);
throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue",
"Unknown data integrity issue with resource.");
@@ -363,18 +365,22 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
// org.hibernate.exception.ConstraintViolationException even though
// it should be a DataAccessException?
final Throwable realCause = dve.getCause();
if (realCause.getMessage().contains("Duplicate entry")) { throw new PlatformDataIntegrityException(
"error.msg.datatable.entry.duplicate", "An entry already exists for datatable `" + dataTableName
+ "` and application table with identifier `" + appTableId + "`.", "dataTableName", dataTableName, appTableId); }
if (realCause.getMessage()
.contains("Duplicate entry")) { throw new PlatformDataIntegrityException(
"error.msg.datatable.entry.duplicate", "An entry already exists for datatable `" + dataTableName
+ "` and application table with identifier `" + appTableId + "`.",
"dataTableName", dataTableName, appTableId); }
logAsErrorUnexpectedDataIntegrityException(dve);
throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue",
"Unknown data integrity issue with resource.");
} catch (final DataAccessException dve) {
final Throwable realCause = dve.getMostSpecificCause();
if (realCause.getMessage().contains("Duplicate entry")) { throw new PlatformDataIntegrityException(
"error.msg.datatable.entry.duplicate", "An entry already exists for datatable `" + dataTableName
+ "` and application table with identifier `" + appTableId + "`.", "dataTableName", dataTableName, appTableId); }
if (realCause.getMessage()
.contains("Duplicate entry")) { throw new PlatformDataIntegrityException(
"error.msg.datatable.entry.duplicate", "An entry already exists for datatable `" + dataTableName
+ "` and application table with identifier `" + appTableId + "`.",
"dataTableName", dataTableName, appTableId); }
logAsErrorUnexpectedDataIntegrityException(dve);
throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue",
@@ -405,18 +411,22 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
// org.hibernate.exception.ConstraintViolationException even though
// it should be a DataAccessException?
final Throwable realCause = dve.getCause();
if (realCause.getMessage().contains("Duplicate entry")) { throw new PlatformDataIntegrityException(
"error.msg.datatable.entry.duplicate", "An entry already exists for datatable `" + dataTableName
+ "` and application table with identifier `" + appTableId + "`.", "dataTableName", dataTableName, appTableId); }
if (realCause.getMessage()
.contains("Duplicate entry")) { throw new PlatformDataIntegrityException(
"error.msg.datatable.entry.duplicate", "An entry already exists for datatable `" + dataTableName
+ "` and application table with identifier `" + appTableId + "`.",
"dataTableName", dataTableName, appTableId); }
logAsErrorUnexpectedDataIntegrityException(dve);
throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue",
"Unknown data integrity issue with resource.");
} catch (final DataAccessException dve) {
final Throwable realCause = dve.getMostSpecificCause();
if (realCause.getMessage().contains("Duplicate entry")) { throw new PlatformDataIntegrityException(
"error.msg.datatable.entry.duplicate", "An entry already exists for datatable `" + dataTableName
+ "` and application table with identifier `" + appTableId + "`.", "dataTableName", dataTableName, appTableId); }
if (realCause.getMessage()
.contains("Duplicate entry")) { throw new PlatformDataIntegrityException(
"error.msg.datatable.entry.duplicate", "An entry already exists for datatable `" + dataTableName
+ "` and application table with identifier `" + appTableId + "`.",
"dataTableName", dataTableName, appTableId); }
logAsErrorUnexpectedDataIntegrityException(dve);
throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue",
@@ -435,8 +445,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
final String sql = "select if((exists (select 1 from information_schema.tables where table_schema = schema() and table_name = ?)) = 1, 'true', 'false')";
final String dataTableExistsString = this.jdbcTemplate.queryForObject(sql, String.class, new Object[] { datatableName });
final boolean dataTableExists = new Boolean(dataTableExistsString);
if (!dataTableExists) { throw new PlatformDataIntegrityException("error.msg.invalid.datatable", "Invalid Data Table: "
+ datatableName, "name", datatableName); }
if (!dataTableExists) { throw new PlatformDataIntegrityException("error.msg.invalid.datatable",
"Invalid Data Table: " + datatableName, "name", datatableName); }
}
private void validateDatatableName(final String name) {
@@ -489,12 +499,11 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
sqlBuilder = sqlBuilder.append("(11)");
}
}
if (mandatory != null) {
if (mandatory) {
sqlBuilder = sqlBuilder.append(" NOT NULL");
} else {
sqlBuilder = sqlBuilder.append(" DEFAULT NULL");
}
if (mandatory) {
sqlBuilder = sqlBuilder.append(" NOT NULL");
} else {
sqlBuilder = sqlBuilder.append(" DEFAULT NULL");
}
sqlBuilder = sqlBuilder.append(", ");
@@ -541,8 +550,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
sqlBuilder = sqlBuilder.append("CREATE TABLE `" + datatableName + "` (");
if (multiRow) {
sqlBuilder = sqlBuilder.append("`id` BIGINT(20) NOT NULL AUTO_INCREMENT, ").append(
"`" + fkColumnName + "` BIGINT(20) NOT NULL, ");
sqlBuilder = sqlBuilder.append("`id` BIGINT(20) NOT NULL AUTO_INCREMENT, ")
.append("`" + fkColumnName + "` BIGINT(20) NOT NULL, ");
} else {
sqlBuilder = sqlBuilder.append("`" + fkColumnName + "` BIGINT(20) NOT NULL, ");
}
@@ -618,8 +627,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
removeMappings.add(dataTableNameAlias + "_" + name);
constrainBuilder.append(", DROP FOREIGN KEY `fk_").append(dataTableNameAlias).append("_").append(name).append("` ");
codeMappings.put(dataTableNameAlias + "_" + newName, (long) codeId);
constrainBuilder.append(",ADD CONSTRAINT `fk_").append(dataTableNameAlias).append("_").append(newName)
.append("` ").append("FOREIGN KEY (`" + newName + "`) ").append("REFERENCES `").append(CODE_VALUES_TABLE)
constrainBuilder.append(",ADD CONSTRAINT `fk_").append(dataTableNameAlias).append("_").append(newName).append("` ")
.append("FOREIGN KEY (`" + newName + "`) ").append("REFERENCES `").append(CODE_VALUES_TABLE)
.append("` (`id`)");
}
@@ -667,13 +676,12 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
}
}
if (mandatory != null) {
if (mandatory) {
sqlBuilder = sqlBuilder.append(" NOT NULL");
} else {
sqlBuilder = sqlBuilder.append(" DEFAULT NULL");
}
if (mandatory) {
sqlBuilder = sqlBuilder.append(" NOT NULL");
} else {
sqlBuilder = sqlBuilder.append(" DEFAULT NULL");
}
if (after != null) {
sqlBuilder = sqlBuilder.append(" AFTER `" + after + "`");
}
@@ -725,13 +733,13 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
sqlBuilder = sqlBuilder.append("(11)");
}
}
if (mandatory != null) {
if (mandatory) {
sqlBuilder = sqlBuilder.append(" NOT NULL");
} else {
sqlBuilder = sqlBuilder.append(" DEFAULT NULL");
}
if (mandatory) {
sqlBuilder = sqlBuilder.append(" NOT NULL");
} else {
sqlBuilder = sqlBuilder.append(" DEFAULT NULL");
}
if (after != null) {
sqlBuilder = sqlBuilder.append(" AFTER `" + after + "`");
}
@@ -938,8 +946,10 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
// "invalid use of null value" SQL exception message
// throw a 503 HTTP error -
// PlatformServiceUnavailableException
if (e.getMessage().toLowerCase().contains("invalid use of null value")) { throw new PlatformServiceUnavailableException(
"error.msg.datatable.column.update.not.allowed", "One of the data table columns contains null values"); }
if (e.getMessage().toLowerCase()
.contains("invalid use of null value")) { throw new PlatformServiceUnavailableException(
"error.msg.datatable.column.update.not.allowed",
"One of the data table columns contains null values"); }
}
}
} catch (final SQLGrammarException e) {
@@ -996,14 +1006,14 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
private void assertDataTableEmpty(final String datatableName) {
final String sql = "select count(*) from `" + datatableName + "`";
final int rowCount = this.jdbcTemplate.queryForObject(sql, Integer.class);
if (rowCount != 0) {
throw new GeneralPlatformDomainRuleException("error.msg.non.empty.datatable.cannot.be.deleted", "Non-empty datatable cannot be deleted.");
}
if (rowCount != 0) { throw new GeneralPlatformDomainRuleException("error.msg.non.empty.datatable.cannot.be.deleted",
"Non-empty datatable cannot be deleted."); }
}
@Transactional
@Override
public CommandProcessingResult updateDatatableEntryOneToOne(final String dataTableName, final Long appTableId, final JsonCommand command) {
public CommandProcessingResult updateDatatableEntryOneToOne(final String dataTableName, final Long appTableId,
final JsonCommand command) {
return updateDatatableEntry(dataTableName, appTableId, null, command);
}
@@ -1194,14 +1204,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
if (appTable.equalsIgnoreCase("m_loan")) {
scopedSQL = "select distinctrow x.* from ("
+ " (select o.id as officeId, l.group_id as groupId, l.client_id as clientId, null as savingsId, l.id as loanId, null as entityId from m_loan l "
+ " join m_client c on c.id = l.client_id "
+ " join m_office o on o.id = c.office_id and o.hierarchy like '"
+ currentUser.getOffice().getHierarchy()
+ "%'"
+ " where l.id = "
+ appTableId
+ ")"
+ " union all "
+ " join m_client c on c.id = l.client_id " + " join m_office o on o.id = c.office_id and o.hierarchy like '"
+ currentUser.getOffice().getHierarchy() + "%'" + " where l.id = " + appTableId + ")" + " union all "
+ " (select o.id as officeId, l.group_id as groupId, l.client_id as clientId, null as savingsId, l.id as loanId, null as entityId from m_loan l "
+ " join m_group g on g.id = l.group_id " + " join m_office o on o.id = g.office_id and o.hierarchy like '"
+ currentUser.getOffice().getHierarchy() + "%'" + " where l.id = " + appTableId + ")" + " ) x";
@@ -1209,30 +1213,20 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
if (appTable.equalsIgnoreCase("m_savings_account")) {
scopedSQL = "select distinctrow x.* from ("
+ " (select o.id as officeId, s.group_id as groupId, s.client_id as clientId, s.id as savingsId, null as loanId, null as entityId from m_savings_account s "
+ " join m_client c on c.id = s.client_id "
+ " join m_office o on o.id = c.office_id and o.hierarchy like '"
+ currentUser.getOffice().getHierarchy()
+ "%'"
+ " where s.id = "
+ appTableId
+ ")"
+ " union all "
+ " join m_client c on c.id = s.client_id " + " join m_office o on o.id = c.office_id and o.hierarchy like '"
+ currentUser.getOffice().getHierarchy() + "%'" + " where s.id = " + appTableId + ")" + " union all "
+ " (select o.id as officeId, s.group_id as groupId, s.client_id as clientId, s.id as savingsId, null as loanId, null as entityId from m_savings_account s "
+ " join m_group g on g.id = s.group_id " + " join m_office o on o.id = g.office_id and o.hierarchy like '"
+ currentUser.getOffice().getHierarchy() + "%'" + " where s.id = " + appTableId + ")" + " ) x";
}
if (appTable.equalsIgnoreCase("m_client")) {
scopedSQL = "select o.id as officeId, null as groupId, c.id as clientId, null as savingsId, null as loanId, null as entityId from m_client c "
+ " join m_office o on o.id = c.office_id and o.hierarchy like '"
+ currentUser.getOffice().getHierarchy()
+ "%'"
+ " join m_office o on o.id = c.office_id and o.hierarchy like '" + currentUser.getOffice().getHierarchy() + "%'"
+ " where c.id = " + appTableId;
}
if (appTable.equalsIgnoreCase("m_group") || appTable.equalsIgnoreCase("m_center")) {
scopedSQL = "select o.id as officeId, g.id as groupId, null as clientId, null as savingsId, null as loanId, null as entityId from m_group g "
+ " join m_office o on o.id = g.office_id and o.hierarchy like '"
+ currentUser.getOffice().getHierarchy()
+ "%'"
+ " join m_office o on o.id = g.office_id and o.hierarchy like '" + currentUser.getOffice().getHierarchy() + "%'"
+ " where g.id = " + appTableId;
}
if (appTable.equalsIgnoreCase("m_office")) {
@@ -1245,8 +1239,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
+ appTable + " as p WHERE p.id = " + appTableId;
}
if (scopedSQL == null) { throw new PlatformDataIntegrityException("error.msg.invalid.dataScopeCriteria", "Application Table: "
+ appTable + " not catered for in data Scoping"); }
if (scopedSQL == null) { throw new PlatformDataIntegrityException("error.msg.invalid.dataScopeCriteria",
"Application Table: " + appTable + " not catered for in data Scoping"); }
return scopedSQL;
@@ -1513,8 +1507,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
// ignores id and foreign key fields
// also ignores locale and dateformat fields that are used for
// validating numeric and date data
if (!((key.equalsIgnoreCase("id")) || (key.equalsIgnoreCase(keyFieldName)) || (key.equals("locale")) || (key
.equals("dateFormat")))) {
if (!((key.equalsIgnoreCase("id")) || (key.equalsIgnoreCase(keyFieldName)) || (key.equals("locale"))
|| (key.equals("dateFormat")))) {
notFound = true;
// matches incoming fields with and without underscores (spaces
// and underscores considered the same)
@@ -1601,8 +1595,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
paramValue = tmpDate.toString();
}
} else if (columnHeader.isDateTimeDisplayType()) {
final LocalDateTime tmpDateTime = JsonParserHelper.convertDateTimeFrom(paramValue, columnHeader.getColumnName(),
dateFormat, clientApplicationLocale);
final LocalDateTime tmpDateTime = JsonParserHelper.convertDateTimeFrom(paramValue, columnHeader.getColumnName(), dateFormat,
clientApplicationLocale);
if (tmpDateTime == null) {
paramValue = null;
} else {
@@ -1626,9 +1620,11 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
final Boolean tmpBoolean = BooleanUtils.toBooleanObject(paramValue);
if (tmpBoolean == null) {
final ApiParameterError error = ApiParameterError.parameterError("validation.msg.invalid.boolean.format",
"The parameter " + columnHeader.getColumnName() + " has value: " + paramValue
+ " which is invalid boolean value.", columnHeader.getColumnName(), paramValue);
final ApiParameterError error = ApiParameterError
.parameterError(
"validation.msg.invalid.boolean.format", "The parameter " + columnHeader.getColumnName()
+ " has value: " + paramValue + " which is invalid boolean value.",
columnHeader.getColumnName(), paramValue);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
dataValidationErrors.add(error);
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
@@ -1638,8 +1634,9 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
} else if (columnHeader.isString()) {
if (paramValue.length() > columnHeader.getColumnLength()) {
final ApiParameterError error = ApiParameterError.parameterError(
"validation.msg.datatable.entry.column.exceeds.maxlength", "The column `" + columnHeader.getColumnName()
+ "` exceeds its defined max-length ", columnHeader.getColumnName(), paramValue);
"validation.msg.datatable.entry.column.exceeds.maxlength",
"The column `" + columnHeader.getColumnName() + "` exceeds its defined max-length ",
columnHeader.getColumnName(), paramValue);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
dataValidationErrors.add(error);
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
@@ -11,9 +11,6 @@ import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@@ -10,7 +10,6 @@ import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@@ -31,88 +31,81 @@ import org.springframework.stereotype.Service;
@Service
public class MifosEntityAccessReadServiceImpl implements MifosEntityAccessReadService {
private final PlatformSecurityContext context;
private final JdbcTemplate jdbcTemplate;
private final PlatformSecurityContext context;
private final JdbcTemplate jdbcTemplate;
private final static Logger logger = LoggerFactory.getLogger(GenericDataServiceImpl.class);
@Autowired
public MifosEntityAccessReadServiceImpl(final PlatformSecurityContext context,
final RoutingDataSource dataSource) {
public MifosEntityAccessReadServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource) {
this.context = context;
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
/*
* (non-Javadoc)
* @see org.mifosplatform.infrastructure.entityaccess.service.MifosEntityAccessReadService#getSQLQueryWithListOfIDsForEntityAccess
* (Long,
* org.mifosplatform.infrastructure.entityaccess.domain.MifosEntityType,
* org.mifosplatform.infrastructure.entityaccess.domain.MifosEntityAccessType,
* org.mifosplatform.infrastructure.entityaccess.domain.MifosEntityType,
* boolean)
*
* This method returns the list of entity IDs as a comma separated list
* Or null if there is no entity restrictions or if there
* @see org.mifosplatform.infrastructure.entityaccess.service.
* MifosEntityAccessReadService#getSQLQueryWithListOfIDsForEntityAccess
* (Long,
* org.mifosplatform.infrastructure.entityaccess.domain.MifosEntityType,
* org.mifosplatform.infrastructure.entityaccess.domain.
* MifosEntityAccessType,
* org.mifosplatform.infrastructure.entityaccess.domain.MifosEntityType,
* boolean)
*
* This method returns the list of entity IDs as a comma separated list Or
* null if there is no entity restrictions or if there
*/
@Override
public String getSQLQueryInClause_WithListOfIDsForEntityAccess (
Long firstEntityId,
MifosEntityType firstEntityType,
MifosEntityAccessType accessType,
MifosEntityType secondEntityType,
boolean includeAllOffices) {
Collection<MifosEntityAccessData> accesslist = retrieveEntityAccessFor (
firstEntityId, firstEntityType, accessType, secondEntityType, includeAllOffices);
public String getSQLQueryInClause_WithListOfIDsForEntityAccess(Long firstEntityId, MifosEntityType firstEntityType,
MifosEntityAccessType accessType, MifosEntityType secondEntityType, boolean includeAllOffices) {
Collection<MifosEntityAccessData> accesslist = retrieveEntityAccessFor(firstEntityId, firstEntityType, accessType, secondEntityType,
includeAllOffices);
String returnIdListStr = null;
StringBuffer accessListCSVStrBuf = null;
if ( (accesslist != null) && (accesslist.size() > 0) ) {
logger.debug("Found " + accesslist.size() +
" access type restrictions while getting entity access configuration for " +
firstEntityType.getType() + ":" + firstEntityId +
" with type " + accessType.toStr() + " against " + secondEntityType.getType()
);
accessListCSVStrBuf = new StringBuffer (" ");
for (int i = 0; i < accesslist.size(); i++) {
MifosEntityAccessData accessData = (MifosEntityAccessData) accesslist.toArray()[i];
if (accessData == null) {
throw new MifosEntityAccessConfigurationException(firstEntityId, firstEntityType,
accessType, secondEntityType);
}
if (accessData.getSecondEntity().getId() == 0) { // If there is any ID that zero, then allow access to all
accessListCSVStrBuf = null;
break;
}
if (i>0) {
accessListCSVStrBuf.append(',');
}
accessListCSVStrBuf.append(accessData.getSecondEntity().getId());
if ((accesslist != null) && (accesslist.size() > 0)) {
logger.debug("Found " + accesslist.size() + " access type restrictions while getting entity access configuration for "
+ firstEntityType.getType() + ":" + firstEntityId + " with type " + accessType.toStr() + " against "
+ secondEntityType.getType());
accessListCSVStrBuf = new StringBuffer(" ");
for (int i = 0; i < accesslist.size(); i++) {
MifosEntityAccessData accessData = (MifosEntityAccessData) accesslist.toArray()[i];
if (accessData == null) { throw new MifosEntityAccessConfigurationException(firstEntityId, firstEntityType, accessType,
secondEntityType); }
if (accessData.getSecondEntity().getId() == 0) { // If there is
// any ID that
// zero, then
// allow access
// to all
accessListCSVStrBuf = null;
break;
}
if (i > 0) {
accessListCSVStrBuf.append(',');
}
accessListCSVStrBuf.append(accessData.getSecondEntity().getId());
}
} else {
logger.debug("Found zero access type restrictions while getting entity access configuration for " +
firstEntityType.getType() + ":" + firstEntityId +
" with type " + accessType.toStr() + " against " + secondEntityType.getType()
);
accessListCSVStrBuf = new StringBuffer();
accessListCSVStrBuf.append ("false"); // Append false so that no rows will be returned
logger.debug("Found zero access type restrictions while getting entity access configuration for " + firstEntityType.getType()
+ ":" + firstEntityId + " with type " + accessType.toStr() + " against " + secondEntityType.getType());
accessListCSVStrBuf = new StringBuffer();
accessListCSVStrBuf.append("false"); // Append false so that no rows
// will be returned
}
if (accessListCSVStrBuf != null) {
returnIdListStr = accessListCSVStrBuf.toString();
returnIdListStr = accessListCSVStrBuf.toString();
}
logger.debug("List of IDs applicable:" + returnIdListStr);
return returnIdListStr;
}
@Override
public Collection<MifosEntityAccessData> retrieveEntityAccessFor(
Long firstEntityId,
MifosEntityType firstEntityType,
MifosEntityAccessType accessType,
MifosEntityType secondEntityType,
boolean includeAllSubOffices) {
final AppUser currentUser = this.context.authenticatedUser();
@Override
public Collection<MifosEntityAccessData> retrieveEntityAccessFor(Long firstEntityId, MifosEntityType firstEntityType,
MifosEntityAccessType accessType, MifosEntityType secondEntityType, boolean includeAllSubOffices) {
final AppUser currentUser = this.context.authenticatedUser();
final String hierarchy = currentUser.getOffice().getHierarchy();
String hierarchySearchString = null;
if (includeAllSubOffices) {
@@ -120,276 +113,267 @@ public class MifosEntityAccessReadServiceImpl implements MifosEntityAccessReadSe
} else {
hierarchySearchString = hierarchy + "%";
}
String sql = getSQLForRetriveEntityAccessFor(firstEntityType,
accessType, secondEntityType);
String sql = getSQLForRetriveEntityAccessFor(firstEntityType, accessType, secondEntityType);
Collection<MifosEntityAccessData> entityAccessData = null;
MifosEntityAccessDataMapper mapper = new MifosEntityAccessDataMapper();
if (includeAllSubOffices && (firstEntityType.getTable().equals("m_office")) ) {
sql += " where firstentity.hierarchy like ? order by firstEntity.hierarchy";
entityAccessData = this.jdbcTemplate.query(sql, mapper, new Object[] { firstEntityId, hierarchySearchString });
if (includeAllSubOffices && (firstEntityType.getTable().equals("m_office"))) {
sql += " where firstentity.hierarchy like ? order by firstEntity.hierarchy";
entityAccessData = this.jdbcTemplate.query(sql, mapper, new Object[] { firstEntityId, hierarchySearchString });
} else {
entityAccessData = this.jdbcTemplate.query(sql, mapper, new Object[] { firstEntityId });
entityAccessData = this.jdbcTemplate.query(sql, mapper, new Object[] { firstEntityId });
}
return entityAccessData;
}
private String getSQLForRetriveEntityAccessFor (
MifosEntityType firstEntityType,
MifosEntityAccessType accessType,
MifosEntityType secondEntityType) {
StringBuffer str = new StringBuffer ("select eea.entity_id as entity_id, entity_type as entity_type, ");
str.append("access_type_code_value_id as access_id, cv.code_value as access_type_desc, c.code_name as code, ");
str.append("firstentity.id as first_entity_id, firstentity.name as entity_name, ");
str.append("otherentity.id as second_entity_id, otherentity.name as second_entity_name, ");
str.append("eea.second_entity_type as second_entity_type ");
str.append("from m_entity_to_entity_access eea ");
str.append("left join m_code_value cv on (cv.code_value = ");
str.append("'");
str.append(accessType.toStr());
str.append("' ");
str.append("and eea.access_type_code_value_id = cv.id) ");
str.append("left join m_code c on (c.code_name = '");
str.append(MifosEntityAccessConstants.ENTITY_ACCESS_CODENAME);
str.append("' and cv.code_id = c.id) ");
str.append("left join ");
str.append(firstEntityType.getTable());
str.append(" firstentity on (eea.entity_type = ");
str.append("'");
str.append(firstEntityType.getType());
str.append("'");
str.append(" and eea.entity_id = firstentity.id) left join ");
str.append(secondEntityType.getTable());
str.append(" otherentity on (eea.second_entity_type = ");
str.append("'");
str.append(secondEntityType.getType());
str.append("' ");
str.append("and eea.second_entity_id = otherentity.id) ");
str.append("where eea.access_type_code_value_id = cv.id ");
str.append("and eea.entity_id = ? ");
logger.debug(str.toString());
return str.toString();
}
private static final class MifosEntityAccessDataMapper implements RowMapper<MifosEntityAccessData> {
@Override
public MifosEntityAccessData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
final String entityType = rs.getString("entity_type");
}
private String getSQLForRetriveEntityAccessFor(MifosEntityType firstEntityType, MifosEntityAccessType accessType,
MifosEntityType secondEntityType) {
StringBuffer str = new StringBuffer("select eea.entity_id as entity_id, entity_type as entity_type, ");
str.append("access_type_code_value_id as access_id, cv.code_value as access_type_desc, c.code_name as code, ");
str.append("firstentity.id as first_entity_id, firstentity.name as entity_name, ");
str.append("otherentity.id as second_entity_id, otherentity.name as second_entity_name, ");
str.append("eea.second_entity_type as second_entity_type ");
str.append("from m_entity_to_entity_access eea ");
str.append("left join m_code_value cv on (cv.code_value = ");
str.append("'");
str.append(accessType.toStr());
str.append("' ");
str.append("and eea.access_type_code_value_id = cv.id) ");
str.append("left join m_code c on (c.code_name = '");
str.append(MifosEntityAccessConstants.ENTITY_ACCESS_CODENAME);
str.append("' and cv.code_id = c.id) ");
str.append("left join ");
str.append(firstEntityType.getTable());
str.append(" firstentity on (eea.entity_type = ");
str.append("'");
str.append(firstEntityType.getType());
str.append("'");
str.append(" and eea.entity_id = firstentity.id) left join ");
str.append(secondEntityType.getTable());
str.append(" otherentity on (eea.second_entity_type = ");
str.append("'");
str.append(secondEntityType.getType());
str.append("' ");
str.append("and eea.second_entity_id = otherentity.id) ");
str.append("where eea.access_type_code_value_id = cv.id ");
str.append("and eea.entity_id = ? ");
logger.debug(str.toString());
return str.toString();
}
private static final class MifosEntityAccessDataMapper implements RowMapper<MifosEntityAccessData> {
@Override
public MifosEntityAccessData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
final String entityType = rs.getString("entity_type");
final Long entityId = rs.getLong("entity_id");
final String entityName = rs.getString("entity_name");
final Long accessId = rs.getLong("access_id");
// final String entityName = rs.getString("entity_name");
// final Long accessId = rs.getLong("access_id");
final String accessTypeDesc = rs.getString("access_type_desc");
final String code = rs.getString("code");
// final String code = rs.getString("code");
final Long secondEntityId = rs.getLong("second_entity_id");
final String secondEntityName = rs.getString("second_entity_name");
// final String secondEntityName =
// rs.getString("second_entity_name");
final String secondEntityType = rs.getString("second_entity_type");
MifosEntity firstEntity = null;
MifosEntityType etype = MifosEntityType.get(entityType);
if (entityId != null && etype != null) {
if (etype != null) {
firstEntity = new MifosEntity(entityId, etype);
}
MifosEntity secondEntity = null;
MifosEntityType secondetype = MifosEntityType.get(secondEntityType);
if (entityId != null && etype != null) {
if (etype != null) {
secondEntity = new MifosEntity(secondEntityId, secondetype);
}
MifosEntityAccessType accessType = null;
if (accessTypeDesc != null) {
accessType = MifosEntityAccessType.get(accessTypeDesc);
}
MifosEntityAccessData returnMifosEntityAccessData = null;
if (firstEntity != null && secondEntity != null && accessType != null) {
returnMifosEntityAccessData = new MifosEntityAccessData(firstEntity, accessType, secondEntity);
}
return returnMifosEntityAccessData;
}
}
}
@Override
public String getSQLQueryInClauseIDList_ForLoanProductsForOffice(Long officeId, boolean includeAllOffices) {
MifosEntityType firstEntityType = MifosEntityType.OFFICE;
MifosEntityAccessType accessType = MifosEntityAccessType.OFFICE_ACCESS_TO_LOAN_PRODUCTS;
MifosEntityType secondEntityType = MifosEntityType.LOAN_PRODUCT;
return getSQLQueryInClause_WithListOfIDsForEntityAccess(officeId, firstEntityType, accessType, secondEntityType, includeAllOffices);
}
@Override
public String getSQLQueryInClauseIDList_ForSavingsProductsForOffice(Long officeId, boolean includeAllOffices) {
MifosEntityType firstEntityType = MifosEntityType.OFFICE;
MifosEntityAccessType accessType = MifosEntityAccessType.OFFICE_ACCESS_TO_SAVINGS_PRODUCTS;
MifosEntityType secondEntityType = MifosEntityType.SAVINGS_PRODUCT;
return getSQLQueryInClause_WithListOfIDsForEntityAccess(officeId, firstEntityType, accessType, secondEntityType, includeAllOffices);
}
@Override
public String getSQLQueryInClauseIDList_ForChargesForOffice(Long officeId, boolean includeAllOffices) {
MifosEntityType firstEntityType = MifosEntityType.OFFICE;
MifosEntityAccessType accessType = MifosEntityAccessType.OFFICE_ACCESS_TO_CHARGES;
MifosEntityType secondEntityType = MifosEntityType.CHARGE;
return getSQLQueryInClause_WithListOfIDsForEntityAccess(officeId, firstEntityType, accessType, secondEntityType, includeAllOffices);
}
@Override
public Collection<MifosEntityRelationData> retrieveAllSupportedMappingTypes() {
EntityRelationMapper entityMapper = new EntityRelationMapper();
final String sql = entityMapper.schema();
final Collection<MifosEntityRelationData> mapTypes = this.jdbcTemplate.query(sql, entityMapper, new Object[] {});
return mapTypes;
}
private static final class EntityRelationMapper implements RowMapper<MifosEntityRelationData> {
private final StringBuilder sqlBuilder = new StringBuilder("select id as id,code_name as mapping_Types from m_entity_relation ");
public String schema() {
return this.sqlBuilder.toString();
}
@Override
public String getSQLQueryInClauseIDList_ForLoanProductsForOffice(
Long officeId, boolean includeAllOffices) {
MifosEntityType firstEntityType = MifosEntityType.OFFICE;
MifosEntityAccessType accessType = MifosEntityAccessType.OFFICE_ACCESS_TO_LOAN_PRODUCTS;
MifosEntityType secondEntityType = MifosEntityType.LOAN_PRODUCT;
return getSQLQueryInClause_WithListOfIDsForEntityAccess (
officeId, firstEntityType, accessType,
secondEntityType, includeAllOffices);
}
@Override
public String getSQLQueryInClauseIDList_ForSavingsProductsForOffice(
Long officeId, boolean includeAllOffices) {
MifosEntityType firstEntityType = MifosEntityType.OFFICE;
MifosEntityAccessType accessType = MifosEntityAccessType.OFFICE_ACCESS_TO_SAVINGS_PRODUCTS;
MifosEntityType secondEntityType = MifosEntityType.SAVINGS_PRODUCT;
return getSQLQueryInClause_WithListOfIDsForEntityAccess (
officeId, firstEntityType, accessType,
secondEntityType, includeAllOffices);
public MifosEntityRelationData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
final Long mappingTypesId = rs.getLong("id");
final String mappingTypes = rs.getString("mapping_Types");
return MifosEntityRelationData.getMappingTypes(mappingTypesId, mappingTypes);
}
@Override
public String getSQLQueryInClauseIDList_ForChargesForOffice(
Long officeId, boolean includeAllOffices) {
MifosEntityType firstEntityType = MifosEntityType.OFFICE;
MifosEntityAccessType accessType = MifosEntityAccessType.OFFICE_ACCESS_TO_CHARGES;
MifosEntityType secondEntityType = MifosEntityType.CHARGE;
}
return getSQLQueryInClause_WithListOfIDsForEntityAccess (
officeId, firstEntityType, accessType,
secondEntityType, includeAllOffices);
}
@Override
public Collection<MifosEntityRelationData> retrieveAllSupportedMappingTypes() {
EntityRelationMapper entityMapper = new EntityRelationMapper();
final String sql = entityMapper.schema();
final Collection<MifosEntityRelationData> mapTypes = this.jdbcTemplate.query(sql, entityMapper, new Object[] {});
return mapTypes;
@Override
public Collection<MifosEntityToEntityMappingData> retrieveEntityToEntityMappings(Long mapId, Long fromId, Long toId) {
EntityToEntityMapper entityToEntityMapper = new EntityToEntityMapper();
String sql = entityToEntityMapper.schema();
final Collection<MifosEntityToEntityMappingData> mapTypes = this.jdbcTemplate.query(sql, entityToEntityMapper,
new Object[] { mapId, fromId, fromId, toId, toId });
return mapTypes;
}
@Override
public Collection<MifosEntityToEntityMappingData> retrieveOneMapping(Long mapId) {
GetOneEntityMapper entityMapper = new GetOneEntityMapper();
String sql = entityMapper.schema();
final Collection<MifosEntityToEntityMappingData> mapTypes = this.jdbcTemplate.query(sql, entityMapper, new Object[] { mapId });
return mapTypes;
}
private static final class GetOneEntityMapper implements RowMapper<MifosEntityToEntityMappingData> {
private final String schema;
public GetOneEntityMapper() {
StringBuffer str = new StringBuffer("select eem.rel_id as relId, ");
str.append("eem.from_id as fromId,eem.to_Id as toId,eem.start_date as startDate,eem.end_date as endDate ");
str.append("from m_entity_to_entity_mapping eem ");
str.append("where eem.id= ? ");
this.schema = str.toString();
}
private static final class EntityRelationMapper implements RowMapper<MifosEntityRelationData> {
private final StringBuilder sqlBuilder = new StringBuilder("select id as id,code_name as mapping_Types from m_entity_relation ");
public String schema() {
return this.sqlBuilder.toString();
}
@Override
public MifosEntityRelationData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
final Long mappingTypesId = rs.getLong("id");
final String mappingTypes = rs.getString("mapping_Types");
return MifosEntityRelationData.getMappingTypes(mappingTypesId, mappingTypes);
}
public String schema() {
return this.schema;
}
@Override
public Collection<MifosEntityToEntityMappingData> retrieveEntityToEntityMappings(Long mapId, Long fromId, Long toId) {
public MifosEntityToEntityMappingData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
EntityToEntityMapper entityToEntityMapper = new EntityToEntityMapper();
String sql = entityToEntityMapper.schema();
final Collection<MifosEntityToEntityMappingData> mapTypes = this.jdbcTemplate.query(sql, entityToEntityMapper, new Object[] {
mapId, fromId, fromId, toId, toId });
return mapTypes;
final Long relId = rs.getLong("relId");
final Long fromId = rs.getLong("fromId");
final Long toId = rs.getLong("toId");
final Date startDate = rs.getDate("startDate");
final Date endDate = rs.getDate("endDate");
return MifosEntityToEntityMappingData.getRelatedEntities(relId, fromId, toId, startDate, endDate);
}
}
private static final class EntityToEntityMapper implements RowMapper<MifosEntityToEntityMappingData> {
private final String schema;
public EntityToEntityMapper() {
StringBuffer str = new StringBuffer("select eem.id as mapId, ");
str.append("eem.rel_id as relId, ");
str.append("eem.from_id as from_id, ");
str.append("eem.to_id as to_id, ");
str.append("eem.start_date as startDate, ");
str.append("eem.end_date as endDate, ");
str.append("case er.code_name ");
str.append("when 'office_access_to_loan_products' then ");
str.append("o.name ");
str.append("when 'office_access_to_savings_products' then ");
str.append("o.name ");
str.append("when 'office_access_to_fees/charges' then ");
str.append("o.name ");
str.append("when 'role_access_to_loan_products' then ");
str.append("r.name ");
str.append("when 'role_access_to_savings_products' then ");
str.append("r.name ");
str.append("end as from_name, ");
str.append("case er.code_name ");
str.append("when 'office_access_to_loan_products' then ");
str.append("lp.name ");
str.append("when 'office_access_to_savings_products' then ");
str.append("sp.name ");
str.append("when 'office_access_to_fees/charges' then ");
str.append("charge.name ");
str.append("when 'role_access_to_loan_products' then ");
str.append("lp.name ");
str.append("when 'role_access_to_savings_products' then ");
str.append("sp.name ");
str.append("end as to_name, ");
str.append("er.code_name ");
str.append("from m_entity_to_entity_mapping eem ");
str.append("join m_entity_relation er on eem.rel_id = er.id ");
str.append("left join m_office o on er.from_entity_type = 1 and eem.from_id = o.id ");
str.append("left join m_role r on er.from_entity_type = 5 and eem.from_id = r.id ");
str.append("left join m_product_loan lp on er.to_entity_type = 2 and eem.to_id = lp.id ");
str.append("left join m_savings_product sp on er.to_entity_type = 3 and eem.to_id = sp.id ");
str.append("left join m_charge charge on er.to_entity_type = 4 and eem.to_id = charge.id ");
str.append("where ");
str.append("er.id = ? and ");
str.append("( ? = 0 or from_id = ? ) and ");
str.append("( ? = 0 or to_id = ? ) ");
this.schema = str.toString();
}
public String schema() {
return this.schema;
}
@Override
public Collection<MifosEntityToEntityMappingData> retrieveOneMapping(Long mapId) {
GetOneEntityMapper entityMapper = new GetOneEntityMapper();
String sql = entityMapper.schema();
final Collection<MifosEntityToEntityMappingData> mapTypes = this.jdbcTemplate.query(sql, entityMapper, new Object[] { mapId });
return mapTypes;
}
private static final class GetOneEntityMapper implements RowMapper<MifosEntityToEntityMappingData> {
private final String schema;
public GetOneEntityMapper() {
StringBuffer str = new StringBuffer("select eem.rel_id as relId, ");
str.append("eem.from_id as fromId,eem.to_Id as toId,eem.start_date as startDate,eem.end_date as endDate ");
str.append("from m_entity_to_entity_mapping eem ");
str.append("where eem.id= ? ");
this.schema = str.toString();
}
public String schema() {
return this.schema;
}
@Override
public MifosEntityToEntityMappingData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
final Long relId = rs.getLong("relId");
final Long fromId = rs.getLong("fromId");
final Long toId = rs.getLong("toId");
final Date startDate = rs.getDate("startDate");
final Date endDate = rs.getDate("endDate");
return MifosEntityToEntityMappingData.getRelatedEntities(relId, fromId, toId, startDate, endDate);
}
}
private static final class EntityToEntityMapper implements RowMapper<MifosEntityToEntityMappingData> {
private final String schema;
public EntityToEntityMapper() {
StringBuffer str = new StringBuffer("select eem.id as mapId, ");
str.append("eem.rel_id as relId, ");
str.append("eem.from_id as from_id, ");
str.append("eem.to_id as to_id, ");
str.append("eem.start_date as startDate, ");
str.append("eem.end_date as endDate, ");
str.append("case er.code_name ");
str.append("when 'office_access_to_loan_products' then ");
str.append("o.name ");
str.append("when 'office_access_to_savings_products' then ");
str.append("o.name ");
str.append("when 'office_access_to_fees/charges' then ");
str.append("o.name ");
str.append("when 'role_access_to_loan_products' then ");
str.append("r.name ");
str.append("when 'role_access_to_savings_products' then ");
str.append("r.name ");
str.append("end as from_name, ");
str.append("case er.code_name ");
str.append("when 'office_access_to_loan_products' then ");
str.append("lp.name ");
str.append("when 'office_access_to_savings_products' then ");
str.append("sp.name ");
str.append("when 'office_access_to_fees/charges' then ");
str.append("charge.name ");
str.append("when 'role_access_to_loan_products' then ");
str.append("lp.name ");
str.append("when 'role_access_to_savings_products' then ");
str.append("sp.name ");
str.append("end as to_name, ");
str.append("er.code_name ");
str.append("from m_entity_to_entity_mapping eem ");
str.append("join m_entity_relation er on eem.rel_id = er.id ");
str.append("left join m_office o on er.from_entity_type = 1 and eem.from_id = o.id ");
str.append("left join m_role r on er.from_entity_type = 5 and eem.from_id = r.id ");
str.append("left join m_product_loan lp on er.to_entity_type = 2 and eem.to_id = lp.id ");
str.append("left join m_savings_product sp on er.to_entity_type = 3 and eem.to_id = sp.id ");
str.append("left join m_charge charge on er.to_entity_type = 4 and eem.to_id = charge.id ");
str.append("where ");
str.append("er.id = ? and ");
str.append("( ? = 0 or from_id = ? ) and ");
str.append("( ? = 0 or to_id = ? ) ");
this.schema = str.toString();
}
public String schema() {
return this.schema;
}
@Override
public MifosEntityToEntityMappingData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
final Long mapId = rs.getLong("mapId");
final Long relId = rs.getLong("relId");
final Long fromId = rs.getLong("from_id");
final Long toId = rs.getLong("to_id");
final String fromEntity = rs.getString("from_name");
final String toEntity = rs.getString("to_name");
final Date startDate = rs.getDate("startDate");
final Date endDate = rs.getDate("endDate");
return MifosEntityToEntityMappingData.getRelatedEntities(mapId, relId, fromId, toId, startDate, endDate, fromEntity, toEntity);
}
public MifosEntityToEntityMappingData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
final Long mapId = rs.getLong("mapId");
final Long relId = rs.getLong("relId");
final Long fromId = rs.getLong("from_id");
final Long toId = rs.getLong("to_id");
final String fromEntity = rs.getString("from_name");
final String toEntity = rs.getString("to_name");
final Date startDate = rs.getDate("startDate");
final Date endDate = rs.getDate("endDate");
return MifosEntityToEntityMappingData.getRelatedEntities(mapId, relId, fromId, toId, startDate, endDate, fromEntity, toEntity);
}
}
}
@@ -9,7 +9,6 @@ import java.util.Date;
import java.util.Map;
import org.mifosplatform.infrastructure.codes.domain.CodeValue;
import org.mifosplatform.infrastructure.codes.domain.CodeValueRepositoryWrapper;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
@@ -35,7 +34,6 @@ import org.springframework.transaction.annotation.Transactional;
public class MifosEntityAccessWriteServiceImpl implements MifosEntityAccessWriteService {
private final static Logger logger = LoggerFactory.getLogger(MifosEntityAccessWriteServiceImpl.class);
private final CodeValueRepositoryWrapper codeValueRepositoryWrapper;
private final MifosEntityAccessRepository entityAccessRepository;
private final MifosEntityRelationRepositoryWrapper mifosEntityRelationRepositoryWrapper;
private final MifosEntityToEntityMappingRepository mifosEntityToEntityMappingRepository;
@@ -44,13 +42,11 @@ public class MifosEntityAccessWriteServiceImpl implements MifosEntityAccessWrite
@Autowired
public MifosEntityAccessWriteServiceImpl(final MifosEntityAccessRepository entityAccessRepository,
final CodeValueRepositoryWrapper codeValueRepositoryWrapper,
final MifosEntityRelationRepositoryWrapper mifosEntityRelationRepositoryWrapper,
final MifosEntityToEntityMappingRepository mifosEntityToEntityMappingRepository,
final MifosEntityToEntityMappingRepositoryWrapper mifosEntityToEntityMappingRepositoryWrapper,
MifosEntityDataValidator fromApiJsonDeserializer) {
this.entityAccessRepository = entityAccessRepository;
this.codeValueRepositoryWrapper = codeValueRepositoryWrapper;
this.mifosEntityToEntityMappingRepository = mifosEntityToEntityMappingRepository;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.mifosEntityRelationRepositoryWrapper = mifosEntityRelationRepositoryWrapper;
@@ -58,7 +54,7 @@ public class MifosEntityAccessWriteServiceImpl implements MifosEntityAccessWrite
}
@Override
public CommandProcessingResult createEntityAccess(JsonCommand command) {
public CommandProcessingResult createEntityAccess(@SuppressWarnings("unused") JsonCommand command) {
// TODO Auto-generated method stub
return null;
}
@@ -88,7 +84,8 @@ public class MifosEntityAccessWriteServiceImpl implements MifosEntityAccessWrite
fromApiJsonDeserializer.checkForEntity(relId.toString(), fromId, toId);
if (startDate != null && endDate != null) {
if (endDate.before(startDate)) { throw new MifosEntityToEntityMappingDateException(startDate.toString(), endDate.toString()); }
if (endDate
.before(startDate)) { throw new MifosEntityToEntityMappingDateException(startDate.toString(), endDate.toString()); }
}
final MifosEntityToEntityMapping newMap = MifosEntityToEntityMapping.newMap(mapId, fromId, toId, startDate, endDate);
@@ -119,7 +116,7 @@ public class MifosEntityAccessWriteServiceImpl implements MifosEntityAccessWrite
fromApiJsonDeserializer.checkForEntity(relId, fromId, toId);
final Map<String, Object> changes = mapForUpdate.updateMap(command);
if (!changes.isEmpty()) {
this.mifosEntityToEntityMappingRepository.saveAndFlush(mapForUpdate);
}
@@ -128,7 +125,7 @@ public class MifosEntityAccessWriteServiceImpl implements MifosEntityAccessWrite
} catch (DataIntegrityViolationException dve) {
handleDataIntegrityIssues(command, dve);
return CommandProcessingResult.empty();
}
}
}
@Transactional
@@ -151,8 +148,8 @@ public class MifosEntityAccessWriteServiceImpl implements MifosEntityAccessWrite
if (realCause.getMessage().contains("rel_id_from_id_to_id")) {
final String fromId = command.stringValueOfParameterNamed(MifosEntityApiResourceConstants.fromEnityType);
final String toId = command.stringValueOfParameterNamed(MifosEntityApiResourceConstants.toEntityType);
throw new PlatformDataIntegrityException("error.msg.duplicate.entity.mapping", "EntityMapping from " + fromId + " to " + toId
+ " already exist");
throw new PlatformDataIntegrityException("error.msg.duplicate.entity.mapping",
"EntityMapping from " + fromId + " to " + toId + " already exist");
}
logAsErrorUnexpectedDataIntegrityException(dve);
@@ -8,12 +8,10 @@ package org.mifosplatform.organisation.holiday.service;
import static org.mifosplatform.organisation.holiday.api.HolidayApiConstants.officesParamName;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.configuration.domain.ConfigurationDomainService;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
@@ -49,7 +47,6 @@ public class HolidayWritePlatformServiceJpaRepositoryImpl implements HolidayWrit
private final HolidayDataValidator fromApiJsonDeserializer;
private final HolidayRepositoryWrapper holidayRepository;
private final WorkingDaysRepositoryWrapper daysRepositoryWrapper;
private final ConfigurationDomainService configurationDomainService;
private final PlatformSecurityContext context;
private final OfficeRepository officeRepository;
private final FromJsonHelper fromApiJsonHelper;
@@ -58,14 +55,13 @@ public class HolidayWritePlatformServiceJpaRepositoryImpl implements HolidayWrit
public HolidayWritePlatformServiceJpaRepositoryImpl(final HolidayDataValidator fromApiJsonDeserializer,
final HolidayRepositoryWrapper holidayRepository, final PlatformSecurityContext context,
final OfficeRepository officeRepository, final FromJsonHelper fromApiJsonHelper,
final WorkingDaysRepositoryWrapper daysRepositoryWrapper, final ConfigurationDomainService configurationDomainService) {
final WorkingDaysRepositoryWrapper daysRepositoryWrapper) {
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.holidayRepository = holidayRepository;
this.context = context;
this.officeRepository = officeRepository;
this.fromApiJsonHelper = fromApiJsonHelper;
this.daysRepositoryWrapper = daysRepositoryWrapper;
this.configurationDomainService = configurationDomainService;
}
@Transactional
@@ -5,47 +5,45 @@
*/
package org.mifosplatform.organisation.teller.api;
import java.util.Collection;
import java.util.Date;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.teller.data.CashierData;
import org.mifosplatform.organisation.teller.service.TellerManagementReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.Collection;
import java.util.Date;
@Path("cashiers")
@Component
@Scope("singleton")
public class CashierApiResource {
private final PlatformSecurityContext securityContext;
private final DefaultToApiJsonSerializer<CashierData> jsonSerializer;
private final TellerManagementReadPlatformService readPlatformService;
private final PortfolioCommandSourceWritePlatformService commandWritePlatformService;
@Autowired
public CashierApiResource(PlatformSecurityContext securityContext, DefaultToApiJsonSerializer<CashierData> jsonSerializer,
TellerManagementReadPlatformService readPlatformService,
PortfolioCommandSourceWritePlatformService commandWritePlatformService) {
this.securityContext = securityContext;
public CashierApiResource(DefaultToApiJsonSerializer<CashierData> jsonSerializer,
TellerManagementReadPlatformService readPlatformService) {
this.jsonSerializer = jsonSerializer;
this.readPlatformService = readPlatformService;
this.commandWritePlatformService = commandWritePlatformService;
}
@GET
@Consumes({MediaType.TEXT_HTML, MediaType.APPLICATION_JSON})
@Consumes({ MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
@Produces(MediaType.APPLICATION_JSON)
public String getCashierData(@QueryParam("officeId") final Long officeId, @QueryParam("tellerId") final Long tellerId,
@QueryParam("staffId") final Long staffId, @QueryParam("date") final String date) {
@QueryParam("staffId") final Long staffId, @QueryParam("date") final String date) {
final DateTimeFormatter dateFormatter = ISODateTimeFormat.basicDate();
final Date dateRestriction = (date != null ? dateFormatter.parseDateTime(date).toDate() : new Date());
@@ -51,7 +51,8 @@ public class TellerApiResource {
@Autowired
public TellerApiResource(PlatformSecurityContext securityContext, DefaultToApiJsonSerializer<TellerData> jsonSerializer,
TellerManagementReadPlatformService readPlatformService, PortfolioCommandSourceWritePlatformService commandWritePlatformService) {
TellerManagementReadPlatformService readPlatformService,
PortfolioCommandSourceWritePlatformService commandWritePlatformService) {
super();
this.securityContext = securityContext;
this.jsonSerializer = jsonSerializer;
@@ -259,8 +260,8 @@ public class TellerApiResource {
final Date fromDate = null;
final Date toDate = null;
final CashierTransactionsWithSummaryData cashierTxnWithSummary = this.readPlatformService.retrieveCashierTransactionsWithSummary(
cashierId, false, fromDate, toDate, currencyCode);
final CashierTransactionsWithSummaryData cashierTxnWithSummary = this.readPlatformService
.retrieveCashierTransactionsWithSummary(cashierId, false, fromDate, toDate, currencyCode);
return this.jsonSerializer.serialize(cashierTxnWithSummary);
}
@@ -8,7 +8,6 @@ package org.mifosplatform.organisation.workingdays.service;
import java.text.ParseException;
import java.util.Map;
import org.mifosplatform.infrastructure.configuration.domain.ConfigurationDomainService;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
@@ -28,14 +27,12 @@ import net.fortuna.ical4j.model.property.RRule;
public class WorkingDaysWritePlatformServiceJpaRepositoryImpl implements WorkingDaysWritePlatformService {
private final WorkingDaysRepositoryWrapper daysRepositoryWrapper;
private final ConfigurationDomainService configurationDomainService;
private final WorkingDayValidator fromApiJsonDeserializer;
@Autowired
public WorkingDaysWritePlatformServiceJpaRepositoryImpl(final WorkingDaysRepositoryWrapper daysRepositoryWrapper,
final ConfigurationDomainService configurationDomainService, final WorkingDayValidator fromApiJsonDeserializer) {
final WorkingDayValidator fromApiJsonDeserializer) {
this.daysRepositoryWrapper = daysRepositoryWrapper;
this.configurationDomainService = configurationDomainService;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
}
@@ -75,23 +75,23 @@ public class ClientChargesApiResource {
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAllClientCharges(
@PathParam("clientId") final Long clientId,
public String retrieveAllClientCharges(@PathParam("clientId") final Long clientId,
@DefaultValue(ClientApiConstants.CLIENT_CHARGE_QUERY_PARAM_STATUS_VALUE_ALL) @QueryParam(ClientApiConstants.CLIENT_CHARGE_QUERY_PARAM_STATUS) final String chargeStatus,
@QueryParam("paid") final Boolean paid, @Context final UriInfo uriInfo, @QueryParam("limit") final Integer limit,
@QueryParam("offset") final Integer offset) {
@QueryParam("pendingPayment") final Boolean pendingPayment, @Context final UriInfo uriInfo,
@QueryParam("limit") final Integer limit, @QueryParam("offset") final Integer offset) {
this.context.authenticatedUser().validateHasReadPermission(ClientApiConstants.CLIENT_CHARGES_RESOURCE_NAME);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
if (!(is(chargeStatus, ClientApiConstants.CLIENT_CHARGE_QUERY_PARAM_STATUS_VALUE_ALL)
|| is(chargeStatus, ClientApiConstants.CLIENT_CHARGE_QUERY_PARAM_STATUS_VALUE_ACTIVE) || is(chargeStatus,
ClientApiConstants.CLIENT_CHARGE_QUERY_PARAM_STATUS_VALUE_INACTIVE))) { throw new UnrecognizedQueryParamException(
ClientApiConstants.CLIENT_CHARGE_QUERY_PARAM_STATUS, chargeStatus, new Object[] {
ClientApiConstants.CLIENT_CHARGE_QUERY_PARAM_STATUS_VALUE_ALL,
ClientApiConstants.CLIENT_CHARGE_QUERY_PARAM_STATUS_VALUE_ACTIVE,
ClientApiConstants.CLIENT_CHARGE_QUERY_PARAM_STATUS_VALUE_INACTIVE }); }
|| is(chargeStatus, ClientApiConstants.CLIENT_CHARGE_QUERY_PARAM_STATUS_VALUE_ACTIVE)
|| is(chargeStatus,
ClientApiConstants.CLIENT_CHARGE_QUERY_PARAM_STATUS_VALUE_INACTIVE))) { throw new UnrecognizedQueryParamException(
ClientApiConstants.CLIENT_CHARGE_QUERY_PARAM_STATUS, chargeStatus,
new Object[] { ClientApiConstants.CLIENT_CHARGE_QUERY_PARAM_STATUS_VALUE_ALL,
ClientApiConstants.CLIENT_CHARGE_QUERY_PARAM_STATUS_VALUE_ACTIVE,
ClientApiConstants.CLIENT_CHARGE_QUERY_PARAM_STATUS_VALUE_INACTIVE }); }
final Page<ClientChargeData> clientCharges = this.clientChargeReadPlatformService.retrieveClientCharges(clientId, chargeStatus,
paid, limit, offset);
pendingPayment, limit, offset);
return this.toApiJsonSerializer.serialize(settings, clientCharges, ClientApiConstants.CLIENT_CHARGES_RESPONSE_DATA_PARAMETERS);
}
@@ -5,8 +5,6 @@
*/
package org.mifosplatform.portfolio.client.api;
import java.util.Collection;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
@@ -27,6 +25,7 @@ import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException;
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.core.service.Page;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.data.ClientTransactionData;
import org.mifosplatform.portfolio.client.service.ClientTransactionReadPlatformService;
@@ -59,10 +58,11 @@ public class ClientTransactionsApiResource {
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAllClientTransactions(@PathParam("clientId") final Long clientId, @Context final UriInfo uriInfo) {
public String retrieveAllClientTransactions(@PathParam("clientId") final Long clientId, @Context final UriInfo uriInfo,
@QueryParam("offset") final Integer offset, @QueryParam("limit") final Integer limit) {
this.context.authenticatedUser().validateHasReadPermission(ClientApiConstants.CLIENT_CHARGES_RESOURCE_NAME);
final Collection<ClientTransactionData> clientTransactions = this.clientTransactionReadPlatformService
.retrieveAllTransactions(clientId);
final Page<ClientTransactionData> clientTransactions = this.clientTransactionReadPlatformService.retrieveAllTransactions(clientId,
limit, offset);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, clientTransactions,
@@ -48,6 +48,8 @@ public class ClientChargeData {
private final Boolean isPaid;
private final Boolean isWaived;
private final LocalDate inactivationDate;
private final Collection<ChargeData> chargeOptions;
@@ -57,11 +59,11 @@ public class ClientChargeData {
public static ClientChargeData instance(Long id, Long clientId, Long chargeId, String name, EnumOptionData chargeTimeType,
LocalDate dueDate, EnumOptionData chargeCalculationType, CurrencyData currency, BigDecimal amount, BigDecimal amountPaid,
BigDecimal amountWaived, BigDecimal amountWrittenOff, BigDecimal amountOutstanding, boolean penalty, Boolean isPaid,
Boolean isActive, LocalDate inactivationDate, Collection<ChargeData> chargeOptions) {
Boolean isWaived, Boolean isActive, LocalDate inactivationDate, Collection<ChargeData> chargeOptions) {
Collection<ClientTransactionData> clientTransactionDatas = null;
return new ClientChargeData(id, clientId, chargeId, name, chargeTimeType, dueDate, chargeCalculationType, currency, amount,
amountPaid, amountWaived, amountWrittenOff, amountOutstanding, penalty, isPaid, isActive, inactivationDate, chargeOptions,
clientTransactionDatas);
amountPaid, amountWaived, amountWrittenOff, amountOutstanding, penalty, isPaid, isWaived, isActive, inactivationDate,
chargeOptions, clientTransactionDatas);
}
public static ClientChargeData addAssociations(ClientChargeData clientChargeData,
@@ -70,7 +72,8 @@ public class ClientChargeData {
clientChargeData.chargeTimeType, clientChargeData.dueDate, clientChargeData.chargeCalculationType,
clientChargeData.currency, clientChargeData.amount, clientChargeData.amountPaid, clientChargeData.amountWaived,
clientChargeData.amountWrittenOff, clientChargeData.amountOutstanding, clientChargeData.penalty, clientChargeData.isPaid,
clientChargeData.isActive, clientChargeData.inactivationDate, clientChargeData.chargeOptions, clientTransactionDatas);
clientChargeData.isWaived, clientChargeData.isActive, clientChargeData.inactivationDate, clientChargeData.chargeOptions,
clientTransactionDatas);
}
public static ClientChargeData template(final Collection<ChargeData> chargeOptions) {
@@ -90,17 +93,18 @@ public class ClientChargeData {
final Boolean penalty = false;
final Boolean isPaid = null;
final Boolean isActive = null;
final Boolean isWaived = null;
final LocalDate inactivationDate = null;
final Collection<ClientTransactionData> clientTransactionDatas = null;
return new ClientChargeData(id, clientId, chargeId, name, chargeTimeType, dueDate, chargeCalculationType, currency, amount,
amountPaid, amountWaived, amountWrittenOff, amountOutstanding, penalty, isPaid, isActive, inactivationDate, chargeOptions,
clientTransactionDatas);
amountPaid, amountWaived, amountWrittenOff, amountOutstanding, penalty, isPaid, isWaived, isActive, inactivationDate,
chargeOptions, clientTransactionDatas);
}
private ClientChargeData(Long id, Long clientId, Long chargeId, String name, EnumOptionData chargeTimeType, LocalDate dueDate,
EnumOptionData chargeCalculationType, CurrencyData currency, BigDecimal amount, BigDecimal amountPaid, BigDecimal amountWaived,
BigDecimal amountWrittenOff, BigDecimal amountOutstanding, boolean penalty, Boolean isPaid, Boolean isActive,
BigDecimal amountWrittenOff, BigDecimal amountOutstanding, boolean penalty, Boolean isPaid, Boolean isWaived, Boolean isActive,
LocalDate inactivationDate, Collection<ChargeData> chargeOptions, Collection<ClientTransactionData> clientTransactionDatas) {
super();
this.id = id;
@@ -118,6 +122,7 @@ public class ClientChargeData {
this.amountOutstanding = amountOutstanding;
this.penalty = penalty;
this.isPaid = isPaid;
this.isWaived = isWaived;
this.isActive = isActive;
this.inactivationDate = inactivationDate;
@@ -75,13 +75,14 @@ public class ClientChargeReadPlatformServiceImpl implements ClientChargeReadPlat
final EnumOptionData chargeCalculationType = ChargeEnumerations.chargeCalculationType(chargeCalculation);
final boolean penalty = rs.getBoolean("penalty");
final Boolean isPaid = rs.getBoolean("isPaid");
final Boolean isWaived = rs.getBoolean("waived");
final Boolean isActive = rs.getBoolean("isActive");
final LocalDate inactivationDate = JdbcSupport.getLocalDate(rs, "inactivationDate");
final Collection<ChargeData> chargeOptions = null;
return ClientChargeData.instance(id, clientId, chargeId, name, chargeTimeType, dueDate, chargeCalculationType, currency, amount,
amountPaid, amountWaived, amountWrittenOff, amountOutstanding, penalty, isPaid, isActive, inactivationDate,
amountPaid, amountWaived, amountWrittenOff, amountOutstanding, penalty, isPaid, isWaived, isActive, inactivationDate,
chargeOptions);
}
@@ -115,9 +116,10 @@ public class ClientChargeReadPlatformServiceImpl implements ClientChargeReadPlat
throw new ClientChargeNotFoundException(clientChargeId, clientId);
}
}
@Override
public Page<ClientChargeData> retrieveClientCharges(Long clientId, String status, Boolean isPaid,Integer limit,Integer offset) {
public Page<ClientChargeData> retrieveClientCharges(Long clientId, String status, Boolean pendingPayment, Integer limit,
Integer offset) {
final ClientChargeMapper rm = new ClientChargeMapper();
final StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.append("select SQL_CALC_FOUND_ROWS ").append(rm.schema()).append(" where cc.client_id=? ");
@@ -130,15 +132,17 @@ public class ClientChargeReadPlatformServiceImpl implements ClientChargeReadPlat
}
// filter for paid charges
if (isPaid != null && isPaid) {
sqlBuilder.append(" and ( cc.is_paid_derived = 1 or cc.waived = 1) ");
} else if (isPaid != null && !isPaid) {
sqlBuilder.append(" and (cc.is_paid_derived = 0 and cc.waived = 0) ");
if (pendingPayment != null && pendingPayment) {
sqlBuilder.append(" and ( cc.is_paid_derived = 0 and cc.waived = 1) ");
} else if (pendingPayment != null && !pendingPayment) {
sqlBuilder.append(" and (cc.is_paid_derived = 1 or cc.waived = 0) ");
}
sqlBuilder.append(" order by cc.charge_time_enum ASC, cc.charge_due_date ASC, cc.is_penalty ASC "+"limit "+limit+" offset "+offset);
sqlBuilder.append(
" order by cc.charge_time_enum ASC, cc.charge_due_date DESC, cc.is_penalty ASC " + "limit " + limit + " offset " + offset);
final String sqlCountRows = "SELECT FOUND_ROWS()";
return this.paginationHelper.fetchPage(this.jdbcTemplate,sqlCountRows, sqlBuilder.toString(),new Object[] { clientId },this.clientChargeMapper);
return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), new Object[] { clientId },
this.clientChargeMapper);
}
}
@@ -7,13 +7,14 @@ package org.mifosplatform.portfolio.client.service;
import java.util.Collection;
import org.mifosplatform.infrastructure.core.service.Page;
import org.mifosplatform.portfolio.client.data.ClientTransactionData;
import org.springframework.transaction.annotation.Transactional;
public interface ClientTransactionReadPlatformService {
@Transactional(readOnly = true)
public Collection<ClientTransactionData> retrieveAllTransactions(Long clientId);
public Page<ClientTransactionData> retrieveAllTransactions(Long clientId, Integer limit, Integer offset);
@Transactional(readOnly = true)
public Collection<ClientTransactionData> retrieveAllTransactions(final Long clientId, final Long chargeId);
@@ -13,6 +13,8 @@ import java.util.Collection;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
import org.mifosplatform.infrastructure.core.service.Page;
import org.mifosplatform.infrastructure.core.service.PaginationHelper;
import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
import org.mifosplatform.organisation.monetary.data.CurrencyData;
import org.mifosplatform.portfolio.client.data.ClientTransactionData;
@@ -29,19 +31,20 @@ import org.springframework.stereotype.Service;
@Service
public class ClientTransactionReadPlatformServiceImpl implements ClientTransactionReadPlatformService {
private final JdbcTemplate jdbcTemplate;
private final ClientTransactionMapper clientTransactionMapper;
private final PaginationHelper<ClientTransactionData> paginationHelper;
@Autowired
public ClientTransactionReadPlatformServiceImpl(final RoutingDataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.clientTransactionMapper = new ClientTransactionMapper();
this.paginationHelper = new PaginationHelper<>();
}
private static final class ClientTransactionMapper implements RowMapper<ClientTransactionData> {
private final String schemaSql;
public ClientTransactionMapper() {
@@ -118,9 +121,13 @@ public class ClientTransactionReadPlatformServiceImpl implements ClientTransacti
}
@Override
public Collection<ClientTransactionData> retrieveAllTransactions(Long clientId) {
Long chargeId=null;
return retrieveAllTransactions(clientId,chargeId);
public Page<ClientTransactionData> retrieveAllTransactions(Long clientId, Integer limit, Integer offset) {
Object[] parameters = new Object[1];
String sql = "select SQL_CALC_FOUND_ROWS " + this.clientTransactionMapper.schema() + " where c.id = ? ";
parameters[0] = clientId;
final String sqlCountRows = "SELECT FOUND_ROWS()";
sql = sql + " order by tr.transaction_date DESC, tr.created_date DESC, tr.id DESC limit " + limit + " offset " + offset;
return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sql, parameters, this.clientTransactionMapper);
}
@Override
@@ -49,12 +49,11 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
dueRepaymentPeriodDate = firstRepaymentPeriodDate;
} else {
Calendar currentCalendar = loanApplicationTerms.getLoanCalendar();
if (currentCalendar == null) {
dueRepaymentPeriodDate = getRepaymentPeriodDate(loanApplicationTerms.getRepaymentPeriodFrequencyType(),
loanApplicationTerms.getRepaymentEvery(), lastRepaymentDate, loanApplicationTerms.getNthDay(),
loanApplicationTerms.getWeekDayType());
} else {
// If we have currentCalendar object, this neans there is a
dueRepaymentPeriodDate = getRepaymentPeriodDate(loanApplicationTerms.getRepaymentPeriodFrequencyType(),
loanApplicationTerms.getRepaymentEvery(), lastRepaymentDate, loanApplicationTerms.getNthDay(),
loanApplicationTerms.getWeekDayType());
if (currentCalendar != null) {
// If we have currentCalendar object, this means there is a
// calendar associated with
// the loan, and we should use it in order to calculate next
// repayment
@@ -79,8 +78,8 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
loanApplicationTerms.getRepaymentEvery(), adjustedDate, loanApplicationTerms.getNthDay(),
loanApplicationTerms.getWeekDayType());
final RepaymentRescheduleType rescheduleType = RepaymentRescheduleType.fromInt(holidayDetailDTO.getWorkingDays()
.getRepaymentReschedulingType());
final RepaymentRescheduleType rescheduleType = RepaymentRescheduleType
.fromInt(holidayDetailDTO.getWorkingDays().getRepaymentReschedulingType());
/**
* Fix for https://mifosforge.jira.com/browse/MIFOSX-1357
@@ -18,6 +18,7 @@ public class PasswordValidationPolicyData implements Serializable {
private final String description;
@SuppressWarnings("unused")
private final boolean active;
@SuppressWarnings("unused")
private final String key;
public PasswordValidationPolicyData(final Long id, final Boolean active, final String description, final String key) {