added ability to fetch available TX types for a customer
diff --git a/api/src/main/java/io/mifos/deposit/api/v1/client/DepositAccountManager.java b/api/src/main/java/io/mifos/deposit/api/v1/client/DepositAccountManager.java
index aae77a7..b9c0c00 100644
--- a/api/src/main/java/io/mifos/deposit/api/v1/client/DepositAccountManager.java
+++ b/api/src/main/java/io/mifos/deposit/api/v1/client/DepositAccountManager.java
@@ -28,6 +28,7 @@
 import io.mifos.deposit.api.v1.definition.domain.ProductDefinitionCommand;
 import io.mifos.deposit.api.v1.instance.ProductInstanceNotFoundException;
 import io.mifos.deposit.api.v1.instance.ProductInstanceValidationException;
+import io.mifos.deposit.api.v1.instance.domain.AvailableTransactionType;
 import io.mifos.deposit.api.v1.instance.domain.ProductInstance;
 import org.springframework.cloud.netflix.feign.FeignClient;
 import org.springframework.http.HttpStatus;
@@ -37,9 +38,11 @@
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
 
 import javax.validation.Valid;
 import java.util.List;
+import java.util.Set;
 
 @SuppressWarnings("unused")
 @FeignClient(value = "deposit-v1", path = "/deposit/v1", configuration = CustomFeignClientsConfiguration.class)
@@ -133,6 +136,17 @@
   List<ProductInstance> fetchProductInstances(@RequestParam(value = "customer", required = true) final String customer);
 
   @RequestMapping(
+      value = "/instances/transactiontypes",
+      method = RequestMethod.GET,
+      consumes = MediaType.APPLICATION_JSON_VALUE,
+      produces = MediaType.ALL_VALUE
+  )
+  @ResponseBody
+  Set<AvailableTransactionType> fetchPossibleTransactionTypes(
+      @RequestParam(value = "customer", required = true) final String customer
+  );
+
+  @RequestMapping(
       value = "/instances/{identifier}",
       method = RequestMethod.POST,
       consumes = MediaType.APPLICATION_JSON_VALUE,
diff --git a/api/src/main/java/io/mifos/deposit/api/v1/instance/domain/AvailableTransactionType.java b/api/src/main/java/io/mifos/deposit/api/v1/instance/domain/AvailableTransactionType.java
new file mode 100644
index 0000000..bd0a2d4
--- /dev/null
+++ b/api/src/main/java/io/mifos/deposit/api/v1/instance/domain/AvailableTransactionType.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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.
+ */
+package io.mifos.deposit.api.v1.instance.domain;
+
+import org.hibernate.validator.constraints.NotEmpty;
+
+public class AvailableTransactionType {
+
+  @NotEmpty
+  private String transactionType;
+
+  public AvailableTransactionType() {
+    super();
+  }
+
+  public String getTransactionType() {
+    return this.transactionType;
+  }
+
+  public void setTransactionType(final String transactionType) {
+    this.transactionType = transactionType;
+  }
+
+  @Override
+  public boolean equals(final Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    final AvailableTransactionType that = (AvailableTransactionType) o;
+
+    return transactionType.equals(that.transactionType);
+  }
+
+  @Override
+  public int hashCode() {
+    return transactionType.hashCode();
+  }
+}
diff --git a/component-test/src/main/java/io/mifos/deposit/TestProductInstance.java b/component-test/src/main/java/io/mifos/deposit/TestProductInstance.java
index be05a00..d023ee9 100644
--- a/component-test/src/main/java/io/mifos/deposit/TestProductInstance.java
+++ b/component-test/src/main/java/io/mifos/deposit/TestProductInstance.java
@@ -15,12 +15,14 @@
  */
 package io.mifos.deposit;
 
+import com.google.common.collect.Sets;
 import io.mifos.accounting.api.v1.domain.Account;
 import io.mifos.deposit.api.v1.EventConstants;
 import io.mifos.deposit.api.v1.definition.domain.Charge;
 import io.mifos.deposit.api.v1.definition.domain.ProductDefinition;
 import io.mifos.deposit.api.v1.instance.ProductInstanceNotFoundException;
 import io.mifos.deposit.api.v1.instance.ProductInstanceValidationException;
+import io.mifos.deposit.api.v1.instance.domain.AvailableTransactionType;
 import io.mifos.deposit.api.v1.instance.domain.ProductInstance;
 import org.apache.commons.lang3.RandomStringUtils;
 import org.junit.Assert;
@@ -30,6 +32,8 @@
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Optional;
+import java.util.Set;
 
 public class TestProductInstance extends AbstractDepositAccountManagementTest {
 
@@ -279,4 +283,51 @@
         super.eventRecorder.wait(EventConstants.ACTIVATE_PRODUCT_INSTANCE,
             fetchedProductInstance.getAccountIdentifier()));
   }
+
+  @Test
+  public void shouldFindAvailableTransactionTypes() throws Exception {
+    final ProductDefinition productDefinition = Fixture.productDefinition();
+
+    super.depositAccountManager.create(productDefinition);
+
+    super.eventRecorder.wait(EventConstants.POST_PRODUCT_DEFINITION, productDefinition.getIdentifier());
+
+    final ProductInstance productInstance = Fixture.productInstance(productDefinition.getIdentifier());
+
+    super.depositAccountManager.create(productInstance);
+
+    super.eventRecorder.wait(EventConstants.POST_PRODUCT_INSTANCE, productInstance.getCustomerIdentifier());
+
+    final Set<AvailableTransactionType> availableTransactionTypesBeforeActivation =
+        super.depositAccountManager.fetchPossibleTransactionTypes(productInstance.getCustomerIdentifier());
+
+    Assert.assertFalse(availableTransactionTypesBeforeActivation.isEmpty());
+    Assert.assertTrue(availableTransactionTypesBeforeActivation.size() == 1);
+    final Optional<AvailableTransactionType> optionalTransactionType =
+        availableTransactionTypesBeforeActivation.stream().findFirst();
+    Assert.assertTrue(optionalTransactionType.isPresent());
+    Assert.assertEquals("ACCO", optionalTransactionType.get().getTransactionType());
+
+    final List<ProductInstance> productInstances = super.depositAccountManager.findProductInstances(productDefinition.getIdentifier());
+    Assert.assertNotNull(productInstances);
+    Assert.assertEquals(1, productInstances.size());
+    final ProductInstance foundProductInstance = productInstances.get(0);
+
+    super.depositAccountManager.postProductInstanceCommand(
+        foundProductInstance.getAccountIdentifier(), EventConstants.ACTIVATE_PRODUCT_INSTANCE_COMMAND);
+
+    super.eventRecorder.wait(EventConstants.ACTIVATE_PRODUCT_INSTANCE, foundProductInstance.getAccountIdentifier());
+
+    final Set<AvailableTransactionType> availableTransactionTypesAfterActivation =
+        super.depositAccountManager.fetchPossibleTransactionTypes(productInstance.getCustomerIdentifier());
+
+    Assert.assertFalse(availableTransactionTypesAfterActivation.isEmpty());
+    Assert.assertTrue(availableTransactionTypesAfterActivation.size() == 4);
+    final HashSet<String> expectedTransactionTypes = Sets.newHashSet("ACCC", "ACCT", "CDPT", "CWDL");
+    availableTransactionTypesAfterActivation.forEach(availableTransactionType ->
+        expectedTransactionTypes.remove(availableTransactionType.getTransactionType())
+    );
+
+    Assert.assertTrue(expectedTransactionTypes.isEmpty());
+  }
 }
diff --git a/service/src/main/java/io/mifos/deposit/service/rest/ProductInstanceRestController.java b/service/src/main/java/io/mifos/deposit/service/rest/ProductInstanceRestController.java
index 7470786..205fd91 100644
--- a/service/src/main/java/io/mifos/deposit/service/rest/ProductInstanceRestController.java
+++ b/service/src/main/java/io/mifos/deposit/service/rest/ProductInstanceRestController.java
@@ -21,6 +21,7 @@
 import io.mifos.core.lang.ServiceException;
 import io.mifos.deposit.api.v1.EventConstants;
 import io.mifos.deposit.api.v1.PermittableGroupIds;
+import io.mifos.deposit.api.v1.instance.domain.AvailableTransactionType;
 import io.mifos.deposit.api.v1.instance.domain.ProductInstance;
 import io.mifos.deposit.service.ServiceConstants;
 import io.mifos.deposit.service.internal.command.ActivateProductInstanceCommand;
@@ -42,7 +43,9 @@
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.validation.Valid;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 @RestController
 @RequestMapping("/instances")
@@ -83,12 +86,48 @@
       produces = MediaType.APPLICATION_JSON_VALUE
   )
   @ResponseBody
-  public ResponseEntity<List<ProductInstance>> fetchProductInstances(@RequestParam(value = "customer", required = true) final String customerIdentifier) {
+  public ResponseEntity<List<ProductInstance>> fetchProductInstances(
+      @RequestParam(value = "customer", required = true) final String customerIdentifier) {
     return ResponseEntity.ok(this.productInstanceService.findByCustomer(customerIdentifier));
   }
 
   @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.INSTANCE_MANAGEMENT)
   @RequestMapping(
+      value = "/transactiontypes",
+      method = RequestMethod.GET,
+      consumes = MediaType.ALL_VALUE,
+      produces = MediaType.APPLICATION_JSON_VALUE
+  )
+  @ResponseBody
+  public ResponseEntity<Set<AvailableTransactionType>> fetchPossibleTransactionTypes(
+      @RequestParam(value = "customer", required = true) final String customerIdentifier) {
+    final HashSet<AvailableTransactionType> availableTransactionTypes = new HashSet<>();
+    final List<ProductInstance> productInstances = this.productInstanceService.findByCustomer(customerIdentifier);
+    productInstances.forEach(productInstance -> {
+      if (productInstance.getState().equals("PENDING")) {
+        final AvailableTransactionType actionOpen = new AvailableTransactionType();
+        actionOpen.setTransactionType("ACCO");
+        availableTransactionTypes.add(actionOpen);
+      } else if (productInstance.getState().equals("ACTIVE")) {
+        final AvailableTransactionType actionDeposit = new AvailableTransactionType();
+        actionDeposit.setTransactionType("CDPT");
+        availableTransactionTypes.add(actionDeposit);
+        final AvailableTransactionType actionWithdrawal = new AvailableTransactionType();
+        actionWithdrawal.setTransactionType("CWDL");
+        availableTransactionTypes.add(actionWithdrawal);
+        final AvailableTransactionType actionTransfer = new AvailableTransactionType();
+        actionTransfer.setTransactionType("ACCT");
+        availableTransactionTypes.add(actionTransfer);
+        final AvailableTransactionType actionClose = new AvailableTransactionType();
+        actionClose.setTransactionType("ACCC");
+        availableTransactionTypes.add(actionClose);
+      }
+    });
+    return ResponseEntity.ok(availableTransactionTypes);
+  }
+
+  @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.INSTANCE_MANAGEMENT)
+  @RequestMapping(
       value = "/{identifier}",
       method = RequestMethod.POST,
       consumes = MediaType.APPLICATION_JSON_VALUE,