mifosx-270 api docs audit/makerchecker/permissions + wip mifosx-97 make functionality match api docs
This commit is contained in:
+439
-53
@@ -937,9 +937,8 @@
|
|||||||
<td><a href="#permissions">Permission</a></td>
|
<td><a href="#permissions">Permission</a></td>
|
||||||
<td>permissions</td>
|
<td>permissions</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td><a href="#permissions_list">List Application
|
<td><a href="#permissions_list">List Application Permissions</a></td>
|
||||||
Permissions</a></td>
|
<td><a href="#permissions_update">Enable/Disable Permissions for Maker Checker</a></td>
|
||||||
<td></td>
|
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@@ -7055,8 +7054,17 @@ Content-Type: application/json
|
|||||||
<div class="method-section">
|
<div class="method-section">
|
||||||
<div class="method-description">
|
<div class="method-description">
|
||||||
<h3>Audits</h3>
|
<h3>Audits</h3>
|
||||||
<p>
|
<p>Every non-read Mifos API request is audited. A fully processed request can
|
||||||
<p />
|
not be changed or deleted. See maker checker api for situations where an audit is not
|
||||||
|
fully processed.<br><br>
|
||||||
|
|
||||||
|
Permissions: To search and look at audit entries a user needs to be attached to a role
|
||||||
|
that has one of the ALL_FUNCTIONS, ALL_FUNCTIONS_READ or READ_AUDIT permissions.<br><br>
|
||||||
|
|
||||||
|
Data Scope: A user can only see audits that are within their data scope. However,
|
||||||
|
'head office' users can see all audits including those that aren't office/branch related
|
||||||
|
e.g. Loan Product changes.
|
||||||
|
<p/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -7065,9 +7073,106 @@ Content-Type: application/json
|
|||||||
<div class="method-section">
|
<div class="method-section">
|
||||||
<div class="method-description">
|
<div class="method-description">
|
||||||
<h4>List Audits</h4>
|
<h4>List Audits</h4>
|
||||||
<p></p>
|
<p>Get a list of audits that match the criteria supplied,
|
||||||
|
and are within the requestors' data scope.</p>
|
||||||
|
<h5>Arguments</h5>
|
||||||
|
<dl class="argument-list">
|
||||||
|
<dt>actionName</dt>
|
||||||
|
<dd>optional</dd>
|
||||||
|
<dd>Examples: CREATE, UPDATE, DISBURSE</dd>
|
||||||
|
|
||||||
|
<dt>entityName</dt>
|
||||||
|
<dd>optional</dd>
|
||||||
|
<dd>Examples: CLIENT, LOAN, FUND</dd>
|
||||||
|
|
||||||
|
<dt>resourceId</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
The id value of the entityName</span>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt>makerId</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
The id value of the application user creating the entry</span>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt>makerDateTimeFrom</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
Get entries created on or after this</span>
|
||||||
|
</dd>
|
||||||
|
<dd>Example: 2013-04-10 08:00:00</dd>
|
||||||
|
|
||||||
|
<dt>makerDateTimeTo</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
Get entries created on or before this</span>
|
||||||
|
</dd>
|
||||||
|
<dd>Example: 2013-05-10 08:00:00</dd>
|
||||||
|
|
||||||
|
<dt>checkerId</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
The id value of the application user that checked (approved) the entry</span>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt>checkerDateTimeFrom</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
Get entries checked on or after this</span>
|
||||||
|
</dd>
|
||||||
|
<dd>Example: 2013-04-10 08:00:00</dd>
|
||||||
|
|
||||||
|
<dt>checkerDateTimeTo</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
Get entries checked on or before this</span>
|
||||||
|
</dd>
|
||||||
|
<dd>Example: 2013-05-10 18:00:00</dd>
|
||||||
|
|
||||||
|
<dt>processingResult</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
The enum value of the processing status</span>
|
||||||
|
</dd>
|
||||||
|
<dd>values:<br>
|
||||||
|
0: Invalid<br>
|
||||||
|
1: processed<br>
|
||||||
|
2: awaiting.approval<br>
|
||||||
|
3: rejected
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt>officeId</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
The id value of the office/branch associated with the entry (if there is one)</span>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt>groupId</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
The id value of the group associated with the entry (if there is one).
|
||||||
|
A group is a general idea and may be a Center, a Group, a Communal Bank or other.</span>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt>clientId</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
The id value of the client associated with the entry (if there is one)</span>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt>loanId</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
The id value of the loan associated with the entry (if there is one)</span>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt>savingsAccountId</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
The id value of the savings account associated with the entry (if there is one)</span>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt>includeJson</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
Values are true, false. Default is false.</span>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
</dl>
|
||||||
<p>Example Requests:</p>
|
<p>Example Requests:</p>
|
||||||
<div class=apiClick>audits</div>
|
<div class=apiClick>audits</div><br>
|
||||||
|
<div class=apiClick>audits?fields=madeOnDate,maker,processingResult</div><br>
|
||||||
|
<div class=apiClick>audits?makerDateTimeFrom=2013-03-25 08:00:00&makerDateTimeTo=2013-04-04 18:00:00</div><br>
|
||||||
|
<div class=apiClick>audits?officeId=1</div><br>
|
||||||
|
<div class=apiClick>audits?officeId=1&includeJson=true</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="method-example">
|
<div class="method-example">
|
||||||
<code class="method-declaration">
|
<code class="method-declaration">
|
||||||
@@ -7156,7 +7261,6 @@ GET https://DomainName/api/v1/audits
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<a id="audits_searchtemplate" name="audits_searchtemplate"
|
<a id="audits_searchtemplate" name="audits_searchtemplate"
|
||||||
class="old-syle-anchor"> </a>
|
class="old-syle-anchor"> </a>
|
||||||
<div class="method-section">
|
<div class="method-section">
|
||||||
@@ -7262,8 +7366,212 @@ GET https://DomainName/api/v1/audits/searchtemplate
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<a id="audits_retrieve" name="audits_retrieve"
|
||||||
|
class="old-syle-anchor"> </a>
|
||||||
|
<div class="method-section">
|
||||||
|
<div class="method-description">
|
||||||
|
<h4>Retrieve an Audit Entry</h4>
|
||||||
|
<p></p>
|
||||||
|
<p>Example Requests:</p>
|
||||||
|
<div class=apiClick>audits/20</div>
|
||||||
|
<div class=apiClick>audits/20?fields=madeOnDate,maker,processingResult</div>
|
||||||
|
</div>
|
||||||
|
<div class="method-example">
|
||||||
|
<code class="method-declaration">
|
||||||
|
GET https://DomainName/api/v1/audits
|
||||||
|
</code>
|
||||||
|
<code class="method-response">
|
||||||
|
{
|
||||||
|
"id": 20,
|
||||||
|
"actionName": "REPAYMENT",
|
||||||
|
"entityName": "LOAN",
|
||||||
|
"resourceId": 868,
|
||||||
|
"maker": "dataentry1",
|
||||||
|
"madeOnDate": 1358449025000,
|
||||||
|
"processingResult": "processed",
|
||||||
|
"commandAsJson": "{\"transactionDate\":\"28 September 2012\",\"transactionAmount\":\"1,967.00\",\"locale\":\"en\",\"dateFormat\":\"dd MMMM yyyy\"}",
|
||||||
|
"officeName": "another office",
|
||||||
|
"clientName": "another client",
|
||||||
|
"loanAccountNo": "23"
|
||||||
|
}
|
||||||
|
</code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Maker Checker starts here -->
|
||||||
|
<a id="makercheckers" name="makercheckers" class="old-syle-anchor"> </a>
|
||||||
|
<div class="method-section">
|
||||||
|
<div class="method-description">
|
||||||
|
<h3>Maker Checker (or 4-eye) functionality</h3>
|
||||||
|
<p>Mifos X Maker Checker functionality allows an MFI to define transactions
|
||||||
|
as having a maker and a checker phase. One user enters, deletes or changes data.
|
||||||
|
Then, another user that has "Checker" rights for that transaction, can inspect
|
||||||
|
and approve the data.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>By default, Maker Checker functionality is disabled.
|
||||||
|
See <a href="#configs_globalconfig_update">Update Global Configuration</a> to enable/disable
|
||||||
|
Maker Checker functionality at a global level.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Additionally, Maker Checker functionality for each transaction (permission) is disabled by default.
|
||||||
|
see <a href="#permissions_update">Enable/Disable Permissions for Maker Checker</a> to enable/disable
|
||||||
|
Maker Checker functionality at a transaction (permission) level.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Finally, to give checking rights to a user (via a role associated with the user) see
|
||||||
|
<a href="#rolespermissions_update">Update a Role's Permissions</a>
|
||||||
|
</p>
|
||||||
|
<p>For example, <br>
|
||||||
|
<code>
|
||||||
|
{
|
||||||
|
"permissions":{
|
||||||
|
"CREATE_GUARANTOR_CHECKER":true,
|
||||||
|
"CREATE_CLIENT_CHECKER":true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code>
|
||||||
|
<br>
|
||||||
|
will give checking rights for CREATE_GUARANTOR and CREATE_CLIENT</p>
|
||||||
|
<p>Alternatively, the special permissions ALL_FUNCTIONS or CHECKER_SUPER_USER will give blanket
|
||||||
|
checking rights.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
When a user "makes" an entry that is enabled for Maker Checker, it is audited and the audit status
|
||||||
|
is set to a value of 2 (awaiting.approval).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
Checkers can only Check and approve entries that they have been permitted to check.<br><br>
|
||||||
|
|
||||||
|
Checkers can only Check and approve entries that are within their data scope. However,
|
||||||
|
'head office' Checkers can Check and approve all entries
|
||||||
|
including those that aren't office/branch related (as long as they have the Checker permissions)
|
||||||
|
e.g. Loan Product changes.
|
||||||
|
<p/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a id="makercheckers_list" name="makercheckers_list"
|
||||||
|
class="old-syle-anchor"> </a>
|
||||||
|
<div class="method-section">
|
||||||
|
<div class="method-description">
|
||||||
|
<h4>List Maker Checker Entries</h4>
|
||||||
|
<p>Get a list of entries that can be checked by the requestor that match the criteria supplied.</p>
|
||||||
|
<h5>Arguments</h5>
|
||||||
|
<dl class="argument-list">
|
||||||
|
<dt>actionName</dt>
|
||||||
|
<dd>optional</dd>
|
||||||
|
<dd>Examples: CREATE, UPDATE, DISBURSE</dd>
|
||||||
|
|
||||||
|
<dt>entityName</dt>
|
||||||
|
<dd>optional</dd>
|
||||||
|
<dd>Examples: CLIENT, LOAN, FUND</dd>
|
||||||
|
|
||||||
|
<dt>resourceId</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
The id value of the entityName</span>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt>makerId</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
The id value of the application user creating the entry</span>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt>makerDateTimeFrom</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
Get entries created on or after this</span>
|
||||||
|
</dd>
|
||||||
|
<dd>Example: 2013-04-10 08:00:00</dd>
|
||||||
|
|
||||||
|
<dt>makerDateTimeTo</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
Get entries created on or before this</span>
|
||||||
|
</dd>
|
||||||
|
<dd>Example: 2013-05-10 08:00:00</dd>
|
||||||
|
|
||||||
|
<dt>officeId</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
The id value of the office/branch associated with the entry (if there is one)</span>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt>groupId</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
The id value of the group associated with the entry (if there is one).
|
||||||
|
A group is a general idea and may be a Center, a Group, a Communal Bank or other.</span>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt>clientId</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
The id value of the client associated with the entry (if there is one)</span>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt>loanId</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
The id value of the loan associated with the entry (if there is one)</span>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt>savingsAccountId</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
The id value of the savings account associated with the entry (if there is one)</span>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt>includeJson</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
Values are true, false. Default is false.</span>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
</dl>
|
||||||
|
<p>Example Requests:</p>
|
||||||
|
<div class=apiClick>makercheckers</div><br>
|
||||||
|
<div class=apiClick>makercheckers?fields=madeOnDate,maker,processingResult</div><br>
|
||||||
|
<div class=apiClick>makercheckers?makerDateTimeFrom=2013-03-25 08:00:00&makerDateTimeTo=2013-04-04 18:00:00</div><br>
|
||||||
|
<div class=apiClick>makercheckers?officeId=1</div><br>
|
||||||
|
<div class=apiClick>makercheckers?officeId=1&includeJson=true</div>
|
||||||
|
</div>
|
||||||
|
<div class="method-example">
|
||||||
|
<code class="method-declaration">
|
||||||
|
GET https://DomainName/api/v1/makercheckers
|
||||||
|
</code>
|
||||||
|
<code class="method-response">
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": 654,
|
||||||
|
"actionName": "CREATE",
|
||||||
|
"entityName": "LOANPRODUCT",
|
||||||
|
"resourceId": 15,
|
||||||
|
"maker": "keithwoodlock",
|
||||||
|
"madeOnDate": 1364924512000,
|
||||||
|
"processingResult": "awaiting.approval"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 666,
|
||||||
|
"actionName": "CREATE",
|
||||||
|
"entityName": "CLIENT",
|
||||||
|
"resourceId": 363,
|
||||||
|
"maker": "keithwoodlock",
|
||||||
|
"madeOnDate": 1365012843000,
|
||||||
|
"processingResult": "awaiting.approval",
|
||||||
|
"officeName": "my office name"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 670,
|
||||||
|
"actionName": "CREATE",
|
||||||
|
"entityName": "CLIENTNOTE",
|
||||||
|
"resourceId": 287,
|
||||||
|
"maker": "keithwoodlock",
|
||||||
|
"madeOnDate": 1365014204000,
|
||||||
|
"processingResult": "awaiting.approval",
|
||||||
|
"officeName": "my office name",
|
||||||
|
"clientName": "gg ggg"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
</code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<a id="makercheckers_searchtemplate" name="makercheckers_searchtemplate"
|
<a id="makercheckers_searchtemplate" name="makercheckers_searchtemplate"
|
||||||
class="old-syle-anchor"> </a>
|
class="old-syle-anchor"> </a>
|
||||||
<div class="method-section">
|
<div class="method-section">
|
||||||
@@ -7320,6 +7628,42 @@ GET https://DomainName/api/v1/audits/searchtemplate
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<a id="makercheckers_approve" name="makercheckers_approve" class="old-syle-anchor"> </a>
|
||||||
|
<div class="method-section">
|
||||||
|
<div class="method-description">
|
||||||
|
<h4>Approve Maker Checker Entry</h4>
|
||||||
|
</div>
|
||||||
|
<div class="method-example">
|
||||||
|
<code class="method-declaration">
|
||||||
|
POST https://DomainName/api/v1/makercheckers/{auditId}?command=approve
|
||||||
|
</code>
|
||||||
|
<code class="method-request">
|
||||||
|
POST makercheckers/1?command=approve
|
||||||
|
Content-Type: application/json
|
||||||
|
</code>
|
||||||
|
<code class="method-response">{ "auditId": 1 } </code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a id="makercheckers_delete" name="makercheckers_delete" class="old-syle-anchor"> </a>
|
||||||
|
<div class="method-section">
|
||||||
|
<div class="method-description">
|
||||||
|
<h4>Delete Maker Checker Entry</h4>
|
||||||
|
</div>
|
||||||
|
<div class="method-example">
|
||||||
|
<code class="method-declaration">
|
||||||
|
DELETE https://DomainName/api/v1/makercheckers/{auditId}
|
||||||
|
</code>
|
||||||
|
<code class="method-request">
|
||||||
|
DELETE makercheckers/1
|
||||||
|
Content-Type: application/json
|
||||||
|
</code>
|
||||||
|
<code class="method-response">{ "auditId": 1 } </code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Fund starts here -->
|
<!-- Fund starts here -->
|
||||||
<a id="funds_create" name="funds_create" class="old-syle-anchor"> </a>
|
<a id="funds_create" name="funds_create" class="old-syle-anchor"> </a>
|
||||||
<div class="method-section">
|
<div class="method-section">
|
||||||
@@ -11324,6 +11668,9 @@ Request body:
|
|||||||
<div class="method-description">
|
<div class="method-description">
|
||||||
<h3>Permissions</h3>
|
<h3>Permissions</h3>
|
||||||
<p>An API capability to support management of application permissions for user administration.</p>
|
<p>An API capability to support management of application permissions for user administration.</p>
|
||||||
|
<p>There is no Mifos X functionality for creating or deleting permissions. Permissions come pre-installed.</p>
|
||||||
|
<p>Permissions are not updated, except in the case of enabling or disabling non-read transactions for
|
||||||
|
Maker Checker functionality</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -11332,10 +11679,25 @@ Request body:
|
|||||||
<div class="method-section">
|
<div class="method-section">
|
||||||
<div class="method-description">
|
<div class="method-description">
|
||||||
<h4>List Application Permissions</h4>
|
<h4>List Application Permissions</h4>
|
||||||
|
<h5>Arguments</h5>
|
||||||
|
<dl class="argument-list">
|
||||||
|
<dt>makerCheckerable</dt>
|
||||||
|
<dd>optional, <span>
|
||||||
|
Values are true, false. Default is false.</span>
|
||||||
|
<p>If makerCheckerable=false or not supplied then a list of application permissions is returned. The "selected"
|
||||||
|
attribute is always true in this case.
|
||||||
|
</p>
|
||||||
|
<p>If makerCheckerable=true then the "selected" attribute shows whether the permission is
|
||||||
|
enabled for Maker Check functionality.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Note: Each Mifos X transaction is associated with a permission.
|
||||||
|
</p>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
<p>Example Requests:</p>
|
<p>Example Requests:</p>
|
||||||
<div class=apiClick>permissions</div>
|
<div class=apiClick>permissions</div><br><br>
|
||||||
<br>
|
<div class=apiClick>permissions?makerCheckerable=true</div><br><br>
|
||||||
<br>
|
|
||||||
<div class=apiClick>permissions?fields=grouping,code</div>
|
<div class=apiClick>permissions?fields=grouping,code</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="method-example">
|
<div class="method-example">
|
||||||
@@ -11364,6 +11726,30 @@ GET https://DomainName/api/v1/permissions
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<a id="permissions_update" name="permissions_update" class="old-syle-anchor"> </a>
|
||||||
|
<div class="method-section">
|
||||||
|
<div class="method-description">
|
||||||
|
<h4>Enable/Disable Permissions for Maker Checker</h4>
|
||||||
|
</div>
|
||||||
|
<div class="method-example">
|
||||||
|
<code class="method-declaration">
|
||||||
|
PUT https://DomainName/api/v1/permissions
|
||||||
|
</code>
|
||||||
|
<code class="method-request">
|
||||||
|
PUT permissions
|
||||||
|
Content-Type: application/json
|
||||||
|
Request Body:
|
||||||
|
{
|
||||||
|
"permissions":{
|
||||||
|
"CREATE_GUARANTOR":true,
|
||||||
|
"CREATE_CLIENT":true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- start of accounting api docs -->
|
<!-- start of accounting api docs -->
|
||||||
<a id="glaccounts" name="glaccounts" class="old-syle-anchor"> </a>
|
<a id="glaccounts" name="glaccounts" class="old-syle-anchor"> </a>
|
||||||
<div class="method-section">
|
<div class="method-section">
|
||||||
@@ -12985,46 +13371,46 @@ GET https://DomainName/api/v1/search?query=000000111
|
|||||||
<td><a href="#configs_codes_codevalues_update">Update a Code Value</a></td>
|
<td><a href="#configs_codes_codevalues_update">Update a Code Value</a></td>
|
||||||
<td><a href="#configs_codes_codevalues_delete">Delete a Code Value</a></td>
|
<td><a href="#configs_codes_codevalues_delete">Delete a Code Value</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="#audits">Audits</a></td>
|
<td><a href="#audits">Audits</a></td>
|
||||||
<td>audits</td>
|
<td>audits</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td><a href="#audits_list">List Audits</a></td>
|
<td><a href="#audits_list">List Audits</a></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="alt">
|
<tr class="alt">
|
||||||
<td></td>
|
<td></td>
|
||||||
<td>audits/{auditId}</td>
|
<td>audits/{auditId}</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td><a href="#audits_retrieve">Retrieve an Audit Entry</a></td>
|
<td><a href="#audits_retrieve">Retrieve an Audit Entry</a></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="#makercheckers">Makercheckers</a></td>
|
<td><a href="#makercheckers">Makercheckers</a></td>
|
||||||
<td>makercheckers</td>
|
<td>makercheckers</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td><a href="#makercheckers_list">List Maker Checker Entries</a></td>
|
<td><a href="#makercheckers_list">List Maker Checker Entries</a></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="alt">
|
<tr class="alt">
|
||||||
<td></td>
|
<td></td>
|
||||||
<td>makercheckers/{auditId}</td>
|
<td>makercheckers/{auditId}</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td><a href="#makercheckers_delete">Delete Maker Checker Entry</a></td>
|
<td><a href="#makercheckers_delete">Delete Maker Checker Entry</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td>makercheckers/{auditId}?command=approve</td>
|
<td>makercheckers/{auditId}?command=approve</td>
|
||||||
<td><a href="#makercheckers_approve">Approve Maker Checker Entry</a></td>
|
<td><a href="#makercheckers_approve">Approve Maker Checker Entry</a></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="alt">
|
<tr class="alt">
|
||||||
<td><a href="#funds">Funds</a></td>
|
<td><a href="#funds">Funds</a></td>
|
||||||
<td>funds</td>
|
<td>funds</td>
|
||||||
@@ -13297,8 +13683,8 @@ GET https://DomainName/api/v1/search?query=000000111
|
|||||||
<td><a href="#permissions">Permission</a></td>
|
<td><a href="#permissions">Permission</a></td>
|
||||||
<td>permissions</td>
|
<td>permissions</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td><a href="#permissions_list">List Permissions</a></td>
|
<td><a href="#permissions_list">List Application Permissions</a></td>
|
||||||
<td></td>
|
<td><a href="#permissions_update">Enable/Disable Permissions for Maker Checker</a></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
Remove READ_MAKERCHECKER permission as no longer used.
|
||||||
|
*/
|
||||||
|
|
||||||
|
delete from m_role_permission
|
||||||
|
where exists
|
||||||
|
(select 'f' from m_permission p
|
||||||
|
where p.id = m_role_permission.permission_id and p.code = 'READ_MAKERCHECKER');
|
||||||
|
|
||||||
|
|
||||||
|
delete from m_permission
|
||||||
|
where code = 'READ_MAKERCHECKER';
|
||||||
|
|
||||||
|
|
||||||
+3
-11
@@ -34,7 +34,6 @@ 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.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;
|
||||||
@@ -50,9 +49,10 @@ public class MakercheckersApiResource {
|
|||||||
"checkedOnDate", "processingResult", "commandAsJson",
|
"checkedOnDate", "processingResult", "commandAsJson",
|
||||||
"officeName", "groupLevelName", "groupName", "clientName",
|
"officeName", "groupLevelName", "groupName", "clientName",
|
||||||
"loanAccountNo", "savingsAccountNo"));
|
"loanAccountNo", "savingsAccountNo"));
|
||||||
private final String resourceNameForPermissions = "MAKERCHECKER";
|
|
||||||
|
|
||||||
private final PlatformSecurityContext context;
|
//Next line removed because read permissions checks part of read services
|
||||||
|
//private final String resourceNameForPermissions = "MAKERCHECKER";
|
||||||
|
|
||||||
private final AuditReadPlatformService readPlatformService;
|
private final AuditReadPlatformService readPlatformService;
|
||||||
private final DefaultToApiJsonSerializer<CommandSourceData> toApiJsonSerializer;
|
private final DefaultToApiJsonSerializer<CommandSourceData> toApiJsonSerializer;
|
||||||
private final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializerAudit;
|
private final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializerAudit;
|
||||||
@@ -62,14 +62,12 @@ public class MakercheckersApiResource {
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public MakercheckersApiResource(
|
public MakercheckersApiResource(
|
||||||
final PlatformSecurityContext context,
|
|
||||||
final AuditReadPlatformService readPlatformService,
|
final AuditReadPlatformService readPlatformService,
|
||||||
final DefaultToApiJsonSerializer<CommandSourceData> toApiJsonSerializer,
|
final DefaultToApiJsonSerializer<CommandSourceData> toApiJsonSerializer,
|
||||||
final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializerAudit,
|
final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializerAudit,
|
||||||
final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate,
|
final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate,
|
||||||
final ApiRequestParameterHelper apiRequestParameterHelper,
|
final ApiRequestParameterHelper apiRequestParameterHelper,
|
||||||
final PortfolioCommandSourceWritePlatformService writePlatformService) {
|
final PortfolioCommandSourceWritePlatformService writePlatformService) {
|
||||||
this.context = context;
|
|
||||||
this.readPlatformService = readPlatformService;
|
this.readPlatformService = readPlatformService;
|
||||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||||
@@ -94,9 +92,6 @@ public class MakercheckersApiResource {
|
|||||||
@QueryParam("loanid") final Integer loanId,
|
@QueryParam("loanid") final Integer loanId,
|
||||||
@QueryParam("savingsAccountId") final Integer savingsAccountId) {
|
@QueryParam("savingsAccountId") final Integer savingsAccountId) {
|
||||||
|
|
||||||
context.authenticatedUser().validateHasReadPermission(
|
|
||||||
resourceNameForPermissions);
|
|
||||||
|
|
||||||
final String extraCriteria = getExtraCriteria(actionName, entityName,
|
final String extraCriteria = getExtraCriteria(actionName, entityName,
|
||||||
resourceId, makerId, makerDateTimeFrom, makerDateTimeTo,
|
resourceId, makerId, makerDateTimeFrom, makerDateTimeTo,
|
||||||
officeId, groupId, clientId, loanId, savingsAccountId);
|
officeId, groupId, clientId, loanId, savingsAccountId);
|
||||||
@@ -118,9 +113,6 @@ public class MakercheckersApiResource {
|
|||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
public String retrieveAuditSearchTemplate(@Context final UriInfo uriInfo) {
|
public String retrieveAuditSearchTemplate(@Context final UriInfo uriInfo) {
|
||||||
|
|
||||||
context.authenticatedUser().validateHasReadPermission(
|
|
||||||
resourceNameForPermissions);
|
|
||||||
|
|
||||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper
|
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper
|
||||||
.process(uriInfo.getQueryParameters());
|
.process(uriInfo.getQueryParameters());
|
||||||
|
|
||||||
|
|||||||
+137
-121
@@ -25,159 +25,175 @@ import org.springframework.data.jpa.domain.AbstractPersistable;
|
|||||||
@Table(name = "m_portfolio_command_source")
|
@Table(name = "m_portfolio_command_source")
|
||||||
public class CommandSource extends AbstractPersistable<Long> {
|
public class CommandSource extends AbstractPersistable<Long> {
|
||||||
|
|
||||||
@Column(name = "action_name", nullable = true, length = 100)
|
@Column(name = "action_name", nullable = true, length = 100)
|
||||||
private String actionName;
|
private String actionName;
|
||||||
|
|
||||||
@Column(name = "entity_name", nullable = true, length = 100)
|
@Column(name = "entity_name", nullable = true, length = 100)
|
||||||
private String entityName;
|
private String entityName;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Column(name = "office_id")
|
@Column(name = "office_id")
|
||||||
private Long officeId;
|
private Long officeId;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Column(name = "group_id")
|
@Column(name = "group_id")
|
||||||
private Long groupId;
|
private Long groupId;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Column(name = "client_id")
|
@Column(name = "client_id")
|
||||||
private Long clientId;
|
private Long clientId;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Column(name = "loan_id")
|
@Column(name = "loan_id")
|
||||||
private Long loanId;
|
private Long loanId;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Column(name = "savings_account_id")
|
@Column(name = "savings_account_id")
|
||||||
private Long savingsId;
|
private Long savingsId;
|
||||||
|
|
||||||
@Column(name = "api_get_url", length = 100)
|
@Column(name = "api_get_url", length = 100)
|
||||||
private String resourceGetUrl;
|
private String resourceGetUrl;
|
||||||
|
|
||||||
@Column(name = "resource_id")
|
@Column(name = "resource_id")
|
||||||
private Long resourceId;
|
private Long resourceId;
|
||||||
|
|
||||||
@Column(name = "subresource_id")
|
@Column(name = "subresource_id")
|
||||||
private Long subresourceId;
|
private Long subresourceId;
|
||||||
|
|
||||||
@Column(name = "command_as_json", length = 1000)
|
@Column(name = "command_as_json", length = 1000)
|
||||||
private String commandAsJson;
|
private String commandAsJson;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "maker_id", nullable = false)
|
@JoinColumn(name = "maker_id", nullable = false)
|
||||||
private AppUser maker;
|
private AppUser maker;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Column(name = "made_on_date", nullable = false)
|
@Column(name = "made_on_date", nullable = false)
|
||||||
@Temporal(TemporalType.TIMESTAMP)
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
private Date madeOnDate;
|
private Date madeOnDate;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "checker_id", nullable = true)
|
@JoinColumn(name = "checker_id", nullable = true)
|
||||||
private AppUser checker;
|
private AppUser checker;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Column(name = "checked_on_date", nullable = true)
|
@Column(name = "checked_on_date", nullable = true)
|
||||||
@Temporal(TemporalType.TIMESTAMP)
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
private Date checkedOnDate;
|
private Date checkedOnDate;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Column(name = "processing_result_enum", nullable = false)
|
@Column(name = "processing_result_enum", nullable = false)
|
||||||
private Integer processingResult;
|
private Integer processingResult;
|
||||||
|
|
||||||
public static CommandSource fullEntryFrom(final CommandWrapper wrapper, final JsonCommand command, final AppUser maker) {
|
public static CommandSource fullEntryFrom(final CommandWrapper wrapper,
|
||||||
return new CommandSource(wrapper.actionName(), wrapper.entityName(), wrapper.getHref(), command.entityId(), command.subentityId(), command.json(), maker, DateTime.now());
|
final JsonCommand command, final AppUser maker) {
|
||||||
}
|
return new CommandSource(wrapper.actionName(), wrapper.entityName(),
|
||||||
|
wrapper.getHref(), command.entityId(), command.subentityId(),
|
||||||
|
command.json(), maker, DateTime.now());
|
||||||
|
}
|
||||||
|
|
||||||
protected CommandSource() {
|
protected CommandSource() {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
private CommandSource(
|
private CommandSource(final String actionName, final String entityName,
|
||||||
final String actionName, final String entityName, final String href,
|
final String href, final Long resourceId, final Long subresourceId,
|
||||||
final Long resourceId, final Long subresourceId,
|
final String commandSerializedAsJson, final AppUser maker,
|
||||||
final String commandSerializedAsJson, final AppUser maker,
|
final DateTime madeOnDateTime) {
|
||||||
final DateTime madeOnDateTime) {
|
this.actionName = actionName;
|
||||||
this.actionName = actionName;
|
this.entityName = entityName;
|
||||||
this.entityName = entityName;
|
this.resourceGetUrl = href;
|
||||||
this.resourceGetUrl = href;
|
this.resourceId = resourceId;
|
||||||
this.resourceId = resourceId;
|
this.subresourceId = subresourceId;
|
||||||
this.subresourceId = subresourceId;
|
this.commandAsJson = commandSerializedAsJson;
|
||||||
this.commandAsJson = commandSerializedAsJson;
|
this.maker = maker;
|
||||||
this.maker = maker;
|
this.madeOnDate = madeOnDateTime.toDate();
|
||||||
this.madeOnDate = madeOnDateTime.toDate();
|
this.processingResult = CommandProcessingResultType.PROCESSED
|
||||||
this.processingResult = CommandProcessingResultType.PROCESSED.getValue();
|
.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void markAsChecked(final AppUser checker, final DateTime checkedOnDate) {
|
public void markAsChecked(final AppUser checker,
|
||||||
this.checker = checker;
|
final DateTime checkedOnDate) {
|
||||||
this.checkedOnDate = checkedOnDate.toDate();
|
this.checker = checker;
|
||||||
this.processingResult = CommandProcessingResultType.PROCESSED.getValue();
|
this.checkedOnDate = checkedOnDate.toDate();
|
||||||
}
|
this.processingResult = CommandProcessingResultType.PROCESSED
|
||||||
|
.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
public void updateResourceId(final Long resourceId) {
|
public void updateResourceId(final Long resourceId) {
|
||||||
this.resourceId = resourceId;
|
this.resourceId = resourceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateSubresourceId(final Long subresourceId) {
|
public void updateSubresourceId(final Long subresourceId) {
|
||||||
this.subresourceId = subresourceId;
|
this.subresourceId = subresourceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateJsonTo(final String json) {
|
public void updateJsonTo(final String json) {
|
||||||
this.commandAsJson = json;
|
this.commandAsJson = json;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long resourceId() {
|
public Long resourceId() {
|
||||||
return this.resourceId;
|
return this.resourceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long subresourceId() {
|
public Long subresourceId() {
|
||||||
return this.subresourceId;
|
return this.subresourceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasJson() {
|
public boolean hasJson() {
|
||||||
return StringUtils.isNotBlank(this.commandAsJson);
|
return StringUtils.isNotBlank(this.commandAsJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String json() {
|
public String json() {
|
||||||
return this.commandAsJson;
|
return this.commandAsJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getActionName() {
|
public String getActionName() {
|
||||||
return this.actionName;
|
return this.actionName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getEntityName() {
|
public String getEntityName() {
|
||||||
return this.entityName;
|
return this.entityName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPermissionCode() {
|
public String getPermissionCode() {
|
||||||
return this.actionName + "_" + this.entityName;
|
return this.actionName + "_" + this.entityName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getResourceId() {
|
public Long getResourceId() {
|
||||||
return this.resourceId;
|
return this.resourceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getSubresourceId() {
|
public Long getSubresourceId() {
|
||||||
return this.subresourceId;
|
return this.subresourceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void markAsAwaitingApproval() {
|
public void markAsAwaitingApproval() {
|
||||||
this.processingResult = CommandProcessingResultType.AWAITING_APPROVAL.getValue();
|
this.processingResult = CommandProcessingResultType.AWAITING_APPROVAL
|
||||||
}
|
.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
public void updateForAudit(final Long officeId, final Long groupId, final Long clientId, final Long loanId, final Long savingsId) {
|
public boolean isMarkedAsAwaitingApproval() {
|
||||||
this.officeId = officeId;
|
if (this.processingResult
|
||||||
this.groupId = groupId;
|
.equals(CommandProcessingResultType.AWAITING_APPROVAL
|
||||||
this.clientId = clientId;
|
.getValue()))
|
||||||
this.loanId = loanId;
|
return true;
|
||||||
this.savingsId = savingsId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getResourceGetUrl() {
|
return false;
|
||||||
return this.resourceGetUrl;
|
}
|
||||||
}
|
|
||||||
|
public void updateForAudit(final Long officeId, final Long groupId,
|
||||||
|
final Long clientId, final Long loanId, final Long savingsId) {
|
||||||
|
this.officeId = officeId;
|
||||||
|
this.groupId = groupId;
|
||||||
|
this.clientId = clientId;
|
||||||
|
this.loanId = loanId;
|
||||||
|
this.savingsId = savingsId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getResourceGetUrl() {
|
||||||
|
return this.resourceGetUrl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* 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,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
package org.mifosplatform.commands.exception;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link RuntimeException} thrown when client resources are not found.
|
||||||
|
*/
|
||||||
|
public class CommandNotAwaitingApprovalException extends AbstractPlatformResourceNotFoundException {
|
||||||
|
|
||||||
|
public CommandNotAwaitingApprovalException(Long id) {
|
||||||
|
super("error.msg.command.id.not.awaiting.approval", "Audit with identifier " + id + " is Not Awaiting Approval", id);
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -13,6 +13,6 @@ import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceN
|
|||||||
public class CommandNotFoundException extends AbstractPlatformResourceNotFoundException {
|
public class CommandNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||||
|
|
||||||
public CommandNotFoundException(Long id) {
|
public CommandNotFoundException(Long id) {
|
||||||
super("error.msg.command.id.invalid", "Command with identifier " + id + " does not exist", id);
|
super("error.msg.command.id.invalid", "Audit with identifier " + id + " does not exist", id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+100
-66
@@ -8,12 +8,13 @@ package org.mifosplatform.commands.service;
|
|||||||
import org.mifosplatform.commands.domain.CommandSource;
|
import org.mifosplatform.commands.domain.CommandSource;
|
||||||
import org.mifosplatform.commands.domain.CommandSourceRepository;
|
import org.mifosplatform.commands.domain.CommandSourceRepository;
|
||||||
import org.mifosplatform.commands.domain.CommandWrapper;
|
import org.mifosplatform.commands.domain.CommandWrapper;
|
||||||
|
import org.mifosplatform.commands.exception.CommandNotAwaitingApprovalException;
|
||||||
|
import org.mifosplatform.commands.exception.CommandNotFoundException;
|
||||||
import org.mifosplatform.commands.exception.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
|
import org.mifosplatform.commands.exception.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
|
||||||
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.serialization.FromJsonHelper;
|
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||||
import org.mifosplatform.portfolio.client.exception.ClientNotFoundException;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@@ -21,87 +22,120 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class PortfolioCommandSourceWritePlatformServiceImpl implements PortfolioCommandSourceWritePlatformService {
|
public class PortfolioCommandSourceWritePlatformServiceImpl implements
|
||||||
|
PortfolioCommandSourceWritePlatformService {
|
||||||
|
|
||||||
private final PlatformSecurityContext context;
|
private final PlatformSecurityContext context;
|
||||||
private final CommandSourceRepository commandSourceRepository;
|
private final CommandSourceRepository commandSourceRepository;
|
||||||
private final FromJsonHelper fromApiJsonHelper;
|
private final FromJsonHelper fromApiJsonHelper;
|
||||||
private final CommandProcessingService processAndLogCommandService;
|
private final CommandProcessingService processAndLogCommandService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public PortfolioCommandSourceWritePlatformServiceImpl(final PlatformSecurityContext context,
|
public PortfolioCommandSourceWritePlatformServiceImpl(
|
||||||
final CommandSourceRepository commandSourceRepository, final FromJsonHelper fromApiJsonHelper,
|
final PlatformSecurityContext context,
|
||||||
final CommandProcessingService processAndLogCommandService) {
|
final CommandSourceRepository commandSourceRepository,
|
||||||
this.context = context;
|
final FromJsonHelper fromApiJsonHelper,
|
||||||
this.commandSourceRepository = commandSourceRepository;
|
final CommandProcessingService processAndLogCommandService) {
|
||||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
this.context = context;
|
||||||
this.processAndLogCommandService = processAndLogCommandService;
|
this.commandSourceRepository = commandSourceRepository;
|
||||||
}
|
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||||
|
this.processAndLogCommandService = processAndLogCommandService;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandProcessingResult logCommandSource(final CommandWrapper wrapper) {
|
public CommandProcessingResult logCommandSource(final CommandWrapper wrapper) {
|
||||||
|
|
||||||
boolean isApprovedByChecker = false;
|
boolean isApprovedByChecker = false;
|
||||||
// check if is update of own account details
|
// check if is update of own account details
|
||||||
if (wrapper.isUpdateOfOwnUserDetails(context.authenticatedUser().getId())) {
|
if (wrapper.isUpdateOfOwnUserDetails(context.authenticatedUser()
|
||||||
// then allow this operation to proceed.
|
.getId())) {
|
||||||
// maker checker doesnt mean anything here.
|
// then allow this operation to proceed.
|
||||||
isApprovedByChecker = true; // set to true in case permissions have
|
// maker checker doesnt mean anything here.
|
||||||
// been maker-checker enabled by
|
isApprovedByChecker = true; // set to true in case permissions have
|
||||||
// accident.
|
// been maker-checker enabled by
|
||||||
} else {
|
// accident.
|
||||||
// if not user changing their own details - check user has
|
} else {
|
||||||
// permission to perform specific task.
|
// if not user changing their own details - check user has
|
||||||
context.authenticatedUser().validateHasPermissionTo(wrapper.getTaskPermissionName());
|
// permission to perform specific task.
|
||||||
}
|
context.authenticatedUser().validateHasPermissionTo(
|
||||||
|
wrapper.getTaskPermissionName());
|
||||||
|
}
|
||||||
|
|
||||||
final String json = wrapper.getJson();
|
final String json = wrapper.getJson();
|
||||||
CommandProcessingResult result = null;
|
CommandProcessingResult result = null;
|
||||||
try {
|
try {
|
||||||
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(json);
|
final JsonElement parsedCommand = this.fromApiJsonHelper
|
||||||
final JsonCommand command = JsonCommand.from(json, parsedCommand, this.fromApiJsonHelper, wrapper.getEntityName(),
|
.parse(json);
|
||||||
wrapper.getEntityId(), wrapper.getSubentityId(), wrapper.getGroupId(), wrapper.getClientId(), wrapper.getLoanId(),
|
final JsonCommand command = JsonCommand.from(json, parsedCommand,
|
||||||
wrapper.getSavingsId(), wrapper.getCodeId(), wrapper.getSupportedEntityType(), wrapper.getSupportedEntityId(),
|
this.fromApiJsonHelper, wrapper.getEntityName(),
|
||||||
wrapper.getTransactionId());
|
wrapper.getEntityId(), wrapper.getSubentityId(),
|
||||||
|
wrapper.getGroupId(), wrapper.getClientId(),
|
||||||
|
wrapper.getLoanId(), wrapper.getSavingsId(),
|
||||||
|
wrapper.getCodeId(), wrapper.getSupportedEntityType(),
|
||||||
|
wrapper.getSupportedEntityId(), wrapper.getTransactionId());
|
||||||
|
|
||||||
result = this.processAndLogCommandService.processAndLogCommand(wrapper, command, isApprovedByChecker);
|
result = this.processAndLogCommandService.processAndLogCommand(
|
||||||
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
|
wrapper, command, isApprovedByChecker);
|
||||||
|
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
|
||||||
|
|
||||||
result = this.processAndLogCommandService.logCommand(e.getCommandSourceResult());
|
result = this.processAndLogCommandService.logCommand(e
|
||||||
}
|
.getCommandSourceResult());
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandProcessingResult approveEntry(final Long commandId) {
|
public CommandProcessingResult approveEntry(final Long makerCheckerId) {
|
||||||
|
|
||||||
final CommandSource commandSourceInput = this.commandSourceRepository.findOne(commandId);
|
CommandSource commandSourceInput = validateMakerCheckerTransaction(makerCheckerId);
|
||||||
if (commandSourceInput == null) {throw new ClientNotFoundException(commandId);}
|
|
||||||
|
|
||||||
context.authenticatedUser().validateHasCheckerPermissionTo(commandSourceInput.getPermissionCode());
|
final CommandWrapper wrapper = CommandWrapper.fromExistingCommand(
|
||||||
|
makerCheckerId, commandSourceInput.getActionName(),
|
||||||
|
commandSourceInput.getEntityName(),
|
||||||
|
commandSourceInput.resourceId(),
|
||||||
|
commandSourceInput.subresourceId(),
|
||||||
|
commandSourceInput.getResourceGetUrl());
|
||||||
|
|
||||||
final CommandWrapper wrapper = CommandWrapper.fromExistingCommand(commandId, commandSourceInput.getActionName(),
|
final JsonElement parsedCommand = this.fromApiJsonHelper
|
||||||
commandSourceInput.getEntityName(), commandSourceInput.resourceId(), commandSourceInput.subresourceId(),
|
.parse(commandSourceInput.json());
|
||||||
commandSourceInput.getResourceGetUrl());
|
final JsonCommand command = JsonCommand.fromExistingCommand(
|
||||||
|
makerCheckerId, commandSourceInput.json(), parsedCommand,
|
||||||
|
this.fromApiJsonHelper, commandSourceInput.getEntityName(),
|
||||||
|
commandSourceInput.resourceId(),
|
||||||
|
commandSourceInput.subresourceId());
|
||||||
|
|
||||||
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(commandSourceInput.json());
|
final boolean makerCheckerApproval = true;
|
||||||
final JsonCommand command = JsonCommand.fromExistingCommand(commandId, commandSourceInput.json(), parsedCommand,
|
return this.processAndLogCommandService.processAndLogCommand(wrapper,
|
||||||
this.fromApiJsonHelper, commandSourceInput.getEntityName(), commandSourceInput.resourceId(),
|
command, makerCheckerApproval);
|
||||||
commandSourceInput.subresourceId());
|
}
|
||||||
|
|
||||||
final boolean makerCheckerApproval = true;
|
@Transactional
|
||||||
return this.processAndLogCommandService.processAndLogCommand(wrapper, command, makerCheckerApproval);
|
@Override
|
||||||
}
|
public Long deleteEntry(final Long makerCheckerId) {
|
||||||
|
|
||||||
@Transactional
|
validateMakerCheckerTransaction(makerCheckerId);
|
||||||
@Override
|
|
||||||
public Long deleteEntry(final Long makerCheckerId) {
|
|
||||||
|
|
||||||
context.authenticatedUser();
|
this.commandSourceRepository.delete(makerCheckerId);
|
||||||
|
|
||||||
this.commandSourceRepository.delete(makerCheckerId);
|
return makerCheckerId;
|
||||||
|
}
|
||||||
|
|
||||||
return makerCheckerId;
|
private CommandSource validateMakerCheckerTransaction(
|
||||||
}
|
final Long makerCheckerId) {
|
||||||
|
|
||||||
|
final CommandSource commandSourceInput = this.commandSourceRepository
|
||||||
|
.findOne(makerCheckerId);
|
||||||
|
if (commandSourceInput == null) {
|
||||||
|
throw new CommandNotFoundException(makerCheckerId);
|
||||||
|
}
|
||||||
|
if (!(commandSourceInput.isMarkedAsAwaitingApproval())) {
|
||||||
|
throw new CommandNotAwaitingApprovalException(makerCheckerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.authenticatedUser().validateHasCheckerPermissionTo(
|
||||||
|
commandSourceInput.getPermissionCode());
|
||||||
|
|
||||||
|
return commandSourceInput;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -441,7 +441,7 @@ public class AppUser extends AbstractPersistable<Long> implements PlatformUser {
|
|||||||
public void validateHasCheckerPermissionTo(final String function) {
|
public void validateHasCheckerPermissionTo(final String function) {
|
||||||
|
|
||||||
final String checkerPermissionName = function.toUpperCase() + "_CHECKER";
|
final String checkerPermissionName = function.toUpperCase() + "_CHECKER";
|
||||||
if (hasNotPermissionTo(checkerPermissionName)) {
|
if (hasNotPermissionTo("CHECKER_SUPER_USER") && hasNotPermissionTo(checkerPermissionName)) {
|
||||||
final String authorizationMessage = "User has no authority to be a checker for: " + function;
|
final String authorizationMessage = "User has no authority to be a checker for: " + function;
|
||||||
throw new NoAuthorizationException(authorizationMessage);
|
throw new NoAuthorizationException(authorizationMessage);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user