From ef43647a105ab783e1ca7869fdb23882b3768eae Mon Sep 17 00:00:00 2001 From: rishy Date: Wed, 25 Jun 2014 11:59:59 +0530 Subject: [PATCH] added ApplySavings command --- .../integrationtests/BatchApiTest.java | 47 ++++++++++++- .../integrationtests/common/BatchHelper.java | 34 ++++++++-- .../batch/api/BatchApiResource.java | 10 ++- .../command/CommandStrategyProvider.java | 1 + .../internal/ApplyLoanCommandStrategy.java | 4 +- .../internal/ApplySavingsCommandStrategy.java | 67 +++++++++++++++++++ .../internal/CreateClientCommandStrategy.java | 4 +- .../internal/UpdateClientCommandStrategy.java | 4 +- .../batch/exception/ErrorHandler.java | 8 ++- .../batch/service/BatchApiServiceImpl.java | 2 +- 10 files changed, 161 insertions(+), 20 deletions(-) create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/batch/command/internal/ApplySavingsCommandStrategy.java diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/BatchApiTest.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/BatchApiTest.java index 40a31b022..2a2f16c6e 100644 --- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/BatchApiTest.java +++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/BatchApiTest.java @@ -13,6 +13,7 @@ import org.mifosplatform.integrationtests.common.BatchHelper; import org.mifosplatform.integrationtests.common.Utils; import org.mifosplatform.integrationtests.common.loans.LoanProductTestBuilder; import org.mifosplatform.integrationtests.common.loans.LoanTransactionHelper; +import org.mifosplatform.integrationtests.common.savings.SavingsProductHelper; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -191,7 +192,7 @@ public class BatchApiTest { .withInterestTypeAsDecliningBalance() // .currencyDetails("0", "100").build(null); - Integer productId = new LoanTransactionHelper(this.requestSpec, this.responseSpec) + final Integer productId = new LoanTransactionHelper(this.requestSpec, this.responseSpec) .getLoanProductId(loanProductJSON); //Create a createClient Request @@ -217,4 +218,48 @@ public class BatchApiTest { Assert.assertEquals("Loan Successfully applied to client " + clientId.getAsString(), 200L, (long) response.get(1).getStatusCode()); } + + /** + * Tests that a new savings accounts was applied to an existing client and a + * 200(OK) status was returned. It first creates a new client and a savings product, + * then uses the cliendId and ProductId to apply a savings account. + * + * @see org.mifosplatform.batch.command.internal.ApplySavingsCommandStrategy + */ + @Test + public void shouldReturnOkStatusForApplySavingsCommand(){ + + final SavingsProductHelper savingsProductHelper = new SavingsProductHelper(); + final String savingsProductJSON = savingsProductHelper // + .withInterestCompoundingPeriodTypeAsDaily() // + .withInterestPostingPeriodTypeAsMonthly() // + .withInterestCalculationPeriodTypeAsDailyBalance() // + .withMinimumOpenningBalance("5000").build(); + + final Integer productId = SavingsProductHelper.createSavingsProduct(savingsProductJSON, + this.requestSpec, this.responseSpec); + + //Create a createClient Request + final BatchRequest br1 = BatchHelper.createClientRequest(4720L, ""); + + //Create a applySavings Request + final BatchRequest br2 = BatchHelper.applySavingsRequest(4721L, 4720L, productId); + + final List batchRequests = new ArrayList<>(); + + batchRequests.add(br1); + batchRequests.add(br2); + + final String jsonifiedRequest = BatchHelper.toJsonString(batchRequests); + + final List response = BatchHelper.postBatchRequestsWithoutEnclosingTransaction(this.requestSpec, + this.responseSpec, jsonifiedRequest); + + //Get the clientId parameter from createClient Response + final JsonElement clientId = new FromJsonHelper().parse(response.get(0).getBody()) + .getAsJsonObject().get("clientId"); + + Assert.assertEquals("Savings Successfully applied to client " + clientId.getAsString(), + 200L, (long) response.get(1).getStatusCode()); + } } \ No newline at end of file diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/BatchHelper.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/BatchHelper.java index f58e12ce6..ee4c99d38 100644 --- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/BatchHelper.java +++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/BatchHelper.java @@ -52,7 +52,7 @@ public class BatchHelper { /** - * Returns a list of BatchResponse with query paramater enclosing transaction set to + * Returns a list of BatchResponse with query parameter enclosing transaction set to * false by posting the jsonified BatchRequest to the server. * * @param requestSpec @@ -67,7 +67,7 @@ public class BatchHelper { } /** - * Returns a list of BatchResponse with query paramater enclosing transaction set to + * Returns a list of BatchResponse with query parameter enclosing transaction set to * true by posting the jsonified BatchRequest to the server. * * @param requestSpec @@ -164,9 +164,10 @@ public class BatchHelper { * * @param requestId * @param reference + * @param productId * @return BatchRequest */ - public static BatchRequest applyLoanRequest(final Long requestId, final Long reference, + public static BatchRequest applyLoanRequest(final Long requestId, final Long reference, final Integer productId) { final BatchRequest br = new BatchRequest(); @@ -176,7 +177,6 @@ public class BatchHelper { br.setMethod("POST"); br.setReference(reference); - //NOTE: Set the value productId according to your db else will result in a '404' response final String body = "{\"dateFormat\": \"dd MMMM yyyy\", \"locale\": \"en_GB\", \"clientId\": \"$.clientId\"," + "\"productId\": "+productId+", \"principal\": \"10,000.00\", \"loanTermFrequency\": 12," + "\"loanTermFrequencyType\": 2, \"loanType\": \"individual\", \"numberOfRepayments\": 10," + @@ -189,6 +189,32 @@ public class BatchHelper { return br; } + /** + * Creates and returns a {@link org.mifosplatform.batch.command.internal.ApplySavingsCommandStrategy} + * Request with given requestId and reference. + * + * @param requestId + * @param reference + * @param productId + * @return BatchRequest + */ + public static BatchRequest applySavingsRequest(final Long requestId, final Long reference, + final Integer productId){ + + final BatchRequest br = new BatchRequest(); + + br.setRequestId(requestId); + br.setRelativeUrl("savingsaccounts"); + br.setMethod("POST"); + br.setReference(reference); + + final String body = "{\"clientId\": \"$.clientId\", \"productId\": "+productId+ "," + + "\"locale\": \"en\", \"dateFormat\": \"dd MMMM yyyy\", \"submittedOnDate\": \"01 March 2011\"}"; + br.setBody(body); + + return br; + } + /** * Checks that the client with given externalId is not created on the server. * diff --git a/mifosng-provider/src/main/java/org/mifosplatform/batch/api/BatchApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/batch/api/BatchApiResource.java index 6f80daeb4..c61b0e57c 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/batch/api/BatchApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/batch/api/BatchApiResource.java @@ -13,6 +13,8 @@ import javax.ws.rs.core.MediaType; import org.mifosplatform.batch.domain.BatchRequest; import org.mifosplatform.batch.domain.BatchResponse; +import org.mifosplatform.batch.exception.ErrorHandler; +import org.mifosplatform.batch.exception.ErrorInfo; import org.mifosplatform.batch.serialization.BatchRequestJsonHelper; import org.mifosplatform.batch.service.BatchApiService; import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer; @@ -96,9 +98,11 @@ public class BatchApiResource { BatchResponse response = new BatchResponse(); - response.setStatusCode(400); - response.setBody("One or more of your requests couldn't be completed because of errors" + - " - Rolling back the whole transaction\n\n" + e.toString()); + //Gets an object of type ErrorInfo, containing information about raised exception + ErrorInfo ex = ErrorHandler.handler(e); + + response.setStatusCode(ex.getStatusCode()); + response.setBody(ex.getMessage()); result.add(response); return this.toApiJsonSerializer.serialize(result); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/batch/command/CommandStrategyProvider.java b/mifosng-provider/src/main/java/org/mifosplatform/batch/command/CommandStrategyProvider.java index c53f3e76c..94ac2783a 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/batch/command/CommandStrategyProvider.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/batch/command/CommandStrategyProvider.java @@ -70,6 +70,7 @@ public class CommandStrategyProvider { this.commandStrategies.put(CommandContext.resource("clients").method("POST").build(), "createClientCommandStrategy"); this.commandStrategies.put(CommandContext.resource("clients\\/\\d+").method("PUT").build(), "updateClientCommandStrategy"); this.commandStrategies.put(CommandContext.resource("loans").method("POST").build(), "applyLoanCommandStrategy"); + this.commandStrategies.put(CommandContext.resource("savingsaccounts").method("POST").build(), "applySavingsCommandStrategy"); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/batch/command/internal/ApplyLoanCommandStrategy.java b/mifosng-provider/src/main/java/org/mifosplatform/batch/command/internal/ApplyLoanCommandStrategy.java index 463c68bc5..5eda17a55 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/batch/command/internal/ApplyLoanCommandStrategy.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/batch/command/internal/ApplyLoanCommandStrategy.java @@ -9,8 +9,6 @@ import org.mifosplatform.portfolio.loanaccount.api.LoansApiResource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.google.gson.Gson; - /** * Implements {@link org.mifosplatform.batch.command.CommandStrategy} and applies a new loan * on an existing client. It passes the contents of the body from the BatchRequest @@ -61,7 +59,7 @@ public class ApplyLoanCommandStrategy implements CommandStrategy{ ErrorInfo ex = ErrorHandler.handler(e); response.setStatusCode(ex.getStatusCode()); - response.setBody(new Gson().toJson(ex)); + response.setBody(ex.getMessage()); } return response; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/batch/command/internal/ApplySavingsCommandStrategy.java b/mifosng-provider/src/main/java/org/mifosplatform/batch/command/internal/ApplySavingsCommandStrategy.java new file mode 100644 index 000000000..fe4290c58 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/batch/command/internal/ApplySavingsCommandStrategy.java @@ -0,0 +1,67 @@ +package org.mifosplatform.batch.command.internal; + +import org.mifosplatform.batch.command.CommandStrategy; +import org.mifosplatform.batch.domain.BatchRequest; +import org.mifosplatform.batch.domain.BatchResponse; +import org.mifosplatform.batch.exception.ErrorHandler; +import org.mifosplatform.batch.exception.ErrorInfo; +import org.mifosplatform.portfolio.savings.api.SavingsAccountsApiResource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * Implements {@link org.mifosplatform.batch.command.CommandStrategy} and applies a new savings + * on an existing client. It passes the contents of the body from the BatchRequest + * to {@link org.mifosplatform.portfolio.client.api.SavingsAccountsApiResource} and gets back + * the response. This class will also catch any errors raised by + * {@link org.mifosplatform.portfolio.client.api.SavingsAccountsApiResource} and map those errors + * to appropriate status codes in BatchResponse. + * + * @author Rishabh Shukla + * + * @see org.mifosplatform.batch.command.CommandStrategy + * @see org.mifosplatform.batch.domain.BatchRequest + * @see org.mifosplatform.batch.domain.BatchResponse + */ +@Component +public class ApplySavingsCommandStrategy implements CommandStrategy{ + + private final SavingsAccountsApiResource savingsAccountsApiResource; + + @Autowired + public ApplySavingsCommandStrategy(final SavingsAccountsApiResource savingsAccountsApiResource) { + this.savingsAccountsApiResource = savingsAccountsApiResource; + } + + @Override + public BatchResponse execute(BatchRequest request) { + + final BatchResponse response = new BatchResponse(); + final String responseBody; + + response.setRequestId(request.getRequestId()); + response.setHeaders(request.getHeaders()); + + //Try-catch blocks to map exceptions to appropriate status codes + try { + + //Calls 'submitApplication' function from 'SavingsAccountsApiResource' to Apply Savings to an existing client + responseBody = savingsAccountsApiResource.submitApplication(request.getBody()); + + response.setStatusCode(200); + //Sets the body of the response after savings is successfully applied + response.setBody(responseBody); + + } + catch (RuntimeException e) { + + //Gets an object of type ErrorInfo, containing information about raised exception + ErrorInfo ex = ErrorHandler.handler(e); + + response.setStatusCode(ex.getStatusCode()); + response.setBody(ex.getMessage()); + } + + return response; + } +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/batch/command/internal/CreateClientCommandStrategy.java b/mifosng-provider/src/main/java/org/mifosplatform/batch/command/internal/CreateClientCommandStrategy.java index 913c0a926..5d126d8fd 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/batch/command/internal/CreateClientCommandStrategy.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/batch/command/internal/CreateClientCommandStrategy.java @@ -9,8 +9,6 @@ import org.mifosplatform.portfolio.client.api.ClientsApiResource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.google.gson.Gson; - /** * Implements {@link org.mifosplatform.batch.command.CommandStrategy} to handle * creation of a new client. It passes the contents of the body from the BatchRequest @@ -61,7 +59,7 @@ public class CreateClientCommandStrategy implements CommandStrategy{ ErrorInfo ex = ErrorHandler.handler(e); response.setStatusCode(ex.getStatusCode()); - response.setBody(new Gson().toJson(ex)); + response.setBody(ex.getMessage()); } return response; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/batch/command/internal/UpdateClientCommandStrategy.java b/mifosng-provider/src/main/java/org/mifosplatform/batch/command/internal/UpdateClientCommandStrategy.java index 1bb9532c2..d8469b047 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/batch/command/internal/UpdateClientCommandStrategy.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/batch/command/internal/UpdateClientCommandStrategy.java @@ -9,8 +9,6 @@ import org.mifosplatform.portfolio.client.api.ClientsApiResource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.google.gson.Gson; - /** * Implements {@link org.mifosplatform.batch.command.CommandStrategy} and updates the * information of an existing client. It passes the contents of the body from the BatchRequest @@ -64,7 +62,7 @@ public class UpdateClientCommandStrategy implements CommandStrategy { ErrorInfo ex = ErrorHandler.handler(e); response.setStatusCode(ex.getStatusCode()); - response.setBody(new Gson().toJson(ex)); + response.setBody(ex.getMessage()); } return response; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/batch/exception/ErrorHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/batch/exception/ErrorHandler.java index acd43abce..ec49da4e9 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/batch/exception/ErrorHandler.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/batch/exception/ErrorHandler.java @@ -4,6 +4,7 @@ import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceN import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException; import org.mifosplatform.infrastructure.core.exception.UnsupportedParameterException; +import org.springframework.transaction.TransactionException; /** * Provides an Error Handler method that returns an object of type {@link ErrorInfo} @@ -35,14 +36,17 @@ public class ErrorHandler extends RuntimeException{ public static ErrorInfo handler(RuntimeException exception) { if(exception instanceof AbstractPlatformResourceNotFoundException) { - return new ErrorInfo(404, 1001, "Requested Resource was not Found"); + return new ErrorInfo(404, 1001, "Requested Resource was not Found: Check for any unavailable Parameters"); } else if(exception instanceof UnsupportedParameterException) { return new ErrorInfo(400, 2001, "UnsupportedParameterException: Check for any unsupported Parameters"); } else if(exception instanceof PlatformApiDataValidationException) { return new ErrorInfo(400, 2002, "ApiDataValidationException: Re-Check the input data"); } else if(exception instanceof PlatformDataIntegrityException) { return new ErrorInfo(403, 3001, "DataIntegrityException: Check for any duplicate data"); - } + } else if(exception instanceof TransactionException) { + return new ErrorInfo(400, 4001, "TransactionException: One or more of your requests were unsuccessful," + + " reverting back all the transactions in this Batch Request"); + } return new ErrorInfo(500, 9999, "Internal Server Error"); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/batch/service/BatchApiServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/batch/service/BatchApiServiceImpl.java index ce6c2ae08..5b4a83f76 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/batch/service/BatchApiServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/batch/service/BatchApiServiceImpl.java @@ -91,7 +91,7 @@ public class BatchApiServiceImpl implements BatchApiService{ //Some detail information about the error final ErrorInfo conflictError = new ErrorInfo(Status.CONFLICT.getStatusCode(), 8001, "Parent request with id " + parentResponse.getRequestId() + " was erroneous!"); - response.setBody(new Gson().toJson(conflictError)); + response.setBody(conflictError.getMessage()); responseList.add(response); //Proceed with next list entry