diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm index dfc30a8c6..2e591724f 100644 --- a/api-docs/apiLive.htm +++ b/api-docs/apiLive.htm @@ -187,6 +187,22 @@ + + Client Identifiers + clients/{clientId}/identifiers + Create an Identifier for a Client + List all Identifiers for a Client + + + + + + clients/{clientId}/identifiers/{identifierId} + + Retrieve a Client Identifier + Update a Client Identifier + Delete a Client Identifier + @@ -434,6 +450,24 @@ + + Loan Guarantors + loans/{loanId}/guarantors + Create a Guarantor + + List Guarantors + + + + + + + loans/{loanId}/guarantors/{guarantorId} + + Retrieve a Guarantor + Update a Guarantor + Delete a Guarantor + @@ -2014,6 +2048,256 @@ GET https://DomainName/api/v1/clients/{clientId}/loans + +   +
+
+

Client Identifiers

+

Client Identifiers refer to documents that are + used to uniquely identify a customer
+ Ex: Drivers License, Passport, Ration card etc +

+ + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
documentKey
Number/String used to uniquely identify a particular + document (Driving License number for a driving license etc)
documentType
Type of the identification document + (License, Passport Etc)
description
Any user comments to be associated + with the Client Identifier
+
+
+ +   +
+
+

List all Identifiers for a Client

+

Example Requests:

+
clients/1/identifiers
+
+
+
clients/1/identifiers?fields=documentKey,documentType,description
+
+
+ +GET https://DomainName/api/v1/clients/{clientId}/identifiers + + +[ + { + "id": 2, + "clientId": 1, + "documentType": { + "id": 3, + "name": "Drivers License" + }, + "documentKey": "12345", + "description": "Issued in the year 2--7" + } +] + +
+
+ +   +
+
+

Retrieve Client Identifier Details Template

+

This is a convenience resource. It can be useful when + building maintenance user interface screens for client + applications. The template data returned consists of any or all + of: +

+

+

Example Request:

+
clients/1/identifiers/template
+
+
+ +GET https://DomainName/api/v1/clients/{clientId}/identifiers/template + + +{ + "allowedDocumentTypes": [ + { + "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 + } + ] +} + +
+
+ + +   +
+
+

Retrieve a Client Identifier

+

Example Requests:

+
clients/1/identifier/2
+
+
+
clients/1/identifier/2?template=true
+
+
+
clients/1/identifiers/2?fields=documentKey,documentType,description
+
+
+ +GET https://DomainName/api/v1/clients/{clientId}/identifiers/{identifierId} + + +{ + "id": 2, + "clientId": 1, + "documentType": { + "id": 3, + "name": "Drivers License" + }, + "documentKey": "12345", + "description": "Issued in 2007" +} + +
+
+ +   +
+
+

Create an Identifier for a Client

+ + + + + + + +
Mandatory Fields
documentKey, documentTypeId +
+
+
+ +POST https://DomainName/api/v1/clients/{clientId}/identifiers + + +POST clients/1/identifiers +Content-Type: application/json +Request Body: +{ +"documentTypeId":"1", +"documentKey":"KA-54677", +"description":"Document has been verified" +} + + +{ + "officeId": 1, + "clientId": 1, + "resourceId": 3 +} + +
+
+ +   +
+
+

Update a Client Identifier

+
+
+ +PUT https://DomainName/api/v1/clients/{clientId}/identifiers/{identifierId} + + +PUT clients/1/identifiers/3 +Content-Type: application/json +Request Body: +{ +"documentTypeId":"4", +"documentKey":"KA-94667", +"description":"Document has been updated" +} + + +{ + "officeId": 1, + "clientId": 1, + "resourceId": 3, + "changes": { + "documentTypeId": 4, + "documentKey": "KA-94667", + "description": "Document has been updated" + } +} + +
+
+ +   +
+
+

Delete a Client Identifier

+
+
+ +DELETE https://DomainName/api/v1/clients/{clientId}/identifiers/{identifierId} + + +DELETE clients/1/identifiers/3 +Content-Type: application/json +No Request Body: + + +{ + "officeId": 1, + "clientId": 1, + "resourceId": 3 +} + +
+
+ +  
@@ -11319,8 +11603,24 @@ Content-Type: application/json - + + Client Identifiers + clients/{clientId}/identifiers + Create an Identifier for a Client + List all Identifiers for a Client + + + + + clients/{clientId}/identifiers/{identifierId} + + Retrieve a Client Identifier + Update a Client Identifier + Delete a Client Identifier + + + Loans loans?calculateLoanSchedule Calculate Loan Repayment Schedule @@ -11328,7 +11628,7 @@ Content-Type: application/json - + loans Submit a new Loan Application @@ -11336,7 +11636,7 @@ Content-Type: application/json - + loans/{loanId} @@ -11344,7 +11644,7 @@ Content-Type: application/json Delete a Loan Application - + loans/{loanId}?command=approve Approve Loan Application @@ -11352,7 +11652,7 @@ Content-Type: application/json - + loans/{loanId}?command=undoApproval Undo Loan Application Approval @@ -11360,7 +11660,7 @@ Content-Type: application/json - + loans/{loanId}?command=reject Reject Loan Application @@ -11368,7 +11668,7 @@ Content-Type: application/json - + loans/{loanId}?command=withdraw Withdraw Loan Application @@ -11376,7 +11676,7 @@ Content-Type: application/json - + loans/{loanId}?command=disburse Disburse Loan @@ -11384,7 +11684,7 @@ Content-Type: application/json - + loans/{loanId}?command=undoDisbursal Undo Loan Application Disbursal @@ -11392,7 +11692,7 @@ Content-Type: application/json - + Loan Transactions loans/{loanId}/transactions?command=repayment Enter a repayment @@ -11400,7 +11700,7 @@ Content-Type: application/json - + loans/{loanId}/transactions?command=waiveInterest Waive Interest @@ -11408,7 +11708,7 @@ Content-Type: application/json - + loans/{loanId}/transactions/{transactionId} @@ -11416,7 +11716,7 @@ Content-Type: application/json - + loans/{loanId}/transactions/{transactionId} Adjust a Transaction @@ -11424,7 +11724,7 @@ Content-Type: application/json - + Loan Charges loans/{loanId}/charges Add a loan charge @@ -11432,7 +11732,7 @@ Content-Type: application/json - + loans/{loanId}/charges/{loanChargeId} @@ -11440,7 +11740,7 @@ Content-Type: application/json Modify a Loan Charge Delete a Loan Charge - + Loan Guarantors loans/{loanId}/guarantors Create a Guarantor @@ -11450,7 +11750,7 @@ Content-Type: application/json - + loans/{loanId}/guarantors/{guarantorId} @@ -11458,7 +11758,6 @@ Content-Type: application/json Update a Guarantor Delete a Guarantor - OFFICE offices @@ -11623,6 +11922,62 @@ Content-Type: application/json Table (One to Many) + General Ledger Account + glaccounts + Create a New Ledger Account + List Ledger Accounts + + + + + + glaccounts/{glaccountId} + + Retrieve a Ledger Account + Update a Ledger Account + Delete a Ledger Account + + + Accounting Closure + glclosures + Create an Accounting Closure + List Accounting Closures + + + + + + glclosures/{glclosureId} + + Retrieve an Accounting Closure + Update an Accounting Closure + Delete an Accounting Closure + + + Journal Entries + journalentries + Create Journal Entries + List Journal Entries + + + + + + journalentries/{entryId} + + Retrieve a single Entry + + + + + + journalentries/{transactionId}/reversal + Reverse Journal Entries + + + + + REPORT reports @@ -11630,7 +11985,7 @@ Content-Type: application/json - + reports/{reportName} @@ -11638,7 +11993,7 @@ Content-Type: application/json - + AUTHENTICATION authentication Verify Authentication @@ -11646,7 +12001,7 @@ Content-Type: application/json - + USER users Create a User @@ -11654,7 +12009,7 @@ Content-Type: application/json - + users/{userId} @@ -11662,7 +12017,7 @@ Content-Type: application/json Update a User Delete a User - + ROLE roles Create a New Role @@ -11670,7 +12025,7 @@ Content-Type: application/json - + roles/{roleId} @@ -11678,7 +12033,7 @@ Content-Type: application/json Update a Role - + roles/{roleId}/permissions @@ -11688,7 +12043,7 @@ Content-Type: application/json Permissions - + PERMISSION permissions @@ -11697,7 +12052,7 @@ Content-Type: application/json - + DEPOSIT PRODUCT depositproducts Create a Deposit product @@ -11705,7 +12060,7 @@ Content-Type: application/json - + depositproducts/{prodcutId} @@ -11713,7 +12068,7 @@ Content-Type: application/json Update a Deposit product Delete a Deposit product - + SAVING PRODUCT savingproducts Create a Saving product @@ -11721,7 +12076,7 @@ Content-Type: application/json - + savingproducts/{prodcutId} @@ -11730,7 +12085,7 @@ Content-Type: application/json Delete a Saving product - + FIXED DEPOSITS depositaccounts Create a New Deposit @@ -11739,7 +12094,7 @@ Content-Type: application/json - + depositaccounts/{accountId} Approve, Undo Approve, @@ -11752,7 +12107,7 @@ Content-Type: application/json Application - + SAVING ACCOUNTS savingaccounts Create a New Saving @@ -11761,7 +12116,7 @@ Content-Type: application/json - + savingaccounts/{accountId} Approve, Undo Approve, diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientIdentifiersApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientIdentifiersApiResource.java index d69f241fc..1f79f67bf 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientIdentifiersApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientIdentifiersApiResource.java @@ -35,6 +35,7 @@ import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext import org.mifosplatform.portfolio.client.data.ClientData; import org.mifosplatform.portfolio.client.data.ClientIdentifierData; import org.mifosplatform.portfolio.client.exception.DuplicateClientIdentifierException; +import org.mifosplatform.portfolio.client.service.ClientIdentifierReadPlatformService; import org.mifosplatform.portfolio.client.service.ClientReadPlatformService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; @@ -46,12 +47,13 @@ import org.springframework.stereotype.Component; public class ClientIdentifiersApiResource { private static final Set CLIENT_IDENTIFIER_DATA_PARAMETERS = new HashSet(Arrays.asList("id", "clientId", - "documentTypeId", "documentKey", "description", "documentTypeName", "allowedDocumentTypes")); + "documentType", "documentKey", "description", "allowedDocumentTypes")); private final String resourceNameForPermissions = "CLIENTIDENTIFIER"; private final PlatformSecurityContext context; private final ClientReadPlatformService clientReadPlatformService; + private final ClientIdentifierReadPlatformService clientIdentifierReadPlatformService; private final CodeValueReadPlatformService codeValueReadPlatformService; private final DefaultToApiJsonSerializer toApiJsonSerializer; private final ApiRequestParameterHelper apiRequestParameterHelper; @@ -62,13 +64,15 @@ public class ClientIdentifiersApiResource { final CodeValueReadPlatformService codeValueReadPlatformService, final DefaultToApiJsonSerializer toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper, - final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { + final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService, + final ClientIdentifierReadPlatformService clientIdentifierReadPlatformService) { this.context = context; this.clientReadPlatformService = readPlatformService; this.codeValueReadPlatformService = codeValueReadPlatformService; this.toApiJsonSerializer = toApiJsonSerializer; this.apiRequestParameterHelper = apiRequestParameterHelper; this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; + this.clientIdentifierReadPlatformService = clientIdentifierReadPlatformService; } @GET @@ -76,11 +80,12 @@ public class ClientIdentifiersApiResource { @Produces({ MediaType.APPLICATION_JSON }) public String retrieveAllClientIdentifiers(@Context final UriInfo uriInfo, @PathParam("clientId") final Long clientId) { - context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); + this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions); - final Collection clientIdentifiers = this.clientReadPlatformService.retrieveClientIdentifiers(clientId); + final Collection clientIdentifiers = this.clientIdentifierReadPlatformService + .retrieveClientIdentifiers(clientId); - final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); return this.toApiJsonSerializer.serialize(settings, clientIdentifiers, CLIENT_IDENTIFIER_DATA_PARAMETERS); } @@ -90,12 +95,12 @@ public class ClientIdentifiersApiResource { @Produces({ MediaType.APPLICATION_JSON }) public String newClientIdentifierDetails(@Context final UriInfo uriInfo) { - context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); + this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions); - final Collection codeValues = codeValueReadPlatformService.retrieveCodeValuesByCode("Customer Identifier"); + final Collection codeValues = this.codeValueReadPlatformService.retrieveCodeValuesByCode("Customer Identifier"); final ClientIdentifierData clientIdentifierData = ClientIdentifierData.template(codeValues); - final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); return this.toApiJsonSerializer.serialize(settings, clientIdentifierData, CLIENT_IDENTIFIER_DATA_PARAMETERS); } @@ -111,11 +116,11 @@ public class ClientIdentifiersApiResource { final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); return this.toApiJsonSerializer.serialize(result); - } catch (DuplicateClientIdentifierException e) { + } catch (final DuplicateClientIdentifierException e) { DuplicateClientIdentifierException rethrowas = e; if (e.getDocumentTypeId() != null) { // need to fetch client info - ClientData clientInfo = this.clientReadPlatformService.retrieveClientByIdentifier(e.getDocumentTypeId(), + final ClientData clientInfo = this.clientReadPlatformService.retrieveClientByIdentifier(e.getDocumentTypeId(), e.getIdentifierKey()); rethrowas = new DuplicateClientIdentifierException(clientInfo.displayName(), clientInfo.officeName(), e.getIdentifierType(), e.getIdentifierKey()); @@ -131,14 +136,14 @@ public class ClientIdentifiersApiResource { public String retrieveClientIdentifiers(@PathParam("clientId") final Long clientId, @PathParam("identifierId") final Long clientIdentifierId, @Context final UriInfo uriInfo) { - context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); + this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions); - final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); - ClientIdentifierData clientIdentifierData = this.clientReadPlatformService.retrieveClientIdentifier(clientId, clientIdentifierId); + ClientIdentifierData clientIdentifierData = this.clientIdentifierReadPlatformService.retrieveClientIdentifier(clientId, + clientIdentifierId); if (settings.isTemplate()) { - final Collection codeValues = codeValueReadPlatformService - .retrieveCodeValuesByCode("Customer Identifier"); + final Collection codeValues = this.codeValueReadPlatformService.retrieveCodeValuesByCode("Customer Identifier"); clientIdentifierData = ClientIdentifierData.template(clientIdentifierData, codeValues); } @@ -159,10 +164,10 @@ public class ClientIdentifiersApiResource { final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); return this.toApiJsonSerializer.serialize(result); - } catch (DuplicateClientIdentifierException e) { + } catch (final DuplicateClientIdentifierException e) { DuplicateClientIdentifierException reThrowAs = e; if (e.getDocumentTypeId() != null) { - ClientData clientInfo = this.clientReadPlatformService.retrieveClientByIdentifier(e.getDocumentTypeId(), + final ClientData clientInfo = this.clientReadPlatformService.retrieveClientByIdentifier(e.getDocumentTypeId(), e.getIdentifierKey()); reThrowAs = new DuplicateClientIdentifierException(clientInfo.displayName(), clientInfo.officeName(), e.getIdentifierType(), e.getIdentifierKey()); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientImagesApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientImagesApiResource.java index 1fa8385fa..cdda2bff7 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientImagesApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientImagesApiResource.java @@ -37,114 +37,133 @@ import com.sun.jersey.core.header.FormDataContentDisposition; import com.sun.jersey.multipart.FormDataBodyPart; import com.sun.jersey.multipart.FormDataParam; -// FIXME - KW - image should be images to keep consistent with rest of API - even if we only support one image per client. -@Path("/clients/{clientId}/image") +@Path("/clients/{clientId}/images") @Component @Scope("singleton") public class ClientImagesApiResource { - private final PlatformSecurityContext context; - private final ClientReadPlatformService clientReadPlatformService; - private final ClientWritePlatformService clientWritePlatformService; - private final DefaultToApiJsonSerializer toApiJsonSerializer; + private final PlatformSecurityContext context; + private final ClientReadPlatformService clientReadPlatformService; + private final ClientWritePlatformService clientWritePlatformService; + private final DefaultToApiJsonSerializer toApiJsonSerializer; - @Autowired - public ClientImagesApiResource(final PlatformSecurityContext context, final ClientReadPlatformService readPlatformService, - final ClientWritePlatformService clientWritePlatformService, final DefaultToApiJsonSerializer toApiJsonSerializer) { - this.context = context; - this.clientReadPlatformService = readPlatformService; - this.clientWritePlatformService = clientWritePlatformService; - this.toApiJsonSerializer = toApiJsonSerializer; - } + @Autowired + public ClientImagesApiResource(final PlatformSecurityContext context, + final ClientReadPlatformService readPlatformService, + final ClientWritePlatformService clientWritePlatformService, + final DefaultToApiJsonSerializer toApiJsonSerializer) { + this.context = context; + this.clientReadPlatformService = readPlatformService; + this.clientWritePlatformService = clientWritePlatformService; + this.toApiJsonSerializer = toApiJsonSerializer; + } - /** - * Upload images through multi-part form upload - */ - @POST - @Consumes({ MediaType.MULTIPART_FORM_DATA }) - @Produces({ MediaType.APPLICATION_JSON }) - public String addNewClientImage(@PathParam("clientId") final Long clientId, @HeaderParam("Content-Length") final Long fileSize, - @FormDataParam("file") final InputStream inputStream, @FormDataParam("file") final FormDataContentDisposition fileDetails, - @FormDataParam("file") final FormDataBodyPart bodyPart) { + /** + * Upload images through multi-part form upload + */ + @POST + @Consumes({ MediaType.MULTIPART_FORM_DATA }) + @Produces({ MediaType.APPLICATION_JSON }) + public String addNewClientImage( + @PathParam("clientId") final Long clientId, + @HeaderParam("Content-Length") final Long fileSize, + @FormDataParam("file") final InputStream inputStream, + @FormDataParam("file") final FormDataContentDisposition fileDetails, + @FormDataParam("file") final FormDataBodyPart bodyPart) { - // TODO: vishwas might need more advances validation (like reading magic - // number) for handling malicious clients - // and clients not setting mime type - FileUtils.validateClientImageNotEmpty(fileDetails.getFileName()); - FileUtils.validateImageMimeType(bodyPart.getMediaType().toString()); - FileUtils.validateFileSizeWithinPermissibleRange(fileSize, fileDetails.getFileName(), ApiConstants.MAX_FILE_UPLOAD_SIZE_IN_MB); + // TODO: vishwas might need more advances validation (like reading magic + // number) for handling malicious clients + // and clients not setting mime type + FileUtils.validateClientImageNotEmpty(fileDetails.getFileName()); + FileUtils.validateImageMimeType(bodyPart.getMediaType().toString()); + FileUtils.validateFileSizeWithinPermissibleRange(fileSize, + fileDetails.getFileName(), + ApiConstants.MAX_FILE_UPLOAD_SIZE_IN_MB); - final CommandProcessingResult result = this.clientWritePlatformService.saveOrUpdateClientImage(clientId, fileDetails.getFileName(), - inputStream); + final CommandProcessingResult result = this.clientWritePlatformService + .saveOrUpdateClientImage(clientId, fileDetails.getFileName(), + inputStream); - return this.toApiJsonSerializer.serialize(result); - } + return this.toApiJsonSerializer.serialize(result); + } - /** - * Upload image as a Data URL (essentially a base64 encoded stream) - */ - @POST - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public String addNewClientImage(@PathParam("clientId") final Long clientId, final String jsonRequestBody) { + /** + * Upload image as a Data URL (essentially a base64 encoded stream) + */ + @POST + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String addNewClientImage(@PathParam("clientId") final Long clientId, + final String jsonRequestBody) { - final Base64EncodedImage base64EncodedImage = FileUtils.extractImageFromDataURL(jsonRequestBody); + final Base64EncodedImage base64EncodedImage = FileUtils + .extractImageFromDataURL(jsonRequestBody); - final CommandProcessingResult result = this.clientWritePlatformService.saveOrUpdateClientImage(clientId, base64EncodedImage); + final CommandProcessingResult result = this.clientWritePlatformService + .saveOrUpdateClientImage(clientId, base64EncodedImage); - return this.toApiJsonSerializer.serialize(result); - } + return this.toApiJsonSerializer.serialize(result); + } - /** - * Returns a base 64 encoded client image - */ - @GET - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public String retrieveClientImage(@PathParam("clientId") final Long clientId) { + /** + * Returns a base 64 encoded client image + */ + @GET + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveClientImage(@PathParam("clientId") final Long clientId) { - context.authenticatedUser().validateHasReadPermission("CLIENTIMAGE"); + context.authenticatedUser().validateHasReadPermission("CLIENTIMAGE"); - final ClientData clientData = this.clientReadPlatformService.retrieveIndividualClient(clientId); + final ClientData clientData = this.clientReadPlatformService + .retrieveIndividualClient(clientId); - if (clientData.imageKeyDoesNotExist()) { throw new ImageNotFoundException("clients", clientId); } + if (clientData.imageKeyDoesNotExist()) { + throw new ImageNotFoundException("clients", clientId); + } - return Base64.encodeFromFile(clientData.imageKey()); - } + return Base64.encodeFromFile(clientData.imageKey()); + } - /** - * This method is added only for consistency with other URL patterns and for - * maintaining consistency of usage of the HTTP "verb" at the client side - */ - @PUT - @Consumes({ MediaType.MULTIPART_FORM_DATA }) - @Produces({ MediaType.APPLICATION_JSON }) - public String updateClientImage(@PathParam("clientId") final Long clientId, @HeaderParam("Content-Length") final Long fileSize, - @FormDataParam("file") final InputStream inputStream, @FormDataParam("file") final FormDataContentDisposition fileDetails, - @FormDataParam("file") final FormDataBodyPart bodyPart) { + /** + * This method is added only for consistency with other URL patterns and for + * maintaining consistency of usage of the HTTP "verb" at the client side + */ + @PUT + @Consumes({ MediaType.MULTIPART_FORM_DATA }) + @Produces({ MediaType.APPLICATION_JSON }) + public String updateClientImage( + @PathParam("clientId") final Long clientId, + @HeaderParam("Content-Length") final Long fileSize, + @FormDataParam("file") final InputStream inputStream, + @FormDataParam("file") final FormDataContentDisposition fileDetails, + @FormDataParam("file") final FormDataBodyPart bodyPart) { - return addNewClientImage(clientId, fileSize, inputStream, fileDetails, bodyPart); - } + return addNewClientImage(clientId, fileSize, inputStream, fileDetails, + bodyPart); + } - @DELETE - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public String deleteClientImage(@PathParam("clientId") final Long clientId) { - this.clientWritePlatformService.deleteClientImage(clientId); + @DELETE + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String deleteClientImage(@PathParam("clientId") final Long clientId) { + this.clientWritePlatformService.deleteClientImage(clientId); - return this.toApiJsonSerializer.serialize(new CommandProcessingResult(clientId)); - } + return this.toApiJsonSerializer.serialize(new CommandProcessingResult( + clientId)); + } - /** - * This method is added only for consistency with other URL patterns and for - * maintaining consistency of usage of the HTTP "verb" at the client side - * - * Upload image as a Data URL (essentially a base64 encoded stream) - */ - @PUT - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public String updateClientImage(@PathParam("clientId") final Long clientId, final String jsonRequestBody) { - return addNewClientImage(clientId, jsonRequestBody); - } + /** + * This method is added only for consistency with other URL patterns and for + * maintaining consistency of usage of the HTTP "verb" at the client side + * + * Upload image as a Data URL (essentially a base64 encoded stream) + */ + @PUT + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String updateClientImage(@PathParam("clientId") final Long clientId, + final String jsonRequestBody) { + return addNewClientImage(clientId, jsonRequestBody); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientIdentifierData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientIdentifierData.java index 56dfda4b5..5b18717c8 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientIdentifierData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientIdentifierData.java @@ -14,37 +14,44 @@ import org.mifosplatform.infrastructure.codes.data.CodeValueData; */ public class ClientIdentifierData { - private final Long id; - private final Long clientId; - private final Long documentTypeId; - private final String documentTypeName; - private final String documentKey; - private final String description; - @SuppressWarnings("unused") - private final Collection allowedDocumentTypes; + private final Long id; + private final Long clientId; + private final CodeValueData documentType; + private final String documentKey; + private final String description; + @SuppressWarnings("unused") + private final Collection allowedDocumentTypes; - public static ClientIdentifierData singleItem(final Long id, final Long clientId, final Long documentTypeId, final String documentKey, - final String description, final String documentTypeName) { - return new ClientIdentifierData(id, clientId, documentTypeId, documentKey, description, documentTypeName, null); - } + public static ClientIdentifierData singleItem(final Long id, + final Long clientId, final CodeValueData documentType, + final String documentKey, final String description) { + return new ClientIdentifierData(id, clientId, documentType, + documentKey, description, null); + } - public static ClientIdentifierData template(final Collection codeValues) { - return new ClientIdentifierData(null, null, null, null, null, null, codeValues); - } + public static ClientIdentifierData template( + final Collection codeValues) { + return new ClientIdentifierData(null, null, null, null, null, + codeValues); + } - public static ClientIdentifierData template(final ClientIdentifierData data, final Collection codeValues) { - return new ClientIdentifierData(data.id, data.clientId, data.documentTypeId, data.documentKey, data.description, - data.documentTypeName, codeValues); - } + public static ClientIdentifierData template( + final ClientIdentifierData data, + final Collection codeValues) { + return new ClientIdentifierData(data.id, data.clientId, + data.documentType, data.documentKey, data.description, + codeValues); + } - public ClientIdentifierData(final Long id, final Long clientId, final Long documentTypeId, final String documentKey, - final String description, final String documentTypeName, final Collection allowedDocumentTypes) { - this.id = id; - this.clientId = clientId; - this.documentTypeId = documentTypeId; - this.documentKey = documentKey; - this.description = description; - this.documentTypeName = documentTypeName; - this.allowedDocumentTypes = allowedDocumentTypes; - } + public ClientIdentifierData(final Long id, final Long clientId, + final CodeValueData documentType, final String documentKey, + final String description, + final Collection allowedDocumentTypes) { + this.id = id; + this.clientId = clientId; + this.documentType = documentType; + this.documentKey = documentKey; + this.description = description; + this.allowedDocumentTypes = allowedDocumentTypes; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/handler/CreateClientIdentifierCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/handler/CreateClientIdentifierCommandHandler.java index aef585d53..b43fdaf00 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/handler/CreateClientIdentifierCommandHandler.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/handler/CreateClientIdentifierCommandHandler.java @@ -8,7 +8,7 @@ package org.mifosplatform.portfolio.client.handler; import org.mifosplatform.commands.handler.NewCommandSourceHandler; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; -import org.mifosplatform.portfolio.client.service.ClientWritePlatformService; +import org.mifosplatform.portfolio.client.service.ClientIdentifierWritePlatformService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -16,17 +16,17 @@ import org.springframework.transaction.annotation.Transactional; @Service public class CreateClientIdentifierCommandHandler implements NewCommandSourceHandler { - private final ClientWritePlatformService clientWritePlatformService; + private final ClientIdentifierWritePlatformService clientIdentifierWritePlatformService; @Autowired - public CreateClientIdentifierCommandHandler(final ClientWritePlatformService clientWritePlatformService) { - this.clientWritePlatformService = clientWritePlatformService; + public CreateClientIdentifierCommandHandler(final ClientIdentifierWritePlatformService clientIdentifierWritePlatformService) { + this.clientIdentifierWritePlatformService = clientIdentifierWritePlatformService; } @Transactional @Override public CommandProcessingResult processCommand(final JsonCommand command) { - return this.clientWritePlatformService.addClientIdentifier(command.getClientId(), command); + return this.clientIdentifierWritePlatformService.addClientIdentifier(command.getClientId(), command); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/handler/DeleteClientIdentifierCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/handler/DeleteClientIdentifierCommandHandler.java index 1177eb07e..bbd406dcb 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/handler/DeleteClientIdentifierCommandHandler.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/handler/DeleteClientIdentifierCommandHandler.java @@ -8,7 +8,7 @@ package org.mifosplatform.portfolio.client.handler; import org.mifosplatform.commands.handler.NewCommandSourceHandler; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; -import org.mifosplatform.portfolio.client.service.ClientWritePlatformService; +import org.mifosplatform.portfolio.client.service.ClientIdentifierWritePlatformService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -16,17 +16,18 @@ import org.springframework.transaction.annotation.Transactional; @Service public class DeleteClientIdentifierCommandHandler implements NewCommandSourceHandler { - private final ClientWritePlatformService clientWritePlatformService; + private final ClientIdentifierWritePlatformService clientIdentifierWritePlatformService; @Autowired - public DeleteClientIdentifierCommandHandler(final ClientWritePlatformService clientWritePlatformService) { - this.clientWritePlatformService = clientWritePlatformService; + public DeleteClientIdentifierCommandHandler(final ClientIdentifierWritePlatformService clientIdentifierWritePlatformService) { + this.clientIdentifierWritePlatformService = clientIdentifierWritePlatformService; } @Transactional @Override public CommandProcessingResult processCommand(final JsonCommand command) { - return this.clientWritePlatformService.deleteClientIdentifier(command.getClientId(), command.entityId(), command.commandId()); + return this.clientIdentifierWritePlatformService.deleteClientIdentifier(command.getClientId(), command.entityId(), + command.commandId()); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/handler/UpdateClientIdentifierCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/handler/UpdateClientIdentifierCommandHandler.java index a556ac73e..64f98f213 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/handler/UpdateClientIdentifierCommandHandler.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/handler/UpdateClientIdentifierCommandHandler.java @@ -8,7 +8,7 @@ package org.mifosplatform.portfolio.client.handler; import org.mifosplatform.commands.handler.NewCommandSourceHandler; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; -import org.mifosplatform.portfolio.client.service.ClientWritePlatformService; +import org.mifosplatform.portfolio.client.service.ClientIdentifierWritePlatformService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -16,17 +16,16 @@ import org.springframework.transaction.annotation.Transactional; @Service public class UpdateClientIdentifierCommandHandler implements NewCommandSourceHandler { - private final ClientWritePlatformService clientWritePlatformService; + private final ClientIdentifierWritePlatformService clientIdentifierWritePlatformService; @Autowired - public UpdateClientIdentifierCommandHandler(final ClientWritePlatformService clientWritePlatformService) { - this.clientWritePlatformService = clientWritePlatformService; + public UpdateClientIdentifierCommandHandler(final ClientIdentifierWritePlatformService clientIdentifierWritePlatformService) { + this.clientIdentifierWritePlatformService = clientIdentifierWritePlatformService; } @Transactional @Override public CommandProcessingResult processCommand(final JsonCommand command) { - - return this.clientWritePlatformService.updateClientIdentifier(command.getClientId(), command.entityId(), command); + return this.clientIdentifierWritePlatformService.updateClientIdentifier(command.getClientId(), command.entityId(), command); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientIdentifierReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientIdentifierReadPlatformService.java new file mode 100755 index 000000000..e3f35ea21 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientIdentifierReadPlatformService.java @@ -0,0 +1,18 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.client.service; + +import java.util.Collection; + +import org.mifosplatform.portfolio.client.data.ClientIdentifierData; + +public interface ClientIdentifierReadPlatformService { + + Collection retrieveClientIdentifiers(Long clientId); + + ClientIdentifierData retrieveClientIdentifier(Long clientId, Long clientIdentifierId); + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientIdentifierReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientIdentifierReadPlatformServiceImpl.java new file mode 100755 index 000000000..56f0c3787 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientIdentifierReadPlatformServiceImpl.java @@ -0,0 +1,105 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.client.service; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collection; + +import org.mifosplatform.infrastructure.codes.data.CodeValueData; +import org.mifosplatform.infrastructure.core.domain.JdbcSupport; +import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.client.data.ClientIdentifierData; +import org.mifosplatform.portfolio.client.exception.ClientIdentifierNotFoundException; +import org.mifosplatform.useradministration.domain.AppUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Service; + +@Service +public class ClientIdentifierReadPlatformServiceImpl implements ClientIdentifierReadPlatformService { + + private final JdbcTemplate jdbcTemplate; + private final PlatformSecurityContext context; + + @Autowired + public ClientIdentifierReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource) { + this.context = context; + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + @Override + public Collection retrieveClientIdentifiers(final Long clientId) { + + AppUser currentUser = context.authenticatedUser(); + String hierarchy = currentUser.getOffice().getHierarchy(); + String hierarchySearchString = hierarchy + "%"; + + ClientIdentityMapper rm = new ClientIdentityMapper(); + + String sql = "select " + rm.schema(); + + sql += " order by ci.id"; + + return this.jdbcTemplate.query(sql, rm, new Object[] { clientId, hierarchySearchString }); + } + + @Override + public ClientIdentifierData retrieveClientIdentifier(final Long clientId, final Long clientIdentifierId) { + try { + AppUser currentUser = context.authenticatedUser(); + String hierarchy = currentUser.getOffice().getHierarchy(); + String hierarchySearchString = hierarchy + "%"; + + ClientIdentityMapper rm = new ClientIdentityMapper(); + + String sql = "select " + rm.schema(); + + sql += " and ci.id = ?"; + + final ClientIdentifierData clientIdentifierData = this.jdbcTemplate.queryForObject(sql, rm, new Object[] { clientId, + hierarchySearchString, clientIdentifierId }); + + return clientIdentifierData; + } catch (EmptyResultDataAccessException e) { + throw new ClientIdentifierNotFoundException(clientIdentifierId); + } + + } + + private static final class ClientIdentityMapper implements RowMapper { + + public ClientIdentityMapper() {} + + public String schema() { + return "ci.id as id, ci.client_id as clientId, ci.document_type_id as documentTypeId, ci.document_key as documentKey," + + " ci.description as description, cv.code_value as documentType " + + " from m_client_identifier ci, m_client c, m_office o, m_code_value cv" + + " where ci.client_id=c.id and c.office_id=o.id" + " and ci.document_type_id=cv.id" + + " and ci.client_id = ? and o.hierarchy like ? "; + } + + @Override + public ClientIdentifierData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + + final Long id = JdbcSupport.getLong(rs, "id"); + final Long clientId = JdbcSupport.getLong(rs, "clientId"); + final Long documentTypeId = JdbcSupport.getLong(rs, "documentTypeId"); + final String documentKey = rs.getString("documentKey"); + final String description = rs.getString("description"); + final String documentTypeName = rs.getString("documentType"); + + CodeValueData documentType = CodeValueData.instance(documentTypeId, documentTypeName); + + return ClientIdentifierData.singleItem(id, clientId, documentType, documentKey, description); + } + + } + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientIdentifierWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientIdentifierWritePlatformService.java new file mode 100755 index 000000000..2b311b0bd --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientIdentifierWritePlatformService.java @@ -0,0 +1,18 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.client.service; + +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; + +public interface ClientIdentifierWritePlatformService { + + CommandProcessingResult addClientIdentifier(Long clientId, JsonCommand command); + + CommandProcessingResult updateClientIdentifier(Long clientId, Long clientIdentifierId, JsonCommand command); + + CommandProcessingResult deleteClientIdentifier(Long clientId, Long clientIdentifierId, Long commandId); +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientIdentifierWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientIdentifierWritePlatformServiceJpaRepositoryImpl.java new file mode 100755 index 000000000..0b4a6d5c0 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientIdentifierWritePlatformServiceJpaRepositoryImpl.java @@ -0,0 +1,181 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.client.service; + +import java.util.Map; + +import org.mifosplatform.infrastructure.codes.domain.CodeValue; +import org.mifosplatform.infrastructure.codes.domain.CodeValueRepositoryWrapper; +import org.mifosplatform.infrastructure.codes.exception.CodeValueNotFoundException; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; +import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.client.command.ClientIdentifierCommand; +import org.mifosplatform.portfolio.client.domain.Client; +import org.mifosplatform.portfolio.client.domain.ClientIdentifier; +import org.mifosplatform.portfolio.client.domain.ClientIdentifierRepository; +import org.mifosplatform.portfolio.client.domain.ClientRepository; +import org.mifosplatform.portfolio.client.exception.ClientIdentifierNotFoundException; +import org.mifosplatform.portfolio.client.exception.ClientNotFoundException; +import org.mifosplatform.portfolio.client.exception.DuplicateClientIdentifierException; +import org.mifosplatform.portfolio.client.serialization.ClientIdentifierCommandFromApiJsonDeserializer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class ClientIdentifierWritePlatformServiceJpaRepositoryImpl implements ClientIdentifierWritePlatformService { + + private final static Logger logger = LoggerFactory.getLogger(ClientIdentifierWritePlatformServiceJpaRepositoryImpl.class); + + private final PlatformSecurityContext context; + private final ClientRepository clientRepository; + private final ClientIdentifierRepository clientIdentifierRepository; + private final CodeValueRepositoryWrapper codeValueRepository; + private final ClientIdentifierCommandFromApiJsonDeserializer clientIdentifierCommandFromApiJsonDeserializer; + + @Autowired + public ClientIdentifierWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, + final ClientRepository clientRepository, final ClientIdentifierRepository clientIdentifierRepository, + final CodeValueRepositoryWrapper codeValueRepository, + final ClientIdentifierCommandFromApiJsonDeserializer clientIdentifierCommandFromApiJsonDeserializer) { + this.context = context; + this.clientRepository = clientRepository; + this.clientIdentifierRepository = clientIdentifierRepository; + this.codeValueRepository = codeValueRepository; + this.clientIdentifierCommandFromApiJsonDeserializer = clientIdentifierCommandFromApiJsonDeserializer; + } + + @Transactional + @Override + public CommandProcessingResult addClientIdentifier(final Long clientId, final JsonCommand command) { + + context.authenticatedUser(); + final ClientIdentifierCommand clientIdentifierCommand = this.clientIdentifierCommandFromApiJsonDeserializer + .commandFromApiJson(command.json()); + clientIdentifierCommand.validateForCreate(); + + String documentKey = clientIdentifierCommand.getDocumentKey(); + String documentTypeLabel = null; + Long documentTypeId = null; + try { + final Client client = this.clientRepository.findOne(clientId); + if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); } + + final CodeValue documentType = this.codeValueRepository.findOneWithNotFoundDetection(clientIdentifierCommand + .getDocumentTypeId()); + documentTypeId = documentType.getId(); + documentTypeLabel = documentType.label(); + + final ClientIdentifier clientIdentifier = ClientIdentifier.fromJson(client, documentType, command); + + this.clientIdentifierRepository.save(clientIdentifier); + + return new CommandProcessingResultBuilder() // + .withCommandId(command.commandId()) // + .withOfficeId(client.getOffice().getId()) // + .withClientId(clientId) // + .withEntityId(clientIdentifier.getId()) // + .build(); + } catch (DataIntegrityViolationException dve) { + handleClientIdentifierDataIntegrityViolation(documentTypeLabel, documentTypeId, documentKey, dve); + return CommandProcessingResult.empty(); + } + } + + @Transactional + @Override + public CommandProcessingResult updateClientIdentifier(final Long clientId, final Long identifierId, final JsonCommand command) { + + context.authenticatedUser(); + final ClientIdentifierCommand clientIdentifierCommand = this.clientIdentifierCommandFromApiJsonDeserializer + .commandFromApiJson(command.json()); + clientIdentifierCommand.validateForUpdate(); + + String documentTypeLabel = null; + String documentKey = null; + Long documentTypeId = clientIdentifierCommand.getDocumentTypeId(); + try { + CodeValue documentType = null; + + final ClientIdentifier clientIdentifierForUpdate = this.clientIdentifierRepository.findOne(identifierId); + if (clientIdentifierForUpdate == null) { throw new ClientIdentifierNotFoundException(identifierId); } + + final Map changes = clientIdentifierForUpdate.update(command); + + if (changes.containsKey("documentTypeId")) { + documentType = this.codeValueRepository.findOneWithNotFoundDetection(documentTypeId); + if (documentType == null) { throw new CodeValueNotFoundException(documentTypeId); } + + documentTypeId = documentType.getId(); + documentTypeLabel = documentType.label(); + clientIdentifierForUpdate.update(documentType); + } + + if (changes.containsKey("documentTypeId") && changes.containsKey("documentKey")) { + documentTypeId = clientIdentifierCommand.getDocumentTypeId(); + documentKey = clientIdentifierCommand.getDocumentKey(); + } else if (changes.containsKey("documentTypeId") && !changes.containsKey("documentKey")) { + documentTypeId = clientIdentifierCommand.getDocumentTypeId(); + documentKey = clientIdentifierForUpdate.documentKey(); + } else if (!changes.containsKey("documentTypeId") && changes.containsKey("documentKey")) { + documentTypeId = clientIdentifierForUpdate.documentTypeId(); + documentKey = clientIdentifierForUpdate.documentKey(); + } + + if (!changes.isEmpty()) { + this.clientIdentifierRepository.saveAndFlush(clientIdentifierForUpdate); + } + + final Client client = this.clientRepository.findOne(clientId); + return new CommandProcessingResultBuilder() // + .withCommandId(command.commandId()) // + .withOfficeId(client.getOffice().getId()) // + .withClientId(clientId) // + .withEntityId(identifierId) // + .with(changes) // + .build(); + } catch (DataIntegrityViolationException dve) { + handleClientIdentifierDataIntegrityViolation(documentTypeLabel, documentTypeId, documentKey, dve); + return new CommandProcessingResult(Long.valueOf(-1)); + } + } + + @Transactional + @Override + public CommandProcessingResult deleteClientIdentifier(final Long clientId, final Long identifierId, final Long commandId) { + final ClientIdentifier clientIdentifier = this.clientIdentifierRepository.findOne(identifierId); + if (clientIdentifier == null) { throw new ClientIdentifierNotFoundException(identifierId); } + this.clientIdentifierRepository.delete(clientIdentifier); + + final Client client = this.clientRepository.findOne(clientId); + return new CommandProcessingResultBuilder().withCommandId(commandId).withOfficeId(client.getOffice().getId()) + .withClientId(clientId).withEntityId(identifierId).build(); + } + + private void handleClientIdentifierDataIntegrityViolation(final String documentTypeLabel, final Long documentTypeId, + final String documentKey, final DataIntegrityViolationException dve) { + + if (dve.getMostSpecificCause().getMessage().contains("unique_client_identifier")) { + throw new DuplicateClientIdentifierException(documentTypeLabel); + } else if (dve.getMostSpecificCause().getMessage().contains("unique_identifier_key")) { throw new DuplicateClientIdentifierException( + documentTypeId, documentTypeLabel, documentKey); } + + logAsErrorUnexpectedDataIntegrityException(dve); + throw new PlatformDataIntegrityException("error.msg.clientIdentifier.unknown.data.integrity.issue", + "Unknown data integrity issue with resource."); + } + + private void logAsErrorUnexpectedDataIntegrityException(final DataIntegrityViolationException dve) { + logger.error(dve.getMessage(), dve); + } + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformService.java index 10fa5373c..9719380e5 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformService.java @@ -10,7 +10,6 @@ import java.util.Collection; import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionData; import org.mifosplatform.portfolio.client.data.ClientAccountSummaryData; import org.mifosplatform.portfolio.client.data.ClientData; -import org.mifosplatform.portfolio.client.data.ClientIdentifierData; import org.mifosplatform.portfolio.client.data.ClientLookup; public interface ClientReadPlatformService { @@ -29,9 +28,6 @@ public interface ClientReadPlatformService { Collection retrieveClientLoanAccountsByLoanOfficerId(Long clientId, Long loanOfficerId); - Collection retrieveClientIdentifiers(Long clientId); - - ClientIdentifierData retrieveClientIdentifier(Long clientId, Long clientIdentifierId); - ClientData retrieveClientByIdentifier(Long identifierTypeId, String identifierKey); + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java index 3faa5a07f..884506537 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java @@ -21,9 +21,7 @@ import org.mifosplatform.organisation.office.service.OfficeReadPlatformService; import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionData; import org.mifosplatform.portfolio.client.data.ClientAccountSummaryData; import org.mifosplatform.portfolio.client.data.ClientData; -import org.mifosplatform.portfolio.client.data.ClientIdentifierData; import org.mifosplatform.portfolio.client.data.ClientLookup; -import org.mifosplatform.portfolio.client.exception.ClientIdentifierNotFoundException; import org.mifosplatform.portfolio.client.exception.ClientNotFoundException; import org.mifosplatform.portfolio.loanaccount.data.LoanStatusEnumData; import org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations; @@ -346,72 +344,6 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService } } - @Override - public Collection retrieveClientIdentifiers(final Long clientId) { - - AppUser currentUser = context.authenticatedUser(); - String hierarchy = currentUser.getOffice().getHierarchy(); - String hierarchySearchString = hierarchy + "%"; - - ClientIdentityMapper rm = new ClientIdentityMapper(); - - String sql = "select " + rm.schema(); - - sql += " order by ci.id"; - - return this.jdbcTemplate.query(sql, rm, new Object[] { clientId, hierarchySearchString }); - } - - @Override - public ClientIdentifierData retrieveClientIdentifier(final Long clientId, final Long clientIdentifierId) { - try { - AppUser currentUser = context.authenticatedUser(); - String hierarchy = currentUser.getOffice().getHierarchy(); - String hierarchySearchString = hierarchy + "%"; - - ClientIdentityMapper rm = new ClientIdentityMapper(); - - String sql = "select " + rm.schema(); - - sql += " and ci.id = ?"; - - final ClientIdentifierData clientIdentifierData = this.jdbcTemplate.queryForObject(sql, rm, new Object[] { clientId, - hierarchySearchString, clientIdentifierId }); - - return clientIdentifierData; - } catch (EmptyResultDataAccessException e) { - throw new ClientIdentifierNotFoundException(clientIdentifierId); - } - - } - - private static final class ClientIdentityMapper implements RowMapper { - - public ClientIdentityMapper() {} - - public String schema() { - return "ci.id as id, ci.client_id as clientId, ci.document_type_id as documentTypeId, ci.document_key as documentKey," - + " ci.description as description, cv.code_value as documentType " - + " from m_client_identifier ci, m_client c, m_office o, m_code_value cv" - + " where ci.client_id=c.id and c.office_id=o.id" + " and ci.document_type_id=cv.id" - + " and ci.client_id = ? and o.hierarchy like ? "; - } - - @Override - public ClientIdentifierData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { - - final Long id = JdbcSupport.getLong(rs, "id"); - final Long clientId = JdbcSupport.getLong(rs, "clientId"); - final Long documentTypeId = JdbcSupport.getLong(rs, "documentTypeId"); - final String documentKey = rs.getString("documentKey"); - final String description = rs.getString("description"); - final String documentTypeName = rs.getString("documentType"); - - return ClientIdentifierData.singleItem(id, clientId, documentTypeId, documentKey, description, documentTypeName); - } - - } - @Override public ClientData retrieveClientByIdentifier(final Long identifierTypeId, final String identifierKey) { try { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformService.java index e09a45030..575d7fde2 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformService.java @@ -29,9 +29,4 @@ public interface ClientWritePlatformService { @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'DELETE_CLIENTIMAGE')") CommandProcessingResult deleteClientImage(Long clientId); - CommandProcessingResult addClientIdentifier(Long clientId, JsonCommand command); - - CommandProcessingResult updateClientIdentifier(Long clientId, Long clientIdentifierId, JsonCommand command); - - CommandProcessingResult deleteClientIdentifier(Long clientId, Long clientIdentifierId, Long commandId); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java index a791139d3..e351c355e 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java @@ -11,9 +11,6 @@ import java.io.InputStream; import java.util.Map; import org.apache.commons.lang.StringUtils; -import org.mifosplatform.infrastructure.codes.domain.CodeValue; -import org.mifosplatform.infrastructure.codes.domain.CodeValueRepositoryWrapper; -import org.mifosplatform.infrastructure.codes.exception.CodeValueNotFoundException; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; @@ -25,18 +22,12 @@ import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext import org.mifosplatform.organisation.office.domain.Office; import org.mifosplatform.organisation.office.domain.OfficeRepository; import org.mifosplatform.organisation.office.exception.OfficeNotFoundException; -import org.mifosplatform.portfolio.client.command.ClientIdentifierCommand; import org.mifosplatform.portfolio.client.domain.AccountNumberGenerator; import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory; import org.mifosplatform.portfolio.client.domain.Client; -import org.mifosplatform.portfolio.client.domain.ClientIdentifier; -import org.mifosplatform.portfolio.client.domain.ClientIdentifierRepository; import org.mifosplatform.portfolio.client.domain.ClientRepository; -import org.mifosplatform.portfolio.client.exception.ClientIdentifierNotFoundException; import org.mifosplatform.portfolio.client.exception.ClientNotFoundException; -import org.mifosplatform.portfolio.client.exception.DuplicateClientIdentifierException; import org.mifosplatform.portfolio.client.serialization.ClientCommandFromApiJsonDeserializer; -import org.mifosplatform.portfolio.client.serialization.ClientIdentifierCommandFromApiJsonDeserializer; import org.mifosplatform.portfolio.group.domain.Group; import org.mifosplatform.portfolio.group.domain.GroupRepository; import org.mifosplatform.portfolio.group.exception.GroupNotFoundException; @@ -54,29 +45,19 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP private final PlatformSecurityContext context; private final ClientRepository clientRepository; - private final ClientIdentifierRepository clientIdentifierRepository; private final OfficeRepository officeRepository; private final GroupRepository groupRepository; - private final CodeValueRepositoryWrapper codeValueRepository; private final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer; - private final ClientIdentifierCommandFromApiJsonDeserializer clientIdentifierCommandFromApiJsonDeserializer; private final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory; @Autowired public ClientWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final ClientRepository clientRepository, - final ClientIdentifierRepository clientIdentifierRepository, final OfficeRepository officeRepository, - final CodeValueRepositoryWrapper codeValueRepository, - final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer, - final ClientIdentifierCommandFromApiJsonDeserializer clientIdentifierCommandFromApiJsonDeserializer, - final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory, - final GroupRepository groupRepository) { + final OfficeRepository officeRepository, final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer, + final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory, final GroupRepository groupRepository) { this.context = context; this.clientRepository = clientRepository; - this.clientIdentifierRepository = clientIdentifierRepository; this.officeRepository = officeRepository; - this.codeValueRepository = codeValueRepository; this.fromApiJsonDeserializer = fromApiJsonDeserializer; - this.clientIdentifierCommandFromApiJsonDeserializer = clientIdentifierCommandFromApiJsonDeserializer; this.accountIdentifierGeneratorFactory = accountIdentifierGeneratorFactory; this.groupRepository = groupRepository; } @@ -132,17 +113,17 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP final Office clientOffice = this.officeRepository.findOne(officeId); if (clientOffice == null) { throw new OfficeNotFoundException(officeId); } - + final Long groupId = command.longValueOfParameterNamed("groupId"); - + Group clientParentGroup = null; - - if(groupId != null){ + + if (groupId != null) { clientParentGroup = this.groupRepository.findOne(groupId); if (clientParentGroup == null) { throw new GroupNotFoundException(groupId); } } - - final Client newClient = Client.fromJson(clientOffice, clientParentGroup , command); + + final Client newClient = Client.fromJson(clientOffice, clientParentGroup, command); this.clientRepository.save(newClient); if (newClient.isAccountNumberRequiresAutoGeneration()) { @@ -203,129 +184,6 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP } } - @Transactional - @Override - public CommandProcessingResult addClientIdentifier(final Long clientId, final JsonCommand command) { - - context.authenticatedUser(); - final ClientIdentifierCommand clientIdentifierCommand = this.clientIdentifierCommandFromApiJsonDeserializer - .commandFromApiJson(command.json()); - clientIdentifierCommand.validateForCreate(); - - String documentKey = clientIdentifierCommand.getDocumentKey(); - String documentTypeLabel = null; - Long documentTypeId = null; - try { - final Client client = this.clientRepository.findOne(clientId); - if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); } - - final CodeValue documentType = this.codeValueRepository.findOneWithNotFoundDetection(clientIdentifierCommand.getDocumentTypeId()); - documentTypeId = documentType.getId(); - documentTypeLabel = documentType.label(); - - final ClientIdentifier clientIdentifier = ClientIdentifier.fromJson(client, documentType, command); - - this.clientIdentifierRepository.save(clientIdentifier); - - return new CommandProcessingResultBuilder() // - .withCommandId(command.commandId()) // - .withOfficeId(client.getOffice().getId()) // - .withClientId(clientId) // - .withEntityId(clientIdentifier.getId()) // - .build(); - } catch (DataIntegrityViolationException dve) { - handleClientIdentifierDataIntegrityViolation(documentTypeLabel, documentTypeId, documentKey, dve); - return CommandProcessingResult.empty(); - } - } - - @Transactional - @Override - public CommandProcessingResult updateClientIdentifier(final Long clientId, final Long identifierId, final JsonCommand command) { - - context.authenticatedUser(); - final ClientIdentifierCommand clientIdentifierCommand = this.clientIdentifierCommandFromApiJsonDeserializer - .commandFromApiJson(command.json()); - clientIdentifierCommand.validateForUpdate(); - - String documentTypeLabel = null; - String documentKey = null; - Long documentTypeId = clientIdentifierCommand.getDocumentTypeId(); - try { - CodeValue documentType = null; - - final ClientIdentifier clientIdentifierForUpdate = this.clientIdentifierRepository.findOne(identifierId); - if (clientIdentifierForUpdate == null) { throw new ClientIdentifierNotFoundException(identifierId); } - - final Map changes = clientIdentifierForUpdate.update(command); - - if (changes.containsKey("documentTypeId")) { - documentType = this.codeValueRepository.findOneWithNotFoundDetection(documentTypeId); - if (documentType == null) { throw new CodeValueNotFoundException(documentTypeId); } - - documentTypeId = documentType.getId(); - documentTypeLabel = documentType.label(); - clientIdentifierForUpdate.update(documentType); - } - - if (changes.containsKey("documentTypeId") && changes.containsKey("documentKey")) { - documentTypeId = clientIdentifierCommand.getDocumentTypeId(); - documentKey = clientIdentifierCommand.getDocumentKey(); - } else if (changes.containsKey("documentTypeId") && !changes.containsKey("documentKey")) { - documentTypeId = clientIdentifierCommand.getDocumentTypeId(); - documentKey = clientIdentifierForUpdate.documentKey(); - } else if (!changes.containsKey("documentTypeId") && changes.containsKey("documentKey")) { - documentTypeId = clientIdentifierForUpdate.documentTypeId(); - documentKey = clientIdentifierForUpdate.documentKey(); - } - - if (!changes.isEmpty()) { - this.clientIdentifierRepository.saveAndFlush(clientIdentifierForUpdate); - } - - final Client client = this.clientRepository.findOne(clientId); - return new CommandProcessingResultBuilder() // - .withCommandId(command.commandId()) // - .withOfficeId(client.getOffice().getId()) // - .withClientId(clientId) // - .withEntityId(identifierId) // - .with(changes) // - .build(); - } catch (DataIntegrityViolationException dve) { - handleClientIdentifierDataIntegrityViolation(documentTypeLabel, documentTypeId, documentKey, dve); - return new CommandProcessingResult(Long.valueOf(-1)); - } - } - - private void handleClientIdentifierDataIntegrityViolation(final String documentTypeLabel, final Long documentTypeId, - final String documentKey, final DataIntegrityViolationException dve) { - - if (dve.getMostSpecificCause().getMessage().contains("unique_client_identifier")) { - throw new DuplicateClientIdentifierException(documentTypeLabel); - } else if (dve.getMostSpecificCause().getMessage().contains("unique_identifier_key")) { throw new DuplicateClientIdentifierException( - documentTypeId, documentTypeLabel, documentKey); } - - logAsErrorUnexpectedDataIntegrityException(dve); - throw new PlatformDataIntegrityException("error.msg.clientIdentifier.unknown.data.integrity.issue", - "Unknown data integrity issue with resource."); - } - - private void logAsErrorUnexpectedDataIntegrityException(final DataIntegrityViolationException dve) { - logger.error(dve.getMessage(), dve); - } - - @Transactional - @Override - public CommandProcessingResult deleteClientIdentifier(final Long clientId, final Long identifierId, final Long commandId) { - final ClientIdentifier clientIdentifier = this.clientIdentifierRepository.findOne(identifierId); - if (clientIdentifier == null) { throw new ClientIdentifierNotFoundException(identifierId); } - this.clientIdentifierRepository.delete(clientIdentifier); - - final Client client = this.clientRepository.findOne(clientId); - return new CommandProcessingResultBuilder().withCommandId(commandId).withOfficeId(client.getOffice().getId()) - .withClientId(clientId).withEntityId(identifierId).build(); - } - @Transactional @Override public CommandProcessingResult saveOrUpdateClientImage(Long clientId, String imageName, InputStream inputStream) { @@ -393,4 +251,9 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP return new CommandProcessingResult(clientId); } + + private void logAsErrorUnexpectedDataIntegrityException(final DataIntegrityViolationException dve) { + logger.error(dve.getMessage(), dve); + } + } \ No newline at end of file