From 58bbaa2e2b25a0aad984f1d276a21c4dd8fdd54b Mon Sep 17 00:00:00 2001 From: jyothsnag Date: Fri, 12 Aug 2016 15:44:07 +0530 Subject: [PATCH] feature implementation of undoreject and undowithdrawal for client --- api-docs/apiLive.htm | 92 +++++ ...ndoRejectAndWithdrawalIntegrationTest.java | 335 ++++++++++++++++++ .../integrationtests/CurrenciesTest.java | 2 + .../integrationtests/common/ClientHelper.java | 202 ++++++++--- .../service/CommandWrapperBuilder.java | 16 + .../client/api/ClientApiConstants.java | 12 +- .../client/api/ClientsApiResource.java | 14 +- .../client/data/ClientDataValidator.java | 49 +++ .../portfolio/client/domain/Client.java | 50 ++- .../UndoRejectClientCommandHandler.java | 30 ++ .../handler/UndoWithdrawalCommandHandler.java | 30 ++ .../service/ClientWritePlatformService.java | 5 + ...WritePlatformServiceJpaRepositoryImpl.java | 57 ++- .../core_db/V318__client_undoreject.sql | 25 ++ 14 files changed, 865 insertions(+), 54 deletions(-) create mode 100644 fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/ClientUndoRejectAndWithdrawalIntegrationTest.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/client/handler/UndoRejectClientCommandHandler.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/client/handler/UndoWithdrawalCommandHandler.java create mode 100644 fineract-provider/src/main/resources/sql/migrations/core_db/V318__client_undoreject.sql diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm index 4ab7a5cee..6b15e12aa 100644 --- a/api-docs/apiLive.htm +++ b/api-docs/apiLive.htm @@ -220,6 +220,22 @@ + + + clients/{clientId}?command=UndoRejection + UndoReject a Client + + + + + + + clients/{clientId}?command=UndoWithdrawal + UndoWithdrawal Client + + + + clients/{clientId}?command=assignStaff @@ -4962,12 +4978,88 @@ Request Body:
POST https://Domain Name/api/v1/clients/{clientId}?command=reactivate POST clients/1?command=reactivate + Content-Type: application/json Request Body: { "reactivationDate":"28 November 2014", "locale":"en", "dateFormat":"dd MMMM yyyy" +} + + +{ + + "clientId":15, + "resourceId":15 +} + +
+ + +   +
+
+

UndoReject a Client

+

Clients can be reactivated after they have been rejected.

+

Trying to reactivate a client in any other state throws an error.

+ + + + + + + +
Mandatory Fields
reopenedDate
+
+
+
+ POST https://Domain Name/api/v1/clients/{clientId}?command=UndoRejection + POST clients/1?command=UndoRejection + +Content-Type: application/json +Request Body: +{ +"reopenedDate":"28 November 2014", +"locale":"en", +"dateFormat":"dd MMMM yyyy" +} + + +{ + + "clientId":15, + "resourceId":15 +} + +
+
+ +  +
+
+

UndoWithdraw a Client

+

Clients can be reactivated after they have been withdrawn.

+

Trying to reactivate a client in any other state throws an error.

+ + + + + + + +
Mandatory Fields
reopenedDate
+
+
+
+ POST https://Domain Name/api/v1/clients/{clientId}?command=UndoWithdrawal + POST clients/1?command=UndoWithdrawal +Content-Type: application/json +Request Body: +{ +"reopenedDate":"28 November 2014", +"locale":"en", +"dateFormat":"dd MMMM yyyy" } diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/ClientUndoRejectAndWithdrawalIntegrationTest.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/ClientUndoRejectAndWithdrawalIntegrationTest.java new file mode 100644 index 000000000..af3b16b25 --- /dev/null +++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/ClientUndoRejectAndWithdrawalIntegrationTest.java @@ -0,0 +1,335 @@ +package org.apache.fineract.integrationtests; + +import static org.junit.Assert.assertEquals; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.HashMap; +import java.util.Locale; +import java.util.Random; + +import org.apache.fineract.infrastructure.core.data.ApiParameterError; +import org.apache.fineract.integrationtests.common.ClientHelper; +import org.apache.fineract.integrationtests.common.CommonConstants; +import org.apache.fineract.integrationtests.common.Utils; +import org.apache.fineract.integrationtests.common.loans.LoanStatusChecker; +import org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper; +import org.apache.fineract.portfolio.client.api.ClientApiConstants; +import org.apache.fineract.portfolio.client.domain.Client; +import org.apache.fineract.portfolio.client.exception.InvalidClientStateTransitionException; +import org.apache.fineract.useradministration.domain.AppUser; +import org.joda.time.LocalDate; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.google.gson.Gson; +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; + +@SuppressWarnings({ "unused" }) +public class ClientUndoRejectAndWithdrawalIntegrationTest { + + private static final String CREATE_CLIENT_URL = "/fineract-provider/api/v1/clients?" + Utils.TENANT_IDENTIFIER; + public static final String DATE_FORMAT = "dd MMMM yyyy"; + private final String submittedOnDate = "submittedOnDate"; + private final String officeId = "officeId"; + private ResponseSpecification responseSpec; + private RequestSpecification requestSpec; + private ClientHelper clientHelper; + + @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.clientHelper = new ClientHelper(this.requestSpec, this.responseSpec); + } + + @Test + public void clientUndoRejectIntegrationTest() { + + // CREATE CLIENT + this.clientHelper = new ClientHelper(this.requestSpec, this.responseSpec); + final Integer clientId = ClientHelper.createClientPending(this.requestSpec, this.responseSpec); + Assert.assertNotNull(clientId); + + // GET CLIENT STATUS + HashMap status = ClientHelper.getClientStatus(requestSpec, responseSpec, + String.valueOf(clientId)); + + ClientStatusChecker.verifyClientPending(status); + + status = this.clientHelper.rejectClient(clientId); + ClientStatusChecker.verifyClientRejected(status); + + status = this.clientHelper.undoReject(clientId); + ClientStatusChecker.verifyClientPending(status); + + } + + @Test + public void testClientUndoRejectWithDateBeforeRejectDate() { + final ResponseSpecification errorResponse = new ResponseSpecBuilder().expectStatusCode(403).build(); + final ClientHelper validationErrorHelper = new ClientHelper(this.requestSpec, errorResponse); + + // CREATE CLIENT + this.clientHelper = new ClientHelper(this.requestSpec, this.responseSpec); + final Integer clientId = ClientHelper.createClientPending(this.requestSpec, this.responseSpec); + Assert.assertNotNull(clientId); + + // GET CLIENT STATUS + HashMap status = ClientHelper.getClientStatus(requestSpec, responseSpec, + String.valueOf(clientId)); + + ClientStatusChecker.verifyClientPending(status); + + status = this.clientHelper.rejectClient(clientId); + ClientStatusChecker.verifyClientRejected(status); + + ArrayList clientErrorData = (ArrayList) validationErrorHelper.undoRejectedclient(clientId, + CommonConstants.RESPONSE_ERROR, ClientHelper.CREATED_DATE); + assertEquals("error.msg.client.reopened.date.cannot.before.client.rejected.date", + ((HashMap) clientErrorData.get(0)).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE)); + + status = this.clientHelper.undoReject(clientId); + ClientStatusChecker.verifyClientPending(status); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testClientUndoRejectWithoutReject() { + final ResponseSpecification errorResponse = new ResponseSpecBuilder().expectStatusCode(403).build(); + final ClientHelper validationErrorHelper = new ClientHelper(this.requestSpec, errorResponse); + + // CREATE CLIENT + this.clientHelper = new ClientHelper(this.requestSpec, this.responseSpec); + final Integer clientId = ClientHelper.createClientPending(this.requestSpec, this.responseSpec); + Assert.assertNotNull(clientId); + + // GET CLIENT STATUS + HashMap status = ClientHelper.getClientStatus(requestSpec, responseSpec, + String.valueOf(clientId)); + ClientStatusChecker.verifyClientPending(status); + + DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US); + Calendar todaysDate = Calendar.getInstance(); + final String undoRejectDate = dateFormat.format(todaysDate.getTime()); + + ArrayList clientErrorData = (ArrayList) validationErrorHelper.undoRejectedclient(clientId, + CommonConstants.RESPONSE_ERROR, undoRejectDate); + assertEquals("error.msg.client.undorejection.on.nonrejected.account", + ((HashMap) clientErrorData.get(0)).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE)); + + status = this.clientHelper.getClientStatus(requestSpec, responseSpec, String.valueOf(clientId)); + ClientStatusChecker.verifyClientPending(status); + + } + + @Test + public void testClientUndoRejectWithFutureDate() { + + final ResponseSpecification errorResponse = new ResponseSpecBuilder().expectStatusCode(400).build(); + final ClientHelper validationErrorHelper = new ClientHelper(this.requestSpec, errorResponse); + + // CREATE CLIENT + this.clientHelper = new ClientHelper(this.requestSpec, this.responseSpec); + final Integer clientId = ClientHelper.createClientPending(this.requestSpec, this.responseSpec); + Assert.assertNotNull(clientId); + + // GET CLIENT STATUS + HashMap status = ClientHelper.getClientStatus(requestSpec, responseSpec, + String.valueOf(clientId)); + + ClientStatusChecker.verifyClientPending(status); + + status = this.clientHelper.rejectClient(clientId); + ClientStatusChecker.verifyClientRejected(status); + DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US); + Calendar todaysDate = Calendar.getInstance(); + todaysDate.add(Calendar.DATE, 1); + final String undoRejectDate = dateFormat.format(todaysDate.getTime()); + ArrayList clientErrorData = (ArrayList) validationErrorHelper.undoWithdrawclient(clientId, + CommonConstants.RESPONSE_ERROR, undoRejectDate); + assertEquals("validation.msg.client.reopenedDate.is.greater.than.date", + ((HashMap) clientErrorData.get(0)).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE)); + + status = this.clientHelper.undoReject(clientId); + ClientStatusChecker.verifyClientPending(status); + + } + + @Test + public void clientUndoWithDrawnIntegrationTest() { + + // CREATE CLIENT + this.clientHelper = new ClientHelper(this.requestSpec, this.responseSpec); + final Integer clientId = ClientHelper.createClientPending(this.requestSpec, this.responseSpec); + Assert.assertNotNull(clientId); + + // GET CLIENT STATUS + HashMap status = ClientHelper.getClientStatus(requestSpec, responseSpec, + String.valueOf(clientId)); + + ClientStatusChecker.verifyClientPending(status); + + status = this.clientHelper.withdrawClient(clientId); + ClientStatusChecker.verifyClientWithdrawn(status); + + status = this.clientHelper.undoWithdrawn(clientId); + ClientStatusChecker.verifyClientPending(status); + + } + + @Test + public void testClientUndoWithDrawnWithDateBeforeWithdrawal() { + + final ResponseSpecification errorResponse = new ResponseSpecBuilder().expectStatusCode(403).build(); + final ClientHelper validationErrorHelper = new ClientHelper(this.requestSpec, errorResponse); + + // CREATE CLIENT + this.clientHelper = new ClientHelper(this.requestSpec, this.responseSpec); + final Integer clientId = ClientHelper.createClientPending(this.requestSpec, this.responseSpec); + Assert.assertNotNull(clientId); + + // GET CLIENT STATUS + HashMap status = ClientHelper.getClientStatus(requestSpec, responseSpec, + String.valueOf(clientId)); + + ClientStatusChecker.verifyClientPending(status); + + status = this.clientHelper.withdrawClient(clientId); + ClientStatusChecker.verifyClientWithdrawn(status); + + ArrayList clientErrorData = (ArrayList) validationErrorHelper.undoWithdrawclient(clientId, + CommonConstants.RESPONSE_ERROR, ClientHelper.CREATED_DATE); + assertEquals("error.msg.client.reopened.date.cannot.before.client.withdrawal.date", + ((HashMap) clientErrorData.get(0)).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE)); + + status = this.clientHelper.undoWithdrawn(clientId); + ClientStatusChecker.verifyClientPending(status); + + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testClientUndoWithDrawnWithoutWithdrawal() { + final ResponseSpecification errorResponse = new ResponseSpecBuilder().expectStatusCode(403).build(); + final ClientHelper validationErrorHelper = new ClientHelper(this.requestSpec, errorResponse); + // CREATE CLIENT + this.clientHelper = new ClientHelper(this.requestSpec, this.responseSpec); + final Integer clientId = ClientHelper.createClientPending(this.requestSpec, this.responseSpec); + Assert.assertNotNull(clientId); + + // GET CLIENT STATUS + HashMap status = ClientHelper.getClientStatus(requestSpec, responseSpec, + String.valueOf(clientId)); + + DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US); + Calendar todaysDate = Calendar.getInstance(); + final String undoWithdrawDate = dateFormat.format(todaysDate.getTime()); + + ArrayList clientErrorData = (ArrayList) validationErrorHelper.undoWithdrawclient(clientId, + CommonConstants.RESPONSE_ERROR, undoWithdrawDate); + assertEquals("error.msg.client.undoWithdrawal.on.nonwithdrawal.account", + ((HashMap) clientErrorData.get(0)).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE)); + + status = this.clientHelper.getClientStatus(requestSpec, responseSpec, String.valueOf(clientId)); + ClientStatusChecker.verifyClientPending(status); + + } + + @Test + public void testClientUndoWithDrawnWithFutureDate() { + + final ResponseSpecification errorResponse = new ResponseSpecBuilder().expectStatusCode(400).build(); + final ClientHelper validationErrorHelper = new ClientHelper(this.requestSpec, errorResponse); + + // CREATE CLIENT + this.clientHelper = new ClientHelper(this.requestSpec, this.responseSpec); + final Integer clientId = ClientHelper.createClientPending(this.requestSpec, this.responseSpec); + Assert.assertNotNull(clientId); + + // GET CLIENT STATUS + HashMap status = ClientHelper.getClientStatus(requestSpec, responseSpec, + String.valueOf(clientId)); + + ClientStatusChecker.verifyClientPending(status); + + status = this.clientHelper.withdrawClient(clientId); + ClientStatusChecker.verifyClientWithdrawn(status); + DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US); + Calendar todaysDate = Calendar.getInstance(); + todaysDate.add(Calendar.DATE, 1); + final String undoWithdrawDate = dateFormat.format(todaysDate.getTime()); + ArrayList clientErrorData = (ArrayList) validationErrorHelper.undoWithdrawclient(clientId, + CommonConstants.RESPONSE_ERROR, undoWithdrawDate); + assertEquals("validation.msg.client.reopenedDate.is.greater.than.date", + ((HashMap) clientErrorData.get(0)).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE)); + + status = this.clientHelper.undoWithdrawn(clientId); + ClientStatusChecker.verifyClientPending(status); + + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testValidateReopenedDate() { + final ResponseSpecification errorResponse = new ResponseSpecBuilder().expectStatusCode(400).build(); + final ClientHelper validationErrorHelper = new ClientHelper(this.requestSpec, errorResponse); + + // CREATE CLIENT + this.clientHelper = new ClientHelper(this.requestSpec, this.responseSpec); + final Integer clientId = ClientHelper.createClientPending(this.requestSpec, this.responseSpec); + Assert.assertNotNull(clientId); + // GET CLIENT STATUS + HashMap status = ClientHelper.getClientStatus(requestSpec, responseSpec, + String.valueOf(clientId)); + ClientStatusChecker.verifyClientPending(status); + + status = this.clientHelper.withdrawClient(clientId); + ClientStatusChecker.verifyClientWithdrawn(status); + status = this.clientHelper.undoWithdrawn(clientId); + ClientStatusChecker.verifyClientPending(status); + ArrayList clientErrorData = (ArrayList) validationErrorHelper.activateClient(clientId, + CommonConstants.RESPONSE_ERROR); + assertEquals("error.msg.clients.submittedOnDate.after.reopened.date", + ((HashMap) clientErrorData.get(0)).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE)); + + } + + @Test + public void testReopenedDate() { + final ResponseSpecification errorResponse = new ResponseSpecBuilder().expectStatusCode(400).build(); + final ClientHelper validationErrorHelper = new ClientHelper(this.requestSpec, errorResponse); + + // CREATE CLIENT + this.clientHelper = new ClientHelper(this.requestSpec, this.responseSpec); + final Integer clientId = ClientHelper.createClientPending(this.requestSpec, this.responseSpec); + Assert.assertNotNull(clientId); + // GET CLIENT STATUS + HashMap status = ClientHelper.getClientStatus(requestSpec, responseSpec, + String.valueOf(clientId)); + ClientStatusChecker.verifyClientPending(status); + + status = this.clientHelper.withdrawClient(clientId); + ClientStatusChecker.verifyClientWithdrawn(status); + status = this.clientHelper.undoWithdrawn(clientId); + ClientStatusChecker.verifyClientPending(status); + status = this.clientHelper.activateClientWithDiffDateOption(clientId, ClientHelper.CREATED_DATE_PLUS_TWO); + + } + + private static String randomIDGenerator(final String prefix, final int lenOfRandomSuffix) { + return Utils.randomStringGenerator(prefix, lenOfRandomSuffix, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + } + +} diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/CurrenciesTest.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/CurrenciesTest.java index a418c4c59..001486f45 100644 --- a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/CurrenciesTest.java +++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/CurrenciesTest.java @@ -73,6 +73,8 @@ public class CurrenciesTest { currenciestoUpdate.add("LBP"); currenciestoUpdate.add("GHC"); currenciestoUpdate.add("USD"); + currenciestoUpdate.add("INR"); + ArrayList currenciesOutput = CurrenciesHelper.updateSelectedCurrencies(this.requestSpec, this.responseSpec, currenciestoUpdate); diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/ClientHelper.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/ClientHelper.java index fa4624972..ec6ea5251 100755 --- a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/ClientHelper.java +++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/ClientHelper.java @@ -20,6 +20,7 @@ package org.apache.fineract.integrationtests.common; import static org.junit.Assert.assertEquals; +import java.util.ArrayList; import java.util.HashMap; import org.apache.fineract.infrastructure.codes.domain.CodeValue; @@ -41,13 +42,18 @@ public class ClientHelper { private static final String REJECT_CLIENT_COMMAND = "reject"; private static final String ACTIVATE_CLIENT_COMMAND = "activate"; private static final String WITHDRAW_CLIENT_COMMAND = "withdraw"; + private static final String UNDOREJECT_CLIENT_COMMAND = "undoRejection"; + private static final String UNDOWITHDRAWN_CLIENT_COMMAND = "undoWithdrawal"; public static final String CREATED_DATE = "27 November 2014"; public static final String CREATED_DATE_PLUS_ONE = "28 November 2014"; + public static final String CREATED_DATE_PLUS_TWO = "29 November 2014"; + public static final String CREATED_DATE_MINUS_ONE = "27 November 2014"; public static final String TRANSACTION_DATE = "01 March 2013"; public static final String LAST_TRANSACTION_DATE = "01 March 2013"; public static final String DATE_FORMAT = "dd MMMM yyyy"; + public ClientHelper(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) { this.requestSpec = requestSpec; @@ -70,6 +76,26 @@ public class ClientHelper { "clientId"); } + + + public static Integer createClientPending(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) { + return createClientPending(requestSpec, responseSpec, "04 March 2014"); + } + + public static Integer createClientPending(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, + final String submittedOnDate) { + return createClientPending(requestSpec, responseSpec, submittedOnDate, "1"); + } + + public static Integer createClientPending(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, + final String submittedOnDate, final String officeId) { + System.out.println("---------------------------------CREATING A CLIENT IN PENDING---------------------------------------------"); + return Utils.performServerPost(requestSpec, responseSpec, CREATE_CLIENT_URL, getTestClientAsJSONPending(submittedOnDate, officeId), + "clientId"); + } + + + public static Integer createClientAsPerson(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) { return createClientAsPerson(requestSpec, responseSpec, "04 March 2011"); } @@ -138,13 +164,30 @@ public class ClientHelper { map.put("lastname", Utils.randomNameGenerator("Client_LastName_", 4)); map.put("externalId", randomIDGenerator("ID_", 7)); map.put("dateFormat", DATE_FORMAT); - map.put("locale", "en"); - map.put("active", "true"); - map.put("activationDate", dateOfJoining); - System.out.println("map : " + map); - return new Gson().toJson(map); + map.put("locale", "en"); + map.put("active", "true"); + map.put("activationDate", dateOfJoining); + System.out.println("map : " + map); + return new Gson().toJson(map); } + public static String getTestClientAsJSONPending(final String submittedOnDate, final String officeId) { + final HashMap map = new HashMap<>(); + map.put("officeId", officeId); + map.put("firstname", Utils.randomNameGenerator("Client_FirstName_", 5)); + map.put("lastname", Utils.randomNameGenerator("Client_LastName_", 4)); + map.put("externalId", randomIDGenerator("ID_", 7)); + map.put("dateFormat", DATE_FORMAT); + map.put("locale", "en"); + map.put("active", "false"); + map.put("submittedOnDate", submittedOnDate); + System.out.println("map : " + map); + return new Gson().toJson(map); + } + + + + public static String getTestPersonClientAsJSON(final String dateOfJoining, final String officeId) { final HashMap map = new HashMap<>(); map.put("officeId", officeId); @@ -251,49 +294,72 @@ public class ClientHelper { } - private String getReactivateClientAsJSON() { + private String getReactivateClientAsJSON() { + final HashMap map = new HashMap<>(); + map.put("locale", CommonConstants.locale); + map.put("dateFormat", CommonConstants.dateFormat); + map.put("reactivationDate", CREATED_DATE_PLUS_ONE); + String clientJson = new Gson().toJson(map); + System.out.println(clientJson); + return clientJson; + + } + + private String getUndoRejectClientAsJSON(final String date) { + final HashMap map = new HashMap<>(); + map.put("locale", CommonConstants.locale); + map.put("dateFormat", CommonConstants.dateFormat); + map.put("reopenedDate", date); + String clientJson = new Gson().toJson(map); + System.out.println(clientJson); + return clientJson; + + } + + private String getUndoWithdrawnClientAsJSON(final String date) { + final HashMap map = new HashMap<>(); + map.put("locale", CommonConstants.locale); + map.put("dateFormat", CommonConstants.dateFormat); + map.put("reopenedDate", date); + String clientJson = new Gson().toJson(map); + System.out.println(clientJson); + return clientJson; + + } + + private String getRejectClientAsJSON() { + final HashMap map = new HashMap<>(); + /* Retrieve Code id for the Code "ClientRejectReason" */ + String codeName = "ClientRejectReason"; + HashMap code = CodeHelper.getCodeByName(this.requestSpec, this.responseSpec, codeName); + Integer clientRejectionReasonCodeId = (Integer) code.get("id"); + + /* Retrieve/Create Code Values for the Code "ClientRejectReason" */ + HashMap codeValue = CodeHelper.retrieveOrCreateCodeValue(clientRejectionReasonCodeId, + this.requestSpec, this.responseSpec); + Integer rejectionReasonId = (Integer) codeValue.get("id"); + + map.put("locale", CommonConstants.locale); + map.put("dateFormat", CommonConstants.dateFormat); + map.put("rejectionDate", CREATED_DATE_PLUS_ONE); + map.put("rejectionReasonId", rejectionReasonId.toString()); + String clientJson = new Gson().toJson(map); + System.out.println(clientJson); + return clientJson; + + } + + private String getActivateClientAsJSON(String date) { final HashMap map = new HashMap<>(); map.put("locale", CommonConstants.locale); map.put("dateFormat", CommonConstants.dateFormat); - map.put("reactivationDate", CREATED_DATE_PLUS_ONE); + map.put("activationDate", date); String clientJson = new Gson().toJson(map); System.out.println(clientJson); return clientJson; - - } - - private String getRejectClientAsJSON() { - final HashMap map = new HashMap<>(); - /* Retrieve Code id for the Code "ClientRejectReason" */ - String codeName = "ClientRejectReason"; - HashMap code = CodeHelper.getCodeByName(this.requestSpec, this.responseSpec, codeName); - Integer clientRejectionReasonCodeId = (Integer) code.get("id"); - - /* Retrieve/Create Code Values for the Code "ClientRejectReason" */ - HashMap codeValue = CodeHelper.retrieveOrCreateCodeValue(clientRejectionReasonCodeId, this.requestSpec, - this.responseSpec); - Integer rejectionReasonId = (Integer) codeValue.get("id"); - - map.put("locale", CommonConstants.locale); - map.put("dateFormat", CommonConstants.dateFormat); - map.put("rejectionDate", CREATED_DATE_PLUS_ONE); - map.put("rejectionReasonId", rejectionReasonId.toString()); - String clientJson = new Gson().toJson(map); - System.out.println(clientJson); - return clientJson; - - } - - private String getActivateClientAsJSON() { - final HashMap map = new HashMap<>(); - map.put("locale", CommonConstants.locale); - map.put("dateFormat", CommonConstants.dateFormat); - map.put("activationDate", CREATED_DATE_PLUS_ONE); - String clientJson = new Gson().toJson(map); - System.out.println(clientJson); - return clientJson; - } + + private String getWithdrawClientAsJSON() { final HashMap map = new HashMap<>(); @@ -366,7 +432,7 @@ public class ClientHelper { public HashMap activateClient(final Integer clientId) { System.out.println("--------------------------------- ACTIVATE CLIENT -------------------------------"); - return performClientActions(createClientOperationURL(ACTIVATE_CLIENT_COMMAND, clientId), getActivateClientAsJSON(), clientId); + return performClientActions(createClientOperationURL(ACTIVATE_CLIENT_COMMAND, clientId), getActivateClientAsJSON(CREATED_DATE_PLUS_ONE), clientId); } public HashMap withdrawClient(final Integer clientId) { @@ -374,10 +440,56 @@ public class ClientHelper { return performClientActions(createClientOperationURL(WITHDRAW_CLIENT_COMMAND, clientId), getWithdrawClientAsJSON(), clientId); } - private String createClientOperationURL(final String command, final Integer clientId) { - return CLIENT_URL + "/" + clientId + "?command=" + command + "&" + Utils.TENANT_IDENTIFIER; - } + private String createClientOperationURL(final String command, final Integer clientId) { + return CLIENT_URL + "/" + clientId + "?command=" + command + "&" + Utils.TENANT_IDENTIFIER; + } + public HashMap undoReject(final Integer clientId) { + System.out.println("--------------------------------- UNDO REJECT CLIENT -------------------------------"); + return performClientActions(createClientOperationURL(UNDOREJECT_CLIENT_COMMAND, clientId), + getUndoRejectClientAsJSON(CREATED_DATE_PLUS_TWO), clientId); + } + + public HashMap undoWithdrawn(final Integer clientId) { + System.out.println("--------------------------------- UNDO WITHDRAWN CLIENT -------------------------------"); + return performClientActions(createClientOperationURL(UNDOWITHDRAWN_CLIENT_COMMAND, clientId), + getUndoWithdrawnClientAsJSON(CREATED_DATE_PLUS_TWO), clientId); + } + + public Object undoRejectedclient(final Integer clientId, final String jsonAttributeToGetBack, + final String rejectedDate) { + System.out.println("----------------------------------UNDO REJECT CLIENT ----------------------------------"); + return performClientActionsWithValidationErrors(createClientOperationURL(UNDOREJECT_CLIENT_COMMAND, clientId), + getUndoRejectClientAsJSON(rejectedDate), jsonAttributeToGetBack); + } + + public Object undoWithdrawclient(final Integer clientId, final String jsonAttributeToGetBack, + final String rejectedDate) { + System.out.println("----------------------------------UNDO WITHDRAW CLIENT ----------------------------------"); + return performClientActionsWithValidationErrors( + createClientOperationURL(UNDOWITHDRAWN_CLIENT_COMMAND, clientId), + getUndoWithdrawnClientAsJSON(rejectedDate), jsonAttributeToGetBack); + } + + public Object activateClient(final Integer clientId, final String jsonAttributeToGetBack) { + System.out.println("--------------------------------- ACTIVATE CLIENT -------------------------------"); + return performClientActionsWithValidationErrors(createClientOperationURL(ACTIVATE_CLIENT_COMMAND, clientId), + getActivateClientAsJSON(CREATED_DATE_PLUS_ONE), jsonAttributeToGetBack); + } + + public HashMap activateClientWithDiffDateOption(final Integer clientId, + final String activationDate) { + System.out.println("--------------------------------- ACTIVATE CLIENT -------------------------------"); + return performClientActions(createClientOperationURL(ACTIVATE_CLIENT_COMMAND, clientId), + getActivateClientAsJSON(activationDate), clientId); + } + + private ArrayList performClientActionsWithValidationErrors(final String postURLForClient, + final String jsonToBeSent, final String jsonAttributeToGetBack) { + return Utils.performServerPost(this.requestSpec, this.responseSpec, postURLForClient, jsonToBeSent, + jsonAttributeToGetBack); + } + private HashMap performClientActions(final String postURLForClient, final String jsonToBeSent, final Integer clientId) { Utils.performServerPost(this.requestSpec, this.responseSpec, postURLForClient, jsonToBeSent, CommonConstants.RESPONSE_STATUS); HashMap response = ClientHelper.getClientStatus(requestSpec, responseSpec, String.valueOf(clientId)); diff --git a/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java b/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java index 2d678b15d..fa408d69e 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java +++ b/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java @@ -582,6 +582,22 @@ public class CommandWrapperBuilder { this.json = json; return this; } + public CommandWrapperBuilder undoRejection(final Long clientId) { + this.actionName = "UNDOREJECT"; + this.entityName = "CLIENT"; + this.entityId = clientId; + this.clientId = clientId; + this.href = "/clients/" + clientId + "?command=undoRejection"; + return this; + } + public CommandWrapperBuilder undoWithdrawal(final Long clientId) { + this.actionName = "UNDOWITHDRAWAL"; + this.entityName = "CLIENT"; + this.entityId = clientId; + this.clientId = clientId; + this.href = "/clients/" + clientId + "?command=undoWithdrawal"; + return this; + } public CommandWrapperBuilder createDatatable(final String datatable, final Long apptableId, final Long datatableId) { this.actionName = "CREATE"; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientApiConstants.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientApiConstants.java index fb07c0ede..e4f3ef102 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientApiConstants.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientApiConstants.java @@ -91,6 +91,8 @@ public class ClientApiConstants { public static final String staffIdParamName = "staffId"; public static final String closureDateParamName = "closureDate"; public static final String closureReasonIdParamName = "closureReasonId"; + public static final String reopenedDateParamName = "reopenedDate"; + public static final String rejectionDateParamName = "rejectionDate"; public static final String rejectionReasonIdParamName = "rejectionReasonId"; @@ -221,8 +223,14 @@ public class ClientApiConstants { public static final Set CLIENT_REJECT_DATA_PARAMETERS = new HashSet<>( Arrays.asList(localeParamName, dateFormatParamName, rejectionDateParamName, rejectionReasonIdParamName)); - public static final Set CLIENT_WITHDRAW_DATA_PARAMETERS = new HashSet<>( - Arrays.asList(localeParamName, dateFormatParamName, withdrawalDateParamName, withdrawalReasonIdParamName)); + public static final Set CLIENT_WITHDRAW_DATA_PARAMETERS = new HashSet<>( + Arrays.asList(localeParamName, dateFormatParamName, withdrawalDateParamName, withdrawalReasonIdParamName)); + + public static final Set UNDOREJECTION_REQUEST_DATA_PARAMETERS = new HashSet<>( + Arrays.asList(localeParamName, dateFormatParamName, reopenedDateParamName)); + + public static final Set UNDOWITHDRAWN_REQUEST_DATA_PARAMETERS = new HashSet<>( + Arrays.asList(localeParamName, dateFormatParamName, reopenedDateParamName)); public static final Set CLIENT_CHARGES_RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList(chargeIdParamName, clientIdParamName, chargeNameParamName, penaltyParamName, chargeTimeTypeParamName, dueAsOfDateParamName, diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientsApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientsApiResource.java index c46447012..f8bf7a88d 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientsApiResource.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientsApiResource.java @@ -273,10 +273,16 @@ public class ClientsApiResource { } else if (is(commandParam, "withdraw")) { commandRequest = builder.withdrawClient(clientId).build(); result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - } else if (is(commandParam, "reactivate")) { - commandRequest = builder.reActivateClient(clientId).build(); - result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - } + } else if (is(commandParam, "reactivate")) { + commandRequest = builder.reActivateClient(clientId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } else if (is(commandParam, "undoRejection")) { + commandRequest = builder.undoRejection(clientId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } else if (is(commandParam, "undoWithdrawal")) { + commandRequest = builder.undoWithdrawal(clientId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } if (result == null) { throw new UnrecognizedQueryParamException("command", commandParam, new Object[] { "activate", "unassignStaff", "assignStaff", "close", "proposeTransfer", "withdrawTransfer", "acceptTransfer", "rejectTransfer", diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/data/ClientDataValidator.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/data/ClientDataValidator.java index 3ddf911f9..663491659 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/data/ClientDataValidator.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/data/ClientDataValidator.java @@ -720,4 +720,53 @@ public final class ClientDataValidator { throwExceptionIfValidationWarningsExist(dataValidationErrors); } + + + public void validateUndoRejection(final JsonCommand command) { + + final String json = command.json(); + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, ClientApiConstants.UNDOREJECTION_REQUEST_DATA_PARAMETERS); + + final List dataValidationErrors = new ArrayList<>(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors) + .resource(ClientApiConstants.CLIENT_RESOURCE_NAME); + + final JsonElement element = command.parsedJson(); + + final LocalDate undoRejectionDate = this.fromApiJsonHelper.extractLocalDateNamed(ClientApiConstants.reopenedDateParamName, + element); + baseDataValidator.reset().parameter(ClientApiConstants.reopenedDateParamName).value(undoRejectionDate).notNull() + .validateDateBeforeOrEqual(DateUtils.getLocalDateOfTenant()); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + + } + public void validateUndoWithDrawn(final JsonCommand command) { + + final String json = command.json(); + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, ClientApiConstants.UNDOWITHDRAWN_REQUEST_DATA_PARAMETERS); + + final List dataValidationErrors = new ArrayList<>(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors) + .resource(ClientApiConstants.CLIENT_RESOURCE_NAME); + + final JsonElement element = command.parsedJson(); + + final LocalDate undoWithdrawnDate = this.fromApiJsonHelper.extractLocalDateNamed(ClientApiConstants.reopenedDateParamName, + element); + baseDataValidator.reset().parameter(ClientApiConstants.reopenedDateParamName).value(undoWithdrawnDate).notNull() + .validateDateBeforeOrEqual(DateUtils.getLocalDateOfTenant()); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + + } + } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java index 96aafba0a..5210f1894 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java @@ -222,6 +222,14 @@ public final class Client extends AbstractPersistable { @Column(name = "legal_form_enum", nullable = true) private Integer legalForm; + @Column(name = "reopened_on_date", nullable = true) + @Temporal(TemporalType.DATE) + private Date reopenedDate; + + @ManyToOne(optional = true) + @JoinColumn(name = "reopened_by_userid", nullable = true) + private AppUser reopenedBy; + public static Client createNew(final AppUser currentUser, final Office clientOffice, final Group clientParentGroup, final Staff staff, final SavingsProduct savingsProduct, final CodeValue gender, final CodeValue clientType, final CodeValue clientClassification, final Integer legalForm, final JsonCommand command) { @@ -453,7 +461,15 @@ public final class Client extends AbstractPersistable { private boolean isDateInTheFuture(final LocalDate localDate) { return localDate.isAfter(DateUtils.getLocalDateOfTenant()); } - + + public boolean isRejected() { + return ClientStatus.fromInt(this.status).isRejected(); + } + + public boolean isWithdrawn() { + return ClientStatus.fromInt(this.status).isWithdrawn(); + } + public Map update(final JsonCommand command) { final Map actualChanges = new LinkedHashMap<>(9); @@ -644,6 +660,17 @@ public final class Client extends AbstractPersistable { dataValidationErrors.add(error); } + if (getReopenedDate() != null && getActivationLocalDate() != null + && getReopenedDate().isAfter(getActivationLocalDate())) { + + final String defaultUserMessage = "reopened date cannot be after the submittedon date"; + final ApiParameterError error = ApiParameterError.parameterError( + "error.msg.clients.submittedOnDate.after.reopened.date", defaultUserMessage, + ClientApiConstants.reopenedDateParamName, this.reopenedDate); + + dataValidationErrors.add(error); + } + if (getActivationLocalDate() != null && isDateInTheFuture(getActivationLocalDate())) { final String defaultUserMessage = "Activation date cannot be in the future."; @@ -891,8 +918,18 @@ public final class Client extends AbstractPersistable { public LocalDate getClosureDate() { return (LocalDate) ObjectUtils.defaultIfNull(new LocalDate(this.closureDate), null); } + public LocalDate getRejectedDate() { + return (LocalDate) ObjectUtils.defaultIfNull(new LocalDate(this.rejectionDate), null); + } + public LocalDate getWithdrawalDate() { + return (LocalDate) ObjectUtils.defaultIfNull(new LocalDate(this.withdrawalDate), null); + } - public CodeValue gender() { + public LocalDate getReopenedDate() { + return this.reopenedDate == null ? null : new LocalDate(this.reopenedDate); + } + + public CodeValue gender() { return this.gender; } @@ -958,6 +995,15 @@ public final class Client extends AbstractPersistable { this.status = ClientStatus.PENDING.getValue(); } + + public void reOpened(AppUser currentUser, Date reopenedDate) { + this.reopenedDate = reopenedDate; + this.reopenedBy = currentUser; + this.updatedBy = currentUser; + this.updatedOnDate = reopenedDate; + this.status = ClientStatus.PENDING.getValue(); + + } public Integer getLegalForm() { return legalForm; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/handler/UndoRejectClientCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/handler/UndoRejectClientCommandHandler.java new file mode 100644 index 000000000..2dee42e77 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/handler/UndoRejectClientCommandHandler.java @@ -0,0 +1,30 @@ +package org.apache.fineract.portfolio.client.handler; + + +import org.apache.fineract.commands.annotation.CommandType; +import org.apache.fineract.commands.handler.NewCommandSourceHandler; +import org.apache.fineract.infrastructure.core.api.JsonCommand; +import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; +import org.apache.fineract.portfolio.client.service.ClientWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@CommandType(entity = "CLIENT", action = "UNDOREJECT") +public class UndoRejectClientCommandHandler implements NewCommandSourceHandler { + + private final ClientWritePlatformService clientWritePlatformService; + + @Autowired + public UndoRejectClientCommandHandler(final ClientWritePlatformService clientWritePlatformService) { + this.clientWritePlatformService = clientWritePlatformService; + } + + @Transactional + @Override + public CommandProcessingResult processCommand(final JsonCommand command) { + + return this.clientWritePlatformService.undoRejection(command.entityId(), command); + } +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/handler/UndoWithdrawalCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/handler/UndoWithdrawalCommandHandler.java new file mode 100644 index 000000000..a3c91637f --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/handler/UndoWithdrawalCommandHandler.java @@ -0,0 +1,30 @@ +package org.apache.fineract.portfolio.client.handler; +import org.apache.fineract.commands.annotation.CommandType; +import org.apache.fineract.commands.handler.NewCommandSourceHandler; +import org.apache.fineract.infrastructure.core.api.JsonCommand; +import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; +import org.apache.fineract.portfolio.client.service.ClientWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@CommandType(entity = "CLIENT", action = "UNDOWITHDRAWAL") +public class UndoWithdrawalCommandHandler implements NewCommandSourceHandler { + + private final ClientWritePlatformService clientWritePlatformService; + + @Autowired + public UndoWithdrawalCommandHandler(final ClientWritePlatformService clientWritePlatformService) { + this.clientWritePlatformService = clientWritePlatformService; + } + + @Transactional + @Override + public CommandProcessingResult processCommand(final JsonCommand command) { + + return this.clientWritePlatformService.undoWithdrawal(command.entityId(), command); + } +} + + diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformService.java index 30f721397..c520aff1a 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformService.java @@ -45,4 +45,9 @@ public interface ClientWritePlatformService { CommandProcessingResult reActivateClient(Long entityId, JsonCommand command); + CommandProcessingResult undoRejection(Long entityId, JsonCommand command); + + CommandProcessingResult undoWithdrawal(Long entityId, JsonCommand command); + + } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java index 038c46d78..5781082eb 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java @@ -844,4 +844,59 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP .withEntityId(entityId) // .build(); } -} \ No newline at end of file + + @Override + public CommandProcessingResult undoRejection(Long entityId, JsonCommand command) { + final AppUser currentUser = this.context.authenticatedUser(); + this.fromApiJsonDeserializer.validateUndoRejection(command); + + final Client client = this.clientRepository.findOneWithNotFoundDetection(entityId); + final LocalDate undoRejectDate = command + .localDateValueOfParameterNamed(ClientApiConstants.reopenedDateParamName); + + if (!client.isRejected()) { + final String errorMessage = "only rejected clients may be reactivated."; + throw new InvalidClientStateTransitionException("undorejection", "on.nonrejected.account", errorMessage); + } else if (client.getRejectedDate().isAfter(undoRejectDate)) { + final String errorMessage = "The client reactivation date cannot be before the client rejected date."; + throw new InvalidClientStateTransitionException("reopened", "date.cannot.before.client.rejected.date", + errorMessage, undoRejectDate, client.getRejectedDate()); + } + + client.reOpened(currentUser, undoRejectDate.toDate()); + this.clientRepository.saveAndFlush(client); + + return new CommandProcessingResultBuilder() // + .withCommandId(command.commandId()) // + .withClientId(entityId) // + .withEntityId(entityId) // + .build(); + } + + @Override + public CommandProcessingResult undoWithdrawal(Long entityId, JsonCommand command) { + final AppUser currentUser = this.context.authenticatedUser(); + this.fromApiJsonDeserializer.validateUndoWithDrawn(command); + + final Client client = this.clientRepository.findOneWithNotFoundDetection(entityId); + final LocalDate undoWithdrawalDate = command + .localDateValueOfParameterNamed(ClientApiConstants.reopenedDateParamName); + + if (!client.isWithdrawn()) { + final String errorMessage = "only withdrawal clients may be reactivated."; + throw new InvalidClientStateTransitionException("undoWithdrawal", "on.nonwithdrawal.account", errorMessage); + } else if (client.getWithdrawalDate().isAfter(undoWithdrawalDate)) { + final String errorMessage = "The client reactivation date cannot be before the client withdrawal date."; + throw new InvalidClientStateTransitionException("reopened", "date.cannot.before.client.withdrawal.date", + errorMessage, undoWithdrawalDate, client.getWithdrawalDate()); + } + client.reOpened(currentUser, undoWithdrawalDate.toDate()); + this.clientRepository.saveAndFlush(client); + + return new CommandProcessingResultBuilder() // + .withCommandId(command.commandId()) // + .withClientId(entityId) // + .withEntityId(entityId) // + .build(); + } +} diff --git a/fineract-provider/src/main/resources/sql/migrations/core_db/V318__client_undoreject.sql b/fineract-provider/src/main/resources/sql/migrations/core_db/V318__client_undoreject.sql new file mode 100644 index 000000000..6f3cccd95 --- /dev/null +++ b/fineract-provider/src/main/resources/sql/migrations/core_db/V318__client_undoreject.sql @@ -0,0 +1,25 @@ +-- +-- Licensed to the Apache Software Foundation (ASF) under one +-- or more contributor license agreements. See the NOTICE file +-- distributed with this work for additional information +-- regarding copyright ownership. The ASF licenses this file +-- to you under the Apache License, Version 2.0 (the +-- "License"); you may not use this file except in compliance +-- with the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, +-- software distributed under the License is distributed on an +-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +-- KIND, either express or implied. See the License for the +-- specific language governing permissions and limitations +-- under the License. +-- + +ALTER TABLE `m_client` + ADD COLUMN `reopened_on_date` DATE NULL AFTER `legal_form_enum`, + ADD COLUMN `reopened_by_userid` BIGINT NULL AFTER `reopened_on_date`; + +INSERT INTO `m_permission` ( `grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'UNDOREJECT_CLIENT', 'CLIENT', 'UNDOREJECT', 1), +('portfolio', 'UNDOREJECT_CLIENT_CHECKER', 'CLIENT', 'UNDOREJECT_CHECKER', 1),('portfolio', 'UNDOWITHDRAWAL_CLIENT', 'CLIENT', 'UNDOWITHDRAWAL', 1),('portfolio', 'UNDOWITHDRAWAL_CLIENT_CHECKER', 'CLIENT', 'UNDOWITHDRAWAL_CHECKER', 1);