Merge remote-tracking branch 'vishwas/mifosx-251'

This commit is contained in:
Keith Woodlock
2013-03-19 17:19:41 +00:00
12 changed files with 793 additions and 167 deletions
+629 -27
View File
@@ -660,7 +660,7 @@
<td></td> <td></td>
<td>savingproducts/{prodcutId}</td> <td>savingproducts/{prodcutId}</td>
<td></td> <td></td>
<td><a href="#savingproducts_retrieve">Retrieve a Saving procduct</a></td> <td><a href="#savingproducts_retrieve">Retrieve a Saving product</a></td>
<td><a href="#savingproducts_update">Update a Saving product</a></td> <td><a href="#savingproducts_update">Update a Saving product</a></td>
<td><a href="#savingproducts_delete">Delete a Saving product</a></td> <td><a href="#savingproducts_delete">Delete a Saving product</a></td>
</tr> </tr>
@@ -742,6 +742,22 @@
<td><a href="#configs_code_update">Update a Code</a></td> <td><a href="#configs_code_update">Update a Code</a></td>
<td><a href="#configs_code_delete">Delete a Code</a></td> <td><a href="#configs_code_delete">Delete a Code</a></td>
</tr> </tr>
<tr>
<td><a href="#configs_codes_codevalues">CODE VALUES</a></td>
<td>codes/{codeId}/codevalues</td>
<td><a href="#configs_codes_codevalues_create">Create a Code Value</a></td>
<td><a href="#configs_codes_codevalues_list">List Code Values</a></td>
<td></td>
<td></td>
</tr>
<tr class="alt">
<td></td>
<td>codes/{codeId}/codevalues/{codevalueId}</td>
<td></td>
<td><a href="#configs_codes_codevalues_retrieve">Retrieve 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>
</tr>
</table> </table>
</div> </div>
</div> </div>
@@ -841,7 +857,7 @@
Data Table (One to Many)</a></td> Data Table (One to Many)</a></td>
</tr> </tr>
<tr> <tr>
<td><a href="#notes">NOTE</a></td> <td><a href="#notes">NOTES</a></td>
<td>{resource}/{resourceId}/notes</td> <td>{resource}/{resourceId}/notes</td>
<td><a href="#resources_addnote">Add a Resource Note</td> <td><a href="#resources_addnote">Add a Resource Note</td>
<td><a href="#resource_notelist">Retrieve a Resource's Notes</a></td> <td><a href="#resource_notelist">Retrieve a Resource's Notes</a></td>
@@ -852,10 +868,38 @@
<td></td> <td></td>
<td>{resource}/{resourceId}/notes/{noteId}</td> <td>{resource}/{resourceId}/notes/{noteId}</td>
<td></td> <td></td>
<td><a href="#resources_retrievenote">Retrieve a Resource Note</a></td> <td><a href="#resources_retrievenote">List All
Notes for a Resource</a></td>
<td><a href="#resources_updatenote">Update a Resource Note</a></td> <td><a href="#resources_updatenote">Update a Resource Note</a></td>
<td><a href="#resources_deletenote">Delete a Resource Note</a></td> <td><a href="#resources_deletenote">Delete a Resource Note</a></td>
</tr> </tr>
<tr>
<td><a href="#documents">Documents</a></td>
<td>{entityType}/{entityId}/documents</td>
<td><a href="#documents_create">Create a Document</td>
<td><a href="#documents_list">List All Document Details</a></td>
<td></td>
<td></td>
</tr>
<tr class="alt">
<td></td>
<td>{entityType}/{entityId}/documents/{documentId}</td>
<td></td>
<td><a href="#documents_retrieve">Retrieve a Documents Details</a></td>
<td><a href="#documents_update">Update a Document</a></td>
<td><a href="#documents_delete">Delete a Document</a></td>
</tr>
<tr class="alt">
<td></td>
<td>{entityType}/{entityId}/documents/{documentId}/attachment</td>
<td></td>
<td><a href="#documents_retrieve_file">Retrieve
binary file associated with a
Document</a>
</td>
<td></td>
<td></td>
</tr>
</table> </table>
</div> </div>
</div> </div>
@@ -7018,7 +7062,7 @@ Request Body: { }
data, their code values are a specific instance of that category.</p> data, their code values are a specific instance of that category.</p>
<p> <p>
Codes are mostly <b>system defined</b> which means the code itself Codes are mostly <b>system defined</b> which means the code itself
comes out of the box and cannot be modifed however its code values comes out of the box and cannot be modified however its code values
can be. e.g. 'Customer Identifier', it defaults to a code value of can be. e.g. 'Customer Identifier', it defaults to a code value of
'Passport' but could be 'Drivers License, National Id' etc 'Passport' but could be 'Drivers License, National Id' etc
<p /> <p />
@@ -7164,6 +7208,174 @@ Content-Type: application/json
</div> </div>
</div> </div>
<!-- Code Value starts here -->
<a id="configs_codes_codevalues" name="configs_codes_codevalues" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h3>Code Values</h3>
<p>Code and code values: Codes represent a specific category of
data, their code values are a specific instance of that category.</p>
<p>
Codes are mostly <b>system defined</b> which means the code itself
comes out of the box and cannot be modified however its code values
can be. e.g. 'Customer Identifier', it defaults to a code value of
'Passport' but could be 'Drivers License, National Id' etc
<p />
</div>
</div>
<a id="configs_codes_codevalues_create" name="configs_codes_codevalues_create"
class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Create a Code Value</h4>
</div>
<div class="method-example">
<code class="method-declaration">
POST https://DomainName/api/v1/codes/1/codevalues
</code>
<code class="method-request">
POST codes/1/codevalues
Content-Type: application/json
Request Body:
{
"name":"Ration Card",
"position":"1"
}
</code>
<code class="method-response">
{
"resourceId": 4
}
</code>
</div>
</div>
<a id="configs_codes_codevalues_list" name="configs_codes_codevalues_list"
class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>List Code Values</h4>
<p>Returns the list of Code Values for a given Code</p>
<p>Example Requests:</p>
<div class=apiClick>codes/1/codevalues</div>
</div>
<div class="method-example">
<code class="method-declaration">
GET https://DomainName/api/v1/codes/{codeId}/codevalues
</code>
<code class="method-response">
[
{
"id": 1,
"name": "Passport",
"position": 0
},
{
"id": 2,
"name": "Id",
"position": 0
},
{
"id": 3,
"name": "Drivers License",
"position": 0
},
{
"id": 4,
"name": "Any Other Id Type",
"position": 0
},
{
"id": 5,
"name": "Ration Card",
"position": 1
}
]
</code>
</div>
</div>
<a id="configs_codes_codevalues_retrieve" name="configs_codes_codevalues_retrieve"
class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Retrieve a Code Value</h4>
<p>Returns the details of a Code Value</p>
<p>Example Requests:</p>
<div class=apiClick>codes/1/codevalues/1</div>
</div>
<div class="method-example">
<code class="method-declaration">
GET https://DomainName/api/v1/codes/{codeId}/codevalues/{codevalueId}
</code>
<code class="method-response">
{
"id": 1,
"name": "Passport",
"position": 0
}
</code>
</div>
</div>
<a id="configs_codes_codevalues_update" name="configs_codes_codevalues_update"
class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Update a Code Value</h4>
<p>Updates the details of a code value.</p>
</div>
<div class="method-example">
<code class="method-declaration">
PUT https://DomainName/api/v1/codes/{codeId}/codevalues/{codevalueId}
</code>
<code class="method-request">
PUT codes/1/codevalues/1
Content-Type: application/json
Request Body:
{
"name": "Indian Passport",
"position":2
}
</code>
<code class="method-response">
{
"resourceId": 1,
"changes": {
"name": "Indian Passport",
"position": 2
}
}
</code>
</div>
</div>
<a id="configs_codes_codevalues_delete" name="configs_codes_codevalues_delete"
class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Delete a Code Value</h4>
<p>Deletes a code value</p>
</div>
<div class="method-example">
<code class="method-declaration">
DELETE https://DomainName/api/v1/codes/{codeId}/codevalues/{codevalueId}
</code>
<code class="method-request">
DELETE codes/1/codevalues/5
Content-Type: application/json
</code>
<code class="method-response">
{
"resourceId": 5
}
</code>
</div>
</div>
<!-- Funds starts here-->
<a id="funds" name="funds" class="old-syle-anchor">&nbsp;</a> <a id="funds" name="funds" class="old-syle-anchor">&nbsp;</a>
<div class="method-section"> <div class="method-section">
<div class="method-description"> <div class="method-description">
@@ -9229,6 +9441,336 @@ No Request Body:
</div> </div>
<!-- end of Notes api docs --> <!-- end of Notes api docs -->
<!-- start of documents api docs -->
<a id="documents" name="documents" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h3>Documents</h3>
<p>Multiple Documents (a combination of a name, description
and a file) may be attached to different Entities
like Clients, Staff, Loans, Savings and Client
Identifiers in the system
</p>
<p>Note: The currently allowed Entities are
<ul>
<li>Clients: URL Pattern as <i>clients</i></li>
<li>Staff: URL Pattern as <i>staff</i></li>
<li>Loans: URL Pattern as <i>loans</i></li>
<li>Savings: URL Pattern as <i>savings</i></li>
<li>Client Identifiers: URL Pattern as <i>client_identifiers</i></li>
</ul>
</p>
<br/>
<table class=matrixHeading>
<tr class="matrixHeadingBG">
<td><div class="mifosXHeading2">Field Descriptions</div></td>
</tr>
<tr class=alt>
<td>parentEntityType</td>
</tr>
<tr>
<td class=fielddesc>The type of the Entity
with which this document is associated
</td>
</tr>
<tr class=alt>
<td>parentEntityId</td>
</tr>
<tr>
<td class=fielddesc>The ID of the entity (client,
loan etc) with which this document is
associated</td>
</tr>
<tr class=alt>
<td>name</td>
</tr>
<tr>
<td class=fielddesc>User Defined name for the
document, need not be the same as the name
of the file associated with the document
</td>
</tr>
<tr class=alt>
<td>fileName</td>
</tr>
<tr>
<td class=fielddesc>The name of the file associated
with this document</td>
</tr>
<tr class=alt>
<td>size</td>
</tr>
<tr>
<td class=fielddesc>The size (in bytes) of the file
associated with this document</td>
</tr>
<tr class=alt>
<td>type</td>
</tr>
<tr>
<td class=fielddesc>Mime Type of the file
associated with this document
</td>
</tr>
<tr class=alt>
<td>description</td>
</tr>
<tr>
<td class=fielddesc>A description of this document
</td>
</tr>
</table>
</div>
</div>
<a id="documents_list" name="documents_list" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>List documents</h4>
<p>Example Requests:</p>
<div class=apiClick>clients/1/documents</div>
<br>
<div class=apiClick>client_identifiers/1/documents</div>
<br>
<div class=apiClick>loans/1/documents?fields=name,description</div>
</div>
<div class="method-example">
<code class="method-declaration">
GET https://DomainName/api/v1/{entityType}/{entityId}/documents
</code>
<code class="method-response">
[
{
"id": 1,
"parentEntityType": "clients",
"parentEntityId": 1,
"name": "Client Details Form ",
"fileName": "CGAP.pdf",
"size": 5246719,
"type": "application/pdf",
"description": "A signed form signed by new member"
}
]
</code>
</div>
</div>
<a id="documents_retrieve" name="documents_retrieve"
class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Retrieve a Document</h4>
<p>Example Requests:</p>
<div class=apiClick>clients/1/documents/1</div>
<br>
<br>
<div class=apiClick>loans/1/documents/1</div>
<br>
<br>
<div class=apiClick>client_identifiers/1/documents/1?fields=name,description</div>
</div>
<div class="method-example">
<code class="method-declaration">
GET https://DomainName/api/v1/documents/{clientId}
</code>
<code class="method-response">
{
"id": 1,
"parentEntityType": "clients",
"parentEntityId": 1,
"name": "Client Details Form ",
"fileName": "CGAP.pdf",
"size": 5246719,
"type": "application/pdf",
"description": "A signed form signed by new member"
}
</code>
</div>
</div>
<a id="documents_create" name="documents_create" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Create a Document</h4>
<p>
<b>Note:</b> A document is created using a Multi-part form upload
<br>
<table class=matrixHeading>
<tr class="matrixHeadingBG">
<td><div class="mifosXHeading2">Body Parts</div></td>
</tr>
<tr class=alt>
<td>name</td>
</tr>
<tr>
<td class=fielddesc>Name or summary of the document
</td>
</tr>
<tr class=alt>
<td>description</td>
</tr>
<tr>
<td class=fielddesc>Description of the document
</tr>
<tr class=alt>
<td>file</td>
</tr>
<tr>
<td class=fielddesc>The file to be uploaded
</td>
</tr>
</table>
</p>
<table class=matrixHeading>
<tr class="matrixHeadingBG">
<td><div class="mifosXHeading2">Mandatory Fields</div></td>
</tr>
<tr class=alt>
<td>file and description</td>
</tr>
</table>
</div>
<div class="method-example">
<code class="method-declaration">
POST https://DomainName/api/v1/{entityType}/{entityId}/documents
</code>
<code class="method-request">
POST clients/1/documents
Content-Type: multipart/form-data
Request Body:
<i>Not Shown (multi-part form data)</i>
</code>
<code class="method-response">
{
"resourceId":3,
"resourceIdentifier":"3"
}
</code>
</div>
</div>
<a id="documents_update" name="documents_update" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Update a Document</h4>
<p>
<b>Note:</b> A document is updated using a Multi-part form upload
<br>
<table class=matrixHeading>
<tr class="matrixHeadingBG">
<td><div class="mifosXHeading2">Body Parts</div></td>
</tr>
<tr class=alt>
<td>name</td>
</tr>
<tr>
<td class=fielddesc>Name or summary of the document
</td>
</tr>
<tr class=alt>
<td>description</td>
</tr>
<tr>
<td class=fielddesc>Description of the document
</tr>
<tr class=alt>
<td>file</td>
</tr>
<tr>
<td class=fielddesc>The file to be uploaded
</td>
</tr>
</table>
</p>
</div>
<div class="method-example">
<code class="method-declaration">
PUT https://DomainName/api/v1/{entityType}/{entityId}/documents/{documentId}
</code>
<code class="method-request">
PUT clients/1/documents/1
Content-Type: multipart/form-data
Request Body:
<i>Not Shown (multi-part form data)</i>
</code>
<code class="method-response">
{
"resourceId":3,
"changes":{},
"resourceIdentifier":"3"
}
</code>
</div>
</div>
<a id="documents_retrieve_file" name="documents_retrieve"
class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Retrieve Binary File associated with Document</h4>
<p>Request used to download the file associated with the document</p>
<p>Example Requests:</p>
<div class=apiClick>clients/1/documents/1/attachment</div>
<br>
<br>
<div class=apiClick>loans/1/documents/1/attachment</div>
</div>
<div class="method-example">
<code class="method-declaration">
GET https://DomainName/api/v1/{entityType}/{entityId}/documents/{documentId}/attachment
</code>
<code class="method-response">
<i>Not Shown: The corresponding Binary file</i>
</code>
</div>
</div>
<a id="documents_delete" name="documents_delete" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Remove a Document</h4>
</div>
<div class="method-example">
<code class="method-declaration">
DELETE https://DomainName/api/v1/{entityType}/{entityId}/documents/{documentId}
</code>
<code class="method-request">
DELETE clients/1/documents/1
Content-Type: application/json
No Request Body:
</code>
<code class="method-response">
{
"resourceId":1,
"changes":{},
"resourceIdentifier":"1"
}
</code>
</div>
<div class="method-example">
<code class="method-declaration">
DELETE https://DomainName/api/v1/{entityType}/{entityId}/documents/{documentId}
</code>
<code class="method-request">
DELETE loans/1/documents/1
Content-Type: application/json
No Request Body:
</code>
<code class="method-response">
{
"resourceId":1,
"changes":{},
"resourceIdentifier":"1"
}
</code>
</div>
</div>
<!-- start of reports api docs --> <!-- start of reports api docs -->
<a id="reports" name="reports" class="old-syle-anchor">&nbsp;</a> <a id="reports" name="reports" class="old-syle-anchor">&nbsp;</a>
<div class="method-section"> <div class="method-section">
@@ -12086,6 +12628,22 @@ Content-Type: application/json
<td><a href="#configs_code_update">Update a Code</a></td> <td><a href="#configs_code_update">Update a Code</a></td>
<td><a href="#configs_code_delete">Delete a Code</a></td> <td><a href="#configs_code_delete">Delete a Code</a></td>
</tr> </tr>
<tr class="alt">
<td><a href="#configs_codes_codevalues">CODE VALUES</a></td>
<td>codes/{codeId}/codevalues</td>
<td><a href="#configs_codes_codevalues_create">Create a Code Value</a></td>
<td><a href="#configs_codes_codevalues_list">List Code Values</a></td>
<td></td>
<td></td>
</tr>
<tr >
<td></td>
<td>codes/{codeId}/codevalues/{codevalueId}</td>
<td></td>
<td><a href="#configs_codes_codevalues_retrieve">Retrieve 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>
</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>
@@ -12181,6 +12739,50 @@ Content-Type: application/json
Table (One to Many)</a></td> Table (One to Many)</a></td>
</tr> </tr>
<tr> <tr>
<td><a href="#documents">Documents</a></td>
<td>{entityType}/{entityId}/documents</td>
<td><a href="#documents_create">Create a Document</td>
<td><a href="#documents_list">List All Document Details</a></td>
<td></td>
<td></td>
</tr>
<tr class="alt">
<td></td>
<td>{entityType}/{entityId}/documents/{documentId}</td>
<td></td>
<td><a href="#documents_retrieve">Retrieve a Documents Details</a></td>
<td><a href="#documents_update">Update a Document</a></td>
<td><a href="#documents_delete">Delete a Document</a></td>
</tr>
<tr>
<td></td>
<td>{entityType}/{entityId}/documents/{documentId}/attachment</td>
<td></td>
<td><a href="#documents_retrieve_file">Retrieve
binary file associated with a
Document</a>
</td>
<td></td>
<td></td>
</tr>
<tr class="alt">
<td><a href="#notes">NOTES</a></td>
<td>{resource}/{resourceId}/notes</td>
<td><a href="#resources_addnote">Add a Resource Note</td>
<td><a href="#resource_notelist">Retrieve a Resource's Notes</a></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td>{resource}/{resourceId}/notes/{noteId}</td>
<td></td>
<td><a href="#resources_retrievenote">List All
Notes for a Resource</a></td>
<td><a href="#resources_updatenote">Update a Resource Note</a></td>
<td><a href="#resources_deletenote">Delete a Resource Note</a></td>
</tr>
<tr class="alt">
<td><a href="#glaccounts">General Ledger Account</a></td> <td><a href="#glaccounts">General Ledger Account</a></td>
<td>glaccounts</td> <td>glaccounts</td>
<td><a href="#glaccounts_create">Create a New Ledger Account</a></td> <td><a href="#glaccounts_create">Create a New Ledger Account</a></td>
@@ -12188,7 +12790,7 @@ Content-Type: application/json
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr class="alt"> <tr>
<td></td> <td></td>
<td>glaccounts/{glaccountId}</td> <td>glaccounts/{glaccountId}</td>
<td></td> <td></td>
@@ -12196,7 +12798,7 @@ Content-Type: application/json
<td><a href="#glaccounts_update">Update a Ledger Account</a></td> <td><a href="#glaccounts_update">Update a Ledger Account</a></td>
<td><a href="#glaccounts_delete">Delete a Ledger Account</a></td> <td><a href="#glaccounts_delete">Delete a Ledger Account</a></td>
</tr> </tr>
<tr> <tr class="alt">
<td><a href="#glclosures">Accounting Closure</a></td> <td><a href="#glclosures">Accounting Closure</a></td>
<td>glclosures</td> <td>glclosures</td>
<td><a href="#glclosures_create">Create an Accounting Closure</a></td> <td><a href="#glclosures_create">Create an Accounting Closure</a></td>
@@ -12204,7 +12806,7 @@ Content-Type: application/json
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr class="alt"> <tr>
<td></td> <td></td>
<td>glclosures/{glclosureId}</td> <td>glclosures/{glclosureId}</td>
<td></td> <td></td>
@@ -12212,7 +12814,7 @@ Content-Type: application/json
<td><a href="#glclosures_update">Update an Accounting Closure</a></td> <td><a href="#glclosures_update">Update an Accounting Closure</a></td>
<td><a href="#glclosures_delete">Delete an Accounting Closure</a></td> <td><a href="#glclosures_delete">Delete an Accounting Closure</a></td>
</tr> </tr>
<tr> <tr class="alt">
<td><a href="#journalentries">Journal Entries</a></td> <td><a href="#journalentries">Journal Entries</a></td>
<td>journalentries</td> <td>journalentries</td>
<td><a href="#journalentries_create">Create Journal Entries</a></td> <td><a href="#journalentries_create">Create Journal Entries</a></td>
@@ -12220,7 +12822,7 @@ Content-Type: application/json
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr class="alt"> <tr>
<td></td> <td></td>
<td>journalentries/{entryId}</td> <td>journalentries/{entryId}</td>
<td></td> <td></td>
@@ -12228,7 +12830,7 @@ Content-Type: application/json
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr class="alt">
<td></td> <td></td>
<td>journalentries/{transactionId}/reversal</td> <td>journalentries/{transactionId}/reversal</td>
<td><a href="#journalentries_reverse">Reverse Journal Entries</a></td> <td><a href="#journalentries_reverse">Reverse Journal Entries</a></td>
@@ -12236,7 +12838,7 @@ Content-Type: application/json
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr class="alt"> <tr>
<td><a href="#reports">REPORT</a></td> <td><a href="#reports">REPORT</a></td>
<td>reports</td> <td>reports</td>
<td></td> <td></td>
@@ -12244,7 +12846,7 @@ Content-Type: application/json
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr class="alt">
<td></td> <td></td>
<td>reports/{reportName}</td> <td>reports/{reportName}</td>
<td></td> <td></td>
@@ -12252,7 +12854,7 @@ Content-Type: application/json
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr class="alt"> <tr>
<td><a href="#authentication">AUTHENTICATION</a></td> <td><a href="#authentication">AUTHENTICATION</a></td>
<td>authentication</td> <td>authentication</td>
<td><a href="#authenticate_request">Verify Authentication</a></td> <td><a href="#authenticate_request">Verify Authentication</a></td>
@@ -12260,7 +12862,7 @@ Content-Type: application/json
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr class="alt">
<td><a href="#users">USER</a></td> <td><a href="#users">USER</a></td>
<td>users</td> <td>users</td>
<td><a href="#users_create">Create a User</a></td> <td><a href="#users_create">Create a User</a></td>
@@ -12268,7 +12870,7 @@ Content-Type: application/json
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr class="alt"> <tr>
<td></td> <td></td>
<td>users/{userId}</td> <td>users/{userId}</td>
<td></td> <td></td>
@@ -12276,7 +12878,7 @@ Content-Type: application/json
<td><a href="#users_update">Update a User</a></td> <td><a href="#users_update">Update a User</a></td>
<td><a href="#users_delete">Delete a User</a></td> <td><a href="#users_delete">Delete a User</a></td>
</tr> </tr>
<tr> <tr class="alt">
<td><a href="#roles">ROLE</a></td> <td><a href="#roles">ROLE</a></td>
<td>roles</td> <td>roles</td>
<td><a href="#roles_create">Create a New Role</a></td> <td><a href="#roles_create">Create a New Role</a></td>
@@ -12284,7 +12886,7 @@ Content-Type: application/json
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr class="alt"> <tr>
<td></td> <td></td>
<td>roles/{roleId}</td> <td>roles/{roleId}</td>
<td></td> <td></td>
@@ -12292,7 +12894,7 @@ Content-Type: application/json
<td><a href="#roles_update">Update a Role</a></td> <td><a href="#roles_update">Update a Role</a></td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr class="alt">
<td></td> <td></td>
<td>roles/{roleId}/permissions</td> <td>roles/{roleId}/permissions</td>
<td></td> <td></td>
@@ -12302,7 +12904,7 @@ Content-Type: application/json
Permissions</a></td> Permissions</a></td>
<td></td> <td></td>
</tr> </tr>
<tr class="alt"> <tr>
<td><a href="#permissions">PERMISSION</a></td> <td><a href="#permissions">PERMISSION</a></td>
<td>permissions</td> <td>permissions</td>
<td></td> <td></td>
@@ -12311,7 +12913,7 @@ Content-Type: application/json
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr class="alt">
<td><a href="#depositproducts">DEPOSIT PRODUCT</a></td> <td><a href="#depositproducts">DEPOSIT PRODUCT</a></td>
<td>depositproducts</td> <td>depositproducts</td>
<td><a href="#depositproducts_create">Create a Deposit product</a></td> <td><a href="#depositproducts_create">Create a Deposit product</a></td>
@@ -12319,7 +12921,7 @@ Content-Type: application/json
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr class="alt"> <tr>
<td></td> <td></td>
<td>depositproducts/{prodcutId}</td> <td>depositproducts/{prodcutId}</td>
<td></td> <td></td>
@@ -12327,7 +12929,7 @@ Content-Type: application/json
<td><a href="#depositproducts_update">Update a Deposit product</a></td> <td><a href="#depositproducts_update">Update a Deposit product</a></td>
<td><a href="#depositproducts_delete">Delete a Deposit product</a></td> <td><a href="#depositproducts_delete">Delete a Deposit product</a></td>
</tr> </tr>
<tr> <tr class="alt">
<td><a href="#savingproducts">SAVING PRODUCT</a></td> <td><a href="#savingproducts">SAVING PRODUCT</a></td>
<td>savingproducts</td> <td>savingproducts</td>
<td><a href="#savingproducts_create">Create a Saving product</a></td> <td><a href="#savingproducts_create">Create a Saving product</a></td>
@@ -12335,7 +12937,7 @@ Content-Type: application/json
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr class="alt"> <tr>
<td></td> <td></td>
<td>savingproducts/{prodcutId}</td> <td>savingproducts/{prodcutId}</td>
<td></td> <td></td>
@@ -12344,7 +12946,7 @@ Content-Type: application/json
<td><a href="#savingproducts_delete">Delete a Saving product</a></td> <td><a href="#savingproducts_delete">Delete a Saving product</a></td>
</tr> </tr>
<tr> <tr class="alt">
<td><a href="#fixeddeposits">FIXED DEPOSITS</a></td> <td><a href="#fixeddeposits">FIXED DEPOSITS</a></td>
<td>depositaccounts</td> <td>depositaccounts</td>
<td><a href="#fixeddeposits_create">Create a New Deposit <td><a href="#fixeddeposits_create">Create a New Deposit
@@ -12353,7 +12955,7 @@ Content-Type: application/json
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr class="alt"> <tr>
<td></td> <td></td>
<td>depositaccounts/{accountId}</td> <td>depositaccounts/{accountId}</td>
<td><a href="#fixeddeposits_approve_etc">Approve, Undo Approve, <td><a href="#fixeddeposits_approve_etc">Approve, Undo Approve,
@@ -12366,7 +12968,7 @@ Content-Type: application/json
Application</a></td> Application</a></td>
</tr> </tr>
<tr> <tr class="alt">
<td><a href="#savingaccounts">SAVING ACCOUNTS</a></td> <td><a href="#savingaccounts">SAVING ACCOUNTS</a></td>
<td>savingaccounts</td> <td>savingaccounts</td>
<td><a href="#savingaccounts_create">Create a New Saving <td><a href="#savingaccounts_create">Create a New Saving
@@ -12375,7 +12977,7 @@ Content-Type: application/json
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr class="alt"> <tr>
<td></td> <td></td>
<td>savingaccounts/{accountId}</td> <td>savingaccounts/{accountId}</td>
<td><a href="#savingaccounts_approve_etc">Approve, Undo Approve, <td><a href="#savingaccounts_approve_etc">Approve, Undo Approve,
+1 -1
View File
@@ -172,7 +172,7 @@ body {
text-align: center; text-align: center;
text-transform: uppercase; text-transform: uppercase;
font-size: 12px; font-size: 12px;
padding: 0 1em; padding: 0 0.5em;
line-height: 40px; line-height: 40px;
border-right: 1px solid transparent; border-right: 1px solid transparent;
border-left: 1px solid transparent; border-left: 1px solid transparent;
@@ -52,7 +52,7 @@ import com.sun.jersey.multipart.FormDataParam;
public class DocumentManagementApiResource { public class DocumentManagementApiResource {
private final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "parentEntityType", "parentEntityId", private final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "parentEntityType", "parentEntityId",
"name", "fileName", "type", "size", "description")); "name", "fileName", "size", "type", "description"));
private final String SystemEntityType = "DOCUMENT"; private final String SystemEntityType = "DOCUMENT";
@@ -76,24 +76,24 @@ public class DocumentManagementApiResource {
@GET @GET
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String retreiveAllDocuments(@Context final UriInfo uriInfo, @PathParam("entityType") String entityType, public String retreiveAllDocuments(@Context final UriInfo uriInfo, @PathParam("entityType") final String entityType,
@PathParam("entityId") Long entityId) { @PathParam("entityId") final Long entityId) {
context.authenticatedUser().validateHasReadPermission(SystemEntityType); this.context.authenticatedUser().validateHasReadPermission(this.SystemEntityType);
final Collection<DocumentData> documentDatas = this.documentReadPlatformService.retrieveAllDocuments(entityType, entityId); final Collection<DocumentData> documentDatas = this.documentReadPlatformService.retrieveAllDocuments(entityType, entityId);
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, documentDatas, RESPONSE_DATA_PARAMETERS); return this.toApiJsonSerializer.serialize(settings, documentDatas, this.RESPONSE_DATA_PARAMETERS);
} }
@POST @POST
@Consumes({ MediaType.MULTIPART_FORM_DATA }) @Consumes({ MediaType.MULTIPART_FORM_DATA })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String createDocument(@PathParam("entityType") String entityType, @PathParam("entityId") Long entityId, public String createDocument(@PathParam("entityType") final String entityType, @PathParam("entityId") final Long entityId,
@HeaderParam("Content-Length") Long fileSize, @FormDataParam("file") InputStream inputStream, @HeaderParam("Content-Length") final Long fileSize, @FormDataParam("file") final InputStream inputStream,
@FormDataParam("file") FormDataContentDisposition fileDetails, @FormDataParam("file") FormDataBodyPart bodyPart, @FormDataParam("file") final FormDataContentDisposition fileDetails, @FormDataParam("file") final FormDataBodyPart bodyPart,
@FormDataParam("name") String name, @FormDataParam("description") String description) { @FormDataParam("name") final String name, @FormDataParam("description") final String description) {
FileUtils.validateFileSizeWithinPermissibleRange(fileSize, name, ApiConstants.MAX_FILE_UPLOAD_SIZE_IN_MB); FileUtils.validateFileSizeWithinPermissibleRange(fileSize, name, ApiConstants.MAX_FILE_UPLOAD_SIZE_IN_MB);
@@ -106,10 +106,10 @@ public class DocumentManagementApiResource {
* TODO: need to extract the actual file type and determine if they are * TODO: need to extract the actual file type and determine if they are
* permissable * permissable
**/ **/
DocumentCommand documentCommand = new DocumentCommand(null, null, entityType, entityId, name, fileDetails.getFileName(), fileSize, final DocumentCommand documentCommand = new DocumentCommand(null, null, entityType, entityId, name, fileDetails.getFileName(),
bodyPart.getMediaType().toString(), description, null); fileSize, bodyPart.getMediaType().toString(), description, null);
Long documentId = this.documentWritePlatformService.createDocument(documentCommand, inputStream); final Long documentId = this.documentWritePlatformService.createDocument(documentCommand, inputStream);
return this.toApiJsonSerializer.serialize(CommandProcessingResult.resourceResult(documentId, null)); return this.toApiJsonSerializer.serialize(CommandProcessingResult.resourceResult(documentId, null));
} }
@@ -118,15 +118,15 @@ public class DocumentManagementApiResource {
@Path("{documentId}") @Path("{documentId}")
@Consumes({ MediaType.MULTIPART_FORM_DATA }) @Consumes({ MediaType.MULTIPART_FORM_DATA })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String updateDocument(@PathParam("entityType") String entityType, @PathParam("entityId") Long entityId, public String updateDocument(@PathParam("entityType") final String entityType, @PathParam("entityId") final Long entityId,
@PathParam("documentId") Long documentId, @HeaderParam("Content-Length") Long fileSize, @PathParam("documentId") final Long documentId, @HeaderParam("Content-Length") final Long fileSize,
@FormDataParam("file") InputStream inputStream, @FormDataParam("file") FormDataContentDisposition fileDetails, @FormDataParam("file") final InputStream inputStream, @FormDataParam("file") final FormDataContentDisposition fileDetails,
@FormDataParam("file") FormDataBodyPart bodyPart, @FormDataParam("name") String name, @FormDataParam("file") final FormDataBodyPart bodyPart, @FormDataParam("name") final String name,
@FormDataParam("description") String description) { @FormDataParam("description") final String description) {
FileUtils.validateFileSizeWithinPermissibleRange(fileSize, name, ApiConstants.MAX_FILE_UPLOAD_SIZE_IN_MB); FileUtils.validateFileSizeWithinPermissibleRange(fileSize, name, ApiConstants.MAX_FILE_UPLOAD_SIZE_IN_MB);
Set<String> modifiedParams = new HashSet<String>(); final Set<String> modifiedParams = new HashSet<String>();
modifiedParams.add("name"); modifiedParams.add("name");
modifiedParams.add("description"); modifiedParams.add("description");
@@ -146,7 +146,11 @@ public class DocumentManagementApiResource {
documentCommand = new DocumentCommand(modifiedParams, documentId, entityType, entityId, name, null, null, null, description, documentCommand = new DocumentCommand(modifiedParams, documentId, entityType, entityId, name, null, null, null, description,
null); null);
} }
CommandProcessingResult identifier = this.documentWritePlatformService.updateDocument(documentCommand, inputStream); /***
* TODO: does not return list of changes, should be done for consistency
* with rest of API
**/
final CommandProcessingResult identifier = this.documentWritePlatformService.updateDocument(documentCommand, inputStream);
return this.toApiJsonSerializer.serialize(identifier); return this.toApiJsonSerializer.serialize(identifier);
} }
@@ -155,32 +159,35 @@ public class DocumentManagementApiResource {
@Path("{documentId}") @Path("{documentId}")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String getDocument(@PathParam("entityType") String entityType, @PathParam("entityId") Long entityId, public String getDocument(@PathParam("entityType") final String entityType, @PathParam("entityId") final Long entityId,
@PathParam("documentId") Long documentId, @Context final UriInfo uriInfo) { @PathParam("documentId") final Long documentId, @Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission(SystemEntityType); this.context.authenticatedUser().validateHasReadPermission(this.SystemEntityType);
final DocumentData documentData = this.documentReadPlatformService.retrieveDocument(entityType, entityId, documentId); final DocumentData documentData = this.documentReadPlatformService.retrieveDocument(entityType, entityId, documentId);
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); // we do not want to send document location as a part of the response
return this.toApiJsonSerializer.serialize(settings, documentData, RESPONSE_DATA_PARAMETERS); documentData.setLocation(null);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, documentData, this.RESPONSE_DATA_PARAMETERS);
} }
@GET @GET
@Path("{documentId}/attachment") @Path("{documentId}/attachment")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_OCTET_STREAM })
public Response downloadFile(@PathParam("entityType") String entityType, @PathParam("entityId") Long entityId, public Response downloadFile(@PathParam("entityType") final String entityType, @PathParam("entityId") final Long entityId,
@PathParam("documentId") Long documentId) { @PathParam("documentId") final Long documentId) {
context.authenticatedUser().validateHasReadPermission(SystemEntityType); this.context.authenticatedUser().validateHasReadPermission(this.SystemEntityType);
DocumentData documentData = this.documentReadPlatformService.retrieveDocument(entityType, entityId, documentId); final DocumentData documentData = this.documentReadPlatformService.retrieveDocument(entityType, entityId, documentId);
File file = new File(documentData.fileLocation()); final File file = new File(documentData.fileLocation());
ResponseBuilder response = Response.ok(file); final ResponseBuilder response = Response.ok(file);
response.header("Content-Disposition", "attachment; filename=\"" + documentData.fileName() + "\""); response.header("Content-Disposition", "attachment; filename=\"" + documentData.fileName() + "\"");
response.header("Content-Type", documentData.contentType()); response.header("Content-Type", documentData.contentType());
return response.build(); return response.build();
} }
@@ -188,8 +195,8 @@ public class DocumentManagementApiResource {
@Path("{documentId}") @Path("{documentId}")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String deleteDocument(@PathParam("entityType") String entityType, @PathParam("entityId") Long entityId, public String deleteDocument(@PathParam("entityType") final String entityType, @PathParam("entityId") final Long entityId,
@PathParam("documentId") Long documentId) { @PathParam("documentId") final Long documentId) {
final DocumentCommand documentCommand = new DocumentCommand(null, documentId, entityType, entityId, null, null, null, null, null, final DocumentCommand documentCommand = new DocumentCommand(null, documentId, entityType, entityId, null, null, null, null, null,
null); null);
@@ -26,7 +26,7 @@ public class DocumentCommand {
private final Set<String> modifiedParameters; private final Set<String> modifiedParameters;
public DocumentCommand(final Set<String> modifiedParameters, final Long id, final String parentEntityType, final Long parentEntityId, public DocumentCommand(final Set<String> modifiedParameters, final Long id, final String parentEntityType, final Long parentEntityId,
final String name, final String fileName, Long size, String type, final String description, String location) { final String name, final String fileName, final Long size, final String type, final String description, final String location) {
this.modifiedParameters = modifiedParameters; this.modifiedParameters = modifiedParameters;
this.id = id; this.id = id;
this.parentEntityType = parentEntityType; this.parentEntityType = parentEntityType;
@@ -40,58 +40,58 @@ public class DocumentCommand {
} }
public Long getId() { public Long getId() {
return id; return this.id;
} }
public String getParentEntityType() { public String getParentEntityType() {
return parentEntityType; return this.parentEntityType;
} }
public Long getParentEntityId() { public Long getParentEntityId() {
return parentEntityId; return this.parentEntityId;
} }
public String getName() { public String getName() {
return name; return this.name;
} }
public String getFileName() { public String getFileName() {
return fileName; return this.fileName;
} }
public Long getSize() { public Long getSize() {
return size; return this.size;
} }
public String getType() { public String getType() {
return type; return this.type;
} }
public String getDescription() { public String getDescription() {
return description; return this.description;
} }
public String getLocation() { public String getLocation() {
return location; return this.location;
} }
public Set<String> getModifiedParameters() { public Set<String> getModifiedParameters() {
return modifiedParameters; return this.modifiedParameters;
} }
public void setFileName(String fileName) { public void setFileName(final String fileName) {
this.fileName = fileName; this.fileName = fileName;
} }
public void setSize(Long size) { public void setSize(final Long size) {
this.size = size; this.size = size;
} }
public void setType(String type) { public void setType(final String type) {
this.type = type; this.type = type;
} }
public void setLocation(String location) { public void setLocation(final String location) {
this.location = location; this.location = location;
} }
@@ -16,38 +16,40 @@ public class DocumentCommandValidator {
private final DocumentCommand command; private final DocumentCommand command;
public DocumentCommandValidator(DocumentCommand command) { public DocumentCommandValidator(final DocumentCommand command) {
this.command = command; this.command = command;
} }
public void validateForUpdate() { public void validateForUpdate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>(); final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("document"); final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("document");
baseDataValidator.reset().parameter("name").value(command.getName()).ignoreIfNull().notBlank(); baseDataValidator.reset().parameter("name").value(this.command.getName()).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("size").value(command.getSize()).ignoreIfNull().integerGreaterThanZero(); baseDataValidator.reset().parameter("size").value(this.command.getSize()).ignoreIfNull().integerGreaterThanZero();
baseDataValidator.reset().parameter("fileName").value(command.getFileName()).ignoreIfNull().notBlank().notExceedingLengthOf(250); baseDataValidator.reset().parameter("fileName").value(this.command.getFileName()).ignoreIfNull().notBlank()
baseDataValidator.reset().parameter("location").value(command.getLocation()).ignoreIfNull().notBlank(); .notExceedingLengthOf(250);
baseDataValidator.reset().parameter("description").value(command.getName()).ignoreIfNull().notExceedingLengthOf(250); baseDataValidator.reset().parameter("location").value(this.command.getLocation()).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("description").value(this.command.getName()).ignoreIfNull().notExceedingLengthOf(250);
baseDataValidator.reset().anyOfNotNull(command.getName(), command.getFileName(), command.getDescription(), command.getLocation(), baseDataValidator.reset().anyOfNotNull(this.command.getName(), this.command.getFileName(), this.command.getDescription(),
command.getSize()); this.command.getLocation(), this.command.getSize());
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); } "Validation errors exist.", dataValidationErrors); }
} }
public void validateForCreate() { public void validateForCreate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>(); final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("document"); final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("document");
baseDataValidator.reset().parameter("parentEntityType").value(command.getParentEntityType()).notBlank().notExceedingLengthOf(50); baseDataValidator.reset().parameter("parentEntityType").value(this.command.getParentEntityType()).notBlank()
baseDataValidator.reset().parameter("parentEntityId").value(command.getParentEntityId()).integerGreaterThanZero(); .notExceedingLengthOf(50);
baseDataValidator.reset().parameter("name").value(command.getName()).notBlank().notExceedingLengthOf(250); baseDataValidator.reset().parameter("parentEntityId").value(this.command.getParentEntityId()).integerGreaterThanZero();
baseDataValidator.reset().parameter("size").value(command.getSize()).integerGreaterThanZero(); baseDataValidator.reset().parameter("name").value(this.command.getName()).notBlank().notExceedingLengthOf(250);
baseDataValidator.reset().parameter("fileName").value(command.getFileName()).notBlank().notExceedingLengthOf(250); baseDataValidator.reset().parameter("size").value(this.command.getSize()).integerGreaterThanZero();
baseDataValidator.reset().parameter("description").value(command.getName()).notExceedingLengthOf(250); baseDataValidator.reset().parameter("fileName").value(this.command.getFileName()).notBlank().notExceedingLengthOf(250);
baseDataValidator.reset().parameter("description").value(this.command.getName()).notExceedingLengthOf(250);
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); } "Validation errors exist.", dataValidationErrors); }
@@ -24,7 +24,7 @@ public class DocumentData {
private final String type; private final String type;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String description; private final String description;
private final String location; private String location;
public DocumentData(final Long id, final String parentEntityType, final Long parentEntityId, final String name, final String fileName, public DocumentData(final Long id, final String parentEntityType, final Long parentEntityId, final String name, final String fileName,
final Long size, final String type, final String description, final String location) { final Long size, final String type, final String description, final String location) {
@@ -50,4 +50,9 @@ public class DocumentData {
public String fileLocation() { public String fileLocation() {
return this.location; return this.location;
} }
public void setLocation(final String location) {
this.location = location;
}
} }
@@ -43,13 +43,13 @@ public class Document extends AbstractPersistable<Long> {
public Document() {} public Document() {}
public static Document createNew(String parentEntityType, Long parentEntityId, String name, String fileName, Long size, String type, public static Document createNew(final String parentEntityType, final Long parentEntityId, final String name, final String fileName,
String description, String location) { final Long size, final String type, final String description, final String location) {
return new Document(parentEntityType, parentEntityId, name, fileName, size, type, description, location); return new Document(parentEntityType, parentEntityId, name, fileName, size, type, description, location);
} }
private Document(String parentEntityType, Long parentEntityId, String name, String fileName, Long size, String type, private Document(final String parentEntityType, final Long parentEntityId, final String name, final String fileName, final Long size,
String description, String location) { final String type, final String description, final String location) {
this.parentEntityType = StringUtils.defaultIfEmpty(parentEntityType, null); this.parentEntityType = StringUtils.defaultIfEmpty(parentEntityType, null);
this.parentEntityId = parentEntityId; this.parentEntityId = parentEntityId;
this.name = StringUtils.defaultIfEmpty(name, null); this.name = StringUtils.defaultIfEmpty(name, null);
@@ -83,66 +83,66 @@ public class Document extends AbstractPersistable<Long> {
} }
public String getParentEntityType() { public String getParentEntityType() {
return parentEntityType; return this.parentEntityType;
} }
public void setParentEntityType(String parentEntityType) { public void setParentEntityType(final String parentEntityType) {
this.parentEntityType = parentEntityType; this.parentEntityType = parentEntityType;
} }
public Long getParentEntityId() { public Long getParentEntityId() {
return parentEntityId; return this.parentEntityId;
} }
public void setParentEntityId(Long parentEntityId) { public void setParentEntityId(final Long parentEntityId) {
this.parentEntityId = parentEntityId; this.parentEntityId = parentEntityId;
} }
public String getName() { public String getName() {
return name; return this.name;
} }
public void setName(String name) { public void setName(final String name) {
this.name = name; this.name = name;
} }
public String getFileName() { public String getFileName() {
return fileName; return this.fileName;
} }
public void setFileName(String fileName) { public void setFileName(final String fileName) {
this.fileName = fileName; this.fileName = fileName;
} }
public Long getSize() { public Long getSize() {
return size; return this.size;
} }
public void setSize(Long size) { public void setSize(final Long size) {
this.size = size; this.size = size;
} }
public String getType() { public String getType() {
return type; return this.type;
} }
public void setType(String type) { public void setType(final String type) {
this.type = type; this.type = type;
} }
public String getDescription() { public String getDescription() {
return description; return this.description;
} }
public void setDescription(String description) { public void setDescription(final String description) {
this.description = description; this.description = description;
} }
public String getLocation() { public String getLocation() {
return location; return this.location;
} }
public void setLocation(String location) { public void setLocation(final String location) {
this.location = location; this.location = location;
} }
@@ -35,13 +35,13 @@ public class DocumentReadPlatformServiceImpl implements DocumentReadPlatformServ
@Override @Override
public Collection<DocumentData> retrieveAllDocuments(final String entityType, final Long entityId) { public Collection<DocumentData> retrieveAllDocuments(final String entityType, final Long entityId) {
context.authenticatedUser(); this.context.authenticatedUser();
// TODO verify if the entities are valid and a user // TODO verify if the entities are valid and a user
// has data // has data
// scope for the particular entities // scope for the particular entities
DocumentMapper mapper = new DocumentMapper(); final DocumentMapper mapper = new DocumentMapper(true);
String sql = "select " + mapper.schema() + " order by d.id"; final String sql = "select " + mapper.schema() + " order by d.id";
return this.jdbcTemplate.query(sql, mapper, new Object[] { entityType, entityId }); return this.jdbcTemplate.query(sql, mapper, new Object[] { entityType, entityId });
} }
@@ -49,21 +49,27 @@ public class DocumentReadPlatformServiceImpl implements DocumentReadPlatformServ
public DocumentData retrieveDocument(final String entityType, final Long entityId, final Long documentId) { public DocumentData retrieveDocument(final String entityType, final Long entityId, final Long documentId) {
try { try {
context.authenticatedUser(); this.context.authenticatedUser();
// TODO verify if the entities are valid and a // TODO verify if the entities are valid and a
// user has data // user has data
// scope for the particular entities // scope for the particular entities
DocumentMapper mapper = new DocumentMapper(); final DocumentMapper mapper = new DocumentMapper(false);
String sql = "select " + mapper.schema() + " and d.id=? "; final String sql = "select " + mapper.schema() + " and d.id=? ";
return this.jdbcTemplate.queryForObject(sql, mapper, new Object[] { entityType, entityId, documentId }); return this.jdbcTemplate.queryForObject(sql, mapper, new Object[] { entityType, entityId, documentId });
} catch (EmptyResultDataAccessException e) { } catch (final EmptyResultDataAccessException e) {
throw new DocumentNotFoundException(entityType, entityId, documentId); throw new DocumentNotFoundException(entityType, entityId, documentId);
} }
} }
private static final class DocumentMapper implements RowMapper<DocumentData> { private static final class DocumentMapper implements RowMapper<DocumentData> {
private final boolean hideLocation;
public DocumentMapper(final boolean hideLocation) {
this.hideLocation = hideLocation;
}
public String schema() { public String schema() {
return "d.id as id, d.parent_entity_type as parentEntityType, d.parent_entity_id as parentEntityId, d.name as name, " return "d.id as id, d.parent_entity_type as parentEntityType, d.parent_entity_id as parentEntityId, d.name as name, "
+ " d.file_name as fileName, d.size as fileSize, d.type as fileType, " + " d.file_name as fileName, d.size as fileSize, d.type as fileType, "
@@ -82,7 +88,10 @@ public class DocumentReadPlatformServiceImpl implements DocumentReadPlatformServ
final String fileName = rs.getString("fileName"); final String fileName = rs.getString("fileName");
final String fileType = rs.getString("fileType"); final String fileType = rs.getString("fileType");
final String description = rs.getString("description"); final String description = rs.getString("description");
final String location = rs.getString("location"); String location = null;
if (!this.hideLocation) {
location = rs.getString("location");
}
return new DocumentData(id, parentEntityType, parentEntityId, name, fileName, fileSize, fileType, description, location); return new DocumentData(id, parentEntityType, parentEntityId, name, fileName, fileSize, fileType, description, location);
} }
@@ -45,15 +45,15 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWr
@Override @Override
public Long createDocument(final DocumentCommand documentCommand, final InputStream inputStream) { public Long createDocument(final DocumentCommand documentCommand, final InputStream inputStream) {
try { try {
context.authenticatedUser(); this.context.authenticatedUser();
DocumentCommandValidator validator = new DocumentCommandValidator(documentCommand); final DocumentCommandValidator validator = new DocumentCommandValidator(documentCommand);
validateParentEntityType(documentCommand); validateParentEntityType(documentCommand);
validator.validateForCreate(); validator.validateForCreate();
String fileUploadLocation = FileUtils.generateFileParentDirectory(documentCommand.getParentEntityType(), final String fileUploadLocation = FileUtils.generateFileParentDirectory(documentCommand.getParentEntityType(),
documentCommand.getParentEntityId()); documentCommand.getParentEntityId());
/** Recursively create the directory if it does not exist **/ /** Recursively create the directory if it does not exist **/
@@ -61,20 +61,20 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWr
new File(fileUploadLocation).mkdirs(); new File(fileUploadLocation).mkdirs();
} }
String fileLocation = FileUtils.saveToFileSystem(inputStream, fileUploadLocation, documentCommand.getFileName()); final String fileLocation = FileUtils.saveToFileSystem(inputStream, fileUploadLocation, documentCommand.getFileName());
Document document = Document.createNew(documentCommand.getParentEntityType(), documentCommand.getParentEntityId(), final Document document = Document.createNew(documentCommand.getParentEntityType(), documentCommand.getParentEntityId(),
documentCommand.getName(), documentCommand.getFileName(), documentCommand.getSize(), documentCommand.getType(), documentCommand.getName(), documentCommand.getFileName(), documentCommand.getSize(), documentCommand.getType(),
documentCommand.getDescription(), fileLocation); documentCommand.getDescription(), fileLocation);
this.documentRepository.save(document); this.documentRepository.save(document);
return document.getId(); return document.getId();
} catch (DataIntegrityViolationException dve) { } catch (final DataIntegrityViolationException dve) {
logger.error(dve.getMessage(), dve); logger.error(dve.getMessage(), dve);
throw new PlatformDataIntegrityException("error.msg.document.unknown.data.integrity.issue", throw new PlatformDataIntegrityException("error.msg.document.unknown.data.integrity.issue",
"Unknown data integrity issue with resource."); "Unknown data integrity issue with resource.");
} catch (IOException ioe) { } catch (final IOException ioe) {
logger.error(ioe.getMessage(), ioe); logger.error(ioe.getMessage(), ioe);
throw new DocumentManagementException(documentCommand.getName()); throw new DocumentManagementException(documentCommand.getName());
} }
@@ -84,20 +84,20 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWr
@Override @Override
public CommandProcessingResult updateDocument(final DocumentCommand documentCommand, final InputStream inputStream) { public CommandProcessingResult updateDocument(final DocumentCommand documentCommand, final InputStream inputStream) {
try { try {
context.authenticatedUser(); this.context.authenticatedUser();
String oldLocation = null; String oldLocation = null;
DocumentCommandValidator validator = new DocumentCommandValidator(documentCommand); final DocumentCommandValidator validator = new DocumentCommandValidator(documentCommand);
validator.validateForUpdate(); validator.validateForUpdate();
// TODO check if entity id is valid and within data scope for the // TODO check if entity id is valid and within data scope for the
// user // user
Document documentForUpdate = this.documentRepository.findOne(documentCommand.getId()); final Document documentForUpdate = this.documentRepository.findOne(documentCommand.getId());
if (documentForUpdate == null) { throw new DocumentNotFoundException(documentCommand.getParentEntityType(), if (documentForUpdate == null) { throw new DocumentNotFoundException(documentCommand.getParentEntityType(),
documentCommand.getParentEntityId(), documentCommand.getId()); } documentCommand.getParentEntityId(), documentCommand.getId()); }
oldLocation = documentForUpdate.getLocation(); oldLocation = documentForUpdate.getLocation();
// if a new file is also passed in // if a new file is also passed in
if (inputStream != null && documentCommand.isFileNameChanged()) { if (inputStream != null && documentCommand.isFileNameChanged()) {
String fileUploadLocation = FileUtils.generateFileParentDirectory(documentCommand.getParentEntityType(), final String fileUploadLocation = FileUtils.generateFileParentDirectory(documentCommand.getParentEntityType(),
documentCommand.getParentEntityId()); documentCommand.getParentEntityId());
/** Recursively create the directory if it does not exist **/ /** Recursively create the directory if it does not exist **/
@@ -105,8 +105,9 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWr
new File(fileUploadLocation).mkdirs(); new File(fileUploadLocation).mkdirs();
} }
// TODO replace file system appender with an Amazon S3 appender // TODO provide switch to toggle between file system appender
String fileLocation = FileUtils.saveToFileSystem(inputStream, fileUploadLocation, documentCommand.getFileName()); // and Amazon S3 appender
final String fileLocation = FileUtils.saveToFileSystem(inputStream, fileUploadLocation, documentCommand.getFileName());
documentCommand.setLocation(fileLocation); documentCommand.setLocation(fileLocation);
} }
@@ -120,11 +121,11 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWr
this.documentRepository.saveAndFlush(documentForUpdate); this.documentRepository.saveAndFlush(documentForUpdate);
return new CommandProcessingResult(documentForUpdate.getId()); return new CommandProcessingResult(documentForUpdate.getId());
} catch (DataIntegrityViolationException dve) { } catch (final DataIntegrityViolationException dve) {
logger.error(dve.getMessage(), dve); logger.error(dve.getMessage(), dve);
throw new PlatformDataIntegrityException("error.msg.document.unknown.data.integrity.issue", throw new PlatformDataIntegrityException("error.msg.document.unknown.data.integrity.issue",
"Unknown data integrity issue with resource."); "Unknown data integrity issue with resource.");
} catch (IOException ioe) { } catch (final IOException ioe) {
logger.error(ioe.getMessage(), ioe); logger.error(ioe.getMessage(), ioe);
throw new DocumentManagementException(documentCommand.getName()); throw new DocumentManagementException(documentCommand.getName());
} }
@@ -133,11 +134,11 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWr
@Transactional @Transactional
@Override @Override
public CommandProcessingResult deleteDocument(final DocumentCommand documentCommand) { public CommandProcessingResult deleteDocument(final DocumentCommand documentCommand) {
context.authenticatedUser(); this.context.authenticatedUser();
validateParentEntityType(documentCommand); validateParentEntityType(documentCommand);
// TODO: Check document is present under this entity Id // TODO: Check document is present under this entity Id
Document document = this.documentRepository.findOne(documentCommand.getId()); final Document document = this.documentRepository.findOne(documentCommand.getId());
if (document == null) { throw new DocumentNotFoundException(documentCommand.getParentEntityType(), if (document == null) { throw new DocumentNotFoundException(documentCommand.getParentEntityType(),
documentCommand.getParentEntityId(), documentCommand.getId()); } documentCommand.getParentEntityId(), documentCommand.getId()); }
@@ -146,20 +147,20 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWr
return new CommandProcessingResult(document.getId()); return new CommandProcessingResult(document.getId());
} }
private void deleteFile(String documentName, String location) { private void deleteFile(final String documentName, final String location) {
File fileToBeDeleted = new File(location); final File fileToBeDeleted = new File(location);
boolean fileDeleted = fileToBeDeleted.delete(); final boolean fileDeleted = fileToBeDeleted.delete();
if (!fileDeleted) { throw new DocumentManagementException(documentName); } if (!fileDeleted) { throw new DocumentManagementException(documentName); }
} }
private void validateParentEntityType(DocumentCommand documentCommand) { private void validateParentEntityType(final DocumentCommand documentCommand) {
if (!checkValidEntityType(documentCommand.getParentEntityType())) { throw new InvalidEntityTypeForDocumentManagementException( if (!checkValidEntityType(documentCommand.getParentEntityType())) { throw new InvalidEntityTypeForDocumentManagementException(
documentCommand.getParentEntityType()); } documentCommand.getParentEntityType()); }
} }
private static boolean checkValidEntityType(final String entityType) { private static boolean checkValidEntityType(final String entityType) {
for (DOCUMENT_MANAGEMENT_ENTITY entities : DOCUMENT_MANAGEMENT_ENTITY.values()) { for (final DOCUMENT_MANAGEMENT_ENTITY entities : DOCUMENT_MANAGEMENT_ENTITY.values()) {
if (entities.name().equalsIgnoreCase(entityType)) { return true; } if (entities.name().equalsIgnoreCase(entityType)) { return true; }
} }
return false; return false;
@@ -49,12 +49,12 @@ public final class ClientIdentifierCommandFromApiJsonDeserializer extends Abstra
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType(); final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters); this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedParameters);
final JsonElement element = fromApiJsonHelper.parse(json); final JsonElement element = this.fromApiJsonHelper.parse(json);
final Long documentTypeId = fromApiJsonHelper.extractLongNamed("documentTypeId", element); final Long documentTypeId = this.fromApiJsonHelper.extractLongNamed("documentTypeId", element);
final String documentKey = fromApiJsonHelper.extractStringNamed("documentKey", element); final String documentKey = this.fromApiJsonHelper.extractStringNamed("documentKey", element);
final String documentDescription = fromApiJsonHelper.extractStringNamed("documentDescription", element); final String documentDescription = this.fromApiJsonHelper.extractStringNamed("documentDescription", element);
return new ClientIdentifierCommand(documentTypeId, documentKey, documentDescription); return new ClientIdentifierCommand(documentTypeId, documentKey, documentDescription);
} }
@@ -37,11 +37,11 @@ public class ClientIdentifierReadPlatformServiceImpl implements ClientIdentifier
@Override @Override
public Collection<ClientIdentifierData> retrieveClientIdentifiers(final Long clientId) { public Collection<ClientIdentifierData> retrieveClientIdentifiers(final Long clientId) {
AppUser currentUser = context.authenticatedUser(); final AppUser currentUser = this.context.authenticatedUser();
String hierarchy = currentUser.getOffice().getHierarchy(); final String hierarchy = currentUser.getOffice().getHierarchy();
String hierarchySearchString = hierarchy + "%"; final String hierarchySearchString = hierarchy + "%";
ClientIdentityMapper rm = new ClientIdentityMapper(); final ClientIdentityMapper rm = new ClientIdentityMapper();
String sql = "select " + rm.schema(); String sql = "select " + rm.schema();
@@ -53,11 +53,11 @@ public class ClientIdentifierReadPlatformServiceImpl implements ClientIdentifier
@Override @Override
public ClientIdentifierData retrieveClientIdentifier(final Long clientId, final Long clientIdentifierId) { public ClientIdentifierData retrieveClientIdentifier(final Long clientId, final Long clientIdentifierId) {
try { try {
AppUser currentUser = context.authenticatedUser(); final AppUser currentUser = this.context.authenticatedUser();
String hierarchy = currentUser.getOffice().getHierarchy(); final String hierarchy = currentUser.getOffice().getHierarchy();
String hierarchySearchString = hierarchy + "%"; final String hierarchySearchString = hierarchy + "%";
ClientIdentityMapper rm = new ClientIdentityMapper(); final ClientIdentityMapper rm = new ClientIdentityMapper();
String sql = "select " + rm.schema(); String sql = "select " + rm.schema();
@@ -67,7 +67,7 @@ public class ClientIdentifierReadPlatformServiceImpl implements ClientIdentifier
hierarchySearchString, clientIdentifierId }); hierarchySearchString, clientIdentifierId });
return clientIdentifierData; return clientIdentifierData;
} catch (EmptyResultDataAccessException e) { } catch (final EmptyResultDataAccessException e) {
throw new ClientIdentifierNotFoundException(clientIdentifierId); throw new ClientIdentifierNotFoundException(clientIdentifierId);
} }
@@ -95,7 +95,7 @@ public class ClientIdentifierReadPlatformServiceImpl implements ClientIdentifier
final String description = rs.getString("description"); final String description = rs.getString("description");
final String documentTypeName = rs.getString("documentType"); final String documentTypeName = rs.getString("documentType");
CodeValueData documentType = CodeValueData.instance(documentTypeId, documentTypeName); final CodeValueData documentType = CodeValueData.instance(documentTypeId, documentTypeName);
return ClientIdentifierData.singleItem(id, clientId, documentType, documentKey, description); return ClientIdentifierData.singleItem(id, clientId, documentType, documentKey, description);
} }
@@ -58,12 +58,12 @@ public class ClientIdentifierWritePlatformServiceJpaRepositoryImpl implements Cl
@Override @Override
public CommandProcessingResult addClientIdentifier(final Long clientId, final JsonCommand command) { public CommandProcessingResult addClientIdentifier(final Long clientId, final JsonCommand command) {
context.authenticatedUser(); this.context.authenticatedUser();
final ClientIdentifierCommand clientIdentifierCommand = this.clientIdentifierCommandFromApiJsonDeserializer final ClientIdentifierCommand clientIdentifierCommand = this.clientIdentifierCommandFromApiJsonDeserializer
.commandFromApiJson(command.json()); .commandFromApiJson(command.json());
clientIdentifierCommand.validateForCreate(); clientIdentifierCommand.validateForCreate();
String documentKey = clientIdentifierCommand.getDocumentKey(); final String documentKey = clientIdentifierCommand.getDocumentKey();
String documentTypeLabel = null; String documentTypeLabel = null;
Long documentTypeId = null; Long documentTypeId = null;
try { try {
@@ -85,7 +85,7 @@ public class ClientIdentifierWritePlatformServiceJpaRepositoryImpl implements Cl
.withClientId(clientId) // .withClientId(clientId) //
.withEntityId(clientIdentifier.getId()) // .withEntityId(clientIdentifier.getId()) //
.build(); .build();
} catch (DataIntegrityViolationException dve) { } catch (final DataIntegrityViolationException dve) {
handleClientIdentifierDataIntegrityViolation(documentTypeLabel, documentTypeId, documentKey, dve); handleClientIdentifierDataIntegrityViolation(documentTypeLabel, documentTypeId, documentKey, dve);
return CommandProcessingResult.empty(); return CommandProcessingResult.empty();
} }
@@ -95,7 +95,7 @@ public class ClientIdentifierWritePlatformServiceJpaRepositoryImpl implements Cl
@Override @Override
public CommandProcessingResult updateClientIdentifier(final Long clientId, final Long identifierId, final JsonCommand command) { public CommandProcessingResult updateClientIdentifier(final Long clientId, final Long identifierId, final JsonCommand command) {
context.authenticatedUser(); this.context.authenticatedUser();
final ClientIdentifierCommand clientIdentifierCommand = this.clientIdentifierCommandFromApiJsonDeserializer final ClientIdentifierCommand clientIdentifierCommand = this.clientIdentifierCommandFromApiJsonDeserializer
.commandFromApiJson(command.json()); .commandFromApiJson(command.json());
clientIdentifierCommand.validateForUpdate(); clientIdentifierCommand.validateForUpdate();
@@ -143,7 +143,7 @@ public class ClientIdentifierWritePlatformServiceJpaRepositoryImpl implements Cl
.withEntityId(identifierId) // .withEntityId(identifierId) //
.with(changes) // .with(changes) //
.build(); .build();
} catch (DataIntegrityViolationException dve) { } catch (final DataIntegrityViolationException dve) {
handleClientIdentifierDataIntegrityViolation(documentTypeLabel, documentTypeId, documentKey, dve); handleClientIdentifierDataIntegrityViolation(documentTypeLabel, documentTypeId, documentKey, dve);
return new CommandProcessingResult(Long.valueOf(-1)); return new CommandProcessingResult(Long.valueOf(-1));
} }