This is an automated email from the ASF dual-hosted git repository.

myrle pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-customer.git

commit 3771232db0ed19ec1b05a24fcce78f4270c4a1fa
Author: mgeiss <[email protected]>
AuthorDate: Thu Jun 29 18:07:15 2017 +0200

    added process steps to fetch actions based on customer state
---
 .../customer/api/v1/client/CustomerManager.java    | 12 ++++-
 .../io/mifos/customer/api/v1/domain/Command.java   |  4 +-
 .../mifos/customer/api/v1/domain/ProcessStep.java  | 31 +++++++++---
 .../main/java/io/mifos/customer/TestCustomer.java  | 45 +++++++++++++++++
 .../repository/TaskInstanceRepository.java         |  3 ++
 .../service/internal/service/CustomerService.java  | 59 +++++++++++++++++++++-
 .../rest/controller/CustomerRestController.java    | 59 ++++++++++------------
 7 files changed, 170 insertions(+), 43 deletions(-)

diff --git 
a/api/src/main/java/io/mifos/customer/api/v1/client/CustomerManager.java 
b/api/src/main/java/io/mifos/customer/api/v1/client/CustomerManager.java
index 4634868..bac6bcb 100644
--- a/api/src/main/java/io/mifos/customer/api/v1/client/CustomerManager.java
+++ b/api/src/main/java/io/mifos/customer/api/v1/client/CustomerManager.java
@@ -25,6 +25,7 @@ import io.mifos.customer.api.v1.domain.ContactDetail;
 import io.mifos.customer.api.v1.domain.IdentificationCard;
 import io.mifos.customer.api.v1.domain.Customer;
 import io.mifos.customer.api.v1.domain.CustomerPage;
+import io.mifos.customer.api.v1.domain.ProcessStep;
 import io.mifos.customer.api.v1.domain.TaskDefinition;
 import org.springframework.cloud.netflix.feign.FeignClient;
 import org.springframework.http.HttpStatus;
@@ -144,7 +145,7 @@ public interface CustomerManager {
   )
   @ThrowsException(status = HttpStatus.NOT_FOUND, exception = 
TaskNotFoundException.class)
   List<TaskDefinition> findTasksForCustomer(@PathVariable("identifier") final 
String identifier,
-                                          @RequestParam(value = 
"includeExecuted", required = false) final Boolean includeExecuted);
+                                            @RequestParam(value = 
"includeExecuted", required = false) final Boolean includeExecuted);
 
   @RequestMapping(
       value = "/customers/{identifier}/address",
@@ -302,4 +303,13 @@ public interface CustomerManager {
       @ThrowsException(status = HttpStatus.BAD_REQUEST, exception = 
TaskValidationException.class)
   })
   void updateTask(@PathVariable("identifier") final String identifier, 
@RequestBody final TaskDefinition taskDefinition);
+
+  @RequestMapping(
+      value = "/customer/{identifier}/actions",
+      method = RequestMethod.GET,
+      produces = MediaType.ALL_VALUE,
+      consumes = MediaType.APPLICATION_JSON_VALUE
+  )
+  @ThrowsException(status = HttpStatus.NOT_FOUND, exception = 
CustomerNotFoundException.class)
+  List<ProcessStep> fetchProcessSteps(@PathVariable(value = "identifier") 
final String customerIdentifier);
 }
diff --git a/api/src/main/java/io/mifos/customer/api/v1/domain/Command.java 
b/api/src/main/java/io/mifos/customer/api/v1/domain/Command.java
index 82e2481..6981ee8 100644
--- a/api/src/main/java/io/mifos/customer/api/v1/domain/Command.java
+++ b/api/src/main/java/io/mifos/customer/api/v1/domain/Command.java
@@ -15,7 +15,7 @@
  */
 package io.mifos.customer.api.v1.domain;
 
-import org.hibernate.validator.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
 
 public final class Command {
 
@@ -27,7 +27,7 @@ public final class Command {
     REOPEN
   }
 
-  @NotBlank
+  @NotNull
   private Action action;
   private String comment;
   private String createdOn;
diff --git 
a/service/src/main/java/io/mifos/customer/service/internal/repository/TaskInstanceRepository.java
 b/api/src/main/java/io/mifos/customer/api/v1/domain/ProcessStep.java
similarity index 53%
copy from 
service/src/main/java/io/mifos/customer/service/internal/repository/TaskInstanceRepository.java
copy to api/src/main/java/io/mifos/customer/api/v1/domain/ProcessStep.java
index d8e45d2..622f41e 100644
--- 
a/service/src/main/java/io/mifos/customer/service/internal/repository/TaskInstanceRepository.java
+++ b/api/src/main/java/io/mifos/customer/api/v1/domain/ProcessStep.java
@@ -13,15 +13,32 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package io.mifos.customer.service.internal.repository;
-
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.stereotype.Repository;
+package io.mifos.customer.api.v1.domain;
 
 import java.util.List;
 
-@Repository
-public interface TaskInstanceRepository extends 
JpaRepository<TaskInstanceEntity, Long> {
+public class ProcessStep {
+
+  private Command command;
+  private List<TaskDefinition> taskDefinitions;
+
+  public ProcessStep() {
+    super();
+  }
+
+  public Command getCommand() {
+    return this.command;
+  }
+
+  public void setCommand(final Command command) {
+    this.command = command;
+  }
+
+  public List<TaskDefinition> getTaskDefinitions() {
+    return this.taskDefinitions;
+  }
 
-  List<TaskInstanceEntity> findByCustomer(final CustomerEntity customer);
+  public void setTaskDefinitions(final List<TaskDefinition> taskDefinitions) {
+    this.taskDefinitions = taskDefinitions;
+  }
 }
diff --git a/component-test/src/main/java/io/mifos/customer/TestCustomer.java 
b/component-test/src/main/java/io/mifos/customer/TestCustomer.java
index 58ce486..83e0152 100644
--- a/component-test/src/main/java/io/mifos/customer/TestCustomer.java
+++ b/component-test/src/main/java/io/mifos/customer/TestCustomer.java
@@ -568,4 +568,49 @@ public class TestCustomer {
 
     this.customerManager.getPortrait(customer.getIdentifier());
   }
+
+  @Test
+  public void shouldReturnAvailableProcessSteps() throws Exception {
+    final Customer customer = CustomerGenerator.createRandomCustomer();
+
+    this.customerManager.createCustomer(customer);
+
+    this.eventRecorder.wait(CustomerEventConstants.POST_CUSTOMER, 
customer.getIdentifier());
+
+    final List<ProcessStep> pendingProcessSteps = 
this.customerManager.fetchProcessSteps(customer.getIdentifier());
+    Assert.assertEquals(2, pendingProcessSteps.size());
+    Assert.assertEquals(Command.Action.ACTIVATE.name(), 
pendingProcessSteps.get(0).getCommand().getAction());
+    Assert.assertEquals(Command.Action.CLOSE.name(), 
pendingProcessSteps.get(1).getCommand().getAction());
+
+    this.customerManager.customerCommand(customer.getIdentifier(), 
CommandGenerator.create(Command.Action.ACTIVATE, "Test"));
+    this.eventRecorder.wait(CustomerEventConstants.ACTIVATE_CUSTOMER, 
customer.getIdentifier());
+
+    final List<ProcessStep> activeProcessSteps = 
this.customerManager.fetchProcessSteps(customer.getIdentifier());
+    Assert.assertEquals(2, activeProcessSteps.size());
+    Assert.assertEquals(Command.Action.LOCK.name(), 
activeProcessSteps.get(0).getCommand().getAction());
+    Assert.assertEquals(Command.Action.CLOSE.name(), 
activeProcessSteps.get(1).getCommand().getAction());
+
+    this.customerManager.customerCommand(customer.getIdentifier(), 
CommandGenerator.create(Command.Action.LOCK, "Test"));
+    this.eventRecorder.wait(CustomerEventConstants.LOCK_CUSTOMER, 
customer.getIdentifier());
+
+    final List<ProcessStep> lockedProcessSteps = 
this.customerManager.fetchProcessSteps(customer.getIdentifier());
+    Assert.assertEquals(2, lockedProcessSteps.size());
+    Assert.assertEquals(Command.Action.UNLOCK.name(), 
lockedProcessSteps.get(0).getCommand().getAction());
+    Assert.assertEquals(Command.Action.CLOSE.name(), 
lockedProcessSteps.get(1).getCommand().getAction());
+
+    this.customerManager.customerCommand(customer.getIdentifier(), 
CommandGenerator.create(Command.Action.UNLOCK, "Test"));
+    this.eventRecorder.wait(CustomerEventConstants.UNLOCK_CUSTOMER, 
customer.getIdentifier());
+
+    final List<ProcessStep> unlockedProcessSteps = 
this.customerManager.fetchProcessSteps(customer.getIdentifier());
+    Assert.assertEquals(2, unlockedProcessSteps.size());
+    Assert.assertEquals(Command.Action.LOCK.name(), 
unlockedProcessSteps.get(0).getCommand().getAction());
+    Assert.assertEquals(Command.Action.CLOSE.name(), 
unlockedProcessSteps.get(1).getCommand().getAction());
+
+    this.customerManager.customerCommand(customer.getIdentifier(), 
CommandGenerator.create(Command.Action.CLOSE, "Test"));
+    this.eventRecorder.wait(CustomerEventConstants.CLOSE_CUSTOMER, 
customer.getIdentifier());
+
+    final List<ProcessStep> closedProcessSteps = 
this.customerManager.fetchProcessSteps(customer.getIdentifier());
+    Assert.assertEquals(1, closedProcessSteps.size());
+    Assert.assertEquals(Command.Action.REOPEN.name(), 
closedProcessSteps.get(0).getCommand().getAction());
+  }
 }
diff --git 
a/service/src/main/java/io/mifos/customer/service/internal/repository/TaskInstanceRepository.java
 
b/service/src/main/java/io/mifos/customer/service/internal/repository/TaskInstanceRepository.java
index d8e45d2..2301f3a 100644
--- 
a/service/src/main/java/io/mifos/customer/service/internal/repository/TaskInstanceRepository.java
+++ 
b/service/src/main/java/io/mifos/customer/service/internal/repository/TaskInstanceRepository.java
@@ -24,4 +24,7 @@ import java.util.List;
 public interface TaskInstanceRepository extends 
JpaRepository<TaskInstanceEntity, Long> {
 
   List<TaskInstanceEntity> findByCustomer(final CustomerEntity customer);
+
+  List<TaskInstanceEntity> findByCustomerAndTaskDefinition(final 
CustomerEntity customer,
+                                                           final 
TaskDefinitionEntity taskDefinitionEntity);
 }
diff --git 
a/service/src/main/java/io/mifos/customer/service/internal/service/CustomerService.java
 
b/service/src/main/java/io/mifos/customer/service/internal/service/CustomerService.java
index 728af4b..5048a4c 100644
--- 
a/service/src/main/java/io/mifos/customer/service/internal/service/CustomerService.java
+++ 
b/service/src/main/java/io/mifos/customer/service/internal/service/CustomerService.java
@@ -19,6 +19,8 @@ import io.mifos.customer.api.v1.domain.Command;
 import io.mifos.customer.api.v1.domain.Customer;
 import io.mifos.customer.api.v1.domain.CustomerPage;
 import io.mifos.customer.api.v1.domain.IdentificationCard;
+import io.mifos.customer.api.v1.domain.ProcessStep;
+import io.mifos.customer.api.v1.domain.TaskDefinition;
 import io.mifos.customer.catalog.api.v1.domain.Value;
 import io.mifos.customer.catalog.service.internal.repository.FieldEntity;
 import io.mifos.customer.catalog.service.internal.repository.FieldValueEntity;
@@ -28,6 +30,7 @@ import 
io.mifos.customer.service.internal.mapper.CommandMapper;
 import io.mifos.customer.service.internal.mapper.ContactDetailMapper;
 import io.mifos.customer.service.internal.mapper.CustomerMapper;
 import io.mifos.customer.service.internal.mapper.IdentificationCardMapper;
+import io.mifos.customer.service.internal.mapper.TaskDefinitionMapper;
 import io.mifos.customer.service.internal.repository.*;
 import io.mifos.customer.service.internal.mapper.AddressMapper;
 import org.slf4j.Logger;
@@ -53,6 +56,8 @@ public class CustomerService {
   private final ContactDetailRepository contactDetailRepository;
   private final FieldValueRepository fieldValueRepository;
   private final CommandRepository commandRepository;
+  private final TaskDefinitionRepository taskDefinitionRepository;
+  private final TaskInstanceRepository taskInstanceRepository;
 
   @Autowired
   public CustomerService(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger 
logger,
@@ -61,7 +66,9 @@ public class CustomerService {
                          final PortraitRepository portraitRepository,
                          final ContactDetailRepository contactDetailRepository,
                          final FieldValueRepository fieldValueRepository,
-                         final CommandRepository commandRepository) {
+                         final CommandRepository commandRepository,
+                         final TaskDefinitionRepository 
taskDefinitionRepository,
+                         final TaskInstanceRepository taskInstanceRepository) {
     super();
     this.logger = logger;
     this.customerRepository = customerRepository;
@@ -70,6 +77,8 @@ public class CustomerService {
     this.contactDetailRepository = contactDetailRepository;
     this.fieldValueRepository = fieldValueRepository;
     this.commandRepository = commandRepository;
+    this.taskDefinitionRepository = taskDefinitionRepository;
+    this.taskInstanceRepository = taskInstanceRepository;
   }
 
   public Boolean customerExists(final String identifier) {
@@ -185,4 +194,52 @@ public class CustomerService {
 
     return identificationCardEntity.map(IdentificationCardMapper::map);
   }
+
+  public List<ProcessStep> getProcessSteps(final String customerIdentifier) {
+    final ArrayList<ProcessStep> processSteps = new ArrayList<>();
+    final CustomerEntity customerEntity = 
this.customerRepository.findByIdentifier(customerIdentifier);
+
+    final Customer.State state = 
Customer.State.valueOf(customerEntity.getCurrentState());
+    switch (state) {
+      case PENDING:
+        processSteps.add(this.buildProcessStep(customerEntity, 
Command.Action.ACTIVATE));
+        processSteps.add(this.buildProcessStep(customerEntity, 
Command.Action.CLOSE));
+        break;
+      case ACTIVE:
+        processSteps.add(this.buildProcessStep(customerEntity, 
Command.Action.LOCK));
+        processSteps.add(this.buildProcessStep(customerEntity, 
Command.Action.CLOSE));
+        break;
+      case LOCKED:
+        processSteps.add(this.buildProcessStep(customerEntity, 
Command.Action.UNLOCK));
+        processSteps.add(this.buildProcessStep(customerEntity, 
Command.Action.CLOSE));
+        break;
+      case CLOSED:
+        processSteps.add(this.buildProcessStep(customerEntity, 
Command.Action.REOPEN));
+        break;
+    }
+
+    return processSteps;
+  }
+
+  private ProcessStep buildProcessStep(final CustomerEntity customerEntity, 
final Command.Action action) {
+    final ProcessStep processStep = new ProcessStep();
+
+    final Command command = new Command();
+    command.setAction(action.name());
+    processStep.setCommand(command);
+
+    final ArrayList<TaskDefinition> taskDefinitions = new ArrayList<>();
+    
this.taskDefinitionRepository.findByAssignedCommandsContaining(action.name())
+        .forEach(taskDefinitionEntity -> {
+          
this.taskInstanceRepository.findByCustomerAndTaskDefinition(customerEntity, 
taskDefinitionEntity)
+              .forEach(taskInstanceEntity -> {
+                if (taskInstanceEntity.getExecutedBy() == null) {
+                  
taskDefinitions.add(TaskDefinitionMapper.map(taskDefinitionEntity));
+                }
+              });
+        });
+    processStep.setTaskDefinitions(taskDefinitions);
+
+    return processStep;
+  }
 }
diff --git 
a/service/src/main/java/io/mifos/customer/service/rest/controller/CustomerRestController.java
 
b/service/src/main/java/io/mifos/customer/service/rest/controller/CustomerRestController.java
index 31a3959..41546b9 100644
--- 
a/service/src/main/java/io/mifos/customer/service/rest/controller/CustomerRestController.java
+++ 
b/service/src/main/java/io/mifos/customer/service/rest/controller/CustomerRestController.java
@@ -182,52 +182,34 @@ public class CustomerRestController {
     if (customerOptional.isPresent()) {
       final Customer customer = customerOptional.get();
       final Command.Action action = 
Command.Action.valueOf(command.getAction());
+      final String currentState = customer.getCurrentState();
       switch (action) {
         case ACTIVATE:
-          if 
(!customer.getCurrentState().equals(Customer.State.PENDING.name())) {
-            throw ServiceException.badRequest(
-                "Customer {0} can not be activated, current state is {1}.",
-                identifier,
-                customer.getCurrentState());
+          if (Customer.State.PENDING.name().equals(currentState)) {
+            this.commandGateway.process(new 
ActivateCustomerCommand(identifier, command.getComment()));
           }
-          this.commandGateway.process(new ActivateCustomerCommand(identifier, 
command.getComment()));
           break;
         case LOCK:
-          if 
(!customer.getCurrentState().equals(Customer.State.ACTIVE.name())) {
-            throw ServiceException.badRequest(
-                "Customer {0} can not be locked, current state is {1}.",
-                identifier,
-                customer.getCurrentState());
+          if (Customer.State.ACTIVE.name().equals(currentState)) {
+            this.commandGateway.process(new LockCustomerCommand(identifier, 
command.getComment()));
           }
-          this.commandGateway.process(new LockCustomerCommand(identifier, 
command.getComment()));
           break;
         case UNLOCK:
-          if 
(!customer.getCurrentState().equals(Customer.State.LOCKED.name())) {
-            throw ServiceException.badRequest(
-                "Customer {0} can not be unlocked, current state is {1}.",
-                identifier,
-                customer.getCurrentState());
+          if (Customer.State.LOCKED.name().equals(currentState)) {
+            this.commandGateway.process(new UnlockCustomerCommand(identifier, 
command.getComment()));
           }
-          this.commandGateway.process(new UnlockCustomerCommand(identifier, 
command.getComment()));
           break;
         case CLOSE:
-          if (!customer.getCurrentState().equals(Customer.State.ACTIVE.name())
-              && 
!customer.getCurrentState().equals(Customer.State.LOCKED.name())) {
-            throw ServiceException.badRequest(
-                "Customer {0} can not be closed, current state is {1}.",
-                identifier,
-                customer.getCurrentState());
+          if (Customer.State.ACTIVE.name().equals(currentState)
+              || Customer.State.LOCKED.name().equals(currentState)
+              || Customer.State.PENDING.name().equals(currentState)) {
+            this.commandGateway.process(new CloseCustomerCommand(identifier, 
command.getComment()));
           }
-          this.commandGateway.process(new CloseCustomerCommand(identifier, 
command.getComment()));
           break;
         case REOPEN:
-          if 
(!customer.getCurrentState().equals(Customer.State.CLOSED.name())) {
-            throw ServiceException.badRequest(
-                "Customer {0} can not be reopened, current state is {1}.",
-                identifier,
-                customer.getCurrentState());
+          if (Customer.State.CLOSED.name().equals(currentState)) {
+            this.commandGateway.process(new ReopenCustomerCommand(identifier, 
command.getComment()));
           }
-          this.commandGateway.process(new ReopenCustomerCommand(identifier, 
command.getComment()));
           break;
         default:
           throw ServiceException.badRequest("Unsupported action {0}.", 
command.getAction());
@@ -607,6 +589,20 @@ public class CustomerRestController {
     return ResponseEntity.accepted().build();
   }
 
+  @Permittable(value = AcceptedTokenType.TENANT, groupId = 
PermittableGroupIds.CUSTOMER)
+  @RequestMapping(
+      value = "/customer/{identifier}/actions",
+      method = RequestMethod.GET,
+      produces = MediaType.APPLICATION_JSON_VALUE,
+      consumes = MediaType.ALL_VALUE
+  )
+  public
+  @ResponseBody
+  ResponseEntity<List<ProcessStep>> fetchProcessSteps(@PathVariable(value = 
"identifier") final String customerIdentifier) {
+    this.throwIfCustomerNotExists(customerIdentifier);
+    return 
ResponseEntity.ok(this.customerService.getProcessSteps(customerIdentifier));
+  }
+
   private Pageable createPageRequest(final Integer pageIndex, final Integer 
size, final String sortColumn, final String sortDirection) {
     final Integer pageIndexToUse = pageIndex != null ? pageIndex : 0;
     final Integer sizeToUse = size != null ? size : 20;
@@ -632,5 +628,4 @@ public class CustomerRestController {
       throw ServiceException.notFound("Identification card {0} not found.", 
number);
     }
   }
-
 }

-- 
To stop receiving notification emails like this one, please contact
[email protected].

Reply via email to