doc changes and related code changes around client update.

This commit is contained in:
Keith Woodlock
2012-05-22 23:05:58 +01:00
parent 87275e1d47
commit 7e6f11d398
10 changed files with 697 additions and 240 deletions
+559 -186
View File
@@ -30,12 +30,12 @@
<li><a href="#clients_template">Retrieve Client Details Template</a></li> <li><a href="#clients_template">Retrieve Client Details Template</a></li>
<li><a href="#clients_retrieve">Retrieve a Client</a></li> <li><a href="#clients_retrieve">Retrieve a Client</a></li>
<li><a href="#clients_create">Create a Client</a></li> <li><a href="#clients_create">Create a Client</a></li>
<li><a href="#clients_update">Update a Client</a></li>
<li><a href="#clients_loansummary">Retrieve a Client's Loan Account Summary</a></li> <li><a href="#clients_loansummary">Retrieve a Client's Loan Account Summary</a></li>
<li><a href="#clients_notes">Retrieve a Client's Notes</a></li> <li><a href="#clients_notes">Retrieve a Client's Notes</a></li>
<li><a href="#clients_addnote">Add a Client Note</a></li> <li><a href="#clients_addnote">Add a Client Note</a></li>
<li><a href="#clients_retrievenote">Retrieve a Client Note</a></li> <li><a href="#clients_retrievenote">Retrieve a Client Note</a></li>
<li><a href="#clients_updatenote">Update a Client Note</a></li> <li><a href="#clients_updatenote">Update a Client Note</a></li>
No update a client?
</ul> </ul>
</div> </div>
</div> </div>
@@ -47,7 +47,6 @@
<li><a href="#loans_template">Retrieve Loan Details Template</a></li> <li><a href="#loans_template">Retrieve Loan Details Template</a></li>
<li><a href="#loans_retrieve">Retrieve a Loan</a></li> <li><a href="#loans_retrieve">Retrieve a Loan</a></li>
<li><a href="#loans_create">Create a New Loan</a></li> <li><a href="#loans_create">Create a New Loan</a></li>
<li><a href="#loans_submit">Submit a Loan Application</a></li>
<li><a href="#loans_approve">Approve a Loan</a></li> <li><a href="#loans_approve">Approve a Loan</a></li>
<li><a href="#loans_disburse">Disburse a Loan</a></li> <li><a href="#loans_disburse">Disburse a Loan</a></li>
<li><a href="#loans_reject">Reject a Loan</a></li> <li><a href="#loans_reject">Reject a Loan</a></li>
@@ -188,67 +187,67 @@
<div class="method-example" id="api-summary-example"> <div class="method-example" id="api-summary-example">
<h4>API Endpoint</h4> <h4>API Endpoint</h4>
<code>https://thedomainname/</code> <code>https://thedomainname/api</code>
<h6>Summary of Resource URL Patterns</h6> <h6>Summary of Resource URL Patterns</h6>
<table> <table>
<tr><td><b>Resources</b></td><td><b>Verbs</b></td></tr> <tr><td><b>Resources</b></td><td><b>Verbs</b></td></tr>
<tr><td>/api/v1/clients</td><td>GET, POST</td></tr> <tr><td>/v1/clients</td><td>GET, POST</td></tr>
<tr><td>/api/v1/clients/template</td><td>GET</td></tr> <tr><td>/v1/clients/template</td><td>GET</td></tr>
<tr><td>/api/v1/clients/{clientId}</td><td>GET</td></tr> <tr><td>/v1/clients/{clientId}</td><td>GET</td></tr>
<tr><td>/api/v1/clients/{clientId}/loans</td><td>GET</td></tr> <tr><td>/v1/clients/{clientId}/loans</td><td>GET</td></tr>
<tr><td>/api/v1/clients/{clientId}/notes</td><td>GET, POST</td></tr> <tr><td>/v1/clients/{clientId}/notes</td><td>GET, POST</td></tr>
<tr><td>/api/v1/clients/{clientId}/notes/{noteId}</td><td>GET, PUT</td></tr> <tr><td>/v1/clients/{clientId}/notes/{noteId}</td><td>GET, PUT</td></tr>
<tr><td></td><td></td></tr> <tr><td></td><td></td></tr>
<tr><td></td><td></td></tr> <tr><td></td><td></td></tr>
<tr><td>/api/v1/loans</td><td>POST</td></tr> <tr><td>/v1/loans</td><td>POST</td></tr>
<tr><td>/api/v1/loans/template</td><td>GET</td></tr> <tr><td>/v1/loans/template</td><td>GET</td></tr>
<tr><td>/api/v1/loans/{loanId}</td><td>GET, POST, DELETE</td></tr> <tr><td>/v1/loans/{loanId}</td><td>GET, POST, DELETE</td></tr>
<tr><td>/api/v1/loans/{loanId}/undo</td><td>POST</td></tr> <tr><td>/v1/loans/{loanId}/undo</td><td>POST</td></tr>
<tr><td>/api/v1/loans/{loanId}/transactions/template</td><td>GET</td></tr> <tr><td>/v1/loans/{loanId}/transactions/template</td><td>GET</td></tr>
<tr><td>/api/v1/loans/{loanId}/transactions</td><td>POST</td></tr> <tr><td>/v1/loans/{loanId}/transactions</td><td>POST</td></tr>
<tr><td>/api/v1/loans/{loanId}/transactions/{repaymentId}</td><td>GET, PUT</td></tr> <tr><td>/v1/loans/{loanId}/transactions/{repaymentId}</td><td>GET, PUT</td></tr>
<tr><td></td><td></td></tr> <tr><td></td><td></td></tr>
<tr><td></td><td></td></tr> <tr><td></td><td></td></tr>
<tr><td>/api/v1/offices</td><td>GET, POST</td></tr> <tr><td>/v1/offices</td><td>GET, POST</td></tr>
<tr><td>/api/v1/offices/template</td><td>GET</td></tr> <tr><td>/v1/offices/template</td><td>GET</td></tr>
<tr><td>/api/v1/offices/{officeId}</td><td>GET, PUT</td></tr> <tr><td>/v1/offices/{officeId}</td><td>GET, PUT</td></tr>
<tr><td></td><td></td></tr> <tr><td></td><td></td></tr>
<tr><td></td><td></td></tr> <tr><td></td><td></td></tr>
<tr><td>/api/v1/loanproducts</td><td>GET, POST</td></tr> <tr><td>/v1/loanproducts</td><td>GET, POST</td></tr>
<tr><td>/api/v1/loanproducts/template</td><td>GET</td></tr> <tr><td>/v1/loanproducts/template</td><td>GET</td></tr>
<tr><td>/api/v1/loanproducts/{productId}</td><td>GET, PUT</td></tr> <tr><td>/v1/loanproducts/{productId}</td><td>GET, PUT</td></tr>
<tr><td></td><td></td></tr> <tr><td></td><td></td></tr>
<tr><td></td><td></td></tr> <tr><td></td><td></td></tr>
<tr><td>/api/v1/configurations/currency</td><td>GET, PUT</td></tr> <tr><td>/v1/configurations/currency</td><td>GET, PUT</td></tr>
<tr><td></td><td></td></tr> <tr><td></td><td></td></tr>
<tr><td></td><td></td></tr> <tr><td></td><td></td></tr>
<tr><td>/api/v1/additionalfields</td><td>GET</td></tr> <tr><td>/v1/additionalfields</td><td>GET</td></tr>
<tr><td>/api/v1/additionalfields/{Type}/{Set}/{id}</td><td>GET, POST</td></tr> <tr><td>/v1/additionalfields/{Type}/{Set}/{id}</td><td>GET, POST</td></tr>
<tr><td></td><td></td></tr> <tr><td></td><td></td></tr>
<tr><td></td><td></td></tr> <tr><td></td><td></td></tr>
<tr><td>/api/v1/reports</td><td>GET</td></tr> <tr><td>/v1/reports</td><td>GET</td></tr>
<tr><td>/api/v1/reports/{reportName}</td><td>GET</td></tr> <tr><td>/v1/reports/{reportName}</td><td>GET</td></tr>
<tr><td></td><td></td></tr> <tr><td></td><td></td></tr>
<tr><td></td><td></td></tr> <tr><td></td><td></td></tr>
<tr><td>/api/v1/authentication</td><td>POST</td></tr> <tr><td>/v1/authentication</td><td>POST</td></tr>
<tr><td></td><td></td></tr> <tr><td></td><td></td></tr>
<tr><td></td><td></td></tr> <tr><td></td><td></td></tr>
<tr><td>/api/v1/useraccounts/current</td><td>GET, PUT</td></tr> <tr><td>/v1/useraccounts/current</td><td>GET, PUT</td></tr>
<tr><td>/api/v1/useraccounts/current/password</td><td>PUT</td></tr> <tr><td>/v1/useraccounts/current/password</td><td>PUT</td></tr>
<tr><td>/api/v1/useraccounts/current/password/template</td><td>GET</td></tr> <tr><td>/v1/useraccounts/current/password/template</td><td>GET</td></tr>
<tr><td></td><td></td></tr> <tr><td></td><td></td></tr>
<tr><td></td><td></td></tr> <tr><td></td><td></td></tr>
<tr><td>/api/v1/users</td><td>GET, POST</td></tr> <tr><td>/v1/users</td><td>GET, POST</td></tr>
<tr><td>/api/v1/users/template</td><td>GET</td></tr> <tr><td>/v1/users/template</td><td>GET</td></tr>
<tr><td>/api/v1/users/{userId}</td><td>GET, PUT, DELETE</td></tr> <tr><td>/v1/users/{userId}</td><td>GET, PUT, DELETE</td></tr>
<tr><td></td><td></td></tr> <tr><td></td><td></td></tr>
<tr><td></td><td></td></tr> <tr><td></td><td></td></tr>
<tr><td>/api/v1/roles</td><td>GET, POST</td></tr> <tr><td>/v1/roles</td><td>GET, POST</td></tr>
<tr><td>/api/v1/roles/template</td><td>GET</td></tr> <tr><td>/v1/roles/template</td><td>GET</td></tr>
<tr><td>/api/v1/roles/{roleId}</td><td>GET, PUT</td></tr> <tr><td>/v1/roles/{roleId}</td><td>GET, PUT</td></tr>
<tr><td></td><td></td></tr> <tr><td></td><td></td></tr>
<tr><td></td><td></td></tr> <tr><td></td><td></td></tr>
<tr><td>/api/v1/permissions</td><td>GET</td></tr> <tr><td>/v1/permissions</td><td>GET</td></tr>
</table> </table>
</div> </div>
</div> </div>
@@ -442,8 +441,7 @@
<div class="method-section"> <div class="method-section">
<div class="method-description"> <div class="method-description">
<h3>Clients</h3> <h3>Clients</h3>
<p>Clients words. <p>Clients ...</p>
</p>
</div> </div>
</div> </div>
@@ -475,13 +473,46 @@
<div class="method-description"> <div class="method-description">
<h4>List Clients</h4> <h4>List Clients</h4>
<p>Example Request: <p>Example Request:
<a style="word-wrap: break-word;" href="http://localhost:8080/mifosng-provider/api/v1/clients">http://localhost:8080/mifosng-provider/api/v1/clients</a> <a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/clients">https://localhost:8443/mifosng-provider/api/v1/clients</a>
</p> </p>
</div> </div>
<div class="method-example"> <div class="method-example">
<code class="method-declaration">GET https://thedomainname/api/v1/clients</code> <code class="method-declaration">GET https://thedomainname/api/v1/clients</code>
<code class="method-response"> to be done <code class="method-response">{
</code> "clients": [
{
"organisationId": 1,
"organisationName": "Demo MFI",
"officeId": 2,
"officeName": "sub branch 1",
"id": 14,
"firstname": "Patrick",
"lastname": "Asare-Frimpong",
"displayName": "Patrick Asare-Frimpong",
"externalId": null,
"joinedDate": "2012-04-18",
"allowedOffices": [],
"maxJoinedOnOffsetFromToday": -34
},
...
...
{
"organisationId": 1,
"organisationName": "Demo MFI",
"officeId": 1,
"officeName": "Demo MFI Head Office",
"id": 17,
"firstname": "Fred",
"lastname": "Ziffle",
"displayName": "Fred Ziffle",
"externalId": null,
"joinedDate": "2012-04-21",
"allowedOffices": [],
"maxJoinedOnOffsetFromToday": -31
}
]
}
</code>
</div> </div>
</div> </div>
@@ -490,16 +521,49 @@
<div class="method-section"> <div class="method-section">
<div class="method-description"> <div class="method-description">
<h4>Retrieve Client Details Template</h4> <h4>Retrieve Client Details Template</h4>
<p>Returns a template that contains the client fields and allowed value lists. This helps build a maintenance User Interface. <p>Returns a template that contains the client fields and allowed value lists. This helps build a maintenance User Interface.</p>
</p>
<p>Example Request: <p>Example Request:
<a style="word-wrap: break-word;" href="http://localhost:8080/mifosng-provider/api/v1/clients/template">http://localhost:8080/mifosng-provider/api/v1/clients/template</a> <a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/clients/template">https://localhost:8443/mifosng-provider/api/v1/clients/template</a>
</p> </p>
</div> </div>
<div class="method-example"> <div class="method-example">
<code class="method-declaration">GET https://thedomainname/api/v1/clients/template</code> <code class="method-declaration">GET https://thedomainname/api/v1/clients/template</code>
<code class="method-response"> to be done <code class="method-response">{
</code> "organisationId": 1,
"organisationName": null,
"officeId": 1,
"officeName": null,
"id": -1,
"firstname": "",
"lastname": "",
"displayName": "",
"externalId": null,
"joinedDate": "2012-05-22",
"allowedOffices": [
{
"id": 1,
"name": "Demo MFI Head Office",
"externalId": "1",
"openingDate": "2009-01-01",
"hierarchy": ".",
"parentName": null,
"parentId": 0,
"allowedParents": []
},
{
"id": 2,
"name": "sub branch 1",
"externalId": "2",
"openingDate": "2012-01-02",
"hierarchy": ".2.",
"parentName": "Demo MFI Head Office",
"parentId": 1,
"allowedParents": []
}
],
"maxJoinedOnOffsetFromToday": 0
}
</code>
</div> </div>
</div> </div>
@@ -508,119 +572,241 @@
<div class="method-section"> <div class="method-section">
<div class="method-description"> <div class="method-description">
<h4>Retrieve a Client</h4> <h4>Retrieve a Client</h4>
<p>Returns client fields. It also returns allowed value lists which help build a maintenance User Interface. <p>Returns client fields. It also returns allowed value lists which help build a maintenance User Interface.
</p> </p>
<p>Example Request: <p>Example Request:
<a style="word-wrap: break-word;" href="http://localhost:8080/mifosng-provider/api/v1/clients/1">http://localhost:8080/mifosng-provider/api/v1/clients/1</a> <a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/clients/1">https://localhost:8443/mifosng-provider/api/v1/clients/1</a>
</p> </p>
</div> </div>
<div class="method-example"> <div class="method-example">
<code class="method-declaration">GET https://thedomainname/api/v1/clients/{clientId}</code> <code class="method-declaration">GET https://thedomainname/api/v1/clients/{clientId}</code>
<code class="method-response"> <code class="method-response">{
</code> "organisationId": 1,
"organisationName": "Demo MFI",
"officeId": 1,
"officeName": "Demo MFI Head Office",
"id": 1,
"firstname": "Patrick",
"lastname": "O'Meara",
"displayName": "Patrick O'Meara",
"externalId": null,
"joinedDate": "2009-01-04",
"allowedOffices": [],
"maxJoinedOnOffsetFromToday": -1234
}
</code>
</div> </div>
</div> </div>
<a id="clients_create" name="clients_create" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Create a Client</h4>
</div>
<div class="method-example">
<code class="method-declaration">POST https://thedomainname/api/v1/clients</code>
<code class="method-request">https://localhost:8443/mifosng-provider/api/v1/clients
Content-Type: application/json
Request Body:
{
"officeId": 1,
"firstname": "Firstname",
"lastname": "Surname",
"externalId": null,
"dateFormat": "dd MMMM yyyy",
"joiningDateFormatted": "04 March 2009"
}
</code>
<code class="method-response">{ "entityId": 2}</code>
</div>
</div>
<a id="clients_create" name="clients_create" class="old-syle-anchor">&nbsp;</a> <a id="clients_update" name="clients_update" class="old-syle-anchor">&nbsp;</a>
<div class="method-section"> <div class="method-section">
<div class="method-description"> <div class="method-description">
<h4>Create a Client</h4> <h4>Update a Client</h4>
</div> </div>
<div class="method-example"> <div class="method-example">
<code class="method-declaration">POST https://thedomainname/api/v1/clients</code> <code class="method-declaration">PUT https://thedomainname/api/v1/clients/1</code>
<code class="method-request">http://localhost:8080/mifosng-provider/api/v1/clients <code class="method-request">PUT https://localhost:8443/mifosng-provider/api/v1/clients/1
Content-Type: application/json
Request Body:
{
"officeId": 1,
"firstname": "Firstname",
"lastname": "Surname",
"externalId": null,
"dateFormat": "dd MMMM yyyy",
"joiningDateFormatted": "04 March 2009"
}
</code>
<code class="method-response">{ "entityId": 2}</code>
</div>
</div>
<a id="clients_loansummary" name="clients_loansummary" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Retrieve a Client's Loan Account Summary</h4>
<p>Example Request:
<a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/clients/1/loans">https://localhost:8443/mifosng-provider/api/v1/clients/1/loans</a>
</p>
</div>
<div class="method-example">
<code class="method-declaration">GET https://thedomainname/api/v1/clients/{clientId}/loans</code>
<code class="method-response">{
"pendingApprovalLoans": [],
"awaitingDisbursalLoans": [
{
"id": 17,
"externalId": null,
"loanProductId": 1,
"loanProductName": "Agricultural Loan",
"loanStatusId": 200,
"pendingApproval": false,
"waitingForDisbursal": true,
"open": false,
"closed": false,
"lifeCycleStatusText": "Approved",
"lifeCycleStatusDate": null
}
],
"openLoans": [],
"closedLoans": [
{
"id": 1,
"externalId": null,
"loanProductId": 1,
"loanProductName": "Agricultural Loan",
"loanStatusId": 600,
"pendingApproval": false,
"waitingForDisbursal": false,
"open": false,
"closed": true,
"lifeCycleStatusText": "Closed",
"lifeCycleStatusDate": null
}
],
"anyLoanCount": 2,
"pendingApprovalLoanCount": 0,
"awaitingDisbursalLoanCount": 1,
"activeLoanCount": 0,
"closedLoanCount": 1
}
</code>
</div>
</div>
Content-Type: application/json <a id="clients_notes" name="clients_notes" class="old-syle-anchor">&nbsp;</a>
Request Body: <div class="method-section">
new json here <div class="method-description">
</code> <h4>Retrieve a Client's Notes</h4>
<code class="method-response"> { "entityId": 2 } <p>Example Request:
</code> <a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/clients/2/notes">https://localhost:8443/mifosng-provider/api/v1/clients/2/notes</a>
</div> </p>
</div> </div>
<a id="clients_loansummary" name="clients_loansummary" class="old-syle-anchor">&nbsp;</a> <div class="method-example">
<div class="method-section"> <code class="method-declaration">GET https://thedomainname/api/v1/clients/{clientId}/notes</code>
<div class="method-description"> <code class="method-response">{
<h4>Retrieve a Client's Loan Account Summary</h4> "notes": [
<p>Example Request: {
<a style="word-wrap: break-word;" href="http://localhost:8080/mifosng-provider/api/v1/clients/1/loans">http://localhost:8080/mifosng-provider/api/v1/clients/1/loans</a> "id": 20,
</p> "clientId": 2,
</div> "loanId": 0,
<div class="method-example"> "loanTransactionId": 0,
<code class="method-declaration">GET https://thedomainname/api/v1/clients/{clientId}/loans</code> "noteTypeId": 100,
<code class="method-response"> "note": "This is an extra note!",
</code> "createdById": 2,
</div> "createdByUsername": "super1",
</div> "createdOn": "2012-04-22T13:50:25.000+01:00",
<a id="clients_notes" name="clients_notes" class="old-syle-anchor">&nbsp;</a> "updatedById": 2,
<div class="method-section"> "updatedByUsername": "super1",
<div class="method-description"> "updatedOn": "2012-04-22T13:50:25.000+01:00"
<h4>Retrieve a Client's Notes</h4> },
<p>Example Request: {
<a style="word-wrap: break-word;" href="http://localhost:8080/mifosng-provider/api/v1/clients/1/notes">http://localhost:8080/mifosng-provider/api/v1/clients/1/notes</a> "id": 16,
</p> "clientId": 2,
</div> "loanId": 0,
<div class="method-example"> "loanTransactionId": 0,
<code class="method-declaration">GET https://thedomainname/api/v1/clients/{clientId}/notes</code> "noteTypeId": 100,
<code class="method-response"> "note": "loan only 1/2 amount expected\r\nyes",
</code> "createdById": 2,
</div> "createdByUsername": "super1",
</div> "createdOn": "2012-04-18T15:15:04.000+01:00",
<a id="clients_addnote" name="clients_addnote" class="old-syle-anchor">&nbsp;</a> "updatedById": 2,
<div class="method-section"> "updatedByUsername": "super1",
<div class="method-description"> "updatedOn": "2012-04-23T09:38:13.000+01:00"
<h4>Add a Client Note</h4> }
</div> ]
<div class="method-example"> }
<code class="method-declaration">POST https://thedomainname/api/v1/clients/{clientId}/notes</code> </code>
<code class="method-request">http://localhost:8080/mifosng-provider/api/v1/clients/1/notes </div>
</div>
<a id="clients_addnote" name="clients_addnote" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Add a Client Note</h4>
</div>
<div class="method-example">
<code class="method-declaration">POST https://thedomainname/api/v1/clients/{clientId}/notes</code>
<code class="method-request">POST https://localhost:8443/mifosng-provider/api/v1/clients/1/notes
Content-Type: application/json
Request Body:
{
"note": "a note about the client"
}
</code>
<code class="method-response">{ "entityId": 40}</code>
</div>
</div>
Content-Type: application/json <a id="clients_retrievenote" name="clients_retrievenote" class="old-syle-anchor">&nbsp;</a>
Request Body: <div class="method-section">
new json here <div class="method-description">
</code> <h4>Retrieve a Client Note</h4>
<code class="method-response"> { "entityId": 2 } <p>Example Request:
</code> <a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/clients/1/notes/40">https://localhost:8443/mifosng-provider/api/v1/clients/1/notes/40</a>
</div> </p>
</div> </div>
<div class="method-example">
<a id="clients_retrievenote" name="clients_retrievenote" class="old-syle-anchor">&nbsp;</a> <code class="method-declaration">GET https://thedomainname/api/v1/clients/{clientId}/notes/{noteId}</code>
<div class="method-section"> <code class="method-response">{
<div class="method-description"> "id": 40,
<h4>Retrieve a Client Note</h4> "clientId": 2,
<p>Example Request: "loanId": 0,
<a style="word-wrap: break-word;" href="http://localhost:8080/mifosng-provider/api/v1/clients/1/notes/1">http://localhost:8080/mifosng-provider/api/v1/clients/1/notes/1</a> "loanTransactionId": 0,
</p> "noteTypeId": 100,
</div> "note": "a note about the client",
<div class="method-example"> "createdById": 1,
<code class="method-declaration">GET https://thedomainname/api/v1/clients/{clientId}/notes/{noteId}</code> "createdByUsername": "mifos",
<code class="method-response"> "createdOn": "2012-05-22T21:40:05.000+01:00",
</code> "updatedById": 1,
</div> "updatedByUsername": "mifos",
</div> "updatedOn": "2012-05-22T21:40:05.000+01:00"
<a id="clients_updatenote" name="clients_updatenote" class="old-syle-anchor">&nbsp;</a> }
<div class="method-section"> </code>
<div class="method-description"> </div>
<h4>Update a Client Note</h4> </div>
</div>
<div class="method-example">
<code class="method-declaration">PUT https://thedomainname/api/v1/clients/{clientId}/notes/{noteId}</code>
<code class="method-request">http://localhost:8080/mifosng-provider/api/v1/clients/1/notes/1
Content-Type: application/json
Request Body:
new json here
</code>
<code class="method-response"> { "entityId": 2 }
</code>
</div>
</div>
<a id="clients_updatenote" name="clients_updatenote" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Update a Client Note</h4>
</div>
<div class="method-example">
<code class="method-declaration">PUT https://thedomainname/api/v1/clients/{clientId}/notes/{noteId}</code>
<code class="method-request">PUT https://localhost:8443/mifosng-provider/api/v1/clients/1/notes/40
Content-Type: application/json
Request Body:
{
"note": "an updated note about the client"
}
</code>
<code class="method-response">{"entityId": 40}</code>
</div>
</div>
<!-- start of loans api docs --> <!-- start of loans api docs -->
@@ -671,7 +857,7 @@
<dd>The 'id' of the Loan Product</dd> <dd>The 'id' of the Loan Product</dd>
</dl> </dl>
<p>Example Request: <p>Example Request:
<a style="word-wrap: break-word;" href="http://localhost:8080/mifosng-provider/api/v1/loans/template?clientId=1&productId=1">http://localhost:8080/mifosng-provider/api/v1/loans/template?clientId=1&productId=1</a> <a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/loans/template?clientId=1&productId=1">https://localhost:8443/mifosng-provider/api/v1/loans/template?clientId=1&productId=1</a>
</p> </p>
</div> </div>
<div class="method-example"> <div class="method-example">
@@ -687,7 +873,7 @@
<p>Returns loan fields. <p>Returns loan fields.
</p> </p>
<p>Example Request: <p>Example Request:
<a style="word-wrap: break-word;" href="http://localhost:8080/mifosng-provider/api/v1/loans/1">http://localhost:8080/mifosng-provider/api/v1/loans/1</a> <a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/loans/1">https://localhost:8443/mifosng-provider/api/v1/loans/1</a>
</p> </p>
</div> </div>
<div class="method-example"> <div class="method-example">
@@ -696,33 +882,32 @@
</code> </code>
</div> </div>
</div> </div>
<a id="loans_create" name="loans_create" class="old-syle-anchor">&nbsp;</a>
<a id="loans_submit" name="loans_submit" class="old-syle-anchor">&nbsp;</a> <a id="loans_create" name="loans_create" class="old-syle-anchor">&nbsp;</a>
<div class="method-section"> <div class="method-section">
<div class="method-description"> <div class="method-description">
<h4>Create a New Loan/Submit a Loan Application</h4> <h4>Create a New Loan/Submit a Loan Application</h4>
<h5>Arguments</h5> <h5>Arguments</h5>
<dl class="argument-list"> <dl class="argument-list">
<dt>command</dt> <dt>command</dt>
<dd>String<span> Optional, case-insensitive</span></dd> <dd>String<span> Optional, case-insensitive</span></dd>
<dd>The default action is to Submit a New Loan Application. If the value is 'calculateLoanSchedule' then a new loan entry is created without entering the loan life cycle.</dd> <dd>The default action is to Submit a New Loan Application. If the value is 'calculateLoanSchedule' then a new loan entry is created without entering the loan life cycle.</dd>
</dl> </dl>
</div> </div>
<div class="method-example"> <div class="method-example">
<code class="method-declaration">POST https://thedomainname/api/v1/loans</code> <code class="method-declaration">POST https://thedomainname/api/v1/loans</code>
<code class="method-request">http://localhost:8080/mifosng-provider/api/v1/loans <code class="method-request">https://localhost:8443/mifosng-provider/api/v1/loans
Content-Type: application/json Content-Type: application/json
Request Body: Request Body:
new json here new json here
</code> </code>
<code class="method-response">{ <code class="method-response">{"entityId": 2}
"entityId": 2 </code>
} </div>
</code> </div>
</div>
</div>
<a id="loans_approve" name="loans_approve" class="old-syle-anchor">&nbsp;</a> <a id="loans_approve" name="loans_approve" class="old-syle-anchor">&nbsp;</a>
<a id="loans_disburse" name="loans_disburse" class="old-syle-anchor">&nbsp;</a> <a id="loans_disburse" name="loans_disburse" class="old-syle-anchor">&nbsp;</a>
<a id="loans_reject" name="loans_reject" class="old-syle-anchor">&nbsp;</a> <a id="loans_reject" name="loans_reject" class="old-syle-anchor">&nbsp;</a>
@@ -742,7 +927,7 @@
</div> </div>
<div class="method-example"> <div class="method-example">
<code class="method-declaration">POST https://thedomainname/api/v1/loans/{loanId}</code> <code class="method-declaration">POST https://thedomainname/api/v1/loans/{loanId}</code>
<code class="method-request">http://localhost:8080/mifosng-provider/api/v1/loans/1?command=approve <code class="method-request">https://localhost:8443/mifosng-provider/api/v1/loans/1?command=approve
Content-Type: application/json Content-Type: application/json
@@ -762,7 +947,7 @@
</div> </div>
<div class="method-example"> <div class="method-example">
<code class="method-declaration">DELETE https://thedomainname/api/v1/loans/{loanId}</code> <code class="method-declaration">DELETE https://thedomainname/api/v1/loans/{loanId}</code>
<code class="method-request">http://localhost:8080/mifosng-provider/api/v1/loans/1 <code class="method-request">https://localhost:8443/mifosng-provider/api/v1/loans/1
Content-Type: application/json Content-Type: application/json
@@ -789,7 +974,7 @@
</div> </div>
<div class="method-example"> <div class="method-example">
<code class="method-declaration">POST https://thedomainname/api/v1/loans/{loanId}/undo</code> <code class="method-declaration">POST https://thedomainname/api/v1/loans/{loanId}/undo</code>
<code class="method-request">http://localhost:8080/mifosng-provider/api/v1/loans/1/undo <code class="method-request">https://localhost:8443/mifosng-provider/api/v1/loans/1/undo
Content-Type: application/json Content-Type: application/json
@@ -818,7 +1003,7 @@
<dd>The default action is to return details for Repayment of a loan. If the value is 'waiver' then details relevant to Waiving a loan amount are returned.</dd> <dd>The default action is to return details for Repayment of a loan. If the value is 'waiver' then details relevant to Waiving a loan amount are returned.</dd>
</dl> </dl>
<p>Example Request: <p>Example Request:
<a style="word-wrap: break-word;" href="http://localhost:8080/mifosng-provider/api/v1/loans/1/transactions/template?type=waiver">http://localhost:8080/mifosng-provider/api/v1/loans/1/transactions/template?type=waiver"</a> <a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/loans/1/transactions/template?type=waiver">https://localhost:8443/mifosng-provider/api/v1/loans/1/transactions/template?type=waiver"</a>
</p> </p>
</div> </div>
<div class="method-example"> <div class="method-example">
@@ -840,7 +1025,7 @@
</div> </div>
<div class="method-example"> <div class="method-example">
<code class="method-declaration">POST https://thedomainname/api/v1/loans/{loanId}/transactions</code> <code class="method-declaration">POST https://thedomainname/api/v1/loans/{loanId}/transactions</code>
<code class="method-request">http://localhost:8080/mifosng-provider/api/v1/loans/1/transactions <code class="method-request">https://localhost:8443/mifosng-provider/api/v1/loans/1/transactions
Content-Type: application/json Content-Type: application/json
@@ -859,7 +1044,7 @@
<div class="method-description"> <div class="method-description">
<h4>Retrieve a Repayment's Details</h4> <h4>Retrieve a Repayment's Details</h4>
<p>Example Request: <p>Example Request:
<a style="word-wrap: break-word;" href="http://localhost:8080/mifosng-provider/api/v1/loans/1/transactions/1">http://localhost:8080/mifosng-provider/api/v1/loans/1/transactions/1</a> <a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/loans/1/transactions/1">https://localhost:8443/mifosng-provider/api/v1/loans/1/transactions/1</a>
</p> </p>
</div> </div>
<div class="method-example"> <div class="method-example">
@@ -876,7 +1061,7 @@
</div> </div>
<div class="method-example"> <div class="method-example">
<code class="method-declaration">POST https://thedomainname/api/v1/loans/{loanId}/transactions/{repaymentId}</code> <code class="method-declaration">POST https://thedomainname/api/v1/loans/{loanId}/transactions/{repaymentId}</code>
<code class="method-request">http://localhost:8080/mifosng-provider/api/v1/loans/1/transactions/1 <code class="method-request">https://localhost:8443/mifosng-provider/api/v1/loans/1/transactions/1
Content-Type: application/json Content-Type: application/json
@@ -1679,7 +1864,7 @@ Request Body:
<dd>The Additional Fields Type (Mifos X database table) to restrict the output to</dd> <dd>The Additional Fields Type (Mifos X database table) to restrict the output to</dd>
</dl> </dl>
<p>Example Request: <p>Example Request:
<a style="word-wrap: break-word;" href="http://localhost:8080/mifosng-provider/api/v1/additionalfields?type=portfolio_client">http://localhost:8080/mifosng-provider/api/v1/additionalfields?type=portfolio_client</a> <a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/additionalfields?type=portfolio_client">https://localhost:8443/mifosng-provider/api/v1/additionalfields?type=portfolio_client</a>
</p> </p>
</div> </div>
<div class="method-example"> <div class="method-example">
@@ -1711,7 +1896,7 @@ Request Body:
Returns the Set of Additional Fields data for the ID provided. The ID is the id field of the Type table e.g. portfolio_client might have an id value of 4. The output is a JSON formatted "Generic Resultset". The Generic Resultset contains Column Heading as well as Data information. The Column Heading information may include allowed values (columnValues array). Returns the Set of Additional Fields data for the ID provided. The ID is the id field of the Type table e.g. portfolio_client might have an id value of 4. The output is a JSON formatted "Generic Resultset". The Generic Resultset contains Column Heading as well as Data information. The Column Heading information may include allowed values (columnValues array).
</p> </p>
<p>Example Request: <p>Example Request:
<a style="word-wrap: break-word;" href="http://localhost:8080/mifosng-provider/api/v1/additionalfields/portfolio_client/Additional Information/2">http://localhost:8080/mifosng-provider/api/v1/additionalfields/portfolio_client/Additional Information/2</a> <a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/additionalfields/portfolio_client/Additional Information/2">https://localhost:8443/mifosng-provider/api/v1/additionalfields/portfolio_client/Additional Information/2</a>
</p> </p>
</div> </div>
<div class="method-example"> <div class="method-example">
@@ -1843,7 +2028,7 @@ Request Body:
</div> </div>
<div class="method-example"> <div class="method-example">
<code class="method-declaration">POST https://thedomainname/api/v1/additionalfields/{type}/{set}/{id}</code> <code class="method-declaration">POST https://thedomainname/api/v1/additionalfields/{type}/{set}/{id}</code>
<code class="method-request">http://localhost:8080/mifosng-provider/api/v1/additionalfields/portfolio_client/Additional Information/2 <code class="method-request">https://localhost:8443/mifosng-provider/api/v1/additionalfields/portfolio_client/Additional Information/2
Content-Type: application/json Content-Type: application/json
@@ -1908,7 +2093,7 @@ Request Body:
<dd>Output will be delivered as a CSV file instead of JSON.</dd> <dd>Output will be delivered as a CSV file instead of JSON.</dd>
</dl> </dl>
<p>Example Request: <p>Example Request:
<a style="word-wrap: break-word;" href="http://localhost:8080/mifosng-provider/api/v1/reports">http://localhost:8080/mifosng-provider/api/v1/reports</a> <a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/reports">https://localhost:8443/mifosng-provider/api/v1/reports</a>
</p> </p>
</div> </div>
<div class="method-example"> <div class="method-example">
@@ -2004,7 +2189,7 @@ Request Body:
<dd>Output will be delivered as a CSV file instead of JSON. Doesn't apply to Pentaho reports.</dd> <dd>Output will be delivered as a CSV file instead of JSON. Doesn't apply to Pentaho reports.</dd>
</dl> </dl>
<p>Example Request: <p>Example Request:
<a style="word-wrap: break-word;" href="http://localhost:8080/mifosng-provider/api/v1/reports/Client%20Listing?R_officeId=1">http://localhost:8080/mifosng-provider/api/v1/reports/Client%20Listing?R_officeId=1</a> <a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/reports/Client%20Listing?R_officeId=1">https://localhost:8443/mifosng-provider/api/v1/reports/Client%20Listing?R_officeId=1</a>
</p> </p>
</div> </div>
<div class="method-example"> <div class="method-example">
@@ -2860,7 +3045,195 @@ Request body:
</div> </div>
<!-- --> <!-- start of roles api docs -->
<a id="permissions" name="permissions" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h3>Permissions</h3>
<p>An API capability to support management of application permissions for user administration.</p>
</div>
</div>
<a id="permissions_list" name="permissions_list" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Retrieve list of permissions</h4>
<p>Returns all permissions.</p>
<p>Example Request:
<a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/permissions">https://localhost:8443/mifosng-provider/api/v1/permissions</a>
</p>
</div>
<div class="method-example">
<code class="method-declaration">GET https://thedomainname/api/v1/permissions</code>
<code class="method-request">GET https://localhost:8443/mifosng-provider/api/v1/permissions</code>
<code class="method-response">
{
"permissions": [
{
"id": 1,
"orgId": 1,
"name": "User administration ALL",
"description": "An application user will have permission to execute all tasks related to user administration.",
"code": "USER_ADMINISTRATION_SUPER_USER_ROLE",
"groupType": 1
},
{
"id": 2,
"orgId": 1,
"name": "Organisation adminsitration ALL",
"description": "An application user will have permission to execute all tasks related to organisation administration.",
"code": "ORGANISATION_ADMINISTRATION_SUPER_USER_ROLE",
"groupType": 2
},
{
"id": 3,
"orgId": 1,
"name": "Portfolio management ALL",
"description": "An application user will have permission to execute all tasks related to portfolio management.",
"code": "PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE",
"groupType": 3
},
{
"id": 4,
"orgId": 1,
"name": "Reporting ALL",
"description": "An application user will have permission to execute and view all reports.",
"code": "REPORTING_SUPER_USER_ROLE",
"groupType": 4
},
{
"id": 5,
"orgId": 1,
"name": "Can submit new loan application",
"description": "Allows an application user to sumit new loan application.",
"code": "CAN_SUBMIT_NEW_LOAN_APPLICATION_ROLE",
"groupType": 3
},
{
"id": 6,
"orgId": 1,
"name": "Can submit historic loan application",
"description": "Allows an application user to sumit new loan application where the submitted on date is in the past.",
"code": "CAN_SUBMIT_HISTORIC_LOAN_APPLICATION_ROLE",
"groupType": 3
},
{
"id": 7,
"orgId": 1,
"name": "Can approve loan application",
"description": "Allows an application user to approve a loan application.",
"code": "CAN_APPROVE_LOAN_ROLE",
"groupType": 3
},
{
"id": 8,
"orgId": 1,
"name": "Can approve loan application in the past",
"description": "Allows an application user to approve a loan application where the approval date is in the past.",
"code": "CAN_APPROVE_LOAN_IN_THE_PAST_ROLE",
"groupType": 3
},
{
"id": 9,
"orgId": 1,
"name": "Can reject loan application",
"description": "Allows an application user to reject a loan application.",
"code": "CAN_REJECT_LOAN_ROLE",
"groupType": 3
},
{
"id": 10,
"orgId": 1,
"name": "Can reject loan application in the past",
"description": "Allows an application user to reject a loan application where the rejected date is in the past.",
"code": "CAN_REJECT_LOAN_IN_THE_PAST_ROLE",
"groupType": 3
},
{
"id": 11,
"orgId": 1,
"name": "Can withdraw loan application",
"description": "Allows an application user to mark loan application as withdrawn by client.",
"code": "CAN_WITHDRAW_LOAN_ROLE",
"groupType": 3
},
{
"id": 12,
"orgId": 1,
"name": "Can withdraw loan application in the past",
"description": "Allows an application user to mark loan application as withdrawn by client where the withdran on date is in the past.",
"code": "CAN_WITHDRAW_LOAN_IN_THE_PAST_ROLE",
"groupType": 3
},
{
"id": 13,
"orgId": 1,
"name": "Can delete submitted loan application",
"description": "Allows an application user to complete delete the loan application if it is submitted but not approved.",
"code": "CAN_DELETE_LOAN_THAT_IS_SUBMITTED_AND_NOT_APPROVED",
"groupType": 3
},
{
"id": 14,
"orgId": 1,
"name": "Can undo loan approval",
"description": "Allows an application user to undo a loan approval.",
"code": "CAN_UNDO_LOAN_APPROVAL_ROLE",
"groupType": 3
},
{
"id": 15,
"orgId": 1,
"name": "Can disburse loan",
"description": "Allows an application user to disburse a loan application.",
"code": "CAN_DISBURSE_LOAN_ROLE",
"groupType": 3
},
{
"id": 16,
"orgId": 1,
"name": "Can disburse loan in the past",
"description": "Allows an application user to disburse a loan where the disbursement date is in the past.",
"code": "CAN_DISBURSE_LOAN_IN_THE_PAST_ROLE",
"groupType": 3
},
{
"id": 17,
"orgId": 1,
"name": "Can undo loan disbursal",
"description": "Allows an application user to undo a loan disbursal if not payments already made.",
"code": "CAN_UNDO_LOAN_DISBURSAL_ROLE",
"groupType": 3
},
{
"id": 18,
"orgId": 1,
"name": "Can enter a repayment against a loan",
"description": "Allows an application user to enter a repayment on the loan.",
"code": "CAN_MAKE_LOAN_REPAYMENT_LOAN_ROLE",
"groupType": 3
},
{
"id": 19,
"orgId": 1,
"name": "Can enter a repayment against a loan in the past",
"description": "Allows an application user to enter a repayment on the loan where the repayment date is in the past.",
"code": "CAN_MAKE_LOAN_REPAYMENT_IN_THE_PAST_ROLE",
"groupType": 3
},
{
"id": 20,
"orgId": 1,
"name": "Can add a new client.",
"description": "Allows an application user to add a new client.",
"code": "CAN_ENROLL_NEW_CLIENT_ROLE",
"groupType": 3
}
]
}
</code>
</div>
</div>
</div> <!-- main-content-wrapper --> </div> <!-- main-content-wrapper -->
</div> </div>
@@ -5,8 +5,9 @@ import javax.xml.bind.annotation.XmlRootElement;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
@XmlRootElement @XmlRootElement
public class EnrollClientCommand { public class ClientCommand {
private Long id;
private String firstname; private String firstname;
private String lastname; private String lastname;
private String fullname; private String fullname;
@@ -17,11 +18,11 @@ public class EnrollClientCommand {
private String joiningDateFormatted; private String joiningDateFormatted;
private LocalDate joiningDate; private LocalDate joiningDate;
protected EnrollClientCommand() { protected ClientCommand() {
// //
} }
public EnrollClientCommand(final String firstname, final String lastname, String fullname, final Long officeId, final LocalDate joiningDate) { public ClientCommand(final String firstname, final String lastname, String fullname, final Long officeId, final LocalDate joiningDate) {
this.firstname = firstname; this.firstname = firstname;
this.lastname = lastname; this.lastname = lastname;
this.fullname = fullname; this.fullname = fullname;
@@ -92,4 +93,12 @@ public class EnrollClientCommand {
public void setJoiningDateFormatted(String joiningDateFormatted) { public void setJoiningDateFormatted(String joiningDateFormatted) {
this.joiningDateFormatted = joiningDateFormatted; this.joiningDateFormatted = joiningDateFormatted;
} }
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
} }
@@ -8,17 +8,17 @@ import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement @XmlRootElement
public class ImportClientCommand { public class ImportClientCommand {
private List<EnrollClientCommand> clients = new ArrayList<EnrollClientCommand>(); private List<ClientCommand> clients = new ArrayList<ClientCommand>();
public ImportClientCommand() { public ImportClientCommand() {
// //
} }
public List<EnrollClientCommand> getClients() { public List<ClientCommand> getClients() {
return clients; return clients;
} }
public void setClients(List<EnrollClientCommand> clients) { public void setClients(List<ClientCommand> clients) {
this.clients = clients; this.clients = clients;
} }
} }
@@ -22,7 +22,7 @@ import org.mifosng.data.LoanSchedule;
import org.mifosng.data.MoneyData; import org.mifosng.data.MoneyData;
import org.mifosng.data.ScheduledLoanInstallment; import org.mifosng.data.ScheduledLoanInstallment;
import org.mifosng.data.command.CalculateLoanScheduleCommand; import org.mifosng.data.command.CalculateLoanScheduleCommand;
import org.mifosng.data.command.EnrollClientCommand; import org.mifosng.data.command.ClientCommand;
import org.mifosng.data.command.ImportClientCommand; import org.mifosng.data.command.ImportClientCommand;
import org.mifosng.data.command.ImportLoanCommand; import org.mifosng.data.command.ImportLoanCommand;
import org.mifosng.data.command.ImportLoanRepaymentsCommand; import org.mifosng.data.command.ImportLoanRepaymentsCommand;
@@ -115,7 +115,7 @@ public class ImportPlatformServiceImpl implements ImportPlatformService {
List<Client> newClientCollection = new ArrayList<Client>(); List<Client> newClientCollection = new ArrayList<Client>();
for (EnrollClientCommand client : command.getClients()) { for (ClientCommand client : command.getClients()) {
Office clientOffice = findById(allOffices, client.getOfficeId()); Office clientOffice = findById(allOffices, client.getOfficeId());
Client newClient = Client.newClient(currentUser.getOrganisation(), clientOffice, client.getFirstname(), client.getLastname(), client.getJoiningDate(), client.getExternalId()); Client newClient = Client.newClient(currentUser.getOrganisation(), clientOffice, client.getFirstname(), client.getLastname(), client.getJoiningDate(), client.getExternalId());
@@ -544,7 +544,7 @@ public class ImportPlatformServiceImpl implements ImportPlatformService {
// success = false; // success = false;
// } // }
List<EnrollClientCommand> parsedClients = new ArrayList<EnrollClientCommand>(); List<ClientCommand> parsedClients = new ArrayList<ClientCommand>();
while (clients.readRecord()) { while (clients.readRecord()) {
String externalId = clients.get("ExternalId"); String externalId = clients.get("ExternalId");
String firstname = clients.get("FirstName"); String firstname = clients.get("FirstName");
@@ -555,7 +555,7 @@ public class ImportPlatformServiceImpl implements ImportPlatformService {
LocalDate joiningDate = new LocalDate(isoParser.parseDateTime(joined)); LocalDate joiningDate = new LocalDate(isoParser.parseDateTime(joined));
EnrollClientCommand parsedClient = new EnrollClientCommand(firstname, lastname, "", matchingOffice.getId(), joiningDate); ClientCommand parsedClient = new ClientCommand(firstname, lastname, "", matchingOffice.getId(), joiningDate);
parsedClient.setExternalId(externalId); parsedClient.setExternalId(externalId);
parsedClients.add(parsedClient); parsedClients.add(parsedClient);
@@ -19,7 +19,7 @@ import org.mifosng.data.ClientLoanAccountSummaryCollectionData;
import org.mifosng.data.EntityIdentifier; import org.mifosng.data.EntityIdentifier;
import org.mifosng.data.NoteData; import org.mifosng.data.NoteData;
import org.mifosng.data.NoteDataList; import org.mifosng.data.NoteDataList;
import org.mifosng.data.command.EnrollClientCommand; import org.mifosng.data.command.ClientCommand;
import org.mifosng.data.command.NoteCommand; import org.mifosng.data.command.NoteCommand;
import org.mifosng.platform.api.infrastructure.ApiDataConversionService; import org.mifosng.platform.api.infrastructure.ApiDataConversionService;
import org.mifosng.platform.client.service.ClientReadPlatformService; import org.mifosng.platform.client.service.ClientReadPlatformService;
@@ -43,8 +43,8 @@ public class ClientApiResource {
private ApiDataConversionService apiDataConversionService; private ApiDataConversionService apiDataConversionService;
@GET @GET
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({ MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
public Response retrieveAllIndividualClients() { public Response retrieveAllIndividualClients() {
Collection<ClientData> clients = this.clientReadPlatformService.retrieveAllIndividualClients(); Collection<ClientData> clients = this.clientReadPlatformService.retrieveAllIndividualClients();
@@ -54,8 +54,8 @@ public class ClientApiResource {
@GET @GET
@Path("{clientId}") @Path("{clientId}")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({ MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
public Response retrieveClientData(@PathParam("clientId") final Long clientId) { public Response retrieveClientData(@PathParam("clientId") final Long clientId) {
ClientData clientData = this.clientReadPlatformService.retrieveIndividualClient(clientId); ClientData clientData = this.clientReadPlatformService.retrieveIndividualClient(clientId);
@@ -65,8 +65,8 @@ public class ClientApiResource {
@GET @GET
@Path("template") @Path("template")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({ MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
public Response newClientDetails() { public Response newClientDetails() {
ClientData clientData = this.clientReadPlatformService.retrieveNewClientDetails(); ClientData clientData = this.clientReadPlatformService.retrieveNewClientDetails();
@@ -75,9 +75,9 @@ public class ClientApiResource {
} }
@POST @POST
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({ MediaType.APPLICATION_JSON }) @Produces({MediaType.APPLICATION_JSON })
public Response enrollClient(final EnrollClientCommand command) { public Response enrollClient(final ClientCommand command) {
LocalDate joiningDate = apiDataConversionService.convertFrom(command.getJoiningDateFormatted(), "joiningDateFormatted", command.getDateFormat()); LocalDate joiningDate = apiDataConversionService.convertFrom(command.getJoiningDateFormatted(), "joiningDateFormatted", command.getDateFormat());
command.setJoiningDate(joiningDate); command.setJoiningDate(joiningDate);
@@ -87,11 +87,25 @@ public class ClientApiResource {
return Response.ok().entity(new EntityIdentifier(clientId)).build(); return Response.ok().entity(new EntityIdentifier(clientId)).build();
} }
@PUT
@Path("{clientId}")
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({MediaType.APPLICATION_JSON })
public Response updateClient(@PathParam("clientId") final Long clientId, final ClientCommand command) {
LocalDate joiningDate = apiDataConversionService.convertFrom(command.getJoiningDateFormatted(), "joiningDateFormatted", command.getDateFormat());
command.setJoiningDate(joiningDate);
command.setId(clientId);
EntityIdentifier identifier = this.clientWritePlatformService.updateClientDetails(command);
return Response.ok().entity(identifier).build();
}
@GET @GET
@Path("{clientId}/loans") @Path("{clientId}/loans")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({ MediaType.APPLICATION_JSON }) @Produces({MediaType.APPLICATION_JSON })
public Response retrieveClientAccount(@PathParam("clientId") final Long clientId) { public Response retrieveClientAccount(@PathParam("clientId") final Long clientId) {
ClientLoanAccountSummaryCollectionData clientAccount = this.clientReadPlatformService.retrieveClientAccountDetails(clientId); ClientLoanAccountSummaryCollectionData clientAccount = this.clientReadPlatformService.retrieveClientAccountDetails(clientId);
@@ -101,8 +115,8 @@ public class ClientApiResource {
@GET @GET
@Path("{clientId}/notes") @Path("{clientId}/notes")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({ MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
public Response retrieveAllClientNotes(@PathParam("clientId") final Long clientId) { public Response retrieveAllClientNotes(@PathParam("clientId") final Long clientId) {
Collection<NoteData> notes = this.clientReadPlatformService.retrieveAllClientNotes(clientId); Collection<NoteData> notes = this.clientReadPlatformService.retrieveAllClientNotes(clientId);
@@ -112,8 +126,8 @@ public class ClientApiResource {
@POST @POST
@Path("{clientId}/notes") @Path("{clientId}/notes")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({ MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
public Response addNewClientNote(@PathParam("clientId") final Long clientId, final NoteCommand command) { public Response addNewClientNote(@PathParam("clientId") final Long clientId, final NoteCommand command) {
command.setClientId(clientId); command.setClientId(clientId);
@@ -125,8 +139,8 @@ public class ClientApiResource {
@GET @GET
@Path("{clientId}/notes/{noteId}") @Path("{clientId}/notes/{noteId}")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({ MediaType.APPLICATION_JSON }) @Produces({MediaType.APPLICATION_JSON })
public Response retrieveClientNote(@PathParam("clientId") final Long clientId, @PathParam("noteId") final Long noteId) { public Response retrieveClientNote(@PathParam("clientId") final Long clientId, @PathParam("noteId") final Long noteId) {
NoteData note = this.clientReadPlatformService.retrieveClientNote(clientId, noteId); NoteData note = this.clientReadPlatformService.retrieveClientNote(clientId, noteId);
@@ -136,8 +150,8 @@ public class ClientApiResource {
@PUT @PUT
@Path("{clientId}/notes/{noteId}") @Path("{clientId}/notes/{noteId}")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({ MediaType.APPLICATION_JSON }) @Produces({MediaType.APPLICATION_JSON })
public Response updateClientNote(@PathParam("clientId") final Long clientId, @PathParam("noteId") final Long noteId, final NoteCommand command) { public Response updateClientNote(@PathParam("clientId") final Long clientId, @PathParam("noteId") final Long noteId, final NoteCommand command) {
command.setClientId(clientId); command.setClientId(clientId);
@@ -13,6 +13,7 @@ import javax.persistence.UniqueConstraint;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosng.data.command.ClientCommand;
import org.mifosng.platform.infrastructure.AbstractAuditableCustom; import org.mifosng.platform.infrastructure.AbstractAuditableCustom;
import org.mifosng.platform.organisation.domain.Office; import org.mifosng.platform.organisation.domain.Office;
import org.mifosng.platform.organisation.domain.Organisation; import org.mifosng.platform.organisation.domain.Organisation;
@@ -34,19 +35,19 @@ public class Client extends AbstractAuditableCustom<AppUser, Long> {
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Column(name = "firstname", length=50) @Column(name = "firstname", length=50)
private final String firstName; private String firstName;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Column(name = "lastname", length=50) @Column(name = "lastname", length=50)
private final String lastName; private String lastName;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Column(name = "joining_date") @Column(name = "joining_date")
@Temporal(TemporalType.DATE) @Temporal(TemporalType.DATE)
private final Date joiningDate; private Date joiningDate;
@Column(name = "external_id", length=100) @Column(name = "external_id", length=100)
private final String externalId; private String externalId;
public static Client newClient(Organisation organisation, public static Client newClient(Organisation organisation,
Office clientOffice, String firstname, String lastname, Office clientOffice, String firstname, String lastname,
@@ -85,4 +86,31 @@ public class Client extends AbstractAuditableCustom<AppUser, Long> {
public boolean identifiedBy(final String identifier) { public boolean identifiedBy(final String identifier) {
return identifier.equalsIgnoreCase(this.externalId); return identifier.equalsIgnoreCase(this.externalId);
} }
public void update(ClientCommand command) {
this.joiningDate = command.getJoiningDate().toDate();
this.firstName = command.getFirstname();
this.lastName = command.getLastname();
if (StringUtils.isNotBlank(command.getFullname())) {
this.firstName = null;
this.lastName = command.getFullname().trim();
}
if (StringUtils.isNotBlank(command.getExternalId())) {
this.externalId = command.getExternalId().trim();
} else {
this.externalId = null;
}
}
public void update(Office clientOffice, String firstname, String lastname, String externalId, LocalDate joiningDate) {
this.joiningDate = joiningDate.toDate();
this.firstName = firstname;
this.lastName = lastname;
this.externalId = externalId;
if (StringUtils.isNotBlank(externalId)) {
this.externalId = externalId.trim();
}
}
} }
@@ -5,14 +5,14 @@ import java.util.List;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.mifosng.data.ApiParameterError; import org.mifosng.data.ApiParameterError;
import org.mifosng.data.command.EnrollClientCommand; import org.mifosng.data.command.ClientCommand;
import org.mifosng.platform.exceptions.PlatformApiDataValidationException; import org.mifosng.platform.exceptions.PlatformApiDataValidationException;
public class EnrollClientCommandValidator { public class ClientCommandValidator {
private final EnrollClientCommand command; private final ClientCommand command;
public EnrollClientCommandValidator(EnrollClientCommand command) { public ClientCommandValidator(ClientCommand command) {
this.command = command; this.command = command;
} }
@@ -1,17 +1,21 @@
package org.mifosng.platform.client.service; package org.mifosng.platform.client.service;
import org.mifosng.data.EntityIdentifier; import org.mifosng.data.EntityIdentifier;
import org.mifosng.data.command.EnrollClientCommand; import org.mifosng.data.command.ClientCommand;
import org.mifosng.data.command.NoteCommand; import org.mifosng.data.command.NoteCommand;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
public interface ClientWritePlatformService { public interface ClientWritePlatformService {
@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_ENROLL_NEW_CLIENT_ROLE')") @PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_ENROLL_NEW_CLIENT_ROLE')")
Long enrollClient(EnrollClientCommand command); Long enrollClient(ClientCommand command);
EntityIdentifier updateClientDetails(ClientCommand command);
// FIXME - add permission for adding and updating client notes. // FIXME - add permission for adding and updating client notes.
EntityIdentifier addClientNote(NoteCommand command); EntityIdentifier addClientNote(NoteCommand command);
EntityIdentifier updateNote(NoteCommand command); EntityIdentifier updateNote(NoteCommand command);
} }
@@ -1,10 +1,10 @@
package org.mifosng.platform.client.service; package org.mifosng.platform.client.service;
import static org.mifosng.platform.Specifications.officesThatMatch; import static org.mifosng.platform.Specifications.*;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.mifosng.data.EntityIdentifier; import org.mifosng.data.EntityIdentifier;
import org.mifosng.data.command.EnrollClientCommand; import org.mifosng.data.command.ClientCommand;
import org.mifosng.data.command.NoteCommand; import org.mifosng.data.command.NoteCommand;
import org.mifosng.platform.client.domain.Client; import org.mifosng.platform.client.domain.Client;
import org.mifosng.platform.client.domain.ClientRepository; import org.mifosng.platform.client.domain.ClientRepository;
@@ -37,11 +37,11 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
@Transactional @Transactional
@Override @Override
public Long enrollClient(final EnrollClientCommand command) { public Long enrollClient(final ClientCommand command) {
AppUser currentUser = context.authenticatedUser(); AppUser currentUser = context.authenticatedUser();
EnrollClientCommandValidator validator = new EnrollClientCommandValidator(command); ClientCommandValidator validator = new ClientCommandValidator(command);
validator.validate(); validator.validate();
Office clientOffice = this.officeRepository.findOne(officesThatMatch(currentUser.getOrganisation(), command.getOfficeId())); Office clientOffice = this.officeRepository.findOne(officesThatMatch(currentUser.getOrganisation(), command.getOfficeId()));
@@ -60,6 +60,33 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
return newClient.getId(); return newClient.getId();
} }
@Transactional
@Override
public EntityIdentifier updateClientDetails(ClientCommand command) {
AppUser currentUser = context.authenticatedUser();
//EnrollClientCommandValidator validator = new EnrollClientCommandValidator(command);
//validator.validate();
Office clientOffice = this.officeRepository.findOne(officesThatMatch(currentUser.getOrganisation(), command.getOfficeId()));
String firstname = command.getFirstname();
String lastname = command.getLastname();
if (StringUtils.isNotBlank(command.getFullname())) {
lastname = command.getFullname();
firstname = null;
}
Client clientForUpdate = this.clientRepository.findOne(clientsThatMatch(currentUser.getOrganisation(), command.getId()));
clientForUpdate.update(clientOffice, firstname, lastname, command.getExternalId(), command.getJoiningDate());
this.clientRepository.save(clientForUpdate);
return new EntityIdentifier(clientForUpdate.getId());
}
@Transactional @Transactional
@Override @Override
public EntityIdentifier addClientNote(NoteCommand command) { public EntityIdentifier addClientNote(NoteCommand command) {
@@ -45,7 +45,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
public LoanProductData retrieveLoanProduct(final Long loanProductId) { public LoanProductData retrieveLoanProduct(final Long loanProductId) {
try { try {
List<CurrencyData> allowedCurrencies = currencyReadPlatformService.retrieveAllowedCurrencies(); List<CurrencyData> allowedCurrencies = currencyReadPlatformService.retrieveAllPlatformCurrencies();
LoanProductMapper rm = new LoanProductMapper(allowedCurrencies); LoanProductMapper rm = new LoanProductMapper(allowedCurrencies);
String sql = "select " + rm.loanProductSchema() + " where lp.id = ?"; String sql = "select " + rm.loanProductSchema() + " where lp.id = ?";
@@ -65,7 +65,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
AppUser currentUser = this.context.authenticatedUser(); AppUser currentUser = this.context.authenticatedUser();
List<CurrencyData> allowedCurrencies = currencyReadPlatformService.retrieveAllowedCurrencies(); List<CurrencyData> allowedCurrencies = currencyReadPlatformService.retrieveAllPlatformCurrencies();
LoanProductMapper rm = new LoanProductMapper(allowedCurrencies); LoanProductMapper rm = new LoanProductMapper(allowedCurrencies);
@@ -134,7 +134,9 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
int currencyDigits = rs.getInt("currencyDigits"); int currencyDigits = rs.getInt("currencyDigits");
CurrencyData currencyData = findCurrencyByCode(currencyCode, allowedCurrencies); CurrencyData currencyData = findCurrencyByCode(currencyCode, allowedCurrencies);
currencyData.setDecimalPlaces(currencyDigits); if (currencyData != null) {
currencyData.setDecimalPlaces(currencyDigits);
}
BigDecimal principal = rs.getBigDecimal("principal"); BigDecimal principal = rs.getBigDecimal("principal");
BigDecimal tolerance = rs.getBigDecimal("tolerance"); BigDecimal tolerance = rs.getBigDecimal("tolerance");