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