fix for MIFOSX-1947
change file name update fix added sql added tests for image api remove comment api doc more tests
This commit is contained in:
@@ -16767,6 +16767,252 @@ Request Body:
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<a id="staff_images" name="staff_images" class="old-syle-anchor"> </a>
|
||||||
|
<div class="method-section">
|
||||||
|
<div class="method-description">
|
||||||
|
<h3>Staff Images</h3>
|
||||||
|
<p>The current API provides support for the addition of a single
|
||||||
|
image for a Staff Member<br/>
|
||||||
|
Allowed formats: JPEG (.jpg or .jpeg), GIF (.gif) and PNG (.png)
|
||||||
|
</p>
|
||||||
|
<p> The API supports two different Approaches for manipulating Staff Images
|
||||||
|
<ul>
|
||||||
|
<li><a href="http://en.wikipedia.org/wiki/Data_URI_scheme" target="_blank"> Data URI's: </a>
|
||||||
|
For easier manipulation by Javascript clients etc in supported Browsers.
|
||||||
|
</li>
|
||||||
|
<li><a href="http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2">
|
||||||
|
Multi-part form data:</a>
|
||||||
|
Images can be uploaded using Multi part forms and downloaded as regular binary files
|
||||||
|
</li>
|
||||||
|
<br/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a id="staff_images_create" name="staff_images_create" class="old-syle-anchor"> </a>
|
||||||
|
<div class="method-section">
|
||||||
|
<div class="method-description">
|
||||||
|
<h4>Upload an Image for a Staff (Data URI)</h4>
|
||||||
|
</div>
|
||||||
|
<div class="method-example">
|
||||||
|
<code class="method-declaration">
|
||||||
|
POST https://DomainName/api/v1/staff/{staffId}/images
|
||||||
|
</code>
|
||||||
|
<code class="method-request">
|
||||||
|
POST staff/1/images
|
||||||
|
Content-Type: text/plain
|
||||||
|
Request Body:
|
||||||
|
data:image/png;base64,iVBORw0KGgoAA
|
||||||
|
AANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0l
|
||||||
|
EQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6
|
||||||
|
P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC
|
||||||
|
</code>
|
||||||
|
<code class="method-response">
|
||||||
|
{
|
||||||
|
"resourceId": 1,
|
||||||
|
"changes": {},
|
||||||
|
"resourceIdentifier": "1"
|
||||||
|
}
|
||||||
|
</code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a id="staff_images_create_form" name="staff_images_create_form" class="old-syle-anchor"> </a>
|
||||||
|
<div class="method-section">
|
||||||
|
<div class="method-description">
|
||||||
|
<h4>Upload an Image for a Staff Member (Multi-part Form data)</h4>
|
||||||
|
<table class=matrixHeading>
|
||||||
|
<tr class="matrixHeadingBG">
|
||||||
|
<td><div class="mifosXHeading2">Mandatory Fields</div></td>
|
||||||
|
</tr>
|
||||||
|
<tr class=alt>
|
||||||
|
<td>file
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<p>
|
||||||
|
The form should contain a required named body part with the
|
||||||
|
name "file". <br/> <br/>
|
||||||
|
If you are using a HTML form, a snippet like
|
||||||
|
<small> <input type="file" name="file"></input> </small>
|
||||||
|
can be used for uploading the image file
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="method-example">
|
||||||
|
<code class="method-declaration">
|
||||||
|
POST https://DomainName/api/v1/staff/{staffId}/images
|
||||||
|
</code>
|
||||||
|
<code class="method-request">
|
||||||
|
POST staff/1/images
|
||||||
|
Content-Type: multipart/form-data
|
||||||
|
Request Body: <i>Not shown</i>
|
||||||
|
</code>
|
||||||
|
<code class="method-response">
|
||||||
|
{
|
||||||
|
"resourceId": 1,
|
||||||
|
"changes": {},
|
||||||
|
"resourceIdentifier": "1"
|
||||||
|
}
|
||||||
|
</code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a id="staff_images_retrieve" name="staff_images_retrieve"
|
||||||
|
class="old-syle-anchor"> </a>
|
||||||
|
<div class="method-section">
|
||||||
|
<div class="method-description">
|
||||||
|
<h4>Get Staff Image (DATA URI)</h4>
|
||||||
|
<p>Optional arguments are identical to those of <a href="#client_images_retrieve_binary">Get Staff Image (Binary file)</a></p>
|
||||||
|
<p>Example Requests:</p>
|
||||||
|
<div class=apiClick>staff/1/images</div>
|
||||||
|
<br>
|
||||||
|
</div>
|
||||||
|
<div class="method-example">
|
||||||
|
<code class="method-declaration">
|
||||||
|
GET https://DomainName/api/v1/staff/{staffId}/images
|
||||||
|
Accept: text/plain
|
||||||
|
|
||||||
|
</code>
|
||||||
|
<code class="method-response">
|
||||||
|
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ
|
||||||
|
bWFnZVJlYWR5ccllPAAAAJ1JREFUeNpi+P//PwMIA4E9EG8E4idQDGLbw+WhiiqA+D8OXAFVAzbp
|
||||||
|
DxBvB2JLIGaGYkuoGEjOhhFIHAbij0BdPgxYACMj42ogJQpifwBiXSDeC8JIbt4LxSC5DyxQjTeB
|
||||||
|
+BeaYb+Q5EBOAVutCzMJHUNNPADzzDokiYdAfAmJvwLkGeTgWQfyKZICS6hYBTwc0QL8ORSjBDhA
|
||||||
|
gAEAOg13B6R/SAgAAAAASUVORK5CYII=
|
||||||
|
</code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a id="staff_images_retrieve_binary" name="staff_images_retrieve_binary"
|
||||||
|
class="old-syle-anchor"> </a>
|
||||||
|
<div class="method-section">
|
||||||
|
<div class="method-description">
|
||||||
|
<h4>Get Staff Image (Binary file)</h4>
|
||||||
|
<h5>Optional Arguments</h5>
|
||||||
|
<dl class="argument-list">
|
||||||
|
<dt>output</dt>
|
||||||
|
<dd>
|
||||||
|
String <span>optional</span> one of <span>octet or inline_octet</span>
|
||||||
|
</dd>
|
||||||
|
<dd>The query parameter overrides the <span>"Accept" Header</span> and sets the Media Type to "application/octet-stream" <br/>
|
||||||
|
<span><b>octet :</b></span> Returns the image binary file as an attachment. The <span>Content-Disposition</span> header is set to <span>attachment;filename=somefile.ext</span> <br/>
|
||||||
|
<span><b>inline_octet :</b></span>The <span>Content-Disposition</span> header is set to <span>inline;filename=somefile.ext</span>
|
||||||
|
</dd>
|
||||||
|
<dt>maxWidth</dt>
|
||||||
|
<dd>
|
||||||
|
Integer <span>optional</span>
|
||||||
|
</dd>
|
||||||
|
<dd>Triggers resizing of the image to the defined width</dd>
|
||||||
|
|
||||||
|
<dt>maxHeight</dt>
|
||||||
|
<dd>
|
||||||
|
<dd>
|
||||||
|
Integer <span>optional</span>
|
||||||
|
</dd>
|
||||||
|
</dd>
|
||||||
|
<dd>Triggers resizing of the image to the defined height</dd>
|
||||||
|
|
||||||
|
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
<div class="method-example">
|
||||||
|
<code class="method-declaration">
|
||||||
|
GET https://DomainName/api/v1/staff/{staffId}/images
|
||||||
|
Accept: application/octet-stream
|
||||||
|
</code>
|
||||||
|
<code class="method-request">
|
||||||
|
POST staff/1/images
|
||||||
|
Accept: application/octet-stream
|
||||||
|
</code>
|
||||||
|
<code class="method-response">
|
||||||
|
<i>Not shown</i>: The corresponding binary (image) file
|
||||||
|
</code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a id="staff_images_update" name="staff_images_update" class="old-syle-anchor"> </a>
|
||||||
|
<div class="method-section">
|
||||||
|
<div class="method-description">
|
||||||
|
<h4>Update a Staff Image (Data URI)</h4>
|
||||||
|
</div>
|
||||||
|
<div class="method-example">
|
||||||
|
<code class="method-declaration">
|
||||||
|
PUT https://DomainName/api/v1/staff/{staffId}/images
|
||||||
|
</code>
|
||||||
|
<code class="method-request">
|
||||||
|
PUT staff/1/images
|
||||||
|
Content-Type: text/plain
|
||||||
|
Request Body:
|
||||||
|
data:image/png;base64,iVBORw0KGgoAA
|
||||||
|
AANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0l
|
||||||
|
EQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6
|
||||||
|
P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC
|
||||||
|
</code>
|
||||||
|
<code class="method-response">
|
||||||
|
{
|
||||||
|
"resourceId": 1,
|
||||||
|
"changes": {},
|
||||||
|
"resourceIdentifier": "1"
|
||||||
|
}
|
||||||
|
</code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a id="staff_images_update_form" name="staff_images_update_form" class="old-syle-anchor"> </a>
|
||||||
|
<div class="method-section">
|
||||||
|
<div class="method-description">
|
||||||
|
<h4>Update a Staff Member Image (Multi-part Form data)</h4>
|
||||||
|
<table class=matrixHeading>
|
||||||
|
<tr class="matrixHeadingBG">
|
||||||
|
<td><div class="mifosXHeading2">Mandatory Fields</div></td>
|
||||||
|
</tr>
|
||||||
|
<tr class=alt>
|
||||||
|
<td>file
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<p>
|
||||||
|
The form should contain a required named body part with the
|
||||||
|
name "file". <br/> <br/>
|
||||||
|
If you are using a HTML form, a snippet like
|
||||||
|
<small> <input type="file" name="file"></input> </small>
|
||||||
|
can be used for uploading the image file
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="method-example">
|
||||||
|
<code class="method-declaration">
|
||||||
|
PUT https://DomainName/api/v1/staff/{staffId}/images
|
||||||
|
</code>
|
||||||
|
<code class="method-request">
|
||||||
|
PUT staff/1/images
|
||||||
|
Content-Type: multipart/form-data
|
||||||
|
Request Body: <i>Not shown</i>
|
||||||
|
</code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a id="staff_images_delete" name="staff_images_delete" class="old-syle-anchor"> </a>
|
||||||
|
<div class="method-section">
|
||||||
|
<div class="method-description">
|
||||||
|
<h4>Delete a Staff Image</h4>
|
||||||
|
</div>
|
||||||
|
<div class="method-example">
|
||||||
|
<code class="method-declaration">
|
||||||
|
DELETE https://DomainName/api/v1/staff/{staffId}/images
|
||||||
|
</code>
|
||||||
|
<code class="method-request">
|
||||||
|
DELETE staff/1/images
|
||||||
|
Content-Type: application/json
|
||||||
|
No Request Body:
|
||||||
|
</code>
|
||||||
|
<code class="method-response">
|
||||||
|
{
|
||||||
|
"resourceId": 1,
|
||||||
|
"changes": {},
|
||||||
|
"resourceIdentifier": "1"
|
||||||
|
}
|
||||||
|
</code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--Charges section starts here-->
|
<!--Charges section starts here-->
|
||||||
<a id="charges" name="charges" class="old-syle-anchor"> </a>
|
<a id="charges" name="charges" class="old-syle-anchor"> </a>
|
||||||
<div class="method-section">
|
<div class="method-section">
|
||||||
@@ -36251,6 +36497,26 @@ No Request Body:
|
|||||||
<td><a href="#staff_update">Update a Staff Member</a></td>
|
<td><a href="#staff_update">Update a Staff Member</a></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><a href="#staff_images">Staff Images</a></td>
|
||||||
|
<td>staff/{staffId}/images</td>
|
||||||
|
<td><a href="#staff_images_create">Upload an Image for a Staff Member (as DATA URI)</a></td>
|
||||||
|
<td><a href="#staff_images_retrieve">Get Staff Image (DATA URI)</a></td>
|
||||||
|
<td><a href="#staff_images_update">Update Staff Image (DATA URI)</a></td>
|
||||||
|
<td><a href="#staff_images_delete">Delete Staff Image</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td><a href="#staff_images_create_form">
|
||||||
|
Upload an Image for a Staff Member (Multi-part form data)</a>
|
||||||
|
</td>
|
||||||
|
<td><a href="#staff_images_retrieve_binary">Get Staff Image (Binary file)</a></td>
|
||||||
|
<td><a href="#staff_images_update_form">
|
||||||
|
Update Staff Image (Multi-part form data)</a>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="#charges">Charges</a></td>
|
<td><a href="#charges">Charges</a></td>
|
||||||
<td>charges</td>
|
<td>charges</td>
|
||||||
|
|||||||
+90
@@ -0,0 +1,90 @@
|
|||||||
|
package org.mifosplatform.integrationtests;
|
||||||
|
|
||||||
|
import com.sun.jersey.core.util.Base64;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mifosplatform.integrationtests.common.ImageHelper;
|
||||||
|
import org.mifosplatform.integrationtests.common.Utils;
|
||||||
|
import org.mifosplatform.integrationtests.common.accounting.AccountHelper;
|
||||||
|
import org.mifosplatform.integrationtests.common.loans.LoanTransactionHelper;
|
||||||
|
import org.mifosplatform.integrationtests.common.organisation.StaffHelper;
|
||||||
|
|
||||||
|
import com.jayway.restassured.builder.RequestSpecBuilder;
|
||||||
|
import com.jayway.restassured.builder.ResponseSpecBuilder;
|
||||||
|
import com.jayway.restassured.http.ContentType;
|
||||||
|
import com.jayway.restassured.specification.RequestSpecification;
|
||||||
|
import com.jayway.restassured.specification.ResponseSpecification;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class StaffImageApiTest {
|
||||||
|
|
||||||
|
private RequestSpecification requestSpec;
|
||||||
|
private ResponseSpecification responseSpec;
|
||||||
|
private LoanTransactionHelper loanTransactionHelper;
|
||||||
|
private AccountHelper accountHelper;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
Utils.initializeRESTAssured();
|
||||||
|
this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
||||||
|
this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
|
||||||
|
this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
|
||||||
|
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
|
||||||
|
this.accountHelper = new AccountHelper(this.requestSpec, this.responseSpec);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createStaffImage() {
|
||||||
|
|
||||||
|
Integer staffId = StaffHelper.createStaff(this.requestSpec, this.responseSpec);
|
||||||
|
Integer imageId = ImageHelper.createImageForStaff(this.requestSpec, this.responseSpec, staffId);
|
||||||
|
Assert.assertNotNull("Image id should not be null", imageId);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getStaffImage(){
|
||||||
|
Integer staffId = StaffHelper.createStaff(this.requestSpec, this.responseSpec);
|
||||||
|
Integer imageId = ImageHelper.createImageForStaff(this.requestSpec, this.responseSpec, staffId);
|
||||||
|
Assert.assertNotNull("Image id should not be null", imageId);
|
||||||
|
String imageAsText = ImageHelper.getStaffImageAsText(this.requestSpec, this.responseSpec, staffId);
|
||||||
|
Assert.assertNotNull("Image id should not be null", imageAsText);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getStaffImageAsBinary(){
|
||||||
|
Integer staffId = StaffHelper.createStaff(this.requestSpec, this.responseSpec);
|
||||||
|
Integer imageId = ImageHelper.createImageForStaff(this.requestSpec, this.responseSpec, staffId);
|
||||||
|
Assert.assertNotNull("Image id should not be null", imageId);
|
||||||
|
byte[] imageAsBytes = ImageHelper.getStaffImageAsBinary(this.requestSpec, this.responseSpec, staffId);
|
||||||
|
Assert.assertNotNull("Image content should not be null", imageAsBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateImage() {
|
||||||
|
|
||||||
|
Integer staffId = StaffHelper.createStaff(this.requestSpec, this.responseSpec);
|
||||||
|
Integer imageId = ImageHelper.createImageForStaff(this.requestSpec, this.responseSpec, staffId);
|
||||||
|
Assert.assertNotNull("Image id should not be null", imageId);
|
||||||
|
imageId = ImageHelper.updateImageForStaff(this.requestSpec, this.responseSpec, staffId);
|
||||||
|
Assert.assertNotNull("Image id should not be null", imageId);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deleteStaffImage() {
|
||||||
|
|
||||||
|
Integer staffId = StaffHelper.createStaff(this.requestSpec, this.responseSpec);
|
||||||
|
Integer imageId = ImageHelper.createImageForStaff(this.requestSpec, this.responseSpec, staffId);
|
||||||
|
Assert.assertNotNull("Image id should not be null", imageId);
|
||||||
|
imageId = ImageHelper.deleteStaffImage(this.requestSpec, this.responseSpec, staffId);
|
||||||
|
Assert.assertNotNull("Image id should not be null", imageId);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+66
@@ -0,0 +1,66 @@
|
|||||||
|
package org.mifosplatform.integrationtests.common;
|
||||||
|
|
||||||
|
import com.jayway.restassured.http.ContentType;
|
||||||
|
import com.jayway.restassured.specification.RequestSpecification;
|
||||||
|
import com.jayway.restassured.specification.ResponseSpecification;
|
||||||
|
import com.sun.jersey.core.util.Base64;
|
||||||
|
import org.apache.http.HttpHeaders;
|
||||||
|
import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ImageHelper {
|
||||||
|
|
||||||
|
private static final String STAFF_IMAGE_URL = "/mifosng-provider/api/v1/staff/";
|
||||||
|
private static final String IMAGES_URI = "/images";
|
||||||
|
|
||||||
|
public static Integer createImageForStaff(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||||
|
Integer staffId) {
|
||||||
|
System.out.println("---------------------------------CREATING AN IMAGE FOR STAFF---------------------------------------------");
|
||||||
|
String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI+ "?" + Utils.TENANT_IDENTIFIER;
|
||||||
|
return Utils.performServerPost(requestSpec, responseSpec, URL, generateImageAsText(), "resourceId");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Integer updateImageForStaff(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||||
|
Integer staffId) {
|
||||||
|
System.out.println("---------------------------------UPDATING AN IMAGE FOR STAFF---------------------------------------------");
|
||||||
|
String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI+ "?" + Utils.TENANT_IDENTIFIER;
|
||||||
|
requestSpec.header(HttpHeaders.CONTENT_TYPE,"mutlipart/form-data");
|
||||||
|
return Utils.performServerPut(requestSpec, responseSpec, URL, generateImageAsText(), "resourceId");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getStaffImageAsText(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||||
|
Integer staffId){
|
||||||
|
System.out.println("---------------------------------RETRIEVING STAFF IMAGE---------------------------------------------");
|
||||||
|
String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI+ "?" + Utils.TENANT_IDENTIFIER;
|
||||||
|
requestSpec.header(HttpHeaders.ACCEPT,"text/plain");
|
||||||
|
return Utils.performGetTextResponse(requestSpec, responseSpec, URL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] getStaffImageAsBinary(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||||
|
Integer staffId){
|
||||||
|
System.out.println("---------------------------------RETRIEVING STAFF IMAGE---------------------------------------------");
|
||||||
|
String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI+ "?" + Utils.TENANT_IDENTIFIER;
|
||||||
|
requestSpec.header(HttpHeaders.ACCEPT,"application/octet-stream");
|
||||||
|
return Utils.performGetBinaryResponse(requestSpec, responseSpec, URL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Integer deleteStaffImage(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||||
|
Integer staffId){
|
||||||
|
System.out.println("---------------------------------RETRIEVING STAFF IMAGE---------------------------------------------");
|
||||||
|
String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI+ "?" + Utils.TENANT_IDENTIFIER;
|
||||||
|
return Utils.performServerDelete(requestSpec, responseSpec, URL, "resourceId");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String generateImageAsText() {
|
||||||
|
return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ\n"
|
||||||
|
+ "bWFnZVJlYWR5ccllPAAAAJ1JREFUeNpi+P//PwMIA4E9EG8E4idQDGLbw+WhiiqA+D8OXAFVAzbp\n"
|
||||||
|
+ "DxBvB2JLIGaGYkuoGEjOhhFIHAbij0BdPgxYACMj42ogJQpifwBiXSDeC8JIbt4LxSC5DyxQjTeB\n"
|
||||||
|
+ "+BeaYb+Q5EBOAVutCzMJHUNNPADzzDokiYdAfAmJvwLkGeTgWQfyKZICS6hYBTwc0QL8ORSjBDhA\n" + "gAEAOg13B6R/SAgAAAAASUVORK5CYII=";
|
||||||
|
}
|
||||||
|
private static byte[] generateImageAsBinary(){
|
||||||
|
return Base64.decode(generateImageAsText().split("base64,")[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
+14
@@ -11,6 +11,10 @@ import static org.hamcrest.Matchers.is;
|
|||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
@@ -72,6 +76,16 @@ public class Utils {
|
|||||||
return (T) from(json).get(jsonAttributeToGetBack);
|
return (T) from(json).get(jsonAttributeToGetBack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String performGetTextResponse(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||||
|
final String getURL){
|
||||||
|
return given().spec(requestSpec).expect().spec(responseSpec).log().ifError().when().get(getURL).andReturn().asString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] performGetBinaryResponse(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||||
|
final String getURL){
|
||||||
|
return given().spec(requestSpec).expect().spec(responseSpec).log().ifError().when().get(getURL).andReturn().asByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
public static <T> T performServerPost(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
public static <T> T performServerPost(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||||
final String postURL, final String jsonBodyToSend, final String jsonAttributeToGetBack) {
|
final String postURL, final String jsonBodyToSend, final String jsonAttributeToGetBack) {
|
||||||
final String json = given().spec(requestSpec).body(jsonBodyToSend).expect().spec(responseSpec).log().ifError().when().post(postURL)
|
final String json = given().spec(requestSpec).body(jsonBodyToSend).expect().spec(responseSpec).log().ifError().when().post(postURL)
|
||||||
|
|||||||
+28
-33
@@ -7,16 +7,7 @@ package org.mifosplatform.infrastructure.documentmanagement.api;
|
|||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.*;
|
||||||
import javax.ws.rs.DELETE;
|
|
||||||
import javax.ws.rs.GET;
|
|
||||||
import javax.ws.rs.HeaderParam;
|
|
||||||
import javax.ws.rs.POST;
|
|
||||||
import javax.ws.rs.PUT;
|
|
||||||
import javax.ws.rs.Path;
|
|
||||||
import javax.ws.rs.PathParam;
|
|
||||||
import javax.ws.rs.Produces;
|
|
||||||
import javax.ws.rs.QueryParam;
|
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.Response.ResponseBuilder;
|
import javax.ws.rs.core.Response.ResponseBuilder;
|
||||||
@@ -70,9 +61,9 @@ public class ImagesApiResource {
|
|||||||
@POST
|
@POST
|
||||||
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
public String addNewClientImage(@PathParam("clientId") final Long clientId, @HeaderParam("Content-Length") final Long fileSize,
|
public String addNewClientImage(@PathParam("clients") final String clientName, @PathParam("clientId") final Long clientId,
|
||||||
@FormDataParam("file") final InputStream inputStream, @FormDataParam("file") final FormDataContentDisposition fileDetails,
|
@HeaderParam("Content-Length") final Long fileSize, @FormDataParam("file") final InputStream inputStream,
|
||||||
@FormDataParam("file") final FormDataBodyPart bodyPart) {
|
@FormDataParam("file") final FormDataContentDisposition fileDetails, @FormDataParam("file") final FormDataBodyPart bodyPart) {
|
||||||
|
|
||||||
// TODO: vishwas might need more advances validation (like reading magic
|
// TODO: vishwas might need more advances validation (like reading magic
|
||||||
// number) for handling malicious clients
|
// number) for handling malicious clients
|
||||||
@@ -80,8 +71,8 @@ public class ImagesApiResource {
|
|||||||
ContentRepositoryUtils.validateClientImageNotEmpty(fileDetails.getFileName());
|
ContentRepositoryUtils.validateClientImageNotEmpty(fileDetails.getFileName());
|
||||||
ContentRepositoryUtils.validateImageMimeType(bodyPart.getMediaType().toString());
|
ContentRepositoryUtils.validateImageMimeType(bodyPart.getMediaType().toString());
|
||||||
|
|
||||||
final CommandProcessingResult result = this.imageWritePlatformService.saveOrUpdateClientImage(clientId, fileDetails.getFileName(),
|
final CommandProcessingResult result = this.imageWritePlatformService.saveOrUpdateImage(clientName, clientId,
|
||||||
inputStream, fileSize);
|
fileDetails.getFileName(), inputStream, fileSize);
|
||||||
|
|
||||||
return this.toApiJsonSerializer.serialize(result);
|
return this.toApiJsonSerializer.serialize(result);
|
||||||
}
|
}
|
||||||
@@ -92,11 +83,12 @@ public class ImagesApiResource {
|
|||||||
@POST
|
@POST
|
||||||
@Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
public String addNewClientImage(@PathParam("clientId") final Long clientId, final String jsonRequestBody) {
|
public String addNewClientImage(@PathParam("clients") final String clientName, @PathParam("clientId") final Long clientId,
|
||||||
|
final String jsonRequestBody) {
|
||||||
|
|
||||||
final Base64EncodedImage base64EncodedImage = ContentRepositoryUtils.extractImageFromDataURL(jsonRequestBody);
|
final Base64EncodedImage base64EncodedImage = ContentRepositoryUtils.extractImageFromDataURL(jsonRequestBody);
|
||||||
|
|
||||||
final CommandProcessingResult result = this.imageWritePlatformService.saveOrUpdateClientImage(clientId, base64EncodedImage);
|
final CommandProcessingResult result = this.imageWritePlatformService.saveOrUpdateImage(clientName, clientId, base64EncodedImage);
|
||||||
|
|
||||||
return this.toApiJsonSerializer.serialize(result);
|
return this.toApiJsonSerializer.serialize(result);
|
||||||
}
|
}
|
||||||
@@ -107,14 +99,15 @@ public class ImagesApiResource {
|
|||||||
@GET
|
@GET
|
||||||
@Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.TEXT_PLAIN })
|
@Produces({ MediaType.TEXT_PLAIN })
|
||||||
public Response retrieveClientImage(@PathParam("clientId") final Long clientId, @QueryParam("maxWidth") final Integer maxWidth,
|
public Response retrieveImage(@PathParam("clients") final String clientName, @PathParam("clientId") final Long clientId,
|
||||||
@QueryParam("maxHeight") final Integer maxHeight, @QueryParam("output") final String output) {
|
@QueryParam("maxWidth") final Integer maxWidth, @QueryParam("maxHeight") final Integer maxHeight,
|
||||||
if (output != null && (output.equals("octet") || output.equals("inline_octet"))) { return downloadClientImage(clientId, maxWidth,
|
@QueryParam("output") final String output) {
|
||||||
maxHeight, output); }
|
if (output != null && (output.equals("octet") || output.equals("inline_octet"))) { return downloadClientImage(clientName, clientId,
|
||||||
|
maxWidth, maxHeight, output); }
|
||||||
|
|
||||||
this.context.authenticatedUser().validateHasReadPermission("CLIENTIMAGE");
|
this.context.authenticatedUser().validateHasReadPermission("CLIENTIMAGE");
|
||||||
|
|
||||||
final ImageData imageData = this.imageReadPlatformService.retrieveClientImage(clientId);
|
final ImageData imageData = this.imageReadPlatformService.retrieveImage(clientName, clientId);
|
||||||
|
|
||||||
// TODO: Need a better way of determining image type
|
// TODO: Need a better way of determining image type
|
||||||
String imageDataURISuffix = ContentRepositoryUtils.IMAGE_DATA_URI_SUFFIX.JPEG.getValue();
|
String imageDataURISuffix = ContentRepositoryUtils.IMAGE_DATA_URI_SUFFIX.JPEG.getValue();
|
||||||
@@ -131,11 +124,12 @@ public class ImagesApiResource {
|
|||||||
@GET
|
@GET
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_OCTET_STREAM })
|
@Produces({ MediaType.APPLICATION_OCTET_STREAM })
|
||||||
public Response downloadClientImage(@PathParam("clientId") final Long clientId, @QueryParam("maxWidth") final Integer maxWidth,
|
public Response downloadClientImage(@PathParam("clients") final String clientName, @PathParam("clientId") final Long clientId,
|
||||||
@QueryParam("maxHeight") final Integer maxHeight, @QueryParam("output") String output) {
|
@QueryParam("maxWidth") final Integer maxWidth, @QueryParam("maxHeight") final Integer maxHeight,
|
||||||
|
@QueryParam("output") String output) {
|
||||||
|
|
||||||
this.context.authenticatedUser().validateHasReadPermission("CLIENTIMAGE");
|
this.context.authenticatedUser().validateHasReadPermission("CLIENTIMAGE");
|
||||||
final ImageData imageData = this.imageReadPlatformService.retrieveClientImage(clientId);
|
final ImageData imageData = this.imageReadPlatformService.retrieveImage(clientName, clientId);
|
||||||
|
|
||||||
final ResponseBuilder response = Response.ok(imageData.getContentOfSize(maxWidth, maxHeight));
|
final ResponseBuilder response = Response.ok(imageData.getContentOfSize(maxWidth, maxHeight));
|
||||||
String dispositionType = "inline_octet".equals(output) ? "inline" : "attachment";
|
String dispositionType = "inline_octet".equals(output) ? "inline" : "attachment";
|
||||||
@@ -155,10 +149,10 @@ public class ImagesApiResource {
|
|||||||
@PUT
|
@PUT
|
||||||
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
public String updateClientImage(@PathParam("clientId") final Long clientId, @HeaderParam("Content-Length") final Long fileSize,
|
public String updateClientImage(@PathParam("clients") final String clientName, @PathParam("clientId") final Long clientId,
|
||||||
@FormDataParam("file") final InputStream inputStream, @FormDataParam("file") final FormDataContentDisposition fileDetails,
|
@HeaderParam("Content-Length") final Long fileSize, @FormDataParam("file") final InputStream inputStream,
|
||||||
@FormDataParam("file") final FormDataBodyPart bodyPart) {
|
@FormDataParam("file") final FormDataContentDisposition fileDetails, @FormDataParam("file") final FormDataBodyPart bodyPart) {
|
||||||
return addNewClientImage(clientId, fileSize, inputStream, fileDetails, bodyPart);
|
return addNewClientImage(clientName, clientId, fileSize, inputStream, fileDetails, bodyPart);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -170,15 +164,16 @@ public class ImagesApiResource {
|
|||||||
@PUT
|
@PUT
|
||||||
@Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
public String updateClientImage(@PathParam("clientId") final Long clientId, final String jsonRequestBody) {
|
public String updateClientImage(@PathParam("clients") final String clientName, @PathParam("clientId") final Long clientId,
|
||||||
return addNewClientImage(clientId, jsonRequestBody);
|
final String jsonRequestBody) {
|
||||||
|
return addNewClientImage(clientName, clientId, jsonRequestBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
@DELETE
|
@DELETE
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
public String deleteClientImage(@PathParam("clientId") final Long clientId) {
|
public String deleteClientImage(@PathParam("clients") final String clientName, @PathParam("clientId") final Long clientId) {
|
||||||
this.imageWritePlatformService.deleteClientImage(clientId);
|
this.imageWritePlatformService.deleteImage(clientName, clientId);
|
||||||
return this.toApiJsonSerializer.serialize(new CommandProcessingResult(clientId));
|
return this.toApiJsonSerializer.serialize(new CommandProcessingResult(clientId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
package org.mifosplatform.infrastructure.documentmanagement.exception;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runtime exception for invalid image types
|
||||||
|
*/
|
||||||
|
public class InvalidImageTypeException extends AbstractPlatformResourceNotFoundException {
|
||||||
|
|
||||||
|
public InvalidImageTypeException(String imageType) {
|
||||||
|
super("error.documentmanagement.imagetype.invalid", "Image type not supported: " + imageType, imageType);
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -9,6 +9,6 @@ import org.mifosplatform.infrastructure.documentmanagement.data.ImageData;
|
|||||||
|
|
||||||
public interface ImageReadPlatformService {
|
public interface ImageReadPlatformService {
|
||||||
|
|
||||||
ImageData retrieveClientImage(Long clientId);
|
ImageData retrieveImage(String clientName, Long clientId);
|
||||||
|
|
||||||
}
|
}
|
||||||
+30
-9
@@ -13,6 +13,8 @@ import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
|
|||||||
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepository;
|
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepository;
|
||||||
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepositoryFactory;
|
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepositoryFactory;
|
||||||
import org.mifosplatform.infrastructure.documentmanagement.data.ImageData;
|
import org.mifosplatform.infrastructure.documentmanagement.data.ImageData;
|
||||||
|
import org.mifosplatform.organisation.staff.domain.Staff;
|
||||||
|
import org.mifosplatform.organisation.staff.domain.StaffRepositoryWrapper;
|
||||||
import org.mifosplatform.portfolio.client.domain.Client;
|
import org.mifosplatform.portfolio.client.domain.Client;
|
||||||
import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper;
|
import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper;
|
||||||
import org.mifosplatform.portfolio.client.exception.ImageNotFoundException;
|
import org.mifosplatform.portfolio.client.exception.ImageNotFoundException;
|
||||||
@@ -28,10 +30,13 @@ public class ImageReadPlatformServiceImpl implements ImageReadPlatformService {
|
|||||||
private final JdbcTemplate jdbcTemplate;
|
private final JdbcTemplate jdbcTemplate;
|
||||||
private final ContentRepositoryFactory contentRepositoryFactory;
|
private final ContentRepositoryFactory contentRepositoryFactory;
|
||||||
private final ClientRepositoryWrapper clientRepositoryWrapper;
|
private final ClientRepositoryWrapper clientRepositoryWrapper;
|
||||||
|
private final StaffRepositoryWrapper staffRepositoryWrapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ImageReadPlatformServiceImpl(final RoutingDataSource dataSource, final ContentRepositoryFactory documentStoreFactory,
|
public ImageReadPlatformServiceImpl(final RoutingDataSource dataSource, final ContentRepositoryFactory documentStoreFactory,
|
||||||
final ClientRepositoryWrapper clientRepositoryWrapper) {
|
final ClientRepositoryWrapper clientRepositoryWrapper,
|
||||||
|
StaffRepositoryWrapper staffRepositoryWrapper) {
|
||||||
|
this.staffRepositoryWrapper = staffRepositoryWrapper;
|
||||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||||
this.contentRepositoryFactory = documentStoreFactory;
|
this.contentRepositoryFactory = documentStoreFactory;
|
||||||
this.clientRepositoryWrapper = clientRepositoryWrapper;
|
this.clientRepositoryWrapper = clientRepositoryWrapper;
|
||||||
@@ -45,9 +50,14 @@ public class ImageReadPlatformServiceImpl implements ImageReadPlatformService {
|
|||||||
this.entityDisplayName = entityDisplayName;
|
this.entityDisplayName = entityDisplayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String schema() {
|
public String schema(String clientName) {
|
||||||
return " image.id as id, image.location as location, image.storage_type_enum as storageType "
|
StringBuilder builder = new StringBuilder("image.id as id, image.location as location, image.storage_type_enum as storageType ");
|
||||||
+ " from m_image image , m_client client " + " where client.image_id = image.id and client.id=?";
|
if (ImageWritePlatformServiceJpaRepositoryImpl.IMAGE_TYPE.CLIENTS.toString().equals(clientName)) {
|
||||||
|
builder.append(" from m_image image , m_client client " + " where client.image_id = image.id and client.id=?");
|
||||||
|
} else if (ImageWritePlatformServiceJpaRepositoryImpl.IMAGE_TYPE.STAFF.toString().equals(clientName)) {
|
||||||
|
builder.append("from m_image image , m_staff staff " + " where staff.image_id = image.id and staff.id=?");
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -61,13 +71,24 @@ public class ImageReadPlatformServiceImpl implements ImageReadPlatformService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImageData retrieveClientImage(final Long clientId) {
|
public ImageData retrieveImage(String clientName, final Long clientId) {
|
||||||
try {
|
try {
|
||||||
final Client client = this.clientRepositoryWrapper.findOneWithNotFoundDetection(clientId);
|
Object owner;
|
||||||
|
String displayName = null;
|
||||||
|
if (ImageWritePlatformServiceJpaRepositoryImpl.IMAGE_TYPE.CLIENTS
|
||||||
|
.toString().equals(clientName)) {
|
||||||
|
owner = this.clientRepositoryWrapper
|
||||||
|
.findOneWithNotFoundDetection(clientId);
|
||||||
|
displayName = ((Client) owner).getDisplayName();
|
||||||
|
} else if (ImageWritePlatformServiceJpaRepositoryImpl.IMAGE_TYPE.STAFF
|
||||||
|
.toString().equals(clientName)) {
|
||||||
|
owner = this.staffRepositoryWrapper
|
||||||
|
.findOneWithNotFoundDetection(clientId);
|
||||||
|
displayName = ((Staff) owner).displayName();
|
||||||
|
}
|
||||||
|
final ImageMapper imageMapper = new ImageMapper(displayName);
|
||||||
|
|
||||||
final ImageMapper imageMapper = new ImageMapper(client.getDisplayName());
|
final String sql = "select " + imageMapper.schema(clientName);
|
||||||
|
|
||||||
final String sql = "select " + imageMapper.schema();
|
|
||||||
|
|
||||||
final ImageData imageData = this.jdbcTemplate.queryForObject(sql, imageMapper, new Object[] { clientId });
|
final ImageData imageData = this.jdbcTemplate.queryForObject(sql, imageMapper, new Object[] { clientId });
|
||||||
final ContentRepository contentRepository = this.contentRepositoryFactory.getRepository(imageData.storageType());
|
final ContentRepository contentRepository = this.contentRepositoryFactory.getRepository(imageData.storageType());
|
||||||
|
|||||||
+3
-3
@@ -14,11 +14,11 @@ import org.springframework.security.access.prepost.PreAuthorize;
|
|||||||
public interface ImageWritePlatformService {
|
public interface ImageWritePlatformService {
|
||||||
|
|
||||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'CREATE_CLIENTIMAGE')")
|
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'CREATE_CLIENTIMAGE')")
|
||||||
CommandProcessingResult saveOrUpdateClientImage(Long clientId, String imageName, InputStream inputStream, Long fileSize);
|
CommandProcessingResult saveOrUpdateImage(String clientName, Long clientId, String imageName, InputStream inputStream, Long fileSize);
|
||||||
|
|
||||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'CREATE_CLIENTIMAGE')")
|
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'CREATE_CLIENTIMAGE')")
|
||||||
CommandProcessingResult saveOrUpdateClientImage(Long clientId, Base64EncodedImage encodedImage);
|
CommandProcessingResult saveOrUpdateImage(String clientName, Long clientId, Base64EncodedImage encodedImage);
|
||||||
|
|
||||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'DELETE_CLIENTIMAGE')")
|
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'DELETE_CLIENTIMAGE')")
|
||||||
CommandProcessingResult deleteClientImage(Long clientId);
|
CommandProcessingResult deleteImage(String clientName, Long clientId);
|
||||||
}
|
}
|
||||||
+101
-23
@@ -14,6 +14,9 @@ import org.mifosplatform.infrastructure.documentmanagement.contentrepository.Con
|
|||||||
import org.mifosplatform.infrastructure.documentmanagement.domain.Image;
|
import org.mifosplatform.infrastructure.documentmanagement.domain.Image;
|
||||||
import org.mifosplatform.infrastructure.documentmanagement.domain.ImageRepository;
|
import org.mifosplatform.infrastructure.documentmanagement.domain.ImageRepository;
|
||||||
import org.mifosplatform.infrastructure.documentmanagement.domain.StorageType;
|
import org.mifosplatform.infrastructure.documentmanagement.domain.StorageType;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.exception.InvalidImageTypeException;
|
||||||
|
import org.mifosplatform.organisation.staff.domain.Staff;
|
||||||
|
import org.mifosplatform.organisation.staff.domain.StaffRepositoryWrapper;
|
||||||
import org.mifosplatform.portfolio.client.domain.Client;
|
import org.mifosplatform.portfolio.client.domain.Client;
|
||||||
import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper;
|
import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -26,80 +29,155 @@ public class ImageWritePlatformServiceJpaRepositoryImpl implements ImageWritePla
|
|||||||
private final ContentRepositoryFactory contentRepositoryFactory;
|
private final ContentRepositoryFactory contentRepositoryFactory;
|
||||||
private final ClientRepositoryWrapper clientRepositoryWrapper;
|
private final ClientRepositoryWrapper clientRepositoryWrapper;
|
||||||
private final ImageRepository imageRepository;
|
private final ImageRepository imageRepository;
|
||||||
|
private final StaffRepositoryWrapper staffRepositoryWrapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ImageWritePlatformServiceJpaRepositoryImpl(final ContentRepositoryFactory documentStoreFactory,
|
public ImageWritePlatformServiceJpaRepositoryImpl(final ContentRepositoryFactory documentStoreFactory,
|
||||||
final ClientRepositoryWrapper clientRepositoryWrapper, final ImageRepository imageRepository) {
|
final ClientRepositoryWrapper clientRepositoryWrapper, final ImageRepository imageRepository, StaffRepositoryWrapper staffRepositoryWrapper) {
|
||||||
this.contentRepositoryFactory = documentStoreFactory;
|
this.contentRepositoryFactory = documentStoreFactory;
|
||||||
this.clientRepositoryWrapper = clientRepositoryWrapper;
|
this.clientRepositoryWrapper = clientRepositoryWrapper;
|
||||||
this.imageRepository = imageRepository;
|
this.imageRepository = imageRepository;
|
||||||
|
this.staffRepositoryWrapper = staffRepositoryWrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
public CommandProcessingResult saveOrUpdateClientImage(final Long clientId, final String imageName, final InputStream inputStream,
|
public CommandProcessingResult saveOrUpdateImage(String clientName, final Long clientId, final String imageName, final InputStream inputStream,
|
||||||
final Long fileSize) {
|
final Long fileSize) {
|
||||||
final Client client = this.clientRepositoryWrapper.findOneWithNotFoundDetection(clientId);
|
Object owner = null;
|
||||||
deletePreviousClientImage(client);
|
if (IMAGE_TYPE.CLIENTS.toString().equals(clientName)){
|
||||||
|
owner =this.clientRepositoryWrapper.findOneWithNotFoundDetection(clientId);
|
||||||
|
} else if (IMAGE_TYPE.STAFF.toString().equals(clientName)) {
|
||||||
|
owner = this.staffRepositoryWrapper.findOneWithNotFoundDetection(clientId);
|
||||||
|
}
|
||||||
|
deletePreviousImage(owner);
|
||||||
|
|
||||||
final ContentRepository contentRepository = this.contentRepositoryFactory.getRepository();
|
final ContentRepository contentRepository = this.contentRepositoryFactory.getRepository();
|
||||||
final String imageLocation = contentRepository.saveImage(inputStream, clientId, imageName, fileSize);
|
final String imageLocation = contentRepository.saveImage(inputStream, clientId, imageName, fileSize);
|
||||||
return updateClientImage(client, imageLocation, contentRepository.getStorageType());
|
return updateImage(owner, imageLocation, contentRepository.getStorageType());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
public CommandProcessingResult saveOrUpdateClientImage(final Long clientId, final Base64EncodedImage encodedImage) {
|
public CommandProcessingResult saveOrUpdateImage(String clientName, final Long clientId, final Base64EncodedImage encodedImage) {
|
||||||
final Client client = this.clientRepositoryWrapper.findOneWithNotFoundDetection(clientId);
|
Object owner = null;
|
||||||
deletePreviousClientImage(client);
|
if (IMAGE_TYPE.CLIENTS.toString().equals(clientName)){
|
||||||
|
owner =this.clientRepositoryWrapper.findOneWithNotFoundDetection(clientId);
|
||||||
|
} else if (IMAGE_TYPE.STAFF.toString().equals(clientName)) {
|
||||||
|
owner = this.staffRepositoryWrapper.findOneWithNotFoundDetection(clientId);
|
||||||
|
}
|
||||||
|
deletePreviousImage(owner);
|
||||||
|
validateImageType(clientName);
|
||||||
|
|
||||||
final ContentRepository contenRepository = this.contentRepositoryFactory.getRepository();
|
final ContentRepository contenRepository = this.contentRepositoryFactory.getRepository();
|
||||||
final String imageLocation = contenRepository.saveImage(encodedImage, clientId, "image");
|
final String imageLocation = contenRepository.saveImage(encodedImage, clientId, "image");
|
||||||
|
|
||||||
return updateClientImage(client, imageLocation, contenRepository.getStorageType());
|
return updateImage(owner, imageLocation, contenRepository.getStorageType());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
public CommandProcessingResult deleteClientImage(final Long clientId) {
|
public CommandProcessingResult deleteImage(String clientName, final Long clientId) {
|
||||||
|
|
||||||
final Client client = this.clientRepositoryWrapper.findOneWithNotFoundDetection(clientId);
|
Object owner = null;
|
||||||
|
Image image = null;
|
||||||
|
if (IMAGE_TYPE.CLIENTS.toString().equals(clientName)){
|
||||||
|
owner =this.clientRepositoryWrapper.findOneWithNotFoundDetection(clientId);
|
||||||
|
Client client = (Client) owner;
|
||||||
|
image = client.getImage();
|
||||||
|
client.setImage(null);
|
||||||
|
this.clientRepositoryWrapper.save(client);
|
||||||
|
|
||||||
final Image image = client.getImage();
|
} else if (IMAGE_TYPE.STAFF.toString().equals(clientName)) {
|
||||||
|
owner = this.staffRepositoryWrapper.findOneWithNotFoundDetection(clientId);
|
||||||
|
Staff staff = (Staff) owner;
|
||||||
|
image = staff.getImage();
|
||||||
|
staff.setImage(null);
|
||||||
|
this.staffRepositoryWrapper.save(staff);
|
||||||
|
|
||||||
|
}
|
||||||
// delete image from the file system
|
// delete image from the file system
|
||||||
if (image != null) {
|
if (image != null) {
|
||||||
final ContentRepository contentRepository = this.contentRepositoryFactory.getRepository(StorageType.fromInt(image
|
final ContentRepository contentRepository = this.contentRepositoryFactory.getRepository(StorageType.fromInt(image
|
||||||
.getStorageType()));
|
.getStorageType()));
|
||||||
contentRepository.deleteImage(clientId, image.getLocation());
|
contentRepository.deleteImage(clientId, image.getLocation());
|
||||||
client.setImage(null);
|
|
||||||
this.imageRepository.delete(image);
|
this.imageRepository.delete(image);
|
||||||
this.clientRepositoryWrapper.save(client);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new CommandProcessingResult(clientId);
|
return new CommandProcessingResult(clientId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deletePreviousClientImage(final Client client) {
|
private void deletePreviousImage(final Object owner) {
|
||||||
final Image image = client.getImage();
|
Image image = null;
|
||||||
|
Long clientId=null;
|
||||||
|
if (owner instanceof Client){
|
||||||
|
Client client = (Client) owner;
|
||||||
|
image = client.getImage();
|
||||||
|
clientId = client.getId();
|
||||||
|
} else if (owner instanceof Staff){
|
||||||
|
Staff staff = (Staff) owner;
|
||||||
|
image = staff.getImage();
|
||||||
|
clientId = staff.getId();
|
||||||
|
}
|
||||||
if (image != null) {
|
if (image != null) {
|
||||||
final ContentRepository contentRepository = this.contentRepositoryFactory.getRepository(StorageType.fromInt(image
|
final ContentRepository contentRepository = this.contentRepositoryFactory.getRepository(StorageType.fromInt(image
|
||||||
.getStorageType()));
|
.getStorageType()));
|
||||||
contentRepository.deleteImage(client.getId(), image.getLocation());
|
contentRepository.deleteImage(clientId, image.getLocation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private CommandProcessingResult updateClientImage(final Client client, final String imageLocation, final StorageType storageType) {
|
private CommandProcessingResult updateImage(final Object owner, final String imageLocation, final StorageType storageType) {
|
||||||
Image image = client.getImage();
|
Image image = null;
|
||||||
|
Long clientId=null;
|
||||||
|
if (owner instanceof Client){
|
||||||
|
Client client = (Client) owner;
|
||||||
|
image = client.getImage();
|
||||||
|
clientId = client.getId();
|
||||||
|
image = createImage(image, imageLocation, storageType);
|
||||||
|
client.setImage(image);
|
||||||
|
this.clientRepositoryWrapper.save(client);
|
||||||
|
} else if (owner instanceof Staff){
|
||||||
|
Staff staff = (Staff) owner;
|
||||||
|
image = staff.getImage();
|
||||||
|
clientId = staff.getId();
|
||||||
|
image = createImage(image, imageLocation, storageType);
|
||||||
|
staff.setImage(image);
|
||||||
|
this.staffRepositoryWrapper.save(staff);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.imageRepository.save(image);
|
||||||
|
return new CommandProcessingResult(clientId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Image createImage(Image image, final String imageLocation, final StorageType storageType) {
|
||||||
if (image == null) {
|
if (image == null) {
|
||||||
image = new Image(imageLocation, storageType);
|
image = new Image(imageLocation, storageType);
|
||||||
} else {
|
} else {
|
||||||
image.setLocation(imageLocation);
|
image.setLocation(imageLocation);
|
||||||
image.setStorageType(storageType.getValue());
|
image.setStorageType(storageType.getValue());
|
||||||
}
|
}
|
||||||
this.imageRepository.save(image);
|
return image;
|
||||||
client.setImage(image);
|
|
||||||
this.clientRepositoryWrapper.save(client);
|
|
||||||
return new CommandProcessingResult(client.getId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateImageType(final String clientName) {
|
||||||
|
if (!checkValidEntityType(clientName)) { throw new InvalidImageTypeException(
|
||||||
|
clientName); }
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean checkValidEntityType(final String entityType) {
|
||||||
|
for (final IMAGE_TYPE entities : IMAGE_TYPE.values()) {
|
||||||
|
if (entities.name().equalsIgnoreCase(entityType)) { return true; }
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** Entities for document Management **/
|
||||||
|
public static enum IMAGE_TYPE {
|
||||||
|
STAFF,CLIENTS;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name().toString().toLowerCase();
|
||||||
|
}}
|
||||||
|
|
||||||
}
|
}
|
||||||
+20
-8
@@ -9,19 +9,13 @@ import java.util.Date;
|
|||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.*;
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.JoinColumn;
|
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import javax.persistence.Table;
|
|
||||||
import javax.persistence.Temporal;
|
|
||||||
import javax.persistence.TemporalType;
|
|
||||||
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.mifosplatform.infrastructure.core.api.JsonCommand;
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.domain.Image;
|
||||||
import org.mifosplatform.organisation.office.domain.Office;
|
import org.mifosplatform.organisation.office.domain.Office;
|
||||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||||
|
|
||||||
@@ -67,6 +61,10 @@ public class Staff extends AbstractPersistable<Long> {
|
|||||||
@JoinColumn(name = "organisational_role_parent_staff_id", nullable = true)
|
@JoinColumn(name = "organisational_role_parent_staff_id", nullable = true)
|
||||||
private Staff organisationalRoleParentStaff;
|
private Staff organisationalRoleParentStaff;
|
||||||
|
|
||||||
|
@OneToOne(optional = true)
|
||||||
|
@JoinColumn(name = "image_id", nullable = true)
|
||||||
|
private Image image;
|
||||||
|
|
||||||
public static Staff fromJson(final Office staffOffice, final JsonCommand command) {
|
public static Staff fromJson(final Office staffOffice, final JsonCommand command) {
|
||||||
|
|
||||||
final String firstnameParamName = "firstname";
|
final String firstnameParamName = "firstname";
|
||||||
@@ -196,6 +194,12 @@ public class Staff extends AbstractPersistable<Long> {
|
|||||||
this.joiningDate = newValue.toDate();
|
this.joiningDate = newValue.toDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final String imageIdParamName = "imageId";
|
||||||
|
if (command.isChangeInLongParameterNamed(imageIdParamName, this.image.getId())) {
|
||||||
|
final Long newValue = command.longValueOfParameterNamed(officeIdParamName);
|
||||||
|
actualChanges.put(officeIdParamName, newValue);
|
||||||
|
}
|
||||||
|
|
||||||
return actualChanges;
|
return actualChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,4 +246,12 @@ public class Staff extends AbstractPersistable<Long> {
|
|||||||
public Office office() {
|
public Office office() {
|
||||||
return this.office;
|
return this.office;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setImage(Image image) {
|
||||||
|
this.image = image;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Image getImage() {
|
||||||
|
return this.image;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+3
@@ -44,4 +44,7 @@ public class StaffRepositoryWrapper {
|
|||||||
if (!hierarchy.startsWith(staffhierarchy)) { throw new StaffNotFoundException(staffId); }
|
if (!hierarchy.startsWith(staffhierarchy)) { throw new StaffNotFoundException(staffId); }
|
||||||
return staff;
|
return staff;
|
||||||
}
|
}
|
||||||
|
public void save(final Staff staff){
|
||||||
|
this.repository.save(staff);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE `m_staff` ADD COLUMN `image_id` BIGINT(20) NULL;
|
||||||
Reference in New Issue
Block a user