You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by na...@apache.org on 2016/05/17 13:17:35 UTC

[1/3] incubator-fineract git commit: Shares Integration Tests and Fixes

Repository: incubator-fineract
Updated Branches:
  refs/heads/develop 0b81e8023 -> 7ae9b67d9


http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/7ae9b67d/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareProductTransactionHelper.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareProductTransactionHelper.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareProductTransactionHelper.java
new file mode 100644
index 0000000..2c8588f
--- /dev/null
+++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareProductTransactionHelper.java
@@ -0,0 +1,51 @@
+/**
+ * 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.
+ */
+package org.apache.fineract.integrationtests.common.shares;
+
+import java.util.Map;
+
+import org.apache.fineract.integrationtests.common.Utils;
+
+import com.jayway.restassured.specification.RequestSpecification;
+import com.jayway.restassured.specification.ResponseSpecification;
+
+
+public class ShareProductTransactionHelper {
+
+    private static final String SHARE_PRODUCT_URL = "/fineract-provider/api/v1/products/share";
+    private static final String CREATE_SHARE_PRODUCT_URL = SHARE_PRODUCT_URL + "?" + Utils.TENANT_IDENTIFIER;
+    
+    public static Integer createShareProduct(final String savingsProductJSON, final RequestSpecification requestSpec,
+            final ResponseSpecification responseSpec) {
+        return Utils.performServerPost(requestSpec, responseSpec, CREATE_SHARE_PRODUCT_URL, savingsProductJSON, "resourceId");
+    }
+    
+    public static Map<String, Object> retrieveShareProduct(final Integer shareProductId, final RequestSpecification requestSpec,
+            final ResponseSpecification responseSpec) {
+        String url = SHARE_PRODUCT_URL+"/"+shareProductId+"?"+Utils.TENANT_IDENTIFIER ;
+        return Utils.performServerGet(requestSpec, responseSpec, url, "");
+    }
+    
+    public static Integer updateShareProduct(final Integer shareProductId, final String provsioningCriteriaJson,
+            final RequestSpecification requestSpec,
+            final ResponseSpecification responseSpec) {
+        String url = SHARE_PRODUCT_URL+"/"+shareProductId+"?"+Utils.TENANT_IDENTIFIER ;
+        return Utils.performServerPut(requestSpec, responseSpec, url, provsioningCriteriaJson, "resourceId");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/7ae9b67d/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/api/AccountsApiResource.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/api/AccountsApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/api/AccountsApiResource.java
index 56df39f..f627c89 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/api/AccountsApiResource.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/api/AccountsApiResource.java
@@ -18,8 +18,6 @@
  */
 package org.apache.fineract.portfolio.accounts.api;
 
-import java.util.Collection;
-
 import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
@@ -39,10 +37,13 @@ import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
 import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
 import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
 import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
+import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.apache.fineract.portfolio.accounts.constants.AccountsApiConstants;
 import org.apache.fineract.portfolio.accounts.data.AccountData;
 import org.apache.fineract.portfolio.accounts.service.AccountReadPlatformService;
+import org.apache.fineract.portfolio.products.exception.ResourceNotFoundException;
+import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Scope;
@@ -59,21 +60,18 @@ public class AccountsApiResource {
     private final DefaultToApiJsonSerializer<AccountData> toApiJsonSerializer;
     private final PlatformSecurityContext platformSecurityContext;
     private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
-    private final DefaultToApiJsonSerializer<Object> toApiObjectJsonSerializer ;
     
     @Autowired
     public AccountsApiResource(final ApplicationContext applicationContext,
             final ApiRequestParameterHelper apiRequestParameterHelper,
             final DefaultToApiJsonSerializer<AccountData> toApiJsonSerializer,
             final PlatformSecurityContext platformSecurityContext,
-            final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
-            final DefaultToApiJsonSerializer<Object> toApiObjectJsonSerializer) {
+            final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
         this.applicationContext = applicationContext ;
         this.apiRequestParameterHelper = apiRequestParameterHelper ;
         this.toApiJsonSerializer = toApiJsonSerializer ;
         this.platformSecurityContext = platformSecurityContext ; 
         this.commandsSourceWritePlatformService = commandsSourceWritePlatformService ;
-        this.toApiObjectJsonSerializer = toApiObjectJsonSerializer ;
     }
     
     @GET
@@ -83,12 +81,16 @@ public class AccountsApiResource {
     public String template(@PathParam("type") final String accountType, @QueryParam("clientId") final Long clientId, 
     		@QueryParam("productId") final Long productId,
             @Context final UriInfo uriInfo) {
-        this.platformSecurityContext.authenticatedUser() ;
-        String serviceName = accountType+AccountsApiConstants.READPLATFORM_NAME ;
-        AccountReadPlatformService service = (AccountReadPlatformService) this.applicationContext.getBean(serviceName) ;
-        final AccountData accountData = service.retrieveTemplate(clientId, productId);
-        final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
-        return this.toApiJsonSerializer.serialize(settings, accountData, service.getResponseDataParams());
+        try {
+            this.platformSecurityContext.authenticatedUser() ;
+            String serviceName = accountType+AccountsApiConstants.READPLATFORM_NAME ;
+            AccountReadPlatformService service = (AccountReadPlatformService) this.applicationContext.getBean(serviceName) ;
+            final AccountData accountData = service.retrieveTemplate(clientId, productId);
+            final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+            return this.toApiJsonSerializer.serialize(settings, accountData, service.getResponseDataParams());    
+        }catch(BeansException e) {
+            throw new ResourceNotFoundException();
+        }
     }
     
     @GET
@@ -97,22 +99,30 @@ public class AccountsApiResource {
     @Produces({ MediaType.APPLICATION_JSON })
     public String retrieveAccount(@PathParam("accountId") final Long accountId, @PathParam("type") final String accountType,
             @Context final UriInfo uriInfo) {
-        String serviceName = accountType+AccountsApiConstants.READPLATFORM_NAME ;
-        final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
-        AccountReadPlatformService service = (AccountReadPlatformService) this.applicationContext.getBean(serviceName) ;
-        AccountData data = service.retrieveOne(accountId, settings.isTemplate()) ;
-        return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams());
+        try {
+            String serviceName = accountType+AccountsApiConstants.READPLATFORM_NAME ;
+            final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+            AccountReadPlatformService service = (AccountReadPlatformService) this.applicationContext.getBean(serviceName) ;
+            AccountData data = service.retrieveOne(accountId, settings.isTemplate()) ;
+            return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams());    
+        }catch(BeansException e) {
+            throw new ResourceNotFoundException();
+        }
     }
     
     @GET
     @Consumes({ MediaType.APPLICATION_JSON })
     @Produces({ MediaType.APPLICATION_JSON })
-    public String retrieveAllAccounts(@PathParam("type") final String accountType, @Context final UriInfo uriInfo) {
-        String serviceName = accountType+AccountsApiConstants.READPLATFORM_NAME ;
-        AccountReadPlatformService service = (AccountReadPlatformService) this.applicationContext.getBean(serviceName) ;
-        Collection<AccountData> data = service.retrieveAll() ;
-        final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
-        return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams()); 
+    public String retrieveAllAccounts(@PathParam("type") final String accountType, @QueryParam("offset") final Integer offset, @QueryParam("limit") final Integer limit, @Context final UriInfo uriInfo) {
+        try {
+            String serviceName = accountType+AccountsApiConstants.READPLATFORM_NAME ;
+            AccountReadPlatformService service = (AccountReadPlatformService) this.applicationContext.getBean(serviceName) ;
+            Page<AccountData> data = service.retrieveAll(offset, limit) ;
+            final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+            return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams());    
+        }catch(BeansException e) {
+            throw new ResourceNotFoundException();
+        }
     }
     
     @POST

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/7ae9b67d/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/service/AccountReadPlatformService.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/service/AccountReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/service/AccountReadPlatformService.java
index 42ef5e3..f22e82a 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/service/AccountReadPlatformService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/service/AccountReadPlatformService.java
@@ -18,9 +18,9 @@
  */
 package org.apache.fineract.portfolio.accounts.service;
 
-import java.util.Collection;
 import java.util.Set;
 
+import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.portfolio.accounts.data.AccountData;
 
 public interface AccountReadPlatformService {
@@ -29,7 +29,7 @@ public interface AccountReadPlatformService {
 
     public AccountData retrieveOne(Long id, boolean includeTemplate);
 
-    public Collection<AccountData> retrieveAll();
+    public Page<AccountData> retrieveAll(final Integer offSet, final Integer limit);
 
     public Set<String> getResponseDataParams();
 

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/7ae9b67d/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/Note.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/Note.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/Note.java
index e18c238..e835fb0 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/Note.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/Note.java
@@ -35,6 +35,7 @@ import org.apache.fineract.portfolio.group.domain.Group;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
 import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
+import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccount;
 import org.apache.fineract.useradministration.domain.AppUser;
 
 @Entity
@@ -67,6 +68,11 @@ public class Note extends AbstractAuditableCustom<AppUser, Long> {
     @JoinColumn(name = "savings_account_id", nullable = true)
     private SavingsAccount savingsAccount;
 
+    @ManyToOne
+    @JoinColumn(name = "share_account_id", nullable = true)
+    private ShareAccount shareAccount;
+    
+    
     public static Note clientNoteFromJson(final Client client, final JsonCommand command) {
         final String note = command.stringValueOfParameterNamed("note");
         return new Note(client, note);
@@ -89,6 +95,10 @@ public class Note extends AbstractAuditableCustom<AppUser, Long> {
         return new Note(account, note);
     }
 
+    public static Note shareNote(final ShareAccount account, final String note) {
+        return new Note(account, note);
+    }
+    
     public Note(final Client client, final String note) {
         this.client = client;
         this.note = note;
@@ -133,6 +143,13 @@ public class Note extends AbstractAuditableCustom<AppUser, Long> {
         this.noteTypeId = NoteType.SAVING_ACCOUNT.getValue();
     }
 
+    public Note(final ShareAccount account, final String note) {
+        this.shareAccount = account;
+        this.client = account.getClient();
+        this.note = note;
+        this.noteTypeId = NoteType.SHARE_ACCOUNT.getValue();
+    }
+    
     public Map<String, Object> update(final JsonCommand command) {
         final Map<String, Object> actualChanges = new LinkedHashMap<>(7);
 

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/7ae9b67d/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/NoteType.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/NoteType.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/NoteType.java
index 01bed9f..bd50c36 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/NoteType.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/NoteType.java
@@ -27,8 +27,9 @@ public enum NoteType {
     LOAN(200, "noteType.loan", "loans"), //
     LOAN_TRANSACTION(300, "noteType.loan.transaction", "loanTransactions"), //
     SAVING_ACCOUNT(500, "noteType.saving", "savings"), //
-    GROUP(600, "noteType.group", "groups");
-
+    GROUP(600, "noteType.group", "groups"),
+    SHARE_ACCOUNT(700, "noteType.shares", "accounts/share");
+    
     private Integer value;
     private String code;
     private String apiUrl;

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/7ae9b67d/fineract-provider/src/main/java/org/apache/fineract/portfolio/products/api/ProductsApiResource.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/products/api/ProductsApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/products/api/ProductsApiResource.java
index 9baddda..a94a146 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/products/api/ProductsApiResource.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/products/api/ProductsApiResource.java
@@ -30,7 +30,6 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.UriInfo;
 
-import org.apache.commons.lang.StringUtils;
 import org.apache.fineract.commands.domain.CommandWrapper;
 import org.apache.fineract.commands.service.CommandWrapperBuilder;
 import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
@@ -42,7 +41,9 @@ import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.apache.fineract.portfolio.products.constants.ProductsApiConstants;
 import org.apache.fineract.portfolio.products.data.ProductData;
+import org.apache.fineract.portfolio.products.exception.ResourceNotFoundException;
 import org.apache.fineract.portfolio.products.service.ProductReadPlatformService;
+import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Scope;
@@ -56,21 +57,18 @@ public class ProductsApiResource {
     private final ApplicationContext applicationContext;
     private final ApiRequestParameterHelper apiRequestParameterHelper;
     private final DefaultToApiJsonSerializer<ProductData> toApiJsonSerializer;
-    private final DefaultToApiJsonSerializer<Object> toApiObjectJsonSerializer;
     private final PlatformSecurityContext platformSecurityContext;
     private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
 
     @Autowired
     public ProductsApiResource(final ApplicationContext applicationContext, final ApiRequestParameterHelper apiRequestParameterHelper,
             final DefaultToApiJsonSerializer<ProductData> toApiJsonSerializer, final PlatformSecurityContext platformSecurityContext,
-            final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
-            final DefaultToApiJsonSerializer<Object> toApiDividendsJsonSerializer) {
+            final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
         this.applicationContext = applicationContext;
         this.apiRequestParameterHelper = apiRequestParameterHelper;
         this.toApiJsonSerializer = toApiJsonSerializer;
         this.platformSecurityContext = platformSecurityContext;
         this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
-        this.toApiObjectJsonSerializer = toApiDividendsJsonSerializer;
     }
 
     @GET
@@ -79,10 +77,14 @@ public class ProductsApiResource {
     @Produces({ MediaType.APPLICATION_JSON })
     public String retrieveTemplate(@PathParam("type") final String productType, @Context final UriInfo uriInfo) {
         String serviceName = productType + ProductsApiConstants.READPLATFORM_NAME;
-        ProductReadPlatformService service = (ProductReadPlatformService) this.applicationContext.getBean(serviceName);
-        ProductData data = service.retrieveTemplate();
-        final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
-        return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams());
+        try {
+            ProductReadPlatformService service = (ProductReadPlatformService) this.applicationContext.getBean(serviceName);
+            ProductData data = service.retrieveTemplate();
+            final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+            return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams());    
+        }catch(BeansException e) {
+            throw new ResourceNotFoundException() ;
+        }
     }
 
     @GET
@@ -91,30 +93,31 @@ public class ProductsApiResource {
     @Produces({ MediaType.APPLICATION_JSON })
     public String retrieveProduct(@PathParam("productId") final Long productId, @PathParam("type") final String productType,
             @Context final UriInfo uriInfo) {
-        String serviceName = productType + ProductsApiConstants.READPLATFORM_NAME;
-        ProductReadPlatformService service = (ProductReadPlatformService) this.applicationContext.getBean(serviceName);
-        final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
-
-        ProductData data = service.retrieveOne(productId, settings.isTemplate());
-
-        return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams());
+        try {
+            String serviceName = productType + ProductsApiConstants.READPLATFORM_NAME;
+            ProductReadPlatformService service = (ProductReadPlatformService) this.applicationContext.getBean(serviceName);
+            final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+            ProductData data = service.retrieveOne(productId, settings.isTemplate());
+            return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams());
+        } catch (BeansException e) {
+            throw new ResourceNotFoundException();
+        }
     }
 
     @GET
     @Consumes({ MediaType.APPLICATION_JSON })
     @Produces({ MediaType.APPLICATION_JSON })
-    public String retrieveAllProducts(/*
-                                       * @PathParam("type") final String
-                                       * productType, @Context final UriInfo
-                                       * uriInfo
-                                       */
-    @PathParam("type") final String productType, @QueryParam("offset") final Integer offset, @QueryParam("limit") final Integer limit,
+    public String retrieveAllProducts(@PathParam("type") final String productType, @QueryParam("offset") final Integer offset, @QueryParam("limit") final Integer limit,
             @Context final UriInfo uriInfo) {
-        String serviceName = productType + ProductsApiConstants.READPLATFORM_NAME;
-        ProductReadPlatformService service = (ProductReadPlatformService) this.applicationContext.getBean(serviceName);
-        Page<ProductData> data = service.retrieveAllProducts(offset, limit);
-        final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
-        return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams());
+        try {
+            String serviceName = productType + ProductsApiConstants.READPLATFORM_NAME;
+            ProductReadPlatformService service = (ProductReadPlatformService) this.applicationContext.getBean(serviceName);
+            Page<ProductData> data = service.retrieveAllProducts(offset, limit);
+            final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+            return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams());    
+        }catch(BeansException e) {
+            throw new ResourceNotFoundException();
+        }
     }
 
     @POST
@@ -152,8 +155,4 @@ public class ProductsApiResource {
         final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
         return this.toApiJsonSerializer.serialize(result);
     }
-
-    private boolean is(final String commandParam, final String commandValue) {
-        return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
-    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/7ae9b67d/fineract-provider/src/main/java/org/apache/fineract/portfolio/products/exception/ResourceNotFoundException.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/products/exception/ResourceNotFoundException.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/products/exception/ResourceNotFoundException.java
new file mode 100644
index 0000000..98135f7
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/products/exception/ResourceNotFoundException.java
@@ -0,0 +1,33 @@
+/**
+ * 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.
+ */
+package org.apache.fineract.portfolio.products.exception;
+
+import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
+
+
+public class ResourceNotFoundException extends AbstractPlatformResourceNotFoundException{
+
+    public ResourceNotFoundException(String globalisationMessageCode, String defaultUserMessage, Object[] defaultUserMessageArgs) {
+        super(globalisationMessageCode, defaultUserMessage, defaultUserMessageArgs);
+    }
+
+    public ResourceNotFoundException() {
+        super("","","") ;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/7ae9b67d/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccount.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccount.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccount.java
index d14194a..59827cb 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccount.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccount.java
@@ -262,9 +262,18 @@ public class ShareAccount extends AbstractPersistable<Long> {
     public void addTransaction(final ShareAccountTransaction transaction) {
         transaction.setShareAccount(this);
         if(transaction.isPendingForApprovalTransaction()) {
-            this.totalSharesPending += transaction.getTotalShares() ;
+            if(this.totalSharesPending == null) {
+                this.totalSharesPending = transaction.getTotalShares() ;
+            }else {
+                this.totalSharesPending += transaction.getTotalShares() ;    
+            }
+            
         }else if(transaction.isPurchasTransaction()) {
-            this.totalSharesApproved += transaction.getTotalShares() ;
+            if(this.totalSharesApproved == null) {
+                this.totalSharesApproved = transaction.getTotalShares() ; 
+            }else {
+                this.totalSharesApproved += transaction.getTotalShares() ;
+            }
         }
         
         this.shareAccountTransactions.add(transaction);
@@ -337,6 +346,10 @@ public class ShareAccount extends AbstractPersistable<Long> {
         return this.client.getDisplayName();
     }
 
+    public Client getClient() {
+        return this.client ;
+    }
+    
     public String getSavingsAccountNo() {
         return this.savingsAccount.getAccountNumber();
     }
@@ -501,6 +514,10 @@ public class ShareAccount extends AbstractPersistable<Long> {
         return this.client.getOffice().getId();
     }
 
+    public void setTotalPendingShares(final Long shares) {
+        this.totalSharesPending = shares ;
+    }
+    
     public ShareAccountTransaction getShareAccountTransaction(final ShareAccountTransaction transaction) {
         ShareAccountTransaction returnTrans = null;
         for (ShareAccountTransaction tran : this.shareAccountTransactions) {
@@ -549,4 +566,12 @@ public class ShareAccount extends AbstractPersistable<Long> {
     public  PeriodFrequencyType getLockinPeriodFrequencyType() {
         return this.lockinPeriodFrequencyType ;
     }
+    
+    public Date getActivatedDate() {
+        return this.activatedDate ;
+    }
+    
+    public Integer status() {
+        return this.status ;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/7ae9b67d/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountTransaction.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountTransaction.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountTransaction.java
index da0d784..fb79206 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountTransaction.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountTransaction.java
@@ -239,6 +239,10 @@ public class ShareAccountTransaction extends AbstractPersistable<Long> {
         }
     }
     
+    public void updateTransactionDate(final Date transactionDate) {
+        this.transactionDate = transactionDate ;
+    }
+    
     public boolean isActive() {
         return this.active ;
     }

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/7ae9b67d/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/serialization/ShareAccountDataSerializer.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/serialization/ShareAccountDataSerializer.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/serialization/ShareAccountDataSerializer.java
index 927f6f1..78b9b35 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/serialization/ShareAccountDataSerializer.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/serialization/ShareAccountDataSerializer.java
@@ -57,6 +57,7 @@ import org.apache.fineract.portfolio.savings.service.SavingsAccountReadPlatformS
 import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccount;
 import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccountCharge;
 import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccountChargePaidBy;
+import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccountStatusType;
 import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccountTransaction;
 import org.apache.fineract.portfolio.shareproducts.domain.ShareProduct;
 import org.apache.fineract.portfolio.shareproducts.domain.ShareProductRepositoryWrapper;
@@ -287,37 +288,56 @@ public class ShareAccountDataSerializer {
         }
 
         Date existingApplicationDate = null ;
+        List<ShareAccountTransaction> purchaseTransactionsList = new ArrayList<>() ;
+        Set<ShareAccountCharge> chargesList = new HashSet<>() ;
+        
         if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.requestedshares_paramname, element)
                 || this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.charges_paramname, element)) {
             Set<ShareAccountTransaction> transactions = account.getShareAccountTransactions();
             List<Long> reveralIds = new ArrayList<>();
             for (ShareAccountTransaction transaction : transactions) {
-                transaction.setActive(false);
-                if(!transaction.isChargeTransaction()) {
-                    existingApplicationDate = transaction.getPurchasedDate() ;
+                if (transaction.isActive()) {
+                    reveralIds.add(transaction.getId());
+                    transaction.setActive(false);
+                    if (!transaction.isChargeTransaction()) {
+                        existingApplicationDate = transaction.getPurchasedDate();
+                        ShareAccountTransaction newtransaction = new ShareAccountTransaction(transaction.getPurchasedDate(),
+                                transaction.getTotalShares(), transaction.getPurchasePrice());
+                        purchaseTransactionsList.add(newtransaction);
+                    }
                 }
-                reveralIds.add(transaction.getId());
             }
             
             actualChanges.put("reversalIds", reveralIds);
             Set<ShareAccountCharge> charges = account.getCharges() ;
             for(ShareAccountCharge charge: charges) {
-                charge.setActive(false);
+                if(charge.isActive()) {
+                    charge.setActive(false);
+                    ChargeTimeType chargeTime = null;
+                    ChargeCalculationType chargeCalculation = null;
+                    Boolean status = Boolean.TRUE;
+                    ShareAccountCharge accountCharge = ShareAccountCharge.createNewWithoutShareAccount(charge.getCharge(), charge.percentageOrAmount(), chargeTime,
+                            chargeCalculation, status);
+                    chargesList.add(accountCharge) ;    
+                }
             }
         }
 
         if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.requestedshares_paramname, element)) {
             Long requestedShares = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.requestedshares_paramname, element);
+            baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname).value(requestedShares).notNull();
             Date applicationDate = null ;
+            purchaseTransactionsList.clear() ;
             if(this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.applicationdate_param, element)) {
                 applicationDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.applicationdate_param, element)
-                        .toDate();    
+                        .toDate();
+                baseDataValidator.reset().parameter(ShareAccountApiConstants.applicationdate_param).value(applicationDate).notNull();
             }else {
                 applicationDate = existingApplicationDate ;
             }
             BigDecimal unitPrice = shareProduct.deriveMarketPrice(applicationDate);
             ShareAccountTransaction transaction = new ShareAccountTransaction(applicationDate, requestedShares, unitPrice);
-            account.addTransaction(transaction);
+            purchaseTransactionsList.add(transaction) ;
             actualChanges.put(ShareAccountApiConstants.requestedshares_paramname, "Transaction");
             
             if(shareProduct.getMinimumClientShares() != null && requestedShares < shareProduct.getMinimumClientShares()) {
@@ -329,13 +349,14 @@ public class ShareAccountDataSerializer {
                 baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname).value(requestedShares)
                 .failWithCode("client.can.not.purchase.shares.morethan.product.definition", "Client can not purchase shares more than product definition");
             }
-        }/*else if(this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.charges_paramname, element)) {
-            //Since we are removing all purchase transactions when either charge param or requestedShares param exists
-            for(ShareAccountTransaction transaction:existingTransactions) {
-                account.addTransaction(transaction);
-            }
-        }*/
-
+        }
+        
+        if(!purchaseTransactionsList.isEmpty()) {
+            ShareAccountTransaction transaction = purchaseTransactionsList.get(0) ;
+            account.addTransaction(transaction);
+            account.setTotalPendingShares(transaction.getTotalShares());
+        }
+        
         if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.allowdividendcalculationforinactiveclients_paramname, element)) {
             Boolean allowdividendsForInactiveClients = this.fromApiJsonHelper.extractBooleanNamed(
                     ShareAccountApiConstants.allowdividendcalculationforinactiveclients_paramname, element);
@@ -381,17 +402,20 @@ public class ShareAccountDataSerializer {
         if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.charges_paramname, element)) {
             shareProduct = account.getShareProduct();
             final MonetaryCurrency currency = shareProduct.getCurrency();
-            Set<ShareAccountCharge> charges = assembleListOfAccountCharges(element, currency.getCode());
-            if (charges != null) {
-                for (ShareAccountCharge charge : charges) {
-                    charge.update(account);
-                }
-                account.addCharges(charges);
-                if (!charges.isEmpty()) {
+            chargesList = assembleListOfAccountCharges(element, currency.getCode());
+            if (chargesList != null) {
+                if (!chargesList.isEmpty()) {
                     actualChanges.put(ShareAccountApiConstants.charges_paramname, new HashSet<ShareAccountCharge>());
                 }
             }
         }
+        if(chargesList != null && !chargesList.isEmpty()) {
+            for (ShareAccountCharge charge : chargesList) {
+                charge.update(account);
+            }
+            account.addCharges(chargesList);
+        }
+        
         createChargeTransaction(account);
         if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
         return actualChanges;
@@ -406,6 +430,9 @@ public class ShareAccountDataSerializer {
         final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
         final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("sharesaccount");
         JsonElement element = jsonCommand.parsedJson();
+        if(!account.status().equals(ShareAccountStatusType.SUBMITTED_AND_PENDING_APPROVAL.getValue())) {
+            baseDataValidator.failWithCodeNoParameterAddedToErrorCode("is.not.pending.for.approval");
+        }
         LocalDate approvedDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.approveddate_paramname, element);
         final LocalDate submittalDate = new LocalDate(account.getSubmittedDate());
         if (approvedDate != null && approvedDate.isBefore(submittalDate)) {
@@ -470,23 +497,15 @@ public class ShareAccountDataSerializer {
     public Map<String, Object> validateAndUndoApprove(JsonCommand jsonCommand, ShareAccount account) {
         Map<String, Object> actualChanges = new HashMap<>();
         if (StringUtils.isBlank(jsonCommand.json())) { throw new InvalidJsonException(); }
-        // final Type typeOfMap = new TypeToken<Map<String, Object>>()
-        // {}.getType();
-        // this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap,
-        // jsonCommand.json(), ShareAccountApiConstants.activateParameters);
-        // final List<ApiParameterError> dataValidationErrors = new
-        // ArrayList<>();
-        // final DataValidatorBuilder baseDataValidator = new
-        // DataValidatorBuilder(dataValidationErrors).resource("sharesaccount");
-        // JsonElement element = jsonCommand.parsedJson();
-        // String notes =
-        // this.fromApiJsonHelper.extractStringNamed(ShareAccountApiConstants.note_paramname,
-        // element);
-        // baseDataValidator.reset().parameter(ShareAccountApiConstants.approveddate_paramname).validateDateAfter(account.get)
-        // AppUser approvedUser =
-        // this.platformSecurityContext.authenticatedUser();
+        final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
+        this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, jsonCommand.json(), ShareAccountApiConstants.activateParameters);
+        final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
+        final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("sharesaccount");
+        if(!account.status().equals(ShareAccountStatusType.APPROVED.getValue())) {
+            baseDataValidator.failWithCodeNoParameterAddedToErrorCode("is.not.in.approved.status");
+        }
         account.undoApprove();
-        updateTotalChargeDerivedForUndoApproval(account) ;
+        updateTotalChargeDerivedForUndoApproval(account);
         actualChanges.put(ShareAccountApiConstants.charges_paramname, Boolean.TRUE);
         return actualChanges;
     }
@@ -537,6 +556,9 @@ public class ShareAccountDataSerializer {
         final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
         final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("sharesaccount");
         JsonElement element = jsonCommand.parsedJson();
+        if(!account.status().equals(ShareAccountStatusType.APPROVED.getValue())) {
+            baseDataValidator.failWithCodeNoParameterAddedToErrorCode("is.not.in.approved.status");
+        }
         LocalDate activatedDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.activatedate_paramname, element);
         baseDataValidator.reset().parameter(ShareAccountApiConstants.activatedate_paramname).value(activatedDate).notNull();
         final LocalDate approvedDate = new LocalDate(account.getApprovedDate());
@@ -565,6 +587,7 @@ public class ShareAccountDataSerializer {
         Set<ShareAccountTransaction> transactions = account.getChargeTransactions();
         for (ShareAccountTransaction transaction : transactions) {
             if (transaction.isChargeTransaction()) {
+                transaction.updateTransactionDate(account.getActivatedDate());
                 transaction.updateAmountPaid(transaction.amount());
             }
         }
@@ -614,6 +637,9 @@ public class ShareAccountDataSerializer {
         final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
         final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("sharesaccount");
         JsonElement element = jsonCommand.parsedJson();
+        if(!account.status().equals(ShareAccountStatusType.ACTIVE.getValue())) {
+            baseDataValidator.failWithCodeNoParameterAddedToErrorCode("is.not.in.active.state") ;
+        }
         LocalDate requestedDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.requesteddate_paramname, element);
         baseDataValidator.reset().parameter(ShareAccountApiConstants.requesteddate_paramname).value(requestedDate).notNull();
         final Long sharesRequested = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.requestedshares_paramname, element);
@@ -775,11 +801,6 @@ public class ShareAccountDataSerializer {
         final Long sharesRequested = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.requestedshares_paramname, element);
         baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname).value(sharesRequested).notNull()
                 .longGreaterThanZero();
-
-        final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(element.getAsJsonObject());
-        final BigDecimal unitPrice = this.fromApiJsonHelper.extractBigDecimalNamed(ShareAccountApiConstants.purchasedprice_paramname,
-                element, locale);
-        baseDataValidator.reset().parameter(ShareAccountApiConstants.purchasedprice_paramname).value(unitPrice).notNull().positiveAmount();
         boolean isTransactionBeforeExistingTransactions = false ;
         Set<ShareAccountTransaction> transactions = account.getShareAccountTransactions() ;
         for(ShareAccountTransaction transaction: transactions) {
@@ -797,6 +818,7 @@ public class ShareAccountDataSerializer {
             .failWithCodeNoParameterAddedToErrorCode("redeem.transaction.date.cannot.be.before.existing.transactions");
         }
         if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
+        BigDecimal unitPrice = account.getShareProduct().deriveMarketPrice(requestedDate.toDate()) ;
         ShareAccountTransaction transaction = ShareAccountTransaction.createRedeemTransaction(requestedDate.toDate(), sharesRequested,
                 unitPrice);
         validateRedeemRequest(account, transaction, baseDataValidator, dataValidationErrors) ;
@@ -949,8 +971,6 @@ public class ShareAccountDataSerializer {
         account.close(closedDate.toDate(), approvedUser);
         handleRedeemSharesChargeTransactions(account, transaction);
         actualChanges.put(ShareAccountApiConstants.requestedshares_paramname, transaction);
-        updateTotalChargeDerived(account);
-       
         return actualChanges;
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/7ae9b67d/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountReadPlatformServiceImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountReadPlatformServiceImpl.java
index 90ab5b0..8d9cbee 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountReadPlatformServiceImpl.java
@@ -30,10 +30,13 @@ import java.util.Set;
 import org.apache.fineract.infrastructure.core.data.EnumOptionData;
 import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
 import org.apache.fineract.infrastructure.core.service.DateUtils;
+import org.apache.fineract.infrastructure.core.service.Page;
+import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.organisation.monetary.data.CurrencyData;
 import org.apache.fineract.portfolio.accountdetails.data.ShareAccountSummaryData;
 import org.apache.fineract.portfolio.accounts.constants.AccountsApiConstants;
+import org.apache.fineract.portfolio.accounts.constants.ShareAccountApiConstants;
 import org.apache.fineract.portfolio.accounts.data.AccountData;
 import org.apache.fineract.portfolio.charge.data.ChargeData;
 import org.apache.fineract.portfolio.charge.service.ChargeReadPlatformService;
@@ -45,17 +48,16 @@ import org.apache.fineract.portfolio.products.service.ProductReadPlatformService
 import org.apache.fineract.portfolio.savings.DepositAccountType;
 import org.apache.fineract.portfolio.savings.data.SavingsAccountData;
 import org.apache.fineract.portfolio.savings.service.SavingsAccountReadPlatformService;
-import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountTransactionData;
 import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountApplicationTimelineData;
-import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountDividendData;
-import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountStatusEnumData;
 import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountChargeData;
 import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountData;
+import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountDividendData;
+import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountStatusEnumData;
+import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountTransactionData;
 import org.apache.fineract.portfolio.shareaccounts.domain.PurchasedSharesStatusType;
 import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccountStatusType;
-import org.apache.fineract.portfolio.shareproducts.SharePeriodFrequencyType;
-import org.apache.fineract.portfolio.shareproducts.data.ShareProductMarketPriceData;
 import org.apache.fineract.portfolio.shareproducts.data.ShareProductData;
+import org.apache.fineract.portfolio.shareproducts.data.ShareProductMarketPriceData;
 import org.apache.fineract.portfolio.shareproducts.service.ShareProductDropdownReadPlatformService;
 import org.joda.time.LocalDate;
 import org.joda.time.format.DateTimeFormat;
@@ -78,7 +80,8 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat
     private final PurchasedSharesReadPlatformService purchasedSharesReadPlatformService;
     private final JdbcTemplate jdbcTemplate;
     private final DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");
-
+    private final PaginationHelper<AccountData> shareAccountDataPaginationHelper = new PaginationHelper<>();
+    
     @Autowired
     public ShareAccountReadPlatformServiceImpl(final RoutingDataSource dataSource, final ApplicationContext applicationContext,
             final ChargeReadPlatformService chargeReadPlatformService,
@@ -148,7 +151,7 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat
         
         ShareAccountMapper mapper = new ShareAccountMapper(charges, purchasedShares);
         String query = "select " + mapper.schema() + "where sa.id=?";
-        ShareAccountData data = this.jdbcTemplate.queryForObject(query, mapper, new Object[] { id });
+        ShareAccountData data = (ShareAccountData)this.jdbcTemplate.queryForObject(query, mapper, new Object[] { id });
         String serviceName = "share" + ProductsApiConstants.READPLATFORM_NAME;
         ProductReadPlatformService service = (ProductReadPlatformService) this.applicationContext.getBean(serviceName);
         final ShareProductData productData = (ShareProductData) service.retrieveOne(data.getProductId(), false);
@@ -179,13 +182,30 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat
     }
 
     @Override
-    public Collection<AccountData> retrieveAll() {
-        return null;
+    public Page<AccountData> retrieveAll(final Integer offSet, final Integer limit) {
+        final Collection<ShareAccountChargeData> charges = null ;
+        final Collection<ShareAccountTransactionData> purchasedShares = null ;
+        ShareAccountMapper mapper = new ShareAccountMapper(charges, purchasedShares) ;
+        StringBuilder sqlBuilder = new StringBuilder();
+        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append(mapper.schema());
+        sqlBuilder.append(" where sa.status_enum = ? ");
+        if (limit != null) {
+            sqlBuilder.append(" limit ").append(limit);
+        }
+        if (offSet != null) {
+            sqlBuilder.append(" offset ").append(offSet);
+        }
+
+        final String sqlCountRows = "SELECT FOUND_ROWS()";
+        Object[] whereClauseItemsitems = new Object[] {ShareAccountStatusType.ACTIVE.getValue()};
+        return this.shareAccountDataPaginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(),
+                whereClauseItemsitems, mapper);
     }
 
     @Override
     public Set<String> getResponseDataParams() {
-        return null;
+        return ShareAccountApiConstants.supportedParameters;
     }
 
     @Override
@@ -222,7 +242,7 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat
         return savingsCharges;
     }
 
-    private final static class ShareAccountMapper implements RowMapper<ShareAccountData> {
+    private final static class ShareAccountMapper implements RowMapper<AccountData> {
 
         private final Collection<ShareAccountChargeData> charges;
         private final Collection<ShareAccountTransactionData> purchasedShares;
@@ -328,16 +348,14 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat
 
             final Integer lockinPeriodFrequencyTypeValue = JdbcSupport.getInteger(rs, "lockinPeriodEnum");
             if (lockinPeriodFrequencyTypeValue != null) {
-                final SharePeriodFrequencyType lockinPeriodType = SharePeriodFrequencyType.fromInt(lockinPeriodFrequencyTypeValue);
-                lockinPeriodFrequencyType = SharesEnumerations.lockinPeriodFrequencyType(lockinPeriodType);
+                lockinPeriodFrequencyType = SharesEnumerations.lockinPeriodFrequencyType(lockinPeriodFrequencyTypeValue);
             }
 
             final Integer minimumActivePeriod = JdbcSupport.getInteger(rs, "minimumactivePeriod");
             EnumOptionData minimumActivePeriodType = null;
             final Integer minimumActivePeriodTypeValue = JdbcSupport.getInteger(rs, "minimumactivePeriodEnum");
             if (minimumActivePeriodTypeValue != null) {
-                final SharePeriodFrequencyType minmumPeriodType = SharePeriodFrequencyType.fromInt(minimumActivePeriodTypeValue);
-                minimumActivePeriodType = SharesEnumerations.lockinPeriodFrequencyType(minmumPeriodType);
+                minimumActivePeriodType = SharesEnumerations.minimumActivePeriodFrequencyType(minimumActivePeriodTypeValue);
             }
 
             final String shortProductName = null;
@@ -467,6 +485,7 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat
             schema = buff.toString();
         }
 
+        @SuppressWarnings("unused")
         @Override
         public ShareAccountDividendData mapRow(ResultSet rs, int rowNum) throws SQLException {
             final Long id = rs.getLong("id");

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/7ae9b67d/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountWritePlatformServiceJpaRepositoryImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountWritePlatformServiceJpaRepositoryImpl.java
index d4f4cd7..4bf7a85 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountWritePlatformServiceJpaRepositoryImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountWritePlatformServiceJpaRepositoryImpl.java
@@ -27,6 +27,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.fineract.accounting.journalentry.service.JournalEntryWritePlatformService;
 import org.apache.fineract.infrastructure.accountnumberformat.domain.AccountNumberFormat;
 import org.apache.fineract.infrastructure.accountnumberformat.domain.AccountNumberFormatRepositoryWrapper;
@@ -39,6 +40,8 @@ import org.apache.fineract.organisation.monetary.data.CurrencyData;
 import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
 import org.apache.fineract.portfolio.accounts.constants.ShareAccountApiConstants;
 import org.apache.fineract.portfolio.client.domain.AccountNumberGenerator;
+import org.apache.fineract.portfolio.note.domain.Note;
+import org.apache.fineract.portfolio.note.domain.NoteRepository;
 import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountTransactionEnumData;
 import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccount;
 import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccountChargePaidBy;
@@ -67,19 +70,23 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA
 
     private final JournalEntryWritePlatformService journalEntryWritePlatformService;
 
+    private final NoteRepository noteRepository;
+    
     @Autowired
     public ShareAccountWritePlatformServiceJpaRepositoryImpl(final ShareAccountDataSerializer accountDataSerializer,
             final ShareAccountRepositoryWrapper shareAccountRepository, 
             final ShareProductRepositoryWrapper shareProductRepository,
             final AccountNumberGenerator accountNumberGenerator,
             final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository,
-            final JournalEntryWritePlatformService journalEntryWritePlatformService) {
+            final JournalEntryWritePlatformService journalEntryWritePlatformService,
+            final NoteRepository noteRepository) {
         this.accountDataSerializer = accountDataSerializer;
         this.shareAccountRepository = shareAccountRepository;
         this.shareProductRepository = shareProductRepository ;
         this.accountNumberGenerator = accountNumberGenerator;
         this.accountNumberFormatRepository = accountNumberFormatRepository;
         this.journalEntryWritePlatformService = journalEntryWritePlatformService;
+        this.noteRepository = noteRepository ;
     }
 
     @Override
@@ -181,6 +188,7 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA
                 this.journalEntryWritePlatformService.revertShareAccountJournalEntries(reversalIds, transactionDate);
                 journalEntryWritePlatformService.createJournalEntriesForShares(populateJournalEntries(account,
                         account.getPendingForApprovalSharePurchaseTransactions()));
+                changes.remove("reversalIds") ;
             }
             return new CommandProcessingResultBuilder() //
                     .withCommandId(jsonCommand.commandId()) //
@@ -231,6 +239,12 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA
             Map<String, Object> changes = this.accountDataSerializer.validateAndApprove(jsonCommand, account);
             if (!changes.isEmpty()) {
                 this.shareAccountRepository.save(account);
+                final String noteText = jsonCommand.stringValueOfParameterNamed("note");
+                if (StringUtils.isNotBlank(noteText)) {
+                    final Note note = Note.shareNote(account, noteText);
+                    changes.put("note", noteText);
+                    this.noteRepository.save(note);
+                }
             }
             Set<ShareAccountTransaction> transactions = account.getShareAccountTransactions();
             Set<ShareAccountTransaction> journalTransactions = new HashSet<>();
@@ -265,6 +279,12 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA
             Map<String, Object> changes = this.accountDataSerializer.validateAndReject(jsonCommand, account);
             if (!changes.isEmpty()) {
                 this.shareAccountRepository.save(account);
+                final String noteText = jsonCommand.stringValueOfParameterNamed("note");
+                if (StringUtils.isNotBlank(noteText)) {
+                    final Note note = Note.shareNote(account, noteText);
+                    changes.put("note", noteText);
+                    this.noteRepository.save(note);
+                }
             }
             Set<ShareAccountTransaction> transactions = account.getShareAccountTransactions();
             Set<ShareAccountTransaction> journalTransactions = new HashSet<>();
@@ -293,6 +313,12 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA
             Map<String, Object> changes = this.accountDataSerializer.validateAndUndoApprove(jsonCommand, account);
             if (!changes.isEmpty()) {
                 this.shareAccountRepository.save(account);
+                final String noteText = jsonCommand.stringValueOfParameterNamed("note");
+                if (StringUtils.isNotBlank(noteText)) {
+                    final Note note = Note.shareNote(account, noteText);
+                    changes.put("note", noteText);
+                    this.noteRepository.save(note);
+                }
             }
             
             Set<ShareAccountTransaction> transactions = account.getShareAccountTransactions() ;
@@ -447,6 +473,12 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA
             Map<String, Object> changes = this.accountDataSerializer.validateAndClose(jsonCommand, account);
             if (!changes.isEmpty()) {
                 this.shareAccountRepository.save(account);
+                final String noteText = jsonCommand.stringValueOfParameterNamed("note");
+                if (StringUtils.isNotBlank(noteText)) {
+                    final Note note = Note.shareNote(account, noteText);
+                    changes.put("note", noteText);
+                    this.noteRepository.save(note);
+                }
                 ShareAccountTransaction transaction = (ShareAccountTransaction) changes
                         .get(ShareAccountApiConstants.requestedshares_paramname);
                 transaction = account.getShareAccountTransaction(transaction);

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/7ae9b67d/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/SharesEnumerations.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/SharesEnumerations.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/SharesEnumerations.java
index 9be43d9..f6bb976 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/SharesEnumerations.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/SharesEnumerations.java
@@ -121,8 +121,39 @@ public class SharesEnumerations {
         return lockinPeriodFrequencyType(SharePeriodFrequencyType.fromInt(id));
     }
 
+    public static EnumOptionData minimumActivePeriodFrequencyType(final int id) {
+        return minimumActivePeriodFrequencyType(SharePeriodFrequencyType.fromInt(id));
+    }
+    
+    public static EnumOptionData minimumActivePeriodFrequencyType(final SharePeriodFrequencyType type) {
+        final String codePrefix = "shares.minimumactive." ;
+        EnumOptionData optionData = new EnumOptionData(SharePeriodFrequencyType.INVALID.getValue().longValue(),
+                SharePeriodFrequencyType.INVALID.getCode(), "Invalid");
+        switch (type) {
+            case INVALID:
+            break;
+            case DAYS:
+                optionData = new EnumOptionData(SharePeriodFrequencyType.DAYS.getValue().longValue(), codePrefix
+                        + SharePeriodFrequencyType.DAYS.getCode(), "Days");
+            break;
+            case WEEKS:
+                optionData = new EnumOptionData(SharePeriodFrequencyType.WEEKS.getValue().longValue(), codePrefix
+                        + SharePeriodFrequencyType.WEEKS.getCode(), "Weeks");
+            break;
+            case MONTHS:
+                optionData = new EnumOptionData(SharePeriodFrequencyType.MONTHS.getValue().longValue(), codePrefix
+                        + SharePeriodFrequencyType.MONTHS.getCode(), "Months");
+            break;
+            case YEARS:
+                optionData = new EnumOptionData(SharePeriodFrequencyType.YEARS.getValue().longValue(), codePrefix
+                        + SharePeriodFrequencyType.YEARS.getCode(), "Years");
+            break;
+        }
+        return optionData;
+    }
+    
     public static EnumOptionData lockinPeriodFrequencyType(final SharePeriodFrequencyType type) {
-        final String codePrefix = "savings.lockin.";
+        final String codePrefix = "shares.lockin." ;
         EnumOptionData optionData = new EnumOptionData(SharePeriodFrequencyType.INVALID.getValue().longValue(),
                 SharePeriodFrequencyType.INVALID.getCode(), "Invalid");
         switch (type) {

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/7ae9b67d/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/serialization/ShareProductDataSerializer.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/serialization/ShareProductDataSerializer.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/serialization/ShareProductDataSerializer.java
index 02c08d9..076861d 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/serialization/ShareProductDataSerializer.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/serialization/ShareProductDataSerializer.java
@@ -172,6 +172,7 @@ public class ShareProductDataSerializer {
                 sharesIssued, unitPrice, shareCapitalValue, minimumClientShares, nominalClientShares, maximumClientShares, marketPriceSet,
                 charges, allowdividendsForInactiveClients, lockinPeriod, lockPeriodType, minimumActivePeriod, minimumActivePeriodType,
                 createdBy, createdDate, modifiedBy, modifiedOn, accountingRuleType);
+       
         for (ShareProductMarketPrice data : marketPriceSet) {
             data.setShareProduct(product);
         }
@@ -204,7 +205,7 @@ public class ShareProductDataSerializer {
     }
 
     private Set<ShareProductMarketPrice> asembleShareMarketPrice(final JsonElement element) {
-        Set<ShareProductMarketPrice> set = null;
+        Set<ShareProductMarketPrice> set = new HashSet<>();
         if (this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.marketprice_paramname, element)) {
             set = new HashSet<>();
             JsonArray array = this.fromApiJsonHelper.extractJsonArrayNamed(ShareProductApiConstants.marketprice_paramname, element);

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/7ae9b67d/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/service/ShareProductReadPlatformServiceImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/service/ShareProductReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/service/ShareProductReadPlatformServiceImpl.java
index 64dc94e..853051c 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/service/ShareProductReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/service/ShareProductReadPlatformServiceImpl.java
@@ -45,9 +45,9 @@ import org.apache.fineract.portfolio.charge.service.ChargeReadPlatformService;
 import org.apache.fineract.portfolio.products.data.ProductData;
 import org.apache.fineract.portfolio.products.exception.ProductNotFoundException;
 import org.apache.fineract.portfolio.products.service.ProductReadPlatformService;
-import org.apache.fineract.portfolio.savings.service.SavingsEnumerations;
-import org.apache.fineract.portfolio.shareproducts.data.ShareProductMarketPriceData;
+import org.apache.fineract.portfolio.shareaccounts.service.SharesEnumerations;
 import org.apache.fineract.portfolio.shareproducts.data.ShareProductData;
+import org.apache.fineract.portfolio.shareproducts.data.ShareProductMarketPriceData;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.dao.EmptyResultDataAccessException;
 import org.springframework.jdbc.core.JdbcTemplate;
@@ -63,7 +63,7 @@ public class ShareProductReadPlatformServiceImpl implements ProductReadPlatformS
     private final ShareProductDropdownReadPlatformService shareProductDropdownReadPlatformService;
     private final AccountingDropdownReadPlatformService accountingDropdownReadPlatformService;
     private final ProductToGLAccountMappingReadPlatformService accountMappingReadPlatformService;
-    private final PaginationHelper<ProductData> provisioningEntryDataPaginationHelper = new PaginationHelper<>();
+    private final PaginationHelper<ProductData> shareProductDataPaginationHelper = new PaginationHelper<>();
 
     @Autowired
     public ShareProductReadPlatformServiceImpl(final RoutingDataSource dataSource,
@@ -81,7 +81,9 @@ public class ShareProductReadPlatformServiceImpl implements ProductReadPlatformS
 
     @Override
     public Page<ProductData> retrieveAllProducts(Integer offSet, Integer limit) {
-        AllShareProductRowMapper mapper = new AllShareProductRowMapper();
+        final Collection<ShareProductMarketPriceData> shareMarketCollection = null ;
+        final Collection<ChargeData> charges = null ;
+        ShareProductRowMapper mapper = new ShareProductRowMapper(shareMarketCollection, charges);
         StringBuilder sqlBuilder = new StringBuilder();
         sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
         sqlBuilder.append(mapper.schema());
@@ -94,7 +96,7 @@ public class ShareProductReadPlatformServiceImpl implements ProductReadPlatformS
 
         final String sqlCountRows = "SELECT FOUND_ROWS()";
         Object[] whereClauseItemsitems = new Object[] {};
-        return this.provisioningEntryDataPaginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(),
+        return this.shareProductDataPaginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(),
                 whereClauseItemsitems, mapper);
     }
 
@@ -168,6 +170,7 @@ public class ShareProductReadPlatformServiceImpl implements ProductReadPlatformS
 
     private static final class AllShareProductRowMapper implements RowMapper<ProductData> {
 
+        @SuppressWarnings("unused")
         @Override
         public ShareProductData mapRow(ResultSet rs, int rowNum) throws SQLException {
             final Long id = rs.getLong("id");
@@ -184,6 +187,7 @@ public class ShareProductReadPlatformServiceImpl implements ProductReadPlatformS
 
     private static final class MarketPriceRowMapper implements RowMapper<ShareProductMarketPriceData> {
 
+        @SuppressWarnings("unused")
         @Override
         public ShareProductMarketPriceData mapRow(ResultSet rs, int rowNum) throws SQLException {
             final Long id = rs.getLong("id");
@@ -226,6 +230,7 @@ public class ShareProductReadPlatformServiceImpl implements ProductReadPlatformS
 
         }
 
+        @SuppressWarnings("unused")
         @Override
         public ShareProductData mapRow(ResultSet rs, int rowNum) throws SQLException {
             final Long id = rs.getLong("id");
@@ -258,14 +263,14 @@ public class ShareProductReadPlatformServiceImpl implements ProductReadPlatformS
             final Integer minimumActviePeriodEnumValue = JdbcSupport.getInteger(rs, "minimum_active_period_frequency_enum");
             EnumOptionData minimumActivePeriodType = null;
             if (minimumActviePeriodEnumValue != null) {
-                minimumActivePeriodType = SavingsEnumerations.lockinPeriodFrequencyType(minimumActviePeriodEnumValue);
+                minimumActivePeriodType = SharesEnumerations.minimumActivePeriodFrequencyType(minimumActviePeriodEnumValue);
             }
 
             final Integer lockinPeriodFrequency = JdbcSupport.getInteger(rs, "lockin_period_frequency");
             EnumOptionData lockinPeriodFrequencyType = null;
             final Integer lockinPeriodFrequencyTypeValue = JdbcSupport.getInteger(rs, "lockin_period_frequency_enum");
             if (lockinPeriodFrequencyTypeValue != null) {
-                lockinPeriodFrequencyType = SavingsEnumerations.lockinPeriodFrequencyType(lockinPeriodFrequencyTypeValue);
+                lockinPeriodFrequencyType = SharesEnumerations.lockinPeriodFrequencyType(lockinPeriodFrequencyTypeValue);
             }
             final Integer accountingRuleId = JdbcSupport.getInteger(rs, "accountingType");
             final EnumOptionData accountingRuleType = AccountingEnumerations.accountingRuleType(accountingRuleId);

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/7ae9b67d/fineract-provider/src/main/resources/sql/migrations/core_db/V307__add_share_notes.sql
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/resources/sql/migrations/core_db/V307__add_share_notes.sql b/fineract-provider/src/main/resources/sql/migrations/core_db/V307__add_share_notes.sql
new file mode 100644
index 0000000..9e52c3e
--- /dev/null
+++ b/fineract-provider/src/main/resources/sql/migrations/core_db/V307__add_share_notes.sql
@@ -0,0 +1,2 @@
+ALTER TABLE `m_note`
+ADD COLUMN `share_account_id` BIGINT(20) NULL DEFAULT NULL AFTER `savings_account_transaction_id`;
\ No newline at end of file


[3/3] incubator-fineract git commit: Shares Integration Tests and Fixes

Posted by na...@apache.org.
Shares Integration Tests and Fixes


Project: http://git-wip-us.apache.org/repos/asf/incubator-fineract/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-fineract/commit/7ae9b67d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-fineract/tree/7ae9b67d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-fineract/diff/7ae9b67d

Branch: refs/heads/develop
Commit: 7ae9b67d930c50b736d995910c4b8f3184569db7
Parents: 0b81e80
Author: Nazeer Hussain Shaik <na...@confluxtechnologies.com>
Authored: Tue May 17 12:34:22 2016 +0530
Committer: Nazeer Hussain Shaik <na...@confluxtechnologies.com>
Committed: Tue May 17 12:34:54 2016 +0530

----------------------------------------------------------------------
 .../common/charges/ChargesHelper.java           |   67 +-
 .../shares/DividendsIntegrationTests.java       |  203 ++++
 .../common/shares/ShareAccountHelper.java       |  144 +++
 .../shares/ShareAccountIntegrationTests.java    | 1032 ++++++++++++++++++
 .../shares/ShareAccountTransactionHelper.java   |   55 +
 .../shares/ShareDividendsTransactionHelper.java |   58 +
 .../common/shares/ShareProductHelper.java       |  199 ++++
 .../shares/ShareProductTransactionHelper.java   |   51 +
 .../accounts/api/AccountsApiResource.java       |   56 +-
 .../service/AccountReadPlatformService.java     |    4 +-
 .../fineract/portfolio/note/domain/Note.java    |   17 +
 .../portfolio/note/domain/NoteType.java         |    5 +-
 .../products/api/ProductsApiResource.java       |   61 +-
 .../exception/ResourceNotFoundException.java    |   33 +
 .../shareaccounts/domain/ShareAccount.java      |   29 +-
 .../domain/ShareAccountTransaction.java         |    4 +
 .../ShareAccountDataSerializer.java             |  108 +-
 .../ShareAccountReadPlatformServiceImpl.java    |   49 +-
 ...ntWritePlatformServiceJpaRepositoryImpl.java |   34 +-
 .../service/SharesEnumerations.java             |   33 +-
 .../ShareProductDataSerializer.java             |    3 +-
 .../ShareProductReadPlatformServiceImpl.java    |   19 +-
 .../core_db/V307__add_share_notes.sql           |    2 +
 23 files changed, 2136 insertions(+), 130 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/7ae9b67d/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/charges/ChargesHelper.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/charges/ChargesHelper.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/charges/ChargesHelper.java
index c8134a6..b4b7dc5 100755
--- a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/charges/ChargesHelper.java
+++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/charges/ChargesHelper.java
@@ -37,7 +37,8 @@ public class ChargesHelper {
     private static final Integer CHARGE_APPLIES_TO_LOAN = 1;
     private static final Integer CHARGE_APPLIES_TO_SAVINGS = 2;
     private static final Integer CHARGE_APPLIES_TO_CLIENT = 3;
-
+    private static final Integer CHARGE_APPLIES_TO_SHARES = 4;
+    
     private static final Integer CHARGE_DISBURSEMENT_FEE = 1;
     private static final Integer CHARGE_SPECIFIED_DUE_DATE = 2;
     private static final Integer CHARGE_SAVINGS_ACTIVATION_FEE = 3;
@@ -48,6 +49,10 @@ public class ChargesHelper {
     private static final Integer CHARGE_OVERDUE_INSTALLMENT_FEE = 9;
     private static final Integer CHARGE_OVERDRAFT_FEE = 10;
     private static final Integer WEEKLY_FEE = 11;
+    private static final Integer SHAREACCOUNT_ACTIVATION = 13 ;
+    private static final Integer SHARE_PURCHASE = 14 ;
+    private static final Integer SHARE_REDEEM = 15 ;
+    
     private static final Integer CHARGE_SAVINGS_NO_ACTIVITY_FEE = 16;
     
     private static final Integer CHARGE_CLIENT_SPECIFIED_DUE_DATE = 1;
@@ -235,6 +240,27 @@ public class ChargesHelper {
         return getLoanInstallmentJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, ChargesHelper.amount, ChargesHelper.penalty);
     }
 
+    public static String getShareAccountActivationChargeJson() {
+        HashMap<String, Object> map = populateDefaultsShareActivationCharge() ;
+        String chargesCreateJson = new Gson().toJson(map);
+        System.out.println(chargesCreateJson);
+        return chargesCreateJson;
+    }
+    
+    public static String getShareAccountPurchaseChargeJson() {
+        HashMap<String, Object> map = populateDefaultsSharePurchaseFlatCharge() ;
+        String chargesCreateJson = new Gson().toJson(map);
+        System.out.println(chargesCreateJson);
+        return chargesCreateJson;
+    }
+    
+    public static String getShareAccountRedeemChargeJson() {
+        HashMap<String, Object> map = populateDefaultsShareRedeemFlatCharge() ;
+        String chargesCreateJson = new Gson().toJson(map);
+        System.out.println(chargesCreateJson);
+        return chargesCreateJson;
+    }
+    
     public static String getLoanOverdueFeeJSON() {
         final HashMap<String, Object> map = populateDefaultsForLoan();
         map.put("penalty", ChargesHelper.penalty);
@@ -287,6 +313,45 @@ public class ChargesHelper {
         return map;
     }
 
+    public static HashMap<String, Object> populateDefaultsShareActivationCharge() {
+        final HashMap<String, Object> map = new HashMap<>();
+        map.put("active", ChargesHelper.active);
+        map.put("amount", ChargesHelper.amount);
+        map.put("chargeAppliesTo", ChargesHelper.CHARGE_APPLIES_TO_SHARES);
+        map.put("chargeCalculationType", ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT);
+        map.put("chargeTimeType",ChargesHelper.SHAREACCOUNT_ACTIVATION);
+        map.put("currencyCode", ChargesHelper.currencyCode);
+        map.put("locale", CommonConstants.locale);
+        map.put("name", Utils.randomNameGenerator("Charge_Share_Activation_", 8));
+        return map;
+    }
+    
+    public static HashMap<String, Object> populateDefaultsSharePurchaseFlatCharge() {
+        final HashMap<String, Object> map = new HashMap<>();
+        map.put("active", ChargesHelper.active);
+        map.put("amount", ChargesHelper.amount);
+        map.put("chargeAppliesTo", ChargesHelper.CHARGE_APPLIES_TO_SHARES);
+        map.put("chargeCalculationType", ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT);
+        map.put("chargeTimeType",ChargesHelper.SHARE_PURCHASE);
+        map.put("currencyCode", ChargesHelper.currencyCode);
+        map.put("locale", CommonConstants.locale);
+        map.put("name", Utils.randomNameGenerator("Charge_Share_Purchase_", 8));
+        return map;
+    }
+    
+    public static HashMap<String, Object> populateDefaultsShareRedeemFlatCharge() {
+        final HashMap<String, Object> map = new HashMap<>();
+        map.put("active", ChargesHelper.active);
+        map.put("amount", ChargesHelper.amount);
+        map.put("chargeAppliesTo", ChargesHelper.CHARGE_APPLIES_TO_SHARES);
+        map.put("chargeCalculationType", ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT);
+        map.put("chargeTimeType",ChargesHelper.SHARE_REDEEM);
+        map.put("currencyCode", ChargesHelper.currencyCode);
+        map.put("locale", CommonConstants.locale);
+        map.put("name", Utils.randomNameGenerator("Charge_Share_Redeem_", 8));
+        return map;
+    }
+    
     public static Integer createCharges(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
             final String request) {
         return Utils.performServerPost(requestSpec, responseSpec, CREATE_CHARGES_URL, request, "resourceId");

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/7ae9b67d/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/DividendsIntegrationTests.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/DividendsIntegrationTests.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/DividendsIntegrationTests.java
new file mode 100644
index 0000000..5634dce
--- /dev/null
+++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/DividendsIntegrationTests.java
@@ -0,0 +1,203 @@
+/**
+ * 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.
+ */
+package org.apache.fineract.integrationtests.common.shares;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.fineract.integrationtests.common.ClientHelper;
+import org.apache.fineract.integrationtests.common.Utils;
+import org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper;
+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;
+
+
+public class DividendsIntegrationTests {
+
+    private final String[] dates = {"01 Jan 2015", "01 Apr 2015", "01 Oct 2015", "01 Dec 2015", "01 Mar 2016"} ;
+    private final String[] shares = {"100", "200", "300", "100", "500"} ;
+    
+    private RequestSpecification requestSpec;
+    private ResponseSpecification responseSpec;
+
+    @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();
+    }
+    
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testCreateDividends() {
+        DateFormat simple = new SimpleDateFormat("dd MMM yyyy");
+        final Integer productId = createShareProduct() ;
+        ArrayList<Integer> clients = new ArrayList<>() ;
+        ArrayList<Integer> savingAccounts = new ArrayList<>() ;
+        ArrayList<Integer> shareAccounts = new ArrayList<>() ;
+        for(int i = 0  ; i < 5; i++) {
+            final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec);
+            clients.add(clientId) ;
+            Assert.assertNotNull(clientId);
+            Integer savingsAccountId = SavingsAccountHelper.openSavingsAccount(requestSpec, responseSpec, clientId, "1000");
+            savingAccounts.add(savingsAccountId) ;
+            Assert.assertNotNull(savingsAccountId);
+            final Integer shareAccountId = createShareAccount(clientId, productId, savingsAccountId, dates[i], shares[i]);
+            shareAccounts.add(shareAccountId) ;
+            Assert.assertNotNull(shareAccountId);
+            Map<String, Object> shareAccountData = ShareAccountTransactionHelper
+                    .retrieveShareAccount(shareAccountId, requestSpec, responseSpec);
+            Assert.assertNotNull(shareAccountData);    
+         // Approve share Account
+            Map<String, Object> approveMap = new HashMap<>();
+            approveMap.put("note", "Share Account Approval Note");
+            approveMap.put("dateFormat", "dd MMMM yyyy");
+            approveMap.put("approvedDate", "01 Jan 2016");
+            approveMap.put("locale", "en");
+            String approve = new Gson().toJson(approveMap);
+            ShareAccountTransactionHelper.postCommand("approve", shareAccountId, approve, requestSpec, responseSpec);
+            //Activate Share Account
+            Map<String, Object> activateMap = new HashMap<>();
+            activateMap.put("dateFormat", "dd MMMM yyyy");
+            activateMap.put("activatedDate", "01 Jan 2016");
+            activateMap.put("locale", "en");
+            String activateJson = new Gson().toJson(activateMap);
+            ShareAccountTransactionHelper.postCommand("activate", shareAccountId, activateJson, requestSpec, responseSpec);
+        }
+        
+        Map<String, Object> dividendsMap = new HashMap<>() ;
+        dividendsMap.put("dividendPeriodStartDate", "01 Jan 2015") ;
+        dividendsMap.put("dividendPeriodEndDate", "01 Apr 2016") ;
+        dividendsMap.put("dividendAmount", "50000") ;
+        dividendsMap.put("dateFormat", "dd MMMM yyyy");
+        dividendsMap.put("locale", "en");
+        String createDividendsJson = new Gson().toJson(dividendsMap);
+        final Integer dividendId = ShareDividendsTransactionHelper.createShareProductDividends(productId, createDividendsJson, requestSpec, responseSpec) ;
+        
+        Map<String, Object> productdividends = ShareDividendsTransactionHelper.retrieveAllDividends(productId, requestSpec, responseSpec);
+        Assert.assertEquals("1", String.valueOf(productdividends.get("totalFilteredRecords")));
+        Map<String,Object> dividend = ((List<Map<String,Object>>)productdividends.get("pageItems")).get(0) ;
+        Assert.assertEquals("50000.0", String.valueOf(dividend.get("amount"))) ;
+        Map<String, Object> status = (Map<String, Object>)dividend.get("status") ;
+        Assert.assertEquals("shareAccountDividendStatusType.initiated", String.valueOf(status.get("code")));
+        List<Integer> startdateList = (List<Integer>) dividend.get("dividendPeriodStartDate");
+        Calendar cal = Calendar.getInstance();
+        cal.set(startdateList.get(0), startdateList.get(1) - 1, startdateList.get(2));
+        Date startDate = cal.getTime();
+        Assert.assertEquals("01 Jan 2015", simple.format(startDate));
+        List<Integer> enddateList = (List<Integer>) dividend.get("dividendPeriodEndDate");
+        cal = Calendar.getInstance();
+        cal.set(enddateList.get(0), enddateList.get(1) - 1, enddateList.get(2));
+        Date endDate = cal.getTime();
+        Assert.assertEquals("01 Apr 2016", simple.format(endDate));
+        
+        
+        
+        Map<String, Object> dividenddetails = ShareDividendsTransactionHelper.retrieveDividendDetails(productId, dividendId, requestSpec, responseSpec) ;
+        Assert.assertEquals("5", String.valueOf(dividenddetails.get("totalFilteredRecords")));
+        List<Map<String, Object>> pageItems = (List<Map<String, Object>>)dividenddetails.get("pageItems") ;
+        for(Map<String, Object> dividendData: pageItems) {
+            Map<String, Object> accountData = (Map<String, Object>) dividendData.get("accountData") ; 
+            String accountId = String.valueOf(accountData.get("id")) ;
+            if(String.valueOf(shareAccounts.get(0)).equals(accountId)) {
+                Assert.assertEquals("11320.755", String.valueOf(dividendData.get("amount")));
+            }else if(String.valueOf(shareAccounts.get(1)).equals(accountId)) {
+                Assert.assertEquals("18172.791", String.valueOf(dividendData.get("amount")));
+            }else if(String.valueOf(shareAccounts.get(2)).equals(accountId)) {
+                Assert.assertEquals("13629.593", String.valueOf(dividendData.get("amount")));
+            }else if(String.valueOf(shareAccounts.get(3)).equals(accountId)) {
+                Assert.assertEquals("3028.7983", String.valueOf(dividendData.get("amount")));
+            }else if(String.valueOf(shareAccounts.get(4)).equals(accountId)) {
+                Assert.assertEquals("3848.0637", String.valueOf(dividendData.get("amount")));
+            }
+            Map<String, Object> statusMap = (Map<String, Object>) dividendData.get("status") ;
+            Assert.assertEquals("shareAccountDividendStatusType.initiated", String.valueOf(statusMap.get("code"))) ;
+        }
+        
+        String jsonString = "" ;
+        ShareDividendsTransactionHelper.postCommand("approve", productId, dividendId, jsonString, requestSpec, responseSpec) ;
+        
+        productdividends = ShareDividendsTransactionHelper.retrieveAllDividends(productId, requestSpec, responseSpec);
+        Assert.assertEquals("1", String.valueOf(productdividends.get("totalFilteredRecords")));
+        dividend = ((List<Map<String,Object>>)productdividends.get("pageItems")).get(0) ;
+        Assert.assertEquals("50000.0", String.valueOf(dividend.get("amount"))) ;
+        status = (Map<String, Object>)dividend.get("status") ;
+        Assert.assertEquals("shareAccountDividendStatusType.approved", String.valueOf(status.get("code")));
+        startdateList = (List<Integer>) dividend.get("dividendPeriodStartDate");
+        cal = Calendar.getInstance();
+        cal.set(startdateList.get(0), startdateList.get(1) - 1, startdateList.get(2));
+        startDate = cal.getTime();
+        Assert.assertEquals("01 Jan 2015", simple.format(startDate));
+        enddateList = (List<Integer>) dividend.get("dividendPeriodEndDate");
+        cal = Calendar.getInstance();
+        cal.set(enddateList.get(0), enddateList.get(1) - 1, enddateList.get(2));
+        endDate = cal.getTime();
+        Assert.assertEquals("01 Apr 2016", simple.format(endDate));
+        
+        dividenddetails = ShareDividendsTransactionHelper.retrieveDividendDetails(productId, dividendId, requestSpec, responseSpec) ;
+        Assert.assertEquals("5", String.valueOf(dividenddetails.get("totalFilteredRecords")));
+        pageItems = (List<Map<String, Object>>)dividenddetails.get("pageItems") ;
+        for(Map<String, Object> dividendData: pageItems) {
+            Map<String, Object> accountData = (Map<String, Object>) dividendData.get("accountData") ; 
+            String accountId = String.valueOf(accountData.get("id")) ;
+            if(String.valueOf(shareAccounts.get(0)).equals(accountId)) {
+                Assert.assertEquals("11320.755", String.valueOf(dividendData.get("amount")));
+            }else if(String.valueOf(shareAccounts.get(1)).equals(accountId)) {
+                Assert.assertEquals("18172.791", String.valueOf(dividendData.get("amount")));
+            }else if(String.valueOf(shareAccounts.get(2)).equals(accountId)) {
+                Assert.assertEquals("13629.593", String.valueOf(dividendData.get("amount")));
+            }else if(String.valueOf(shareAccounts.get(3)).equals(accountId)) {
+                Assert.assertEquals("3028.7983", String.valueOf(dividendData.get("amount")));
+            }else if(String.valueOf(shareAccounts.get(4)).equals(accountId)) {
+                Assert.assertEquals("3848.0637", String.valueOf(dividendData.get("amount")));
+            }
+            Map<String, Object> statusMap = (Map<String, Object>) dividendData.get("status") ;
+            Assert.assertEquals("shareAccountDividendStatusType.initiated", String.valueOf(statusMap.get("code"))) ;
+        }
+        
+    }
+    
+    private Integer createShareProduct() {
+        String shareProductJson = new ShareProductHelper().build();
+        return ShareProductTransactionHelper.createShareProduct(shareProductJson, requestSpec, responseSpec);
+    }
+    
+    private Integer createShareAccount(final Integer clientId, final Integer productId, final Integer savingsAccountId,
+            String applicationDate, String requestedShares) {
+        String josn = new ShareAccountHelper().withClientId(String.valueOf(clientId)).withProductId(String.valueOf(productId))
+                .withExternalId("External1").withSavingsAccountId(String.valueOf(savingsAccountId)).withSubmittedDate("01 Jan 2016")
+                .withApplicationDate(applicationDate).withRequestedShares(requestedShares).build();
+        return ShareAccountTransactionHelper.createShareAccount(josn, requestSpec, responseSpec);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/7ae9b67d/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountHelper.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountHelper.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountHelper.java
new file mode 100644
index 0000000..9984656
--- /dev/null
+++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountHelper.java
@@ -0,0 +1,144 @@
+/**
+ * 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.
+ */
+package org.apache.fineract.integrationtests.common.shares;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.google.gson.Gson;
+
+
+public class ShareAccountHelper {
+
+    private static final String LOCALE = "en_GB";
+    
+    private String clientId ;
+    
+    private String productId ;
+    
+    private String submittedDate ;
+    
+    private String externalId ;
+    
+    private String savingsAccountId ;
+    
+    private String requestedShares ;
+    
+    private String applicationDate ;
+    
+    private String allowDividendCalculationForInactiveClients ;
+    
+    private String minimumActivePeriod ;
+    
+    private String minimumActivePeriodFrequencyType ;
+    
+    private String lockinPeriodFrequency ;
+    
+    private String lockinPeriodFrequencyType ;
+    
+    private List<Map<String, Object>> charges = null ;
+            //chargeId , amount
+    
+    public String build() {
+        final HashMap<String, Object> map = new HashMap<>();
+        map.put("locale", LOCALE);
+        if(this.clientId != null) {
+            map.put("clientId", this.clientId) ;    
+        }
+        if(this.productId != null) {
+            map.put("productId", this.productId) ;
+        }
+        map.put("dateFormat", "dd MMMM yyyy");
+        
+        if(this.savingsAccountId != null) {
+            map.put("savingsAccountId", savingsAccountId) ;
+        }
+ 
+        if(externalId != null) {
+            map.put("externalId", this.externalId) ;
+        }
+        
+        if(submittedDate != null) {
+            map.put("submittedDate", this.submittedDate) ;
+        }
+        
+        if(applicationDate != null) {
+            map.put("applicationDate", this.applicationDate) ;
+        }
+        
+        if(this.requestedShares != null) {
+            map.put("requestedShares", this.requestedShares) ;
+        }
+        
+        if(this.allowDividendCalculationForInactiveClients != null) {
+            map.put("allowDividendCalculationForInactiveClients", this.allowDividendCalculationForInactiveClients) ;
+        }
+        
+        if(this.charges != null) {
+           map.put("charges", this.charges) ;
+        }
+        
+        String shareAccountCreateJson = new Gson().toJson(map);
+        System.out.println(shareAccountCreateJson);
+        return shareAccountCreateJson;
+    }
+    
+    public ShareAccountHelper withClientId(final String clientId) {
+        this.clientId = clientId ;
+        return this ;
+    }
+    
+    public ShareAccountHelper withProductId(final String productId) {
+        this.productId = productId ;
+        return this ;
+    }
+    
+    public ShareAccountHelper withSavingsAccountId(final String savingsAccountId) {
+        this.savingsAccountId = savingsAccountId ;
+        return this ;
+    }
+    
+    public ShareAccountHelper withSubmittedDate(final String submittedDate) {
+        this.submittedDate = submittedDate ;
+        return this ;
+    }
+    
+    public ShareAccountHelper withRequestedShares(final String requestedShares) {
+        this.requestedShares = requestedShares ;
+        return this ;
+    }
+    
+    public ShareAccountHelper withApplicationDate(final String applicationDate) {
+        this.applicationDate = applicationDate ;
+        return this ;
+    }
+    
+    public ShareAccountHelper withExternalId(final String externalId) {
+        this.externalId = externalId ;
+        return this ;
+    }
+    
+    public ShareAccountHelper withCharges(final List<Map<String,Object>> charges) {
+        this.charges = new ArrayList<>() ;
+        this.charges.addAll(charges) ;
+        return this ;
+    }
+}


[2/3] incubator-fineract git commit: Shares Integration Tests and Fixes

Posted by na...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/7ae9b67d/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountIntegrationTests.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountIntegrationTests.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountIntegrationTests.java
new file mode 100644
index 0000000..cb90464
--- /dev/null
+++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountIntegrationTests.java
@@ -0,0 +1,1032 @@
+/**
+ * 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.
+ */
+package org.apache.fineract.integrationtests.common.shares;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.fineract.infrastructure.core.service.DateUtils;
+import org.apache.fineract.integrationtests.common.ClientHelper;
+import org.apache.fineract.integrationtests.common.Utils;
+import org.apache.fineract.integrationtests.common.charges.ChargesHelper;
+import org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper;
+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;
+
+public class ShareAccountIntegrationTests {
+
+    private RequestSpecification requestSpec;
+    private ResponseSpecification responseSpec;
+    private ShareProductHelper shareProductHelper;
+
+    @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();
+    }
+
+    @Test
+    public void testCreateShareProduct() {
+        // This method will check create share product, get share product,
+        // update share product.
+        System.out.println("------------------------------CREATING NEW SHARE PRODUCT ---------------------------------------");
+        shareProductHelper = new ShareProductHelper();
+        final Integer shareProductId = createShareProduct();
+        Assert.assertNotNull(shareProductId);
+        System.out.println("------------------------------CREATING SHARE PRODUCT COMPLETE---------------------------------------");
+
+        System.out.println("------------------------------RETRIEVING SHARE PRODUCT---------------------------------------");
+        Map<String, Object> shareProductData = ShareProductTransactionHelper
+                .retrieveShareProduct(shareProductId, requestSpec, responseSpec);
+        Assert.assertNotNull(shareProductData);
+        shareProductHelper.verifyShareProduct(shareProductData);
+
+        System.out.println("------------------------------RETRIEVING SHARE PRODUCT COMPLETE---------------------------------------");
+
+        System.out.println("------------------------------UPDATING SHARE PRODUCT---------------------------------------");
+
+        Map<String, Object> shareProductDataForUpdate = new HashMap<>();
+
+        shareProductDataForUpdate.put("totalShares", "2000");
+        shareProductDataForUpdate.put("sharesIssued", "2000");
+
+        String updateShareProductJsonString = new Gson().toJson(shareProductDataForUpdate);
+        Integer updatedProductId = ShareProductTransactionHelper.updateShareProduct(shareProductId, updateShareProductJsonString,
+                requestSpec, responseSpec);
+        Assert.assertNotNull(updatedProductId);
+        Map<String, Object> updatedShareProductData = ShareProductTransactionHelper.retrieveShareProduct(updatedProductId, requestSpec,
+                responseSpec);
+        String updatedTotalShares = String.valueOf(updatedShareProductData.get("totalShares"));
+        String updatedSharesIssued = String.valueOf(updatedShareProductData.get("totalSharesIssued"));
+        Assert.assertEquals("2000", updatedTotalShares);
+        Assert.assertEquals("2000", updatedSharesIssued);
+        System.out.println("------------------------------UPDATING SHARE PRODUCT COMPLETE---------------------------------------");
+
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testCreateShareAccount() {
+        shareProductHelper = new ShareProductHelper();
+        final Integer productId = createShareProduct();
+        Assert.assertNotNull(productId);
+        final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec);
+        Assert.assertNotNull(clientId);
+        Integer savingsAccountId = SavingsAccountHelper.openSavingsAccount(requestSpec, responseSpec, clientId, "1000");
+        Assert.assertNotNull(savingsAccountId);
+        final Integer shareAccountId = createShareAccount(clientId, productId, savingsAccountId);
+        Assert.assertNotNull(shareAccountId);
+        Map<String, Object> shareProductData = ShareAccountTransactionHelper
+                .retrieveShareAccount(shareAccountId, requestSpec, responseSpec);
+        Assert.assertNotNull(shareProductData);
+
+        Map<String, Object> shareAccountDataForUpdate = new HashMap<>();
+        shareAccountDataForUpdate.put("requestedShares", 30);
+        shareAccountDataForUpdate.put("applicationDate", "02 Mar 2016");
+        shareAccountDataForUpdate.put("dateFormat", "dd MMMM yyyy");
+        shareAccountDataForUpdate.put("locale", "en_GB");
+        String updateShareAccountJsonString = new Gson().toJson(shareAccountDataForUpdate);
+        ShareAccountTransactionHelper.updateShareAccount(shareAccountId, updateShareAccountJsonString, requestSpec, responseSpec);
+        shareProductData = ShareAccountTransactionHelper.retrieveShareAccount(shareAccountId, requestSpec, responseSpec);
+        List<Map<String, Object>> transactions = (List<Map<String, Object>>) shareProductData.get("purchasedShares");
+        Assert.assertNotNull(transactions);
+        Assert.assertEquals(1, transactions.size());
+        Map<String, Object> transaction = transactions.get(0);
+        Assert.assertEquals("30", String.valueOf(transaction.get("numberOfShares")));
+        Assert.assertEquals("60.0", String.valueOf(transaction.get("amount")));
+        Assert.assertEquals("60.0", String.valueOf(transaction.get("amountPaid")));
+        List<Integer> dateList = (List<Integer>) transaction.get("purchasedDate");
+        Calendar cal = Calendar.getInstance();
+        cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2));
+        Date date = cal.getTime();
+        DateFormat simple = new SimpleDateFormat("dd MMM yyyy");
+        Assert.assertEquals("02 Mar 2016", simple.format(date));
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testShareAccountApproval() {
+        DateFormat simple = new SimpleDateFormat("dd MMM yyyy");
+        shareProductHelper = new ShareProductHelper();
+        final Integer productId = createShareProduct();
+        Assert.assertNotNull(productId);
+        final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec);
+        Assert.assertNotNull(clientId);
+        Integer savingsAccountId = SavingsAccountHelper.openSavingsAccount(requestSpec, responseSpec, clientId, "1000");
+        Assert.assertNotNull(savingsAccountId);
+        String activationCharge = ChargesHelper.getShareAccountActivationChargeJson();
+        Integer activationChargeId = ChargesHelper.createCharges(requestSpec, responseSpec, activationCharge);
+        String purchaseCharge = ChargesHelper.getShareAccountPurchaseChargeJson();
+        Integer purchaseChargeId = ChargesHelper.createCharges(requestSpec, responseSpec, purchaseCharge);
+        String redeemCharge = ChargesHelper.getShareAccountRedeemChargeJson();
+        Integer redeemChargeId = ChargesHelper.createCharges(requestSpec, responseSpec, redeemCharge);
+        List<Map<String, Object>> charges = new ArrayList<>();
+        charges.add(createCharge(activationChargeId, "2"));
+        charges.add(createCharge(purchaseChargeId, "2"));
+        charges.add(createCharge(redeemChargeId, "1"));
+        final Integer shareAccountId = createShareAccount(clientId, productId, savingsAccountId, charges);
+        Assert.assertNotNull(shareAccountId);
+        Map<String, Object> shareAccountData = ShareAccountTransactionHelper
+                .retrieveShareAccount(shareAccountId, requestSpec, responseSpec);
+        Assert.assertNotNull(shareAccountData);
+        
+     // Approve share Account
+        Map<String, Object> approveMap = new HashMap<>();
+        approveMap.put("note", "Share Account Approval Note");
+        approveMap.put("dateFormat", "dd MMMM yyyy");
+        approveMap.put("approvedDate", "01 Jan 2016");
+        approveMap.put("locale", "en");
+        String approve = new Gson().toJson(approveMap);
+        ShareAccountTransactionHelper.postCommand("approve", shareAccountId, approve, requestSpec, responseSpec);
+        shareAccountData = ShareAccountTransactionHelper
+                .retrieveShareAccount(shareAccountId, requestSpec, responseSpec);
+        Map<String, Object> statusMap = (Map<String, Object>) shareAccountData.get("status");
+        Assert.assertEquals("shareAccountStatusType.approved", String.valueOf(statusMap.get("code")));
+        Map<String, Object> timelineMap = (Map<String, Object>) shareAccountData.get("timeline");
+        List<Integer> dateList = (List<Integer>) timelineMap.get("approvedDate");
+        Calendar cal = Calendar.getInstance();
+        cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2));
+        Date approvedDate = cal.getTime();
+        Assert.assertEquals("01 Jan 2016", simple.format(approvedDate));
+        List<Map<String, Object>> transactions = (List<Map<String, Object>>) shareAccountData.get("purchasedShares");
+        Assert.assertNotNull(transactions);
+        Assert.assertEquals(2, transactions.size());
+        for (int i = 0; i < transactions.size(); i++) {
+            Map<String, Object> transaction = transactions.get(i);
+            Map<String, Object> transactionTypeMap = (Map<String, Object>) transaction.get("type");
+            dateList = (List<Integer>) transaction.get("purchasedDate");
+            cal = Calendar.getInstance();
+            cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2));
+            Date date = cal.getTime();
+            String transactionType = (String) transactionTypeMap.get("code");
+            if (transactionType.equals("purchasedSharesType.purchased")) {
+                Assert.assertEquals("25", String.valueOf(transaction.get("numberOfShares")));
+                Assert.assertEquals("52.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("52.0", String.valueOf(transaction.get("amountPaid")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice")));
+                Assert.assertEquals("01 Jan 2016", simple.format(date));
+            } else if (transactionType.equals("charge.payment")) {
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("0", String.valueOf(transaction.get("amountPaid")));
+                Date transactionDate = DateUtils.getDateOfTenant() ;
+                Assert.assertEquals(simple.format(transactionDate), simple.format(date));
+            }
+        }
+
+        Map<String, Object> summaryMap = (Map<String, Object>) shareAccountData.get("summary");
+        Assert.assertEquals("25", String.valueOf(summaryMap.get("totalApprovedShares")));
+        Assert.assertEquals("0", String.valueOf(summaryMap.get("totalPendingForApprovalShares")));
+    }
+    @Test
+    @SuppressWarnings("unchecked")
+    public void rejectShareAccount() {
+        shareProductHelper = new ShareProductHelper();
+        final Integer productId = createShareProduct();
+        Assert.assertNotNull(productId);
+        final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec);
+        Assert.assertNotNull(clientId);
+        Integer savingsAccountId = SavingsAccountHelper.openSavingsAccount(requestSpec, responseSpec, clientId, "1000");
+        Assert.assertNotNull(savingsAccountId);
+        String activationCharge = ChargesHelper.getShareAccountActivationChargeJson();
+        Integer activationChargeId = ChargesHelper.createCharges(requestSpec, responseSpec, activationCharge);
+        String purchaseCharge = ChargesHelper.getShareAccountPurchaseChargeJson();
+        Integer purchaseChargeId = ChargesHelper.createCharges(requestSpec, responseSpec, purchaseCharge);
+        String redeemCharge = ChargesHelper.getShareAccountRedeemChargeJson();
+        Integer redeemChargeId = ChargesHelper.createCharges(requestSpec, responseSpec, redeemCharge);
+        List<Map<String, Object>> charges = new ArrayList<>();
+        charges.add(createCharge(activationChargeId, "2"));
+        charges.add(createCharge(purchaseChargeId, "2"));
+        charges.add(createCharge(redeemChargeId, "1"));
+        final Integer shareAccountId = createShareAccount(clientId, productId, savingsAccountId, charges);
+        Assert.assertNotNull(shareAccountId);
+        Map<String, Object> shareAccountData = ShareAccountTransactionHelper
+                .retrieveShareAccount(shareAccountId, requestSpec, responseSpec);
+        Assert.assertNotNull(shareAccountData);
+        
+        // Reject share Account
+        Map<String, Object> rejectMap = new HashMap<>();
+        rejectMap.put("note", "Share Account Rejection Note");
+        String rejectJson = new Gson().toJson(rejectMap);
+        ShareAccountTransactionHelper.postCommand("reject", shareAccountId, rejectJson, requestSpec, responseSpec);
+        shareAccountData = ShareAccountTransactionHelper
+                .retrieveShareAccount(shareAccountId, requestSpec, responseSpec);
+        DateFormat simple = new SimpleDateFormat("dd MMM yyyy");
+        Map<String, Object> statusMap = (Map<String, Object>) shareAccountData.get("status");
+        Assert.assertEquals("shareAccountStatusType.rejected", String.valueOf(statusMap.get("code")));
+        Map<String, Object> timelineMap = (Map<String, Object>) shareAccountData.get("timeline");
+        List<Integer> dateList = (List<Integer>) timelineMap.get("rejectedDate");
+        Calendar cal = Calendar.getInstance();
+        cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2));
+        Date rejectedDate = cal.getTime();
+        Date currentTenantDate = DateUtils.getDateOfTenant() ;
+        Assert.assertEquals(simple.format(currentTenantDate), simple.format(rejectedDate));
+        
+        List<Map<String, Object>> transactions = (List<Map<String, Object>>) shareAccountData.get("purchasedShares");
+        Assert.assertNotNull(transactions);
+        Assert.assertEquals(2, transactions.size());
+        for (int i = 0; i < transactions.size(); i++) {
+            Map<String, Object> transaction = transactions.get(i);
+            Map<String, Object> transactionTypeMap = (Map<String, Object>) transaction.get("type");
+            dateList = (List<Integer>) transaction.get("purchasedDate");
+            cal = Calendar.getInstance();
+            cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2));
+            Date date = cal.getTime();
+            String transactionType = (String) transactionTypeMap.get("code");
+            if (transactionType.equals("purchasedSharesType.purchased")) {
+                Assert.assertEquals("25", String.valueOf(transaction.get("numberOfShares")));
+                Assert.assertEquals("52.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("50.0", String.valueOf(transaction.get("amountPaid")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice")));
+                Assert.assertEquals("01 Jan 2016", simple.format(date));
+            } else if (transactionType.equals("charge.payment")) {
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("0", String.valueOf(transaction.get("amountPaid")));
+                Date transactionDate = DateUtils.getDateOfTenant() ;
+                Assert.assertEquals(simple.format(transactionDate), simple.format(date));
+            }
+        }
+
+        Map<String, Object> summaryMap = (Map<String, Object>) shareAccountData.get("summary");
+        Assert.assertEquals("0", String.valueOf(summaryMap.get("totalApprovedShares")));
+        Assert.assertEquals("0", String.valueOf(summaryMap.get("totalPendingForApprovalShares")));
+    }
+    
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testShareAccountUndoApproval() {
+        DateFormat simple = new SimpleDateFormat("dd MMM yyyy");
+        shareProductHelper = new ShareProductHelper();
+        final Integer productId = createShareProduct();
+        Assert.assertNotNull(productId);
+        final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec);
+        Assert.assertNotNull(clientId);
+        Integer savingsAccountId = SavingsAccountHelper.openSavingsAccount(requestSpec, responseSpec, clientId, "1000");
+        Assert.assertNotNull(savingsAccountId);
+        String activationCharge = ChargesHelper.getShareAccountActivationChargeJson();
+        Integer activationChargeId = ChargesHelper.createCharges(requestSpec, responseSpec, activationCharge);
+        String purchaseCharge = ChargesHelper.getShareAccountPurchaseChargeJson();
+        Integer purchaseChargeId = ChargesHelper.createCharges(requestSpec, responseSpec, purchaseCharge);
+        String redeemCharge = ChargesHelper.getShareAccountRedeemChargeJson();
+        Integer redeemChargeId = ChargesHelper.createCharges(requestSpec, responseSpec, redeemCharge);
+        List<Map<String, Object>> charges = new ArrayList<>();
+        charges.add(createCharge(activationChargeId, "2"));
+        charges.add(createCharge(purchaseChargeId, "2"));
+        charges.add(createCharge(redeemChargeId, "1"));
+        final Integer shareAccountId = createShareAccount(clientId, productId, savingsAccountId, charges);
+        Assert.assertNotNull(shareAccountId);
+        Map<String, Object> shareAccountData = ShareAccountTransactionHelper
+                .retrieveShareAccount(shareAccountId, requestSpec, responseSpec);
+        Assert.assertNotNull(shareAccountData);
+        
+     // Approve share Account
+        Map<String, Object> approveMap = new HashMap<>();
+        approveMap.put("note", "Share Account Approval Note");
+        approveMap.put("dateFormat", "dd MMMM yyyy");
+        approveMap.put("approvedDate", "01 Jan 2016");
+        approveMap.put("locale", "en");
+        String approve = new Gson().toJson(approveMap);
+        ShareAccountTransactionHelper.postCommand("approve", shareAccountId, approve, requestSpec, responseSpec);
+        shareAccountData = ShareAccountTransactionHelper
+                .retrieveShareAccount(shareAccountId, requestSpec, responseSpec);
+        Map<String, Object> statusMap = (Map<String, Object>) shareAccountData.get("status");
+        Assert.assertEquals("shareAccountStatusType.approved", String.valueOf(statusMap.get("code")));
+        Map<String, Object> timelineMap = (Map<String, Object>) shareAccountData.get("timeline");
+        List<Integer> dateList = (List<Integer>) timelineMap.get("approvedDate");
+        Calendar cal = Calendar.getInstance();
+        cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2));
+        Date approvedDate = cal.getTime();
+        Assert.assertEquals("01 Jan 2016", simple.format(approvedDate));
+        
+        // Undo Approval share Account
+        Map<String, Object> undoApprovalMap = new HashMap<>();
+        String undoApprovalJson = new Gson().toJson(undoApprovalMap);
+        ShareAccountTransactionHelper.postCommand("undoapproval", shareAccountId, undoApprovalJson, requestSpec, responseSpec);
+        
+        shareAccountData = ShareAccountTransactionHelper
+                .retrieveShareAccount(shareAccountId, requestSpec, responseSpec);
+        
+        statusMap = (Map<String, Object>) shareAccountData.get("status");
+        Assert.assertEquals("shareAccountStatusType.submitted.and.pending.approval", String.valueOf(statusMap.get("code")));
+        
+        List<Map<String, Object>> transactions = (List<Map<String, Object>>) shareAccountData.get("purchasedShares");
+        Assert.assertNotNull(transactions);
+        Assert.assertEquals(2, transactions.size());
+        for (int i = 0; i < transactions.size(); i++) {
+            Map<String, Object> transaction = transactions.get(i);
+            Map<String, Object> transactionTypeMap = (Map<String, Object>) transaction.get("type");
+            dateList = (List<Integer>) transaction.get("purchasedDate");
+            cal = Calendar.getInstance();
+            cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2));
+            Date date = cal.getTime();
+            String transactionType = (String) transactionTypeMap.get("code");
+            if (transactionType.equals("purchasedSharesType.purchased")) {
+                Assert.assertEquals("25", String.valueOf(transaction.get("numberOfShares")));
+                Assert.assertEquals("52.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("0.0", String.valueOf(transaction.get("amountPaid")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice")));
+                Assert.assertEquals("01 Jan 2016", simple.format(date));
+            } else if (transactionType.equals("charge.payment")) {
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("0", String.valueOf(transaction.get("amountPaid")));
+                Date transactionDate = DateUtils.getDateOfTenant() ;
+                Assert.assertEquals(simple.format(transactionDate), simple.format(date));
+            }
+        }
+
+        Map<String, Object> summaryMap = (Map<String, Object>) shareAccountData.get("summary");
+        Assert.assertEquals("0", String.valueOf(summaryMap.get("totalApprovedShares")));
+        Assert.assertEquals("25", String.valueOf(summaryMap.get("totalPendingForApprovalShares")));
+    }
+    
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testCreateShareAccountWithCharges() {
+        shareProductHelper = new ShareProductHelper();
+        final Integer productId = createShareProduct();
+        Assert.assertNotNull(productId);
+        final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec);
+        Assert.assertNotNull(clientId);
+        Integer savingsAccountId = SavingsAccountHelper.openSavingsAccount(requestSpec, responseSpec, clientId, "1000");
+        Assert.assertNotNull(savingsAccountId);
+        String activationCharge = ChargesHelper.getShareAccountActivationChargeJson();
+        Integer activationChargeId = ChargesHelper.createCharges(requestSpec, responseSpec, activationCharge);
+        String purchaseCharge = ChargesHelper.getShareAccountPurchaseChargeJson();
+        Integer purchaseChargeId = ChargesHelper.createCharges(requestSpec, responseSpec, purchaseCharge);
+        String redeemCharge = ChargesHelper.getShareAccountRedeemChargeJson();
+        Integer redeemChargeId = ChargesHelper.createCharges(requestSpec, responseSpec, redeemCharge);
+        List<Map<String, Object>> charges = new ArrayList<>();
+        charges.add(createCharge(activationChargeId, "2"));
+        charges.add(createCharge(purchaseChargeId, "2"));
+        charges.add(createCharge(redeemChargeId, "1"));
+        final Integer shareAccountId = createShareAccount(clientId, productId, savingsAccountId, charges);
+        Assert.assertNotNull(shareAccountId);
+        Map<String, Object> shareAccountData = ShareAccountTransactionHelper
+                .retrieveShareAccount(shareAccountId, requestSpec, responseSpec);
+        Assert.assertNotNull(shareAccountData);
+
+        Map<String, Object> shareAccountDataForUpdate = new HashMap<>();
+        shareAccountDataForUpdate.put("requestedShares", 30);
+        shareAccountDataForUpdate.put("applicationDate", "02 Mar 2016");
+        shareAccountDataForUpdate.put("dateFormat", "dd MMMM yyyy");
+        shareAccountDataForUpdate.put("locale", "en_GB");
+        shareAccountDataForUpdate.put("charges", charges);
+
+        String updateShareAccountJsonString = new Gson().toJson(shareAccountDataForUpdate);
+        ShareAccountTransactionHelper.updateShareAccount(shareAccountId, updateShareAccountJsonString, requestSpec, responseSpec);
+        shareAccountData = ShareAccountTransactionHelper.retrieveShareAccount(shareAccountId, requestSpec, responseSpec);
+        List<Map<String, Object>> transactions = (List<Map<String, Object>>) shareAccountData.get("purchasedShares");
+        Assert.assertNotNull(transactions);
+        Assert.assertEquals(2, transactions.size());
+        DateFormat simple = new SimpleDateFormat("dd MMM yyyy");
+        for (int i = 0; i < transactions.size(); i++) {
+            Map<String, Object> transaction = transactions.get(i);
+            Map<String, Object> transactionTypeMap = (Map<String, Object>) transaction.get("type");
+            List<Integer> dateList = (List<Integer>) transaction.get("purchasedDate");
+            Calendar cal = Calendar.getInstance();
+            cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2));
+            Date date = cal.getTime();
+            String transactionType = (String) transactionTypeMap.get("code");
+            if (transactionType.equals("purchasedSharesType.purchased")) {
+                Assert.assertEquals("30", String.valueOf(transaction.get("numberOfShares")));
+                Assert.assertEquals("62.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("60.0", String.valueOf(transaction.get("amountPaid")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice")));
+                Assert.assertEquals("02 Mar 2016", simple.format(date));
+            } else if (transactionType.equals("charge.payment")) {
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("0", String.valueOf(transaction.get("amountPaid")));
+                Assert.assertEquals("0", String.valueOf(transaction.get("chargeAmount")));
+            }
+        }
+
+        //charges verification
+        List<Map<String, Object>> chargesList = (List<Map<String, Object>>) shareAccountData.get("charges") ;
+        for(Map<String, Object> chargeDef: chargesList) {
+            Map<String, Object> chargeTimeTypeMap = (Map<String, Object>) chargeDef.get("chargeTimeType") ;
+            String chargeTimeType = String.valueOf(chargeTimeTypeMap.get("code")) ;
+            if(chargeTimeType.equals("chargeTimeType.activation")) {
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("0", String.valueOf(chargeDef.get("amountPaid")));
+            }else if(chargeTimeType.equals("chargeTimeType.sharespurchase")) {
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("0", String.valueOf(chargeDef.get("amountPaid")));
+            }else if(chargeTimeType.equals("chargeTimeType.sharesredeem")) {
+                Assert.assertEquals("1.0", String.valueOf(chargeDef.get("amountOrPercentage")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("0", String.valueOf(chargeDef.get("amountPaid")));
+            }else {
+                Assert.fail("Other Charge defintion found");
+            }
+        }
+        
+        // Approve share Account
+        Map<String, Object> approveMap = new HashMap<>();
+        approveMap.put("note", "Share Account Approval Note");
+        approveMap.put("dateFormat", "dd MMMM yyyy");
+        approveMap.put("approvedDate", "01 Jan 2016");
+        approveMap.put("locale", "en");
+        String approve = new Gson().toJson(approveMap);
+        ShareAccountTransactionHelper.postCommand("approve", shareAccountId, approve, requestSpec, responseSpec);
+        shareAccountData = ShareAccountTransactionHelper
+                .retrieveShareAccount(shareAccountId, requestSpec, responseSpec);
+        Map<String, Object> statusMap = (Map<String, Object>) shareAccountData.get("status");
+        Assert.assertEquals("shareAccountStatusType.approved", String.valueOf(statusMap.get("code")));
+        Map<String, Object> timelineMap = (Map<String, Object>) shareAccountData.get("timeline");
+        List<Integer> dateList = (List<Integer>) timelineMap.get("approvedDate");
+        Calendar cal = Calendar.getInstance();
+        cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2));
+        Date approvedDate = cal.getTime();
+        Assert.assertEquals("01 Jan 2016", simple.format(approvedDate));
+
+        //charges verification
+        chargesList = (List<Map<String, Object>>) shareAccountData.get("charges") ;
+        for(Map<String, Object> chargeDef: chargesList) {
+            Map<String, Object> chargeTimeTypeMap = (Map<String, Object>) chargeDef.get("chargeTimeType") ;
+            String chargeTimeType = String.valueOf(chargeTimeTypeMap.get("code")) ;
+            if(chargeTimeType.equals("chargeTimeType.activation")) {
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("0", String.valueOf(chargeDef.get("amountPaid")));
+            }else if(chargeTimeType.equals("chargeTimeType.sharespurchase")) {
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountPaid")));
+            }else if(chargeTimeType.equals("chargeTimeType.sharesredeem")) {
+                Assert.assertEquals("1.0", String.valueOf(chargeDef.get("amountOrPercentage")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("0", String.valueOf(chargeDef.get("amountPaid")));
+            }else {
+                Assert.fail("Other Charge defintion found");
+            }
+        }
+        
+        Map<String, Object> activateMap = new HashMap<>();
+        activateMap.put("dateFormat", "dd MMMM yyyy");
+        activateMap.put("activatedDate", "01 Jan 2016");
+        activateMap.put("locale", "en");
+        String activateJson = new Gson().toJson(activateMap);
+        ShareAccountTransactionHelper.postCommand("activate", shareAccountId, activateJson, requestSpec, responseSpec);
+        shareAccountData = ShareAccountTransactionHelper.retrieveShareAccount(shareAccountId, requestSpec, responseSpec);
+        statusMap = (Map<String, Object>) shareAccountData.get("status");
+        Assert.assertEquals("shareAccountStatusType.active", String.valueOf(statusMap.get("code")));
+        timelineMap = (Map<String, Object>) shareAccountData.get("timeline");
+        dateList = (List<Integer>) timelineMap.get("activatedDate");
+        cal = Calendar.getInstance();
+        cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2));
+        Date activatedDate = cal.getTime();
+        Assert.assertEquals("01 Jan 2016", simple.format(activatedDate));
+
+        transactions = (List<Map<String, Object>>) shareAccountData.get("purchasedShares");
+        Assert.assertNotNull(transactions);
+        Assert.assertEquals(2, transactions.size());
+        for (int i = 0; i < transactions.size(); i++) {
+            Map<String, Object> transaction = transactions.get(i);
+            Map<String, Object> transactionTypeMap = (Map<String, Object>) transaction.get("type");
+            dateList = (List<Integer>) transaction.get("purchasedDate");
+            cal = Calendar.getInstance();
+            cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2));
+            Date date = cal.getTime();
+            String transactionType = (String) transactionTypeMap.get("code");
+            if (transactionType.equals("purchasedSharesType.purchased")) {
+                Assert.assertEquals("30", String.valueOf(transaction.get("numberOfShares")));
+                Assert.assertEquals("62.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("62.0", String.valueOf(transaction.get("amountPaid")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice")));
+                Assert.assertEquals("02 Mar 2016", simple.format(date));
+            } else if (transactionType.equals("charge.payment")) {
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("amountPaid")));
+                Assert.assertEquals("0", String.valueOf(transaction.get("chargeAmount")));
+                Assert.assertEquals("01 Jan 2016", simple.format(date));
+            }
+        }
+
+      //charges verification
+        chargesList = (List<Map<String, Object>>) shareAccountData.get("charges") ;
+        for(Map<String, Object> chargeDef: chargesList) {
+            Map<String, Object> chargeTimeTypeMap = (Map<String, Object>) chargeDef.get("chargeTimeType") ;
+            String chargeTimeType = String.valueOf(chargeTimeTypeMap.get("code")) ;
+            if(chargeTimeType.equals("chargeTimeType.activation")) {
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountPaid")));
+            }else if(chargeTimeType.equals("chargeTimeType.sharespurchase")) {
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountPaid")));
+            }else if(chargeTimeType.equals("chargeTimeType.sharesredeem")) {
+                Assert.assertEquals("1.0", String.valueOf(chargeDef.get("amountOrPercentage")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("0", String.valueOf(chargeDef.get("amountPaid")));
+            }else {
+                Assert.fail("Other Charge defintion found");
+            }
+        }
+        
+        Map<String, Object> summaryMap = (Map<String, Object>) shareAccountData.get("summary");
+        Assert.assertEquals("30", String.valueOf(summaryMap.get("totalApprovedShares")));
+        Assert.assertEquals("0", String.valueOf(summaryMap.get("totalPendingForApprovalShares")));
+
+        // apply additional shares
+        Map<String, Object> additionalSharesRequestMap = new HashMap<>();
+        additionalSharesRequestMap.put("requestedDate", "01 Apr 2016");
+        additionalSharesRequestMap.put("dateFormat", "dd MMMM yyyy");
+        additionalSharesRequestMap.put("locale", "en");
+        additionalSharesRequestMap.put("requestedShares", "15");
+        String additionalSharesRequestJson = new Gson().toJson(additionalSharesRequestMap);
+        ShareAccountTransactionHelper.postCommand("applyadditionalshares", shareAccountId, additionalSharesRequestJson, requestSpec,
+                responseSpec);
+        shareAccountData = ShareAccountTransactionHelper.retrieveShareAccount(shareAccountId, requestSpec, responseSpec);
+        transactions = (List<Map<String, Object>>) shareAccountData.get("purchasedShares");
+        Assert.assertNotNull(transactions);
+        Assert.assertEquals(3, transactions.size());
+        String addtionalSharesRequestId = null;
+        for (int i = 0; i < transactions.size(); i++) {
+            Map<String, Object> transaction = transactions.get(i);
+            Map<String, Object> transactionTypeMap = (Map<String, Object>) transaction.get("type");
+            dateList = (List<Integer>) transaction.get("purchasedDate");
+            cal = Calendar.getInstance();
+            cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2));
+            Date date = cal.getTime();
+            String transactionType = (String) transactionTypeMap.get("code");
+            String transactionDate = simple.format(date);
+            if (transactionType.equals("purchasedSharesType.purchased") && transactionDate.equals("02 Mar 2016")) {
+                Assert.assertEquals("30", String.valueOf(transaction.get("numberOfShares")));
+                Assert.assertEquals("62.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("62.0", String.valueOf(transaction.get("amountPaid")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice")));
+            } else if (transactionType.equals("purchasedSharesType.purchased") && transactionDate.equals("01 Apr 2016")) {
+                addtionalSharesRequestId = String.valueOf(transaction.get("id"));
+                Assert.assertEquals("15", String.valueOf(transaction.get("numberOfShares")));
+                Assert.assertEquals("32.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("30.0", String.valueOf(transaction.get("amountPaid")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice")));
+                Map<String, Object> transactionstatusMap = (Map<String, Object>) transaction.get("status");
+                Assert.assertEquals("purchasedSharesStatusType.applied", String.valueOf(transactionstatusMap.get("code")));
+
+            } else if (transactionType.equals("charge.payment")) {
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("amountPaid")));
+                Assert.assertEquals("0", String.valueOf(transaction.get("chargeAmount")));
+                Assert.assertEquals("01 Jan 2016", transactionDate);
+            }
+        }
+
+      //charges verification
+        chargesList = (List<Map<String, Object>>) shareAccountData.get("charges") ;
+        for(Map<String, Object> chargeDef: chargesList) {
+            Map<String, Object> chargeTimeTypeMap = (Map<String, Object>) chargeDef.get("chargeTimeType") ;
+            String chargeTimeType = String.valueOf(chargeTimeTypeMap.get("code")) ;
+            if(chargeTimeType.equals("chargeTimeType.activation")) {
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountPaid")));
+            }else if(chargeTimeType.equals("chargeTimeType.sharespurchase")) {
+                Assert.assertEquals("4.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountPaid")));
+            }else if(chargeTimeType.equals("chargeTimeType.sharesredeem")) {
+                Assert.assertEquals("1.0", String.valueOf(chargeDef.get("amountOrPercentage")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("0", String.valueOf(chargeDef.get("amountPaid")));
+            }else {
+                Assert.fail("Other Charge defintion found");
+            }
+        }
+        
+        summaryMap = (Map<String, Object>) shareAccountData.get("summary");
+        Assert.assertEquals("30", String.valueOf(summaryMap.get("totalApprovedShares")));
+        Assert.assertEquals("15", String.valueOf(summaryMap.get("totalPendingForApprovalShares")));
+
+        // Approve additional Shares request
+        Map<String, List<Map<String, Object>>> approveadditionalsharesMap = new HashMap<>();
+        List<Map<String, Object>> list = new ArrayList<>();
+        Map<String, Object> idsMap = new HashMap<>();
+        idsMap.put("id", addtionalSharesRequestId);
+        list.add(idsMap);
+        approveadditionalsharesMap.put("requestedShares", list);
+        String approveadditionalsharesJson = new Gson().toJson(approveadditionalsharesMap);
+        ShareAccountTransactionHelper.postCommand("approveadditionalshares", shareAccountId, approveadditionalsharesJson, requestSpec,
+                responseSpec);
+
+        shareAccountData = ShareAccountTransactionHelper.retrieveShareAccount(shareAccountId, requestSpec, responseSpec);
+        transactions = (List<Map<String, Object>>) shareAccountData.get("purchasedShares");
+        Assert.assertNotNull(transactions);
+        Assert.assertEquals(3, transactions.size());
+        for (int i = 0; i < transactions.size(); i++) {
+            Map<String, Object> transaction = transactions.get(i);
+            Map<String, Object> transactionTypeMap = (Map<String, Object>) transaction.get("type");
+            dateList = (List<Integer>) transaction.get("purchasedDate");
+            cal = Calendar.getInstance();
+            cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2));
+            Date date = cal.getTime();
+            String transactionType = (String) transactionTypeMap.get("code");
+            String transactionDate = simple.format(date);
+            if (transactionType.equals("purchasedSharesType.purchased") && transactionDate.equals("02 Mar 2016")) {
+                Assert.assertEquals("30", String.valueOf(transaction.get("numberOfShares")));
+                Assert.assertEquals("62.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("62.0", String.valueOf(transaction.get("amountPaid")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice")));
+            } else if (transactionType.equals("purchasedSharesType.purchased") && transactionDate.equals("01 Apr 2016")) {
+                Assert.assertEquals("15", String.valueOf(transaction.get("numberOfShares")));
+                Assert.assertEquals("32.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("32.0", String.valueOf(transaction.get("amountPaid")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice")));
+                Map<String, Object> transactionstatusMap = (Map<String, Object>) transaction.get("status");
+                Assert.assertEquals("purchasedSharesStatusType.approved", String.valueOf(transactionstatusMap.get("code")));
+
+            } else if (transactionType.equals("charge.payment")) {
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("amountPaid")));
+                Assert.assertEquals("0", String.valueOf(transaction.get("chargeAmount")));
+                Assert.assertEquals("01 Jan 2016", transactionDate);
+            }
+        }
+
+      //charges verification
+        chargesList = (List<Map<String, Object>>) shareAccountData.get("charges") ;
+        for(Map<String, Object> chargeDef: chargesList) {
+            Map<String, Object> chargeTimeTypeMap = (Map<String, Object>) chargeDef.get("chargeTimeType") ;
+            String chargeTimeType = String.valueOf(chargeTimeTypeMap.get("code")) ;
+            if(chargeTimeType.equals("chargeTimeType.activation")) {
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountPaid")));
+            }else if(chargeTimeType.equals("chargeTimeType.sharespurchase")) {
+                Assert.assertEquals("4.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("4.0", String.valueOf(chargeDef.get("amountPaid")));
+            }else if(chargeTimeType.equals("chargeTimeType.sharesredeem")) {
+                Assert.assertEquals("1.0", String.valueOf(chargeDef.get("amountOrPercentage")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("0", String.valueOf(chargeDef.get("amountPaid")));
+            }else {
+                Assert.fail("Other Charge defintion found");
+            }
+        }
+        
+        summaryMap = (Map<String, Object>) shareAccountData.get("summary");
+        Assert.assertEquals("45", String.valueOf(summaryMap.get("totalApprovedShares")));
+        Assert.assertEquals("0", String.valueOf(summaryMap.get("totalPendingForApprovalShares")));
+
+        // apply aditional shres and reject it
+        additionalSharesRequestMap = new HashMap<>();
+        additionalSharesRequestMap.put("requestedDate", "01 May 2016");
+        additionalSharesRequestMap.put("dateFormat", "dd MMMM yyyy");
+        additionalSharesRequestMap.put("locale", "en");
+        additionalSharesRequestMap.put("requestedShares", "20");
+        additionalSharesRequestJson = new Gson().toJson(additionalSharesRequestMap);
+        ShareAccountTransactionHelper.postCommand("applyadditionalshares", shareAccountId, additionalSharesRequestJson, requestSpec,
+                responseSpec);
+        shareAccountData = ShareAccountTransactionHelper.retrieveShareAccount(shareAccountId, requestSpec, responseSpec);
+        transactions = (List<Map<String, Object>>) shareAccountData.get("purchasedShares");
+        Assert.assertNotNull(transactions);
+        Assert.assertEquals(4, transactions.size());
+        addtionalSharesRequestId = null;
+        for (int i = 0; i < transactions.size(); i++) {
+            Map<String, Object> transaction = transactions.get(i);
+            Map<String, Object> transactionTypeMap = (Map<String, Object>) transaction.get("type");
+            dateList = (List<Integer>) transaction.get("purchasedDate");
+            cal = Calendar.getInstance();
+            cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2));
+            Date date = cal.getTime();
+            String transactionType = (String) transactionTypeMap.get("code");
+            String transactionDate = simple.format(date);
+            if (transactionType.equals("purchasedSharesType.purchased") && transactionDate.equals("01 May 2016")) {
+                addtionalSharesRequestId = String.valueOf(transaction.get("id"));
+                Assert.assertEquals("20", String.valueOf(transaction.get("numberOfShares")));
+                Assert.assertEquals("42.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("40.0", String.valueOf(transaction.get("amountPaid")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice")));
+                Map<String, Object> transactionstatusMap = (Map<String, Object>) transaction.get("status");
+                Assert.assertEquals("purchasedSharesStatusType.applied", String.valueOf(transactionstatusMap.get("code")));
+            }
+        }
+
+      //charges verification
+        chargesList = (List<Map<String, Object>>) shareAccountData.get("charges") ;
+        for(Map<String, Object> chargeDef: chargesList) {
+            Map<String, Object> chargeTimeTypeMap = (Map<String, Object>) chargeDef.get("chargeTimeType") ;
+            String chargeTimeType = String.valueOf(chargeTimeTypeMap.get("code")) ;
+            if(chargeTimeType.equals("chargeTimeType.activation")) {
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountPaid")));
+            }else if(chargeTimeType.equals("chargeTimeType.sharespurchase")) {
+                Assert.assertEquals("6.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("4.0", String.valueOf(chargeDef.get("amountPaid")));
+            }else if(chargeTimeType.equals("chargeTimeType.sharesredeem")) {
+                Assert.assertEquals("1.0", String.valueOf(chargeDef.get("amountOrPercentage")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("0", String.valueOf(chargeDef.get("amountPaid")));
+            }else {
+                Assert.fail("Other Charge defintion found");
+            }
+        }
+        
+        summaryMap = (Map<String, Object>) shareAccountData.get("summary");
+        Assert.assertEquals("45", String.valueOf(summaryMap.get("totalApprovedShares")));
+        Assert.assertEquals("20", String.valueOf(summaryMap.get("totalPendingForApprovalShares")));
+
+        // rejectadditionalshares
+        Map<String, List<Map<String, Object>>> rejectadditionalsharesMap = new HashMap<>();
+        list = new ArrayList<>();
+        idsMap = new HashMap<>();
+        idsMap.put("id", addtionalSharesRequestId);
+        list.add(idsMap);
+        rejectadditionalsharesMap.put("requestedShares", list);
+        String rejectadditionalsharesJson = new Gson().toJson(rejectadditionalsharesMap);
+        ShareAccountTransactionHelper.postCommand("rejectadditionalshares", shareAccountId, rejectadditionalsharesJson, requestSpec,
+                responseSpec);
+        shareAccountData = ShareAccountTransactionHelper.retrieveShareAccount(shareAccountId, requestSpec, responseSpec);
+        transactions = (List<Map<String, Object>>) shareAccountData.get("purchasedShares");
+        Assert.assertNotNull(transactions);
+        Assert.assertEquals(4, transactions.size());
+        for (int i = 0; i < transactions.size(); i++) {
+            Map<String, Object> transaction = transactions.get(i);
+            Map<String, Object> transactionTypeMap = (Map<String, Object>) transaction.get("type");
+            dateList = (List<Integer>) transaction.get("purchasedDate");
+            cal = Calendar.getInstance();
+            cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2));
+            Date date = cal.getTime();
+            String transactionType = (String) transactionTypeMap.get("code");
+            String transactionDate = simple.format(date);
+            if (transactionType.equals("purchasedSharesType.purchased") && transactionDate.equals("01 May 2016")) {
+                addtionalSharesRequestId = String.valueOf(transaction.get("id"));
+                Assert.assertEquals("20", String.valueOf(transaction.get("numberOfShares")));
+                Assert.assertEquals("40.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("40.0", String.valueOf(transaction.get("amountPaid")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice")));
+                Map<String, Object> transactionstatusMap = (Map<String, Object>) transaction.get("status");
+                Assert.assertEquals("purchasedSharesStatusType.rejected", String.valueOf(transactionstatusMap.get("code")));
+            }
+        }
+
+      //charges verification
+        chargesList = (List<Map<String, Object>>) shareAccountData.get("charges") ;
+        for(Map<String, Object> chargeDef: chargesList) {
+            Map<String, Object> chargeTimeTypeMap = (Map<String, Object>) chargeDef.get("chargeTimeType") ;
+            String chargeTimeType = String.valueOf(chargeTimeTypeMap.get("code")) ;
+            if(chargeTimeType.equals("chargeTimeType.activation")) {
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountPaid")));
+            }else if(chargeTimeType.equals("chargeTimeType.sharespurchase")) {
+                Assert.assertEquals("6.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("6.0", String.valueOf(chargeDef.get("amountPaid")));
+            }else if(chargeTimeType.equals("chargeTimeType.sharesredeem")) {
+                Assert.assertEquals("1.0", String.valueOf(chargeDef.get("amountOrPercentage")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("0", String.valueOf(chargeDef.get("amountPaid")));
+            }else {
+                Assert.fail("Other Charge defintion found");
+            }
+        }
+        
+        summaryMap = (Map<String, Object>) shareAccountData.get("summary");
+        Assert.assertEquals("45", String.valueOf(summaryMap.get("totalApprovedShares")));
+        Assert.assertEquals("0", String.valueOf(summaryMap.get("totalPendingForApprovalShares")));
+
+        // redeem shares
+        Map<String, Object> redeemRequestMap = new HashMap<>();
+        redeemRequestMap.put("requestedDate", "05 May 2016");
+        redeemRequestMap.put("dateFormat", "dd MMMM yyyy");
+        redeemRequestMap.put("locale", "en");
+        redeemRequestMap.put("requestedShares", "15");
+        String redeemRequestJson = new Gson().toJson(redeemRequestMap);
+        ShareAccountTransactionHelper.postCommand("redeemshares", shareAccountId, redeemRequestJson, requestSpec, responseSpec);
+        shareAccountData = ShareAccountTransactionHelper.retrieveShareAccount(shareAccountId, requestSpec, responseSpec);
+        transactions = (List<Map<String, Object>>) shareAccountData.get("purchasedShares");
+        Assert.assertNotNull(transactions);
+        Assert.assertEquals(5, transactions.size());
+        for (int i = 0; i < transactions.size(); i++) {
+            Map<String, Object> transaction = transactions.get(i);
+            Map<String, Object> transactionTypeMap = (Map<String, Object>) transaction.get("type");
+            dateList = (List<Integer>) transaction.get("purchasedDate");
+            cal = Calendar.getInstance();
+            cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2));
+            Date date = cal.getTime();
+            String transactionType = (String) transactionTypeMap.get("code");
+            String transactionDate = simple.format(date);
+            if (transactionType.equals("purchasedSharesType.purchased") && transactionDate.equals("02 Mar 2016")) {
+                Assert.assertEquals("30", String.valueOf(transaction.get("numberOfShares")));
+                Assert.assertEquals("62.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("62.0", String.valueOf(transaction.get("amountPaid")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice")));
+            } else if (transactionType.equals("purchasedSharesType.purchased") && transactionDate.equals("01 Apr 2016")) {
+                Assert.assertEquals("15", String.valueOf(transaction.get("numberOfShares")));
+                Assert.assertEquals("32.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("32.0", String.valueOf(transaction.get("amountPaid")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice")));
+                Map<String, Object> transactionstatusMap = (Map<String, Object>) transaction.get("status");
+                Assert.assertEquals("purchasedSharesStatusType.approved", String.valueOf(transactionstatusMap.get("code")));
+            } else if (transactionType.equals("purchasedSharesType.redeemed") && transactionDate.equals("05 May 2016")) {
+                Assert.assertEquals("15", String.valueOf(transaction.get("numberOfShares")));
+                Assert.assertEquals("29.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("29.0", String.valueOf(transaction.get("amountPaid")));
+                Assert.assertEquals("1.0", String.valueOf(transaction.get("chargeAmount")));
+                Map<String, Object> transactionstatusMap = (Map<String, Object>) transaction.get("status");
+                Assert.assertEquals("purchasedSharesStatusType.approved", String.valueOf(transactionstatusMap.get("code")));
+            } else if (transactionType.equals("charge.payment")) {
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("amountPaid")));
+                Assert.assertEquals("0", String.valueOf(transaction.get("chargeAmount")));
+                Assert.assertEquals("01 Jan 2016", transactionDate);
+            }
+        }
+
+      //charges verification
+        chargesList = (List<Map<String, Object>>) shareAccountData.get("charges") ;
+        for(Map<String, Object> chargeDef: chargesList) {
+            Map<String, Object> chargeTimeTypeMap = (Map<String, Object>) chargeDef.get("chargeTimeType") ;
+            String chargeTimeType = String.valueOf(chargeTimeTypeMap.get("code")) ;
+            if(chargeTimeType.equals("chargeTimeType.activation")) {
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountPaid")));
+            }else if(chargeTimeType.equals("chargeTimeType.sharespurchase")) {
+                Assert.assertEquals("6.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("6.0", String.valueOf(chargeDef.get("amountPaid")));
+            }else if(chargeTimeType.equals("chargeTimeType.sharesredeem")) {
+                Assert.assertEquals("1.0", String.valueOf(chargeDef.get("amountOrPercentage")));
+                Assert.assertEquals("1.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("1.0", String.valueOf(chargeDef.get("amountPaid")));
+            }else {
+                Assert.fail("Other Charge defintion found");
+            }
+        }
+        summaryMap = (Map<String, Object>) shareAccountData.get("summary");
+        Assert.assertEquals("30", String.valueOf(summaryMap.get("totalApprovedShares")));
+        Assert.assertEquals("0", String.valueOf(summaryMap.get("totalPendingForApprovalShares")));
+        
+        //Close Share Account
+        Map<String, Object> closeAccountMap = new HashMap<>();
+        closeAccountMap.put("note", "Share Account Close Note");
+        closeAccountMap.put("dateFormat", "dd MMMM yyyy");
+        closeAccountMap.put("closedDate", "10 May 2016");
+        closeAccountMap.put("locale", "en");
+        String closeJson = new Gson().toJson(closeAccountMap);
+        ShareAccountTransactionHelper.postCommand("close", shareAccountId, closeJson, requestSpec, responseSpec);
+        shareAccountData = ShareAccountTransactionHelper
+                .retrieveShareAccount(shareAccountId, requestSpec, responseSpec);
+        statusMap = (Map<String, Object>) shareAccountData.get("status");
+        Assert.assertEquals("shareAccountStatusType.closed", String.valueOf(statusMap.get("code")));
+        transactions = (List<Map<String, Object>>) shareAccountData.get("purchasedShares");
+        Assert.assertNotNull(transactions);
+        Assert.assertEquals(6, transactions.size());
+        for (int i = 0; i < transactions.size(); i++) {
+            Map<String, Object> transaction = transactions.get(i);
+            Map<String, Object> transactionTypeMap = (Map<String, Object>) transaction.get("type");
+            dateList = (List<Integer>) transaction.get("purchasedDate");
+            cal = Calendar.getInstance();
+            cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2));
+            Date date = cal.getTime();
+            String transactionType = (String) transactionTypeMap.get("code");
+            String transactionDate = simple.format(date);
+            if (transactionType.equals("purchasedSharesType.purchased") && transactionDate.equals("02 Mar 2016")) {
+                Assert.assertEquals("30", String.valueOf(transaction.get("numberOfShares")));
+                Assert.assertEquals("62.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("62.0", String.valueOf(transaction.get("amountPaid")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice")));
+            } else if (transactionType.equals("purchasedSharesType.purchased") && transactionDate.equals("01 Apr 2016")) {
+                Assert.assertEquals("15", String.valueOf(transaction.get("numberOfShares")));
+                Assert.assertEquals("32.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("32.0", String.valueOf(transaction.get("amountPaid")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice")));
+                Map<String, Object> transactionstatusMap = (Map<String, Object>) transaction.get("status");
+                Assert.assertEquals("purchasedSharesStatusType.approved", String.valueOf(transactionstatusMap.get("code")));
+            } else if (transactionType.equals("purchasedSharesType.redeemed") && transactionDate.equals("05 May 2016")) {
+                Assert.assertEquals("15", String.valueOf(transaction.get("numberOfShares")));
+                Assert.assertEquals("29.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("29.0", String.valueOf(transaction.get("amountPaid")));
+                Assert.assertEquals("1.0", String.valueOf(transaction.get("chargeAmount")));
+                Map<String, Object> transactionstatusMap = (Map<String, Object>) transaction.get("status");
+                Assert.assertEquals("purchasedSharesStatusType.approved", String.valueOf(transactionstatusMap.get("code")));
+            }else if (transactionType.equals("purchasedSharesType.redeemed") && transactionDate.equals("10 May 2016")) {
+                Assert.assertEquals("30", String.valueOf(transaction.get("numberOfShares")));
+                Assert.assertEquals("59.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("59.0", String.valueOf(transaction.get("amountPaid")));
+                Assert.assertEquals("1.0", String.valueOf(transaction.get("chargeAmount")));
+                Map<String, Object> transactionstatusMap = (Map<String, Object>) transaction.get("status");
+                Assert.assertEquals("purchasedSharesStatusType.approved", String.valueOf(transactionstatusMap.get("code")));
+            }else if (transactionType.equals("charge.payment")) {
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("amount")));
+                Assert.assertEquals("2.0", String.valueOf(transaction.get("amountPaid")));
+                Assert.assertEquals("0", String.valueOf(transaction.get("chargeAmount")));
+                Assert.assertEquals("01 Jan 2016", transactionDate);
+            }
+        }
+      //charges verification
+        chargesList = (List<Map<String, Object>>) shareAccountData.get("charges") ;
+        for(Map<String, Object> chargeDef: chargesList) {
+            Map<String, Object> chargeTimeTypeMap = (Map<String, Object>) chargeDef.get("chargeTimeType") ;
+            String chargeTimeType = String.valueOf(chargeTimeTypeMap.get("code")) ;
+            if(chargeTimeType.equals("chargeTimeType.activation")) {
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountPaid")));
+            }else if(chargeTimeType.equals("chargeTimeType.sharespurchase")) {
+                Assert.assertEquals("6.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("6.0", String.valueOf(chargeDef.get("amountPaid")));
+            }else if(chargeTimeType.equals("chargeTimeType.sharesredeem")) {
+                Assert.assertEquals("1.0", String.valueOf(chargeDef.get("amountOrPercentage")));
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount")));
+                Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding")));
+                Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountPaid")));
+            }else {
+                Assert.fail("Other Charge defintion found");
+            }
+        }
+        summaryMap = (Map<String, Object>) shareAccountData.get("summary");
+        Assert.assertEquals("0", String.valueOf(summaryMap.get("totalApprovedShares")));
+        Assert.assertEquals("0", String.valueOf(summaryMap.get("totalPendingForApprovalShares")));
+    }
+
+    private Integer createShareProduct() {
+        String shareProductJson = shareProductHelper.build();
+        return ShareProductTransactionHelper.createShareProduct(shareProductJson, requestSpec, responseSpec);
+    }
+
+    private Integer createShareAccount(final Integer clientId, final Integer productId, final Integer savingsAccountId) {
+        String josn = new ShareAccountHelper().withClientId(String.valueOf(clientId)).withProductId(String.valueOf(productId))
+                .withExternalId("External1").withSavingsAccountId(String.valueOf(savingsAccountId)).withSubmittedDate("01 Jan 2016")
+                .withApplicationDate("01 Jan 2016").withRequestedShares("25").build();
+        return ShareAccountTransactionHelper.createShareAccount(josn, requestSpec, responseSpec);
+    }
+
+    private Integer createShareAccount(final Integer clientId, final Integer productId, final Integer savingsAccountId,
+            List<Map<String, Object>> charges) {
+        String josn = new ShareAccountHelper().withClientId(String.valueOf(clientId)).withProductId(String.valueOf(productId))
+                .withExternalId("External1").withSavingsAccountId(String.valueOf(savingsAccountId)).withSubmittedDate("01 Jan 2016")
+                .withApplicationDate("01 Jan 2016").withRequestedShares("25").withCharges(charges).build();
+        return ShareAccountTransactionHelper.createShareAccount(josn, requestSpec, responseSpec);
+    }
+
+    private Map<String, Object> createCharge(final Integer chargeId, String amount) {
+        Map<String, Object> map = new HashMap<>();
+        map.put("chargeId", chargeId);
+        map.put("amount", amount);
+        return map;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/7ae9b67d/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountTransactionHelper.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountTransactionHelper.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountTransactionHelper.java
new file mode 100644
index 0000000..a4685a3
--- /dev/null
+++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountTransactionHelper.java
@@ -0,0 +1,55 @@
+/**
+ * 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.
+ */
+package org.apache.fineract.integrationtests.common.shares;
+
+import java.util.Map;
+
+import org.apache.fineract.integrationtests.common.Utils;
+
+import com.jayway.restassured.specification.RequestSpecification;
+import com.jayway.restassured.specification.ResponseSpecification;
+
+public class ShareAccountTransactionHelper {
+
+    private static final String SHARE_ACCOUNT_URL = "/fineract-provider/api/v1/accounts/share";
+    private static final String CREATE_SHARE_ACCOUNT_URL = SHARE_ACCOUNT_URL + "?" + Utils.TENANT_IDENTIFIER;
+
+    public static Integer createShareAccount(final String shareProductJSON, final RequestSpecification requestSpec,
+            final ResponseSpecification responseSpec) {
+        return Utils.performServerPost(requestSpec, responseSpec, CREATE_SHARE_ACCOUNT_URL, shareProductJSON, "resourceId");
+    }
+
+    public static Map<String, Object> retrieveShareAccount(final Integer shareProductId, final RequestSpecification requestSpec,
+            final ResponseSpecification responseSpec) {
+        String url = SHARE_ACCOUNT_URL + "/" + shareProductId + "?" + Utils.TENANT_IDENTIFIER;
+        return Utils.performServerGet(requestSpec, responseSpec, url, "");
+    }
+
+    public static Integer updateShareAccount(final Integer shareAccountId, final String shareAccountJson,
+            final RequestSpecification requestSpec, final ResponseSpecification responseSpec) {
+        String url = SHARE_ACCOUNT_URL + "/" + shareAccountId + "?" + Utils.TENANT_IDENTIFIER;
+        return Utils.performServerPut(requestSpec, responseSpec, url, shareAccountJson, "resourceId");
+    }
+
+    public static Integer postCommand(final String command, final Integer shareAccountId, String jsonBody, final RequestSpecification requestSpec,
+            final ResponseSpecification responseSpec) {
+        String url = SHARE_ACCOUNT_URL + "/" + shareAccountId + "?command=" + command + "&" + Utils.TENANT_IDENTIFIER;
+        return Utils.performServerPost(requestSpec, responseSpec, url, jsonBody, "resourceId");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/7ae9b67d/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareDividendsTransactionHelper.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareDividendsTransactionHelper.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareDividendsTransactionHelper.java
new file mode 100644
index 0000000..19a1e26
--- /dev/null
+++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareDividendsTransactionHelper.java
@@ -0,0 +1,58 @@
+/**
+ * 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.
+ */
+package org.apache.fineract.integrationtests.common.shares;
+
+import java.util.Map;
+
+import org.apache.fineract.integrationtests.common.Utils;
+
+import com.jayway.restassured.specification.RequestSpecification;
+import com.jayway.restassured.specification.ResponseSpecification;
+
+
+
+public class ShareDividendsTransactionHelper {
+
+    private static final String SHARE_PRODUCT_URL = "/fineract-provider/api/v1/shareproduct";
+    private static final String DIVIDEND = "dividend" ;
+    
+    public static Integer createShareProductDividends(final Integer productId, final String dividendJson, final RequestSpecification requestSpec,
+            final ResponseSpecification responseSpec) {
+        String url = SHARE_PRODUCT_URL + "/" + productId + "/" + DIVIDEND + "?" + Utils.TENANT_IDENTIFIER ;
+        return Utils.performServerPost(requestSpec, responseSpec, url, dividendJson, "subResourceId");
+    }
+    
+    public static Integer postCommand(final String command, final Integer productId, final Integer dividendId, String jsonBody, final RequestSpecification requestSpec,
+            final ResponseSpecification responseSpec) {
+        String url = SHARE_PRODUCT_URL + "/" + productId + "/"+DIVIDEND + "/"+ dividendId + "?command=" + command + "&" + Utils.TENANT_IDENTIFIER;
+        return Utils.performServerPut(requestSpec, responseSpec, url, jsonBody, "resourceId");
+    }
+    
+    public static Map<String, Object> retrieveDividendDetails(final Integer productId, final Integer dividendId, final RequestSpecification requestSpec,
+            final ResponseSpecification responseSpec) {
+        String url = SHARE_PRODUCT_URL + "/" + productId + "/"+DIVIDEND + "/"+ dividendId +"?" + Utils.TENANT_IDENTIFIER;
+        return Utils.performServerGet(requestSpec, responseSpec, url, "");
+    }
+    
+    public static Map<String, Object> retrieveAllDividends(final Integer productId, final RequestSpecification requestSpec,
+            final ResponseSpecification responseSpec) {
+        String url = SHARE_PRODUCT_URL + "/" + productId + "/"+DIVIDEND +"?" + Utils.TENANT_IDENTIFIER;
+        return Utils.performServerGet(requestSpec, responseSpec, url, "");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/7ae9b67d/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareProductHelper.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareProductHelper.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareProductHelper.java
new file mode 100644
index 0000000..c59bbbc
--- /dev/null
+++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareProductHelper.java
@@ -0,0 +1,199 @@
+/**
+ * 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.
+ */
+package org.apache.fineract.integrationtests.common.shares;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.fineract.infrastructure.core.service.DateUtils;
+import org.apache.fineract.integrationtests.common.Utils;
+import org.joda.time.LocalDate;
+import org.junit.Assert;
+
+import com.google.gson.Gson;
+
+
+public class ShareProductHelper {
+
+    
+    private static final String NONE = "1";
+    private static final String CASH_BASED = "2";
+    private static final String LOCALE = "en_GB";
+    private static final String DIGITS_AFTER_DECIMAL = "4";
+    private static final String IN_MULTIPLES_OF = "0";
+    private static final String USD = "USD";
+    
+    private String productName = Utils.randomNameGenerator("SHARE_PRODUCT_", 6);
+    private String shortName = Utils.randomNameGenerator("", 4);
+    private String description = Utils.randomNameGenerator("", 20);
+    private String totalShares = "10000";
+    private final String currencyCode = USD;
+    private String sharesIssued = "10000";
+    private String unitPrice = "2.0" ;
+    private String minimumShares = "10" ;
+    private String nominalShares = "20" ;
+    private String maximumShares = "3000" ;
+    private String allowDividendCalculationForInactiveClients = "true" ;
+    private String lockinPeriodFrequency = "1";
+    private String lockinPeriodFrequencyType = "0";
+    private String accountingRule = NONE;
+    
+    String minimumActivePeriodForDividends = "1";
+    String minimumactiveperiodFrequencyType = "0";
+    
+    private List<Map<String, String>> charges = null ;
+    private List<Map<String, String>> marketPrices = null ;
+    
+    
+    public String build() {
+        final HashMap<String, Object> map = new HashMap<>();
+        map.put("name", this.productName);
+        map.put("shortName", this.shortName);
+        map.put("description", this.description);
+        map.put("currencyCode", this.currencyCode);
+        map.put("locale", LOCALE);
+        map.put("digitsAfterDecimal", DIGITS_AFTER_DECIMAL);
+        map.put("inMultiplesOf", IN_MULTIPLES_OF);
+        map.put("totalShares", this.totalShares) ;
+        map.put("sharesIssued", this.sharesIssued);
+        map.put("unitPrice", this.unitPrice) ;
+        map.put("minimumShares", this.minimumShares) ;
+        map.put("nominalShares", this.nominalShares) ;
+        map.put("maximumShares", this.maximumShares) ;
+        map.put("allowDividendCalculationForInactiveClients", this.allowDividendCalculationForInactiveClients) ;
+        map.put("accountingRule", this.accountingRule) ;
+        map.put("minimumActivePeriodForDividends", this.minimumActivePeriodForDividends) ;
+        map.put("minimumactiveperiodFrequencyType", this.minimumactiveperiodFrequencyType) ;
+        map.put("lockinPeriodFrequency", this.lockinPeriodFrequency) ;
+        map.put("lockinPeriodFrequencyType", this.lockinPeriodFrequencyType) ;
+        
+        if(charges != null) {
+            map.put("chargesSelected", charges) ;
+        }
+        
+        if(marketPrices != null) {
+            map.put("marketPricePeriods", marketPrices) ;
+        }
+        
+        String shareProductCreateJson = new Gson().toJson(map);
+        System.out.println(shareProductCreateJson);
+        return shareProductCreateJson;
+    }
+    
+    public ShareProductHelper withCashBasedAccounting() {
+        this.accountingRule = CASH_BASED ;
+        return this ;
+    }
+    
+    public ShareProductHelper withMarketPrice() {
+        this.marketPrices = new ArrayList<>() ;
+        LocalDate currentDate = DateUtils.getLocalDateOfTenant() ;
+        String[] prices = {"3.0", "4.0", "5.0", "6.0", "7.0"} ;
+        DateFormat simple = new SimpleDateFormat("dd MMMM yyyy");
+        for(int i =0 ; i < prices.length; i++) {
+            currentDate = currentDate.plusMonths(2) ;
+            Map<String, String> marketPrice = new HashMap<>() ;
+            marketPrice.put("fromDate", simple.format(currentDate)) ;
+            marketPrice.put("shareValue", prices[i]) ;
+            this.marketPrices.add(marketPrice) ;
+        }
+        return this ;
+    }
+    
+    public ShareProductHelper withCharges(final ArrayList<Long> charges) {
+        if(charges != null && !charges.isEmpty()) {
+            this.charges = new ArrayList<>() ;
+            for(Long chargeId: charges) {
+                Map<String, String> charge = new HashMap<>() ;
+                charge.put("id", String.valueOf(chargeId.longValue())) ;
+                this.charges.add(charge) ;
+            }
+        }
+        return this ;
+    }
+
+    @SuppressWarnings("unchecked")
+    public void verifyShareProduct(Map<String, Object> shareProductData) {
+        String productName = (String)shareProductData.get("name") ;
+        Assert.assertEquals(this.productName, productName);
+        String shortName = (String)shareProductData.get("shortName") ;
+        Assert.assertEquals(this.shortName, shortName);
+        
+        String description = (String)shareProductData.get("description") ;
+        Assert.assertEquals(this.description, description);
+        
+        Map<String, String> currency = (Map<String,String>)shareProductData.get("currency") ;
+        String currencyCode = currency.get("code") ;
+        Assert.assertEquals(this.currencyCode, currencyCode);
+        
+        String digitsAfterDecimal = String.valueOf(currency.get("decimalPlaces")) ;
+        Assert.assertEquals(DIGITS_AFTER_DECIMAL, digitsAfterDecimal);
+        
+        String inMultiplesOf = String.valueOf(currency.get("inMultiplesOf")) ;
+        Assert.assertEquals(IN_MULTIPLES_OF, inMultiplesOf);
+        
+        String totalShares = String.valueOf(shareProductData.get("totalShares")) ;
+        Assert.assertEquals(this.totalShares, totalShares);
+        
+        String sharesIssued = String.valueOf(shareProductData.get("totalSharesIssued")) ;
+        Assert.assertEquals(this.sharesIssued, sharesIssued);
+        
+        String unitPrice = String.valueOf(shareProductData.get("unitPrice")) ;
+        Assert.assertEquals(this.unitPrice, unitPrice);
+        
+        String minimumShares = String.valueOf(shareProductData.get("minimumShares")) ;
+        Assert.assertEquals(this.minimumShares, minimumShares);
+        
+        String nominalShares = String.valueOf(shareProductData.get("nominalShares")) ;
+        Assert.assertEquals(this.nominalShares, nominalShares);
+        
+        String maximumShares = String.valueOf(shareProductData.get("maximumShares")) ;
+        Assert.assertEquals(this.maximumShares, maximumShares);
+        
+        String allowDividendCalculationForInactiveClients = String.valueOf(shareProductData.get("allowDividendCalculationForInactiveClients")) ;
+        Assert.assertEquals(this.allowDividendCalculationForInactiveClients, allowDividendCalculationForInactiveClients);
+        
+        Map<String, Object> accountingRuleMap = (Map<String, Object>) shareProductData.get("accountingRule") ;
+        String accountingRule = String.valueOf(accountingRuleMap.get("id")) ;
+        Assert.assertEquals(this.accountingRule, accountingRule);
+        
+        String minimumActivePeriodForDividends = String.valueOf(shareProductData.get("minimumActivePeriod")) ;
+        Assert.assertEquals(this.minimumActivePeriodForDividends, minimumActivePeriodForDividends);
+        
+        Map<String, Object> minimumActivePeriodType = (Map<String, Object>) shareProductData.get("minimumActivePeriodForDividendsTypeEnum") ;
+        String minimumactiveperiodFrequencyType = String.valueOf(minimumActivePeriodType.get("id")) ;
+        Assert.assertEquals(this.minimumactiveperiodFrequencyType, minimumactiveperiodFrequencyType);
+        
+        String lockinPeriodFrequency = String.valueOf(shareProductData.get("lockinPeriod")) ;
+        Assert.assertEquals(this.lockinPeriodFrequency, lockinPeriodFrequency);
+        
+        Map<String, Object> lockinPeriodType = (Map<String, Object>) shareProductData.get("lockPeriodTypeEnum") ;
+        String lockinPeriodFrequencyType = String.valueOf(lockinPeriodType.get("id")) ;
+        Assert.assertEquals(this.lockinPeriodFrequencyType, lockinPeriodFrequencyType);
+        
+        ArrayList<Map<String, String>> charges = (ArrayList<Map<String, String>>)shareProductData.get("chargesSelected") ;
+        
+        ArrayList<Map<String, String>> marketPrices = (ArrayList<Map<String, String>>)shareProductData.get("marketPricePeriods") ;
+        
+    }
+}