fineract-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From raj...@apache.org
Subject [11/12] incubator-fineract git commit: Shares And Dividends Implementation
Date Wed, 13 Apr 2016 14:35:23 GMT
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/serialization/ProductToGLAccountMappingFromApiJsonDeserializer.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/serialization/ProductToGLAccountMappingFromApiJsonDeserializer.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/serialization/ProductToGLAccountMappingFromApiJsonDeserializer.java
index 1755828..6189087 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/serialization/ProductToGLAccountMappingFromApiJsonDeserializer.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/serialization/ProductToGLAccountMappingFromApiJsonDeserializer.java
@@ -26,6 +26,7 @@ import java.util.List;
 import java.util.Locale;
 
 import org.apache.commons.lang.StringUtils;
+import org.apache.fineract.accounting.common.AccountingConstants.SHARES_PRODUCT_ACCOUNTING_PARAMS;
 import org.apache.fineract.accounting.common.AccountingRuleType;
 import org.apache.fineract.accounting.common.AccountingConstants.LOAN_PRODUCT_ACCOUNTING_PARAMS;
 import org.apache.fineract.accounting.common.AccountingConstants.SAVINGS_PRODUCT_ACCOUNTING_PARAMS;
@@ -38,6 +39,7 @@ import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidati
 import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
 import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
 import org.apache.fineract.portfolio.savings.DepositAccountType;
+import org.apache.fineract.portfolio.shareproducts.constants.ShareProductApiConstants;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
@@ -118,8 +120,8 @@ public final class ProductToGLAccountMappingFromApiJsonDeserializer {
 
             final Long incomeFromRecoveryAccountId = this.fromApiJsonHelper.extractLongNamed(
                     LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_RECOVERY.getValue(), element);
-            baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_RECOVERY.getValue()).value(incomeFromRecoveryAccountId)
-                    .notNull().integerGreaterThanZero();
+            baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_RECOVERY.getValue())
+                    .value(incomeFromRecoveryAccountId).notNull().integerGreaterThanZero();
 
             final Long writeOffAccountId = this.fromApiJsonHelper.extractLongNamed(
                     LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), element);
@@ -227,6 +229,47 @@ public final class ProductToGLAccountMappingFromApiJsonDeserializer {
         throwExceptionIfValidationWarningsExist(dataValidationErrors);
     }
 
+    public void validateForShareProductCreate(final String json) {
+        if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
+
+        final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
+        final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
+                .resource(ShareProductApiConstants.SHARE_PRODUCT_RESOURCE_NAME);
+
+        final JsonElement element = this.fromApiJsonHelper.parse(json);
+
+        // accounting related data validation
+        final Integer accountingRuleType = this.fromApiJsonHelper
+                .extractIntegerNamed(accountingRuleParamName, element, Locale.getDefault());
+        baseDataValidator.reset().parameter(accountingRuleParamName).value(accountingRuleType).notNull().inMinMaxRange(1, 3);
+
+        if (isCashBasedAccounting(accountingRuleType)) {
+
+            final Long shareReferenceId = this.fromApiJsonHelper.extractLongNamed(
+                    SHARES_PRODUCT_ACCOUNTING_PARAMS.SHARES_REFERENCE.getValue(), element);
+            baseDataValidator.reset().parameter(SHARES_PRODUCT_ACCOUNTING_PARAMS.SHARES_REFERENCE.getValue())
+                    .value(shareReferenceId).notNull().integerGreaterThanZero();
+            
+            final Long shareSuspenseId = this.fromApiJsonHelper.extractLongNamed(
+                    SHARES_PRODUCT_ACCOUNTING_PARAMS.SHARES_SUSPENSE.getValue(), element);
+            baseDataValidator.reset().parameter(SHARES_PRODUCT_ACCOUNTING_PARAMS.SHARES_SUSPENSE.getValue())
+                    .value(shareSuspenseId).notNull().integerGreaterThanZero();
+            
+            final Long incomeFromFeeAccountId = this.fromApiJsonHelper.extractLongNamed(
+                    SHARES_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), element);
+            baseDataValidator.reset().parameter(SHARES_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue())
+                    .value(incomeFromFeeAccountId).notNull().integerGreaterThanZero();
+            
+            final Long shareEquityId = this.fromApiJsonHelper.extractLongNamed(
+                    SHARES_PRODUCT_ACCOUNTING_PARAMS.SHARES_EQUITY.getValue(), element);
+            baseDataValidator.reset().parameter(SHARES_PRODUCT_ACCOUNTING_PARAMS.SHARES_EQUITY.getValue())
+                    .value(shareEquityId).notNull().integerGreaterThanZero();
+
+        }
+
+        throwExceptionIfValidationWarningsExist(dataValidationErrors);
+    }
+
     private boolean isCashBasedAccounting(final Integer accountingRuleType) {
         return AccountingRuleType.CASH_BASED.getValue().equals(accountingRuleType);
     }

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingReadPlatformService.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingReadPlatformService.java
index 2a903d5..0ce6232 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingReadPlatformService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingReadPlatformService.java
@@ -41,5 +41,11 @@ public interface ProductToGLAccountMappingReadPlatformService {
     public List<ChargeToGLAccountMapper> fetchFeeToIncomeAccountMappingsForSavingsProduct(final Long savingsProductId);
 
     public List<ChargeToGLAccountMapper> fetchPenaltyToIncomeAccountMappingsForSavingsProduct(final Long savingsProductId);
+    
+    public Map<String, Object> fetchAccountMappingDetailsForShareProduct(final Long productId, final Integer accountingType);
+
+    public List<PaymentTypeToGLAccountMapper> fetchPaymentTypeToFundSourceMappingsForShareProduct(final Long productId);
+
+    public List<ChargeToGLAccountMapper> fetchFeeToIncomeAccountMappingsForShareProduct(final Long productId);
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingReadPlatformServiceImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingReadPlatformServiceImpl.java
index ef1a2af..b5a84f2 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingReadPlatformServiceImpl.java
@@ -29,8 +29,10 @@ import org.apache.fineract.accounting.common.AccountingRuleType;
 import org.apache.fineract.accounting.common.AccountingConstants.ACCRUAL_ACCOUNTS_FOR_LOAN;
 import org.apache.fineract.accounting.common.AccountingConstants.CASH_ACCOUNTS_FOR_LOAN;
 import org.apache.fineract.accounting.common.AccountingConstants.CASH_ACCOUNTS_FOR_SAVINGS;
+import org.apache.fineract.accounting.common.AccountingConstants.CASH_ACCOUNTS_FOR_SHARES;
 import org.apache.fineract.accounting.common.AccountingConstants.LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS;
 import org.apache.fineract.accounting.common.AccountingConstants.SAVINGS_PRODUCT_ACCOUNTING_DATA_PARAMS;
+import org.apache.fineract.accounting.common.AccountingConstants.SHARES_PRODUCT_ACCOUNTING_PARAMS;
 import org.apache.fineract.accounting.glaccount.data.GLAccountData;
 import org.apache.fineract.accounting.producttoaccountmapping.data.ChargeToGLAccountMapper;
 import org.apache.fineract.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
@@ -326,4 +328,50 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
         return chargeToGLAccountMappers;
     }
 
+    @Override
+    public Map<String, Object> fetchAccountMappingDetailsForShareProduct(Long productId, Integer accountingType) {
+
+        final Map<String, Object> accountMappingDetails = new LinkedHashMap<>(8);
+
+        final ProductToGLAccountMappingMapper rm = new ProductToGLAccountMappingMapper();
+        final String sql = "select " + rm.schema() + " and product_id = ? and payment_type is null and mapping.charge_id is null ";
+
+        final List<Map<String, Object>> listOfProductToGLAccountMaps = this.jdbcTemplate.query(sql, rm, new Object[] {
+                PortfolioProductType.SHARES.getValue(), productId });
+
+        if (AccountingRuleType.CASH_BASED.getValue().equals(accountingType)) {
+            for (final Map<String, Object> productToGLAccountMap : listOfProductToGLAccountMaps) {
+                final Integer financialAccountType = (Integer) productToGLAccountMap.get("financialAccountType");
+                final CASH_ACCOUNTS_FOR_SHARES glAccountForShares = CASH_ACCOUNTS_FOR_SHARES.fromInt(financialAccountType);
+
+                final Long glAccountId = (Long) productToGLAccountMap.get("glAccountId");
+                final String glAccountName = (String) productToGLAccountMap.get("glAccountName");
+                final String glCode = (String) productToGLAccountMap.get("glCode");
+                final GLAccountData gLAccountData = new GLAccountData(glAccountId, glAccountName, glCode);
+
+                if (glAccountForShares.equals(CASH_ACCOUNTS_FOR_SHARES.SHARES_REFERENCE)) {
+                    accountMappingDetails.put(SHARES_PRODUCT_ACCOUNTING_PARAMS.SHARES_REFERENCE.getValue(), gLAccountData);
+                } else if (glAccountForShares.equals(CASH_ACCOUNTS_FOR_SHARES.SHARES_SUSPENSE)) {
+                    accountMappingDetails.put(SHARES_PRODUCT_ACCOUNTING_PARAMS.SHARES_SUSPENSE.getValue(), gLAccountData);
+                } else if (glAccountForShares.equals(CASH_ACCOUNTS_FOR_SHARES.INCOME_FROM_FEES)) {
+                    accountMappingDetails.put(SHARES_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), gLAccountData);
+                } else if (glAccountForShares.equals(CASH_ACCOUNTS_FOR_SHARES.SHARES_EQUITY)) {
+                    accountMappingDetails.put(SHARES_PRODUCT_ACCOUNTING_PARAMS.SHARES_EQUITY.getValue(), gLAccountData);
+                }
+            }
+        }
+        return accountMappingDetails;
+
+    }
+
+    @Override
+    public List<PaymentTypeToGLAccountMapper> fetchPaymentTypeToFundSourceMappingsForShareProduct(Long productId) {
+        return fetchPaymentTypeToFundSourceMappings(PortfolioProductType.SHARES, productId);
+    }
+
+    @Override
+    public List<ChargeToGLAccountMapper> fetchFeeToIncomeAccountMappingsForShareProduct(Long productId) {
+        return fetchChargeToIncomeAccountMappings(PortfolioProductType.SHARES, productId, false);
+    }
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingWritePlatformService.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingWritePlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingWritePlatformService.java
index 359a3d1..c471a13 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingWritePlatformService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingWritePlatformService.java
@@ -35,4 +35,9 @@ public interface ProductToGLAccountMappingWritePlatformService {
     Map<String, Object> updateSavingsProductToGLAccountMapping(Long savingsProductId, JsonCommand command, boolean accountingRuleChanged,
             int accountingRuleTypeId, DepositAccountType accountType);
 
+    void createShareProductToGLAccountMapping(Long shareProductId, JsonCommand command);
+
+    Map<String, Object> updateShareProductToGLAccountMapping(Long shareProductId, JsonCommand command, boolean accountingRuleChanged,
+            int accountingRuleTypeId);
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingWritePlatformServiceImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingWritePlatformServiceImpl.java
index 8e0c87b..c735997 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingWritePlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingWritePlatformServiceImpl.java
@@ -24,10 +24,12 @@ import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
 
+import org.apache.fineract.accounting.common.AccountingConstants.SHARES_PRODUCT_ACCOUNTING_PARAMS;
 import org.apache.fineract.accounting.common.AccountingRuleType;
 import org.apache.fineract.accounting.common.AccountingConstants.ACCRUAL_ACCOUNTS_FOR_LOAN;
 import org.apache.fineract.accounting.common.AccountingConstants.CASH_ACCOUNTS_FOR_LOAN;
 import org.apache.fineract.accounting.common.AccountingConstants.CASH_ACCOUNTS_FOR_SAVINGS;
+import org.apache.fineract.accounting.common.AccountingConstants.CASH_ACCOUNTS_FOR_SHARES;
 import org.apache.fineract.accounting.common.AccountingConstants.LOAN_PRODUCT_ACCOUNTING_PARAMS;
 import org.apache.fineract.accounting.common.AccountingConstants.SAVINGS_PRODUCT_ACCOUNTING_PARAMS;
 import org.apache.fineract.accounting.producttoaccountmapping.serialization.ProductToGLAccountMappingFromApiJsonDeserializer;
@@ -47,16 +49,19 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
     private final ProductToGLAccountMappingFromApiJsonDeserializer deserializer;
     private final LoanProductToGLAccountMappingHelper loanProductToGLAccountMappingHelper;
     private final SavingsProductToGLAccountMappingHelper savingsProductToGLAccountMappingHelper;
+    private final ShareProductToGLAccountMappingHelper shareProductToGLAccountMappingHelper;
 
     @Autowired
     public ProductToGLAccountMappingWritePlatformServiceImpl(final FromJsonHelper fromApiJsonHelper,
             final ProductToGLAccountMappingFromApiJsonDeserializer deserializer,
             final LoanProductToGLAccountMappingHelper loanProductToGLAccountMappingHelper,
-            final SavingsProductToGLAccountMappingHelper savingsProductToGLAccountMappingHelper) {
+            final SavingsProductToGLAccountMappingHelper savingsProductToGLAccountMappingHelper,
+            final ShareProductToGLAccountMappingHelper shareProductToGLAccountMappingHelper) {
         this.fromApiJsonHelper = fromApiJsonHelper;
         this.deserializer = deserializer;
         this.loanProductToGLAccountMappingHelper = loanProductToGLAccountMappingHelper;
         this.savingsProductToGLAccountMappingHelper = savingsProductToGLAccountMappingHelper;
+        this.shareProductToGLAccountMappingHelper = shareProductToGLAccountMappingHelper;
     }
 
     @Override
@@ -232,6 +237,50 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
 
     @Override
     @Transactional
+    public void createShareProductToGLAccountMapping(final Long shareProductId, final JsonCommand command) {
+
+        this.deserializer.validateForShareProductCreate(command.json());
+        final JsonElement element = this.fromApiJsonHelper.parse(command.json());
+        final Integer accountingRuleTypeId = this.fromApiJsonHelper.extractIntegerNamed(accountingRuleParamName, element,
+                Locale.getDefault());
+        final AccountingRuleType accountingRuleType = AccountingRuleType.fromInt(accountingRuleTypeId);
+
+        switch (accountingRuleType) {
+            case NONE:
+            break;
+            case CASH_BASED:
+                // asset
+                this.shareProductToGLAccountMappingHelper.saveSharesToAssetAccountMapping(element,
+                        SHARES_PRODUCT_ACCOUNTING_PARAMS.SHARES_REFERENCE.getValue(), shareProductId,
+                        CASH_ACCOUNTS_FOR_SHARES.SHARES_REFERENCE.getValue());
+
+                // income
+                this.shareProductToGLAccountMappingHelper.saveSharesToIncomeAccountMapping(element,
+                        SHARES_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), shareProductId,
+                        CASH_ACCOUNTS_FOR_SHARES.INCOME_FROM_FEES.getValue());
+
+                // expenses
+                this.shareProductToGLAccountMappingHelper.saveSharesToEquityAccountMapping(element,
+                        SHARES_PRODUCT_ACCOUNTING_PARAMS.SHARES_EQUITY.getValue(), shareProductId,
+                        CASH_ACCOUNTS_FOR_SHARES.SHARES_EQUITY.getValue());
+
+                // liability
+                this.shareProductToGLAccountMappingHelper.saveSharesToLiabilityAccountMapping(element,
+                        SHARES_PRODUCT_ACCOUNTING_PARAMS.SHARES_SUSPENSE.getValue(), shareProductId,
+                        CASH_ACCOUNTS_FOR_SHARES.SHARES_SUSPENSE.getValue());
+
+                // advanced accounting mappings
+                this.savingsProductToGLAccountMappingHelper.savePaymentChannelToFundSourceMappings(command, element, shareProductId, null);
+                this.savingsProductToGLAccountMappingHelper.saveChargesToIncomeAccountMappings(command, element, shareProductId, null);
+            break;
+            default:
+            break;
+        }
+
+    }
+
+    @Override
+    @Transactional
     public Map<String, Object> updateLoanProductToGLAccountMapping(final Long loanProductId, final JsonCommand command,
             final boolean accountingRuleChanged, final int accountingRuleTypeId) {
         /***
@@ -293,4 +342,34 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
         }
         return changes;
     }
+
+    @Override
+    public Map<String, Object> updateShareProductToGLAccountMapping(final Long shareProductId, final JsonCommand command,
+            final boolean accountingRuleChanged, final int accountingRuleTypeId) {
+        /***
+         * Variable tracks all accounting mapping properties that have been
+         * updated
+         ***/
+        Map<String, Object> changes = new HashMap<>();
+        final JsonElement element = this.fromApiJsonHelper.parse(command.json());
+        final AccountingRuleType accountingRuleType = AccountingRuleType.fromInt(accountingRuleTypeId);
+
+        /***
+         * If the accounting rule has been changed, delete all existing mapping
+         * for the product and recreate a new set of mappings
+         ***/
+        if (accountingRuleChanged) {
+            this.shareProductToGLAccountMappingHelper.deleteSharesProductToGLAccountMapping(shareProductId);
+            createShareProductToGLAccountMapping(shareProductId, command);
+            changes = this.shareProductToGLAccountMappingHelper.populateChangesForNewSharesProductToGLAccountMappingCreation(element,
+                    accountingRuleType);
+        }/*** else examine and update individual changes ***/
+        else {
+            this.shareProductToGLAccountMappingHelper.handleChangesToSharesProductToGLAccountMappings(shareProductId, changes, element,
+                    accountingRuleType);
+            this.shareProductToGLAccountMappingHelper.updatePaymentChannelToFundSourceMappings(command, element, shareProductId, changes);
+            this.shareProductToGLAccountMappingHelper.updateChargesToIncomeAccountMappings(command, element, shareProductId, changes);
+        }
+        return changes;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ShareProductToGLAccountMappingHelper.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ShareProductToGLAccountMappingHelper.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ShareProductToGLAccountMappingHelper.java
new file mode 100644
index 0000000..489532f
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ShareProductToGLAccountMappingHelper.java
@@ -0,0 +1,204 @@
+/**
+ * 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.accounting.producttoaccountmapping.service;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.fineract.accounting.common.AccountingRuleType;
+import org.apache.fineract.accounting.common.AccountingConstants.CASH_ACCOUNTS_FOR_SHARES;
+import org.apache.fineract.accounting.common.AccountingConstants.SHARES_PRODUCT_ACCOUNTING_PARAMS;
+import org.apache.fineract.accounting.glaccount.domain.GLAccountRepository;
+import org.apache.fineract.accounting.glaccount.domain.GLAccountRepositoryWrapper;
+import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
+import org.apache.fineract.accounting.producttoaccountmapping.domain.PortfolioProductType;
+import org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGLAccountMappingRepository;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.portfolio.charge.domain.ChargeRepositoryWrapper;
+import org.apache.fineract.portfolio.paymenttype.domain.PaymentTypeRepositoryWrapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.google.gson.JsonElement;
+
+@Component
+public class ShareProductToGLAccountMappingHelper extends ProductToGLAccountMappingHelper {
+
+    @Autowired
+    public ShareProductToGLAccountMappingHelper(final GLAccountRepository glAccountRepository,
+            final ProductToGLAccountMappingRepository glAccountMappingRepository, final FromJsonHelper fromApiJsonHelper,
+            final ChargeRepositoryWrapper chargeRepositoryWrapper, final GLAccountRepositoryWrapper accountRepositoryWrapper,
+            final PaymentTypeRepositoryWrapper paymentTypeRepositoryWrapper) {
+        super(glAccountRepository, glAccountMappingRepository, fromApiJsonHelper, chargeRepositoryWrapper, accountRepositoryWrapper,
+                paymentTypeRepositoryWrapper);
+    }
+
+    /*** Set of abstractions for saving Share Products to GL Account Mappings ***/
+
+    public void saveSharesToAssetAccountMapping(final JsonElement element, final String paramName, final Long productId,
+            final int placeHolderTypeId) {
+        saveProductToAccountMapping(element, paramName, productId, placeHolderTypeId, GLAccountType.ASSET, PortfolioProductType.SHARES);
+    }
+
+    public void saveSharesToIncomeAccountMapping(final JsonElement element, final String paramName, final Long productId,
+            final int placeHolderTypeId) {
+        saveProductToAccountMapping(element, paramName, productId, placeHolderTypeId, GLAccountType.INCOME, PortfolioProductType.SHARES);
+    }
+
+    public void saveSharesToEquityAccountMapping(final JsonElement element, final String paramName, final Long productId,
+            final int placeHolderTypeId) {
+        saveProductToAccountMapping(element, paramName, productId, placeHolderTypeId, GLAccountType.EQUITY, PortfolioProductType.SHARES);
+    }
+
+    public void saveSharesToLiabilityAccountMapping(final JsonElement element, final String paramName, final Long productId,
+            final int placeHolderTypeId) {
+        saveProductToAccountMapping(element, paramName, productId, placeHolderTypeId, GLAccountType.LIABILITY, PortfolioProductType.SHARES);
+    }
+
+    /*** Set of abstractions for merging Shares Products to GL Account Mappings ***/
+
+    public void mergeSharesToAssetAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
+            final int accountTypeId, final String accountTypeName, final Map<String, Object> changes) {
+        mergeProductToAccountMappingChanges(element, paramName, productId, accountTypeId, accountTypeName, changes, GLAccountType.ASSET,
+                PortfolioProductType.SHARES);
+    }
+
+    public void mergeSharesToIncomeAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
+            final int accountTypeId, final String accountTypeName, final Map<String, Object> changes) {
+        mergeProductToAccountMappingChanges(element, paramName, productId, accountTypeId, accountTypeName, changes, GLAccountType.INCOME,
+                PortfolioProductType.SHARES);
+    }
+
+    public void mergeSharesToEquityAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
+            final int accountTypeId, final String accountTypeName, final Map<String, Object> changes) {
+        mergeProductToAccountMappingChanges(element, paramName, productId, accountTypeId, accountTypeName, changes, GLAccountType.EQUITY,
+                PortfolioProductType.SHARES);
+    }
+
+    public void mergeSharesToLiabilityAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
+            final int accountTypeId, final String accountTypeName, final Map<String, Object> changes) {
+        mergeProductToAccountMappingChanges(element, paramName, productId, accountTypeId, accountTypeName, changes,
+                GLAccountType.LIABILITY, PortfolioProductType.SHARES);
+    }
+
+    /*** Abstractions for payments channel related to Shares products ***/
+
+    public void savePaymentChannelToFundSourceMappings(final JsonCommand command, final JsonElement element, final Long productId,
+            final Map<String, Object> changes) {
+        savePaymentChannelToFundSourceMappings(command, element, productId, changes, PortfolioProductType.SHARES);
+    }
+
+    public void updatePaymentChannelToFundSourceMappings(final JsonCommand command, final JsonElement element, final Long productId,
+            final Map<String, Object> changes) {
+        updatePaymentChannelToFundSourceMappings(command, element, productId, changes, PortfolioProductType.SHARES);
+    }
+
+    public void saveChargesToIncomeAccountMappings(final JsonCommand command, final JsonElement element, final Long productId,
+            final Map<String, Object> changes) {
+        saveChargesToIncomeOrLiabilityAccountMappings(command, element, productId, changes, PortfolioProductType.SHARES, true);
+        saveChargesToIncomeOrLiabilityAccountMappings(command, element, productId, changes, PortfolioProductType.SHARES, false);
+    }
+
+    public void updateChargesToIncomeAccountMappings(final JsonCommand command, final JsonElement element, final Long productId,
+            final Map<String, Object> changes) {
+        updateChargeToIncomeAccountMappings(command, element, productId, changes, PortfolioProductType.SHARES, true);
+        updateChargeToIncomeAccountMappings(command, element, productId, changes, PortfolioProductType.SHARES, false);
+    }
+
+    public Map<String, Object> populateChangesForNewSharesProductToGLAccountMappingCreation(final JsonElement element,
+            final AccountingRuleType accountingRuleType) {
+        final Map<String, Object> changes = new HashMap<>();
+
+        final Long shareReferenceId = this.fromApiJsonHelper.extractLongNamed(SHARES_PRODUCT_ACCOUNTING_PARAMS.SHARES_REFERENCE.getValue(),
+                element);
+        final Long incomeFromFeeAccountId = this.fromApiJsonHelper.extractLongNamed(
+                SHARES_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), element);
+        final Long shareSuspenseId = this.fromApiJsonHelper.extractLongNamed(SHARES_PRODUCT_ACCOUNTING_PARAMS.SHARES_SUSPENSE.getValue(),
+                element);
+        final Long shareEquityId = this.fromApiJsonHelper.extractLongNamed(SHARES_PRODUCT_ACCOUNTING_PARAMS.SHARES_EQUITY.getValue(),
+                element);
+
+        switch (accountingRuleType) {
+            case NONE:
+            break;
+            case CASH_BASED:
+                changes.put(SHARES_PRODUCT_ACCOUNTING_PARAMS.SHARES_REFERENCE.getValue(), shareReferenceId);
+                changes.put(SHARES_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), incomeFromFeeAccountId);
+                changes.put(SHARES_PRODUCT_ACCOUNTING_PARAMS.SHARES_SUSPENSE.getValue(), shareSuspenseId);
+                changes.put(SHARES_PRODUCT_ACCOUNTING_PARAMS.SHARES_EQUITY.getValue(), shareEquityId);
+            break;
+            case ACCRUAL_PERIODIC:
+            break;
+            case ACCRUAL_UPFRONT:
+            break;
+            default:
+            break;
+        }
+        return changes;
+    }
+
+    /**
+     * Examines and updates each account mapping for given loan product with
+     * changes passed in from the Json element
+     * 
+     * @param sharesProductId
+     * @param changes
+     * @param element
+     * @param accountingRuleType
+     */
+    public void handleChangesToSharesProductToGLAccountMappings(final Long sharesProductId, final Map<String, Object> changes,
+            final JsonElement element, final AccountingRuleType accountingRuleType) {
+        switch (accountingRuleType) {
+            case NONE:
+            break;
+            case CASH_BASED:
+                // asset
+                mergeSharesToAssetAccountMappingChanges(element, SHARES_PRODUCT_ACCOUNTING_PARAMS.SHARES_REFERENCE.getValue(),
+                        sharesProductId, CASH_ACCOUNTS_FOR_SHARES.SHARES_REFERENCE.getValue(),
+                        CASH_ACCOUNTS_FOR_SHARES.SHARES_REFERENCE.toString(), changes);
+
+                // income
+                mergeSharesToIncomeAccountMappingChanges(element, SHARES_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(),
+                        sharesProductId, CASH_ACCOUNTS_FOR_SHARES.INCOME_FROM_FEES.getValue(),
+                        CASH_ACCOUNTS_FOR_SHARES.INCOME_FROM_FEES.toString(), changes);
+
+                // liability
+                mergeSharesToLiabilityAccountMappingChanges(element, SHARES_PRODUCT_ACCOUNTING_PARAMS.SHARES_SUSPENSE.getValue(),
+                        sharesProductId, CASH_ACCOUNTS_FOR_SHARES.SHARES_SUSPENSE.getValue(),
+                        CASH_ACCOUNTS_FOR_SHARES.SHARES_SUSPENSE.toString(), changes);
+
+                // equity
+                mergeSharesToEquityAccountMappingChanges(element, SHARES_PRODUCT_ACCOUNTING_PARAMS.SHARES_EQUITY.getValue(),
+                        sharesProductId, CASH_ACCOUNTS_FOR_SHARES.SHARES_EQUITY.getValue(),
+                        CASH_ACCOUNTS_FOR_SHARES.SHARES_EQUITY.toString(), changes);
+            break;
+            case ACCRUAL_PERIODIC:
+            break;
+            case ACCRUAL_UPFRONT:
+            break;
+            default:
+            break;
+        }
+    }
+
+    public void deleteSharesProductToGLAccountMapping(final Long sharesProductId) {
+        deleteProductToGLAccountMapping(sharesProductId, PortfolioProductType.SHARES);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java b/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java
index cc33ecc..bd13574 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java
@@ -830,7 +830,7 @@ public class CommandWrapperBuilder {
         this.href = "/loans/" + loanId;
         return this;
     }
-    
+
     public CommandWrapperBuilder undoLastDisbursalLoanApplication(final Long loanId) {
         this.actionName = "DISBURSALLASTUNDO";
         this.entityName = "LOAN";
@@ -2584,36 +2584,82 @@ public class CommandWrapperBuilder {
         this.href = "/loans/" + loanId + "/schedule";
         return this;
     }
-    
+
     public CommandWrapperBuilder createProduct(String productType) {
-        this.entityName = productType.toUpperCase()+"PRODUCT" ; //To Support different type of products
+        this.entityName = productType.toUpperCase() + "PRODUCT"; // To Support
+                                                                 // different
+                                                                 // type of
+                                                                 // products
         this.actionName = "CREATE";
         this.entityId = null;
-        this.href = "/products/"+productType;
+        this.href = "/products/" + productType;
         return this;
     }
-    
+
     public CommandWrapperBuilder updateProduct(String productType, final Long productId) {
-        this.entityName = productType.toUpperCase()+"PRODUCT" ;
+        this.entityName = productType.toUpperCase() + "PRODUCT";
         this.actionName = "UPDATE";
         this.entityId = productId;
-        this.href = "/products/" + productType+"/"+productId;
+        this.href = "/products/" + productType + "/" + productId;
         return this;
     }
-    
+
     public CommandWrapperBuilder createAccount(String accountType) {
-        this.entityName = accountType.toUpperCase()+"ACCOUNT" ; //To Support different type of Accounts
+        this.entityName = accountType.toUpperCase() + "ACCOUNT"; // To Support
+                                                                 // different
+                                                                 // type of
+                                                                 // Accounts
         this.actionName = "CREATE";
         this.entityId = null;
-        this.href = "/accounts/"+accountType;
+        this.href = "/accounts/" + accountType;
         return this;
     }
-    
+
     public CommandWrapperBuilder updateAccount(String accountType, final Long accountId) {
-        this.entityName = accountType.toUpperCase()+"ACCOUNT" ;
+        this.entityName = accountType.toUpperCase() + "ACCOUNT";
         this.actionName = "UPDATE";
         this.entityId = accountId;
-        this.href = "/accounts/" + accountType+"/"+accountId;
+        this.href = "/accounts/" + accountType + "/" + accountId;
+        return this;
+    }
+
+    public CommandWrapperBuilder createProductCommand(String productType, String command, final Long productId) {
+        this.entityName = productType.toUpperCase() + "PRODUCT";
+        this.actionName = "CREATE" + "_" + command.toUpperCase();
+        this.entityId = productId;
+        this.href = "/products/" + productType + "/" + productId + "?command=" + command;
+        return this;
+    }
+
+    public CommandWrapperBuilder createShareProductDividendPayoutCommand(final Long productId) {
+        this.entityName = "SHAREPRODUCT";
+        this.actionName = "CREATE_DIVIDEND";
+        this.entityId = productId;
+        this.href = "/shareproduct/" + productId + "/dividend";
+        return this;
+    }
+
+    public CommandWrapperBuilder approveShareProductDividendPayoutCommand(final Long productId, final Long dividendId) {
+        this.entityName = "SHAREPRODUCT";
+        this.actionName = "APPROVE_DIVIDEND";
+        this.entityId = dividendId;
+        this.href = "/shareproduct/" + productId + "/dividend/" + dividendId;
+        return this;
+    }
+    
+    public CommandWrapperBuilder deleteShareProductDividendPayoutCommand(final Long productId, final Long dividendId) {
+        this.entityName = "SHAREPRODUCT";
+        this.actionName = "DELETE_DIVIDEND";
+        this.entityId = dividendId;
+        this.href = "/shareproduct/" + productId + "/dividend/" + dividendId;
+        return this;
+    }
+    
+    public CommandWrapperBuilder createAccountCommand(String accountType, final Long accountId, String command) {
+        this.entityName = accountType.toUpperCase()+"ACCOUNT" ;
+        this.actionName = command.toUpperCase();
+        this.entityId = accountId;
+        this.href = "/accounts/" + accountType+"/"+accountId+"?command="+command;
         return this;
     }
     

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/infrastructure/accountnumberformat/domain/EntityAccountType.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/accountnumberformat/domain/EntityAccountType.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/accountnumberformat/domain/EntityAccountType.java
index 2c2a65a..2ba4784 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/accountnumberformat/domain/EntityAccountType.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/accountnumberformat/domain/EntityAccountType.java
@@ -23,7 +23,7 @@ import java.util.Map;
 
 public enum EntityAccountType {
     CLIENT(1, "accountType.client"), LOAN(2, "accountType.loan"), SAVINGS(3, "accountType.savings"), CENTER(4, "accountType.center"), 
-    GROUP(5, "accountType.group");
+    GROUP(5, "accountType.group"), SHARES(6, "accountType.shares");
 
     private final Integer value;
     private final String code;

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/SearchParameters.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/SearchParameters.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/SearchParameters.java
index 67ed845..97c98ba 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/SearchParameters.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/SearchParameters.java
@@ -43,13 +43,13 @@ public final class SearchParameters {
     private final Long savingsId;
     private final Boolean orphansOnly;
 
-  //Provisning Entries Search Params
-    private final Long provisioningEntryId ;
-    private final Long productId ;
-    private final Long categoryId ;
-	private final boolean isSelfUser;
-    
-	public static SearchParameters from(final String sqlSearch, final Long officeId, final String externalId, final String name,
+    // Provisning Entries Search Params
+    private final Long provisioningEntryId;
+    private final Long productId;
+    private final Long categoryId;
+    private final boolean isSelfUser;
+
+    public static SearchParameters from(final String sqlSearch, final Long officeId, final String externalId, final String name,
             final String hierarchy) {
         final Long staffId = null;
         final String accountNo = null;
@@ -145,6 +145,20 @@ public final class SearchParameters {
                 loanId, savingsId, orphansOnly, isSelfUser);
     }
 
+    public static SearchParameters forPaginationAndAccountNumberSearch(final Integer offset, final Integer limit, final String orderBy,
+            final String sortOrder, final String accountNumber) {
+
+        final Integer maxLimitAllowed = getCheckedLimit(limit);
+        final Long staffId = null;
+        final Long loanId = null;
+        final Long savingsId = null;
+        final Boolean orphansOnly = false;
+        final boolean isSelfUser = false;
+
+        return new SearchParameters(null, null, null, null, null, null, null, offset, maxLimitAllowed, orderBy, sortOrder, staffId,
+                accountNumber, loanId, savingsId, orphansOnly, isSelfUser);
+    }
+
     public static SearchParameters forPagination(final Integer offset, final Integer limit) {
 
         final Integer maxLimitAllowed = getCheckedLimit(limit);
@@ -160,11 +174,11 @@ public final class SearchParameters {
                 loanId, savingsId, orphansOnly, isSelfUser);
     }
 
-    public final static SearchParameters forProvisioningEntries(final Long provisioningEntryId, final Long officeId, final Long productId, 
+    public final static SearchParameters forProvisioningEntries(final Long provisioningEntryId, final Long officeId, final Long productId,
             final Long categoryId, final Integer offset, final Integer limit) {
-        return new SearchParameters(provisioningEntryId, officeId, productId, categoryId, offset, limit) ;
+        return new SearchParameters(provisioningEntryId, officeId, productId, categoryId, offset, limit);
     }
-    
+
     public static SearchParameters forSavings(final String sqlSearch, final String externalId, final Integer offset, final Integer limit,
             final String orderBy, final String sortOrder) {
 
@@ -216,11 +230,11 @@ public final class SearchParameters {
         this.savingsId = savingsId;
         this.orphansOnly = orphansOnly;
         this.currencyCode = null;
-        this.provisioningEntryId = null ;
-        this.productId = null ;
-        this.categoryId = null ;
+        this.provisioningEntryId = null;
+        this.productId = null;
+        this.categoryId = null;
         this.isSelfUser = isSelfUser;
-      
+
     }
 
     private SearchParameters(final Long provisioningEntryId, final Long officeId, final Long productId, final Long categoryId,
@@ -242,17 +256,17 @@ public final class SearchParameters {
         this.officeId = officeId;
         this.offset = offset;
         this.limit = limit;
-        this.provisioningEntryId = provisioningEntryId ;
-        this.productId = productId ;
-        this.categoryId = categoryId ;
+        this.provisioningEntryId = provisioningEntryId;
+        this.productId = productId;
+        this.categoryId = categoryId;
         this.isSelfUser = false;
-        
+
     }
-    
-    public SearchParameters(final String sqlSearch, final Long officeId, final String externalId, final String name, final String hierarchy,
-            final String firstname, final String lastname, final Integer offset, final Integer limit, final String orderBy,
-            final String sortOrder, final Long staffId, final String accountNo, final Long loanId, final Long savingsId,
-            final Boolean orphansOnly, final String currencyCode) {
+
+    public SearchParameters(final String sqlSearch, final Long officeId, final String externalId, final String name,
+            final String hierarchy, final String firstname, final String lastname, final Integer offset, final Integer limit,
+            final String orderBy, final String sortOrder, final Long staffId, final String accountNo, final Long loanId,
+            final Long savingsId, final Boolean orphansOnly, final String currencyCode) {
         this.sqlSearch = sqlSearch;
         this.officeId = officeId;
         this.externalId = externalId;
@@ -270,9 +284,9 @@ public final class SearchParameters {
         this.savingsId = savingsId;
         this.orphansOnly = orphansOnly;
         this.currencyCode = currencyCode;
-        this.provisioningEntryId = null ;
-        this.productId = null ;
-        this.categoryId = null ;
+        this.provisioningEntryId = null;
+        this.productId = null;
+        this.categoryId = null;
         this.isSelfUser = false;
     }
 
@@ -400,32 +414,33 @@ public final class SearchParameters {
         if (this.orphansOnly != null) { return this.orphansOnly; }
         return false;
     }
-    
+
     public Long getProvisioningEntryId() {
         return this.provisioningEntryId;
     }
-    
+
     public boolean isProvisioningEntryIdPassed() {
-        return this.provisioningEntryId != null && this.provisioningEntryId != 0 ;
+        return this.provisioningEntryId != null && this.provisioningEntryId != 0;
     }
-    
+
     public Long getProductId() {
         return this.productId;
     }
 
     public boolean isProductIdPassed() {
-        return this.productId != null && this.productId != 0 ;
+        return this.productId != null && this.productId != 0;
     }
+
     public Long getCategoryId() {
         return this.categoryId;
     }
-    
+
     public boolean isCategoryIdPassed() {
-        return this.categoryId != null && this.categoryId != 0 ;
+        return this.categoryId != null && this.categoryId != 0;
     }
 
     public boolean isSelfUser() {
-		return this.isSelfUser;
-	}
+        return this.isSelfUser;
+    }
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityAccessType.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityAccessType.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityAccessType.java
index a54ac0f..b4c11d1 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityAccessType.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityAccessType.java
@@ -25,7 +25,7 @@ public class FineractEntityAccessType {
 	public static final FineractEntityAccessType OFFICE_ACCESS_TO_LOAN_PRODUCTS = new FineractEntityAccessType("Office Access to Loan Products");
 	public static final FineractEntityAccessType OFFICE_ACCESS_TO_SAVINGS_PRODUCTS = new FineractEntityAccessType("Office Access to Savings Products");
 	public static final FineractEntityAccessType OFFICE_ACCESS_TO_CHARGES = new FineractEntityAccessType("Office Access to Fees/Charges");
-    
+     
     private FineractEntityAccessType (String str) {
     	this.str = str;
     }

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityType.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityType.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityType.java
index 8280095..dd8e384 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityType.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityType.java
@@ -27,7 +27,8 @@ public class FineractEntityType {
 	public static FineractEntityType LOAN_PRODUCT = new FineractEntityType ("loan_product", "Loan Products", "m_product_loan");
 	public static FineractEntityType SAVINGS_PRODUCT = new FineractEntityType ("savings_product", "Savings Products", "m_savings_product");
 	public static FineractEntityType CHARGE = new FineractEntityType ("charge", "Fees/Charges", "m_charge");
-		
+	public static FineractEntityType SHARE_PRODUCT = new FineractEntityType("shares_product", "Shares Products", "m_share_product") ;
+	
 	private FineractEntityType (String type, String description, String table_name) {
 		this.type = type;
 		this.description = description;
@@ -56,9 +57,11 @@ public class FineractEntityType {
     			retType = LOAN_PRODUCT;
     	} else if (type.equals(SAVINGS_PRODUCT)) { 
     			retType = SAVINGS_PRODUCT;
-    	} else if (type.equals(CHARGE)) 
-    			retType = CHARGE;
-    	
+    	} else if (type.equals(CHARGE)) {
+    		retType = CHARGE;
+    	}else if(type.equals(SHARE_PRODUCT)) {
+    		retType = SHARE_PRODUCT ;
+    	}
     	return retType;
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobName.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobName.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobName.java
index b244804..999840b 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobName.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobName.java
@@ -29,17 +29,18 @@ public enum JobName {
     TRANSFER_FEE_CHARGE_FOR_LOANS("Transfer Fee For Loans From Savings"), //
     ACCOUNTING_RUNNING_BALANCE_UPDATE("Update Accounting Running Balances"), //
     PAY_DUE_SAVINGS_CHARGES("Pay Due Savings Charges"), //
-    APPLY_CHARGE_TO_OVERDUE_LOAN_INSTALLMENT("Apply penalty to overdue loans"),
-    EXECUTE_STANDING_INSTRUCTIONS("Execute Standing Instruction"),
-    ADD_ACCRUAL_ENTRIES("Add Accrual Transactions"),
-    UPDATE_NPA("Update Non Performing Assets"),
-    UPDATE_DEPOSITS_ACCOUNT_MATURITY_DETAILS("Update Deposit Accounts Maturity details"),
-    TRANSFER_INTEREST_TO_SAVINGS("Transfer Interest To Savings"),
-    ADD_PERIODIC_ACCRUAL_ENTRIES("Add Periodic Accrual Transactions"),
-    RECALCULATE_INTEREST_FOR_LOAN("Recalculate Interest For Loans"),
-    GENERATE_RD_SCEHDULE("Generate Mandatory Savings Schedule"),
-    GENERATE_LOANLOSS_PROVISIONING("Generate Loan Loss Provisioning");
-    
+    APPLY_CHARGE_TO_OVERDUE_LOAN_INSTALLMENT("Apply penalty to overdue loans"), //
+    EXECUTE_STANDING_INSTRUCTIONS("Execute Standing Instruction"), //
+    ADD_ACCRUAL_ENTRIES("Add Accrual Transactions"), //
+    UPDATE_NPA("Update Non Performing Assets"), //
+    UPDATE_DEPOSITS_ACCOUNT_MATURITY_DETAILS("Update Deposit Accounts Maturity details"), //
+    TRANSFER_INTEREST_TO_SAVINGS("Transfer Interest To Savings"), //
+    ADD_PERIODIC_ACCRUAL_ENTRIES("Add Periodic Accrual Transactions"), //
+    RECALCULATE_INTEREST_FOR_LOAN("Recalculate Interest For Loans"), //
+    GENERATE_RD_SCEHDULE("Generate Mandatory Savings Schedule"), //
+    GENERATE_LOANLOSS_PROVISIONING("Generate Loan Loss Provisioning"), //
+    POST_DIVIDENTS_FOR_SHARES("Post Dividends For Shares");
+
     private final String name;
 
     private JobName(final String name) {

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerWritePlatformServiceJpaImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerWritePlatformServiceJpaImpl.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerWritePlatformServiceJpaImpl.java
index 8a6d15f..bff951c 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerWritePlatformServiceJpaImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerWritePlatformServiceJpaImpl.java
@@ -422,6 +422,7 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
             final String uniqueVal = String.valueOf(time) + currentUser.getId() + cashierOffice.getId();
             final String transactionId = Long.toHexString(Long.parseLong(uniqueVal));
             ClientTransaction clientTransaction = null;
+            final Long shareTransactionId = null;
 
             final JournalEntry debitJournalEntry = JournalEntry.createNew(cashierOffice, null, // payment
                                                                                                // detail
@@ -430,7 +431,7 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
                     transactionId, false, // manual entry
                     cashierTxn.getTxnDate(), JournalEntryType.DEBIT, cashierTxn.getTxnAmount(), cashierTxn.getTxnNote(), // Description
                     null, null, null, // entity Type, entityId, reference number
-                    null, null, clientTransaction); // Loan and Savings Txn
+                    null, null, clientTransaction, shareTransactionId); // Loan and Savings Txn
 
             final JournalEntry creditJournalEntry = JournalEntry.createNew(cashierOffice, null, // payment
                                                                                                 // detail
@@ -439,7 +440,7 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
                     transactionId, false, // manual entry
                     cashierTxn.getTxnDate(), JournalEntryType.CREDIT, cashierTxn.getTxnAmount(), cashierTxn.getTxnNote(), // Description
                     null, null, null, // entity Type, entityId, reference number
-                    null, null, clientTransaction); // Loan and Savings Txn
+                    null, null, clientTransaction, shareTransactionId); // Loan and Savings Txn
 
             this.glJournalEntryRepository.saveAndFlush(debitJournalEntry);
             this.glJournalEntryRepository.saveAndFlush(creditJournalEntry);

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/AccountSummaryCollectionData.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/AccountSummaryCollectionData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/AccountSummaryCollectionData.java
index 2e7f1c6..f4faaca 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/AccountSummaryCollectionData.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/AccountSummaryCollectionData.java
@@ -23,30 +23,31 @@ import java.util.Collection;
 /**
  * Immutable data object representing a summary of various accounts.
  */
+@SuppressWarnings("unused")
 public class AccountSummaryCollectionData {
 
-    @SuppressWarnings("unused")
     private final Collection<LoanAccountSummaryData> loanAccounts;
-    @SuppressWarnings("unused")
     private final Collection<SavingsAccountSummaryData> savingsAccounts;
-    @SuppressWarnings("unused")
+    private final Collection<ShareAccountSummaryData> shareAccounts ;
+    
     private final Collection<LoanAccountSummaryData> memberLoanAccounts;
-    @SuppressWarnings("unused")
     private final Collection<SavingsAccountSummaryData> memberSavingsAccounts;
 
     public AccountSummaryCollectionData(final Collection<LoanAccountSummaryData> loanAccounts,
-            final Collection<SavingsAccountSummaryData> savingsAccounts) {
+            final Collection<SavingsAccountSummaryData> savingsAccounts, final Collection<ShareAccountSummaryData> shareAccounts) {
         this.loanAccounts = defaultLoanAccountsIfEmpty(loanAccounts);
         this.savingsAccounts = defaultSavingsAccountsIfEmpty(savingsAccounts);
+        this.shareAccounts = defaultShareAccountsIfEmpty(shareAccounts) ;
         this.memberLoanAccounts = null;
         this.memberSavingsAccounts = null;
     }
-
+    
     public AccountSummaryCollectionData(final Collection<LoanAccountSummaryData> loanAccounts,
             final Collection<SavingsAccountSummaryData> savingsAccounts, final Collection<LoanAccountSummaryData> memberLoanAccounts,
             final Collection<SavingsAccountSummaryData> memberSavingsAccounts) {
         this.loanAccounts = defaultLoanAccountsIfEmpty(loanAccounts);
         this.savingsAccounts = defaultSavingsAccountsIfEmpty(savingsAccounts);
+        this.shareAccounts = null ;
         this.memberLoanAccounts = defaultLoanAccountsIfEmpty(memberLoanAccounts);
         this.memberSavingsAccounts = defaultSavingsAccountsIfEmpty(memberSavingsAccounts);
     }
@@ -66,5 +67,13 @@ public class AccountSummaryCollectionData {
         }
         return returnCollection;
     }
+    
+    private Collection<ShareAccountSummaryData> defaultShareAccountsIfEmpty(final Collection<ShareAccountSummaryData> collection) {
+        Collection<ShareAccountSummaryData> returnCollection = null;
+        if (collection != null && !collection.isEmpty()) {
+            returnCollection = collection;
+        }
+        return returnCollection;
+    }
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/ShareAccountSummaryData.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/ShareAccountSummaryData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/ShareAccountSummaryData.java
new file mode 100644
index 0000000..b4c0351
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/ShareAccountSummaryData.java
@@ -0,0 +1,73 @@
+/**
+ * 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.accountdetails.data;
+
+import org.apache.fineract.organisation.monetary.data.CurrencyData;
+import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountApplicationTimelineData;
+import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountStatusEnumData;
+
+@SuppressWarnings("unused")
+public class ShareAccountSummaryData {
+
+	private final Long id;
+	private final String accountNo;
+	private final Long totalApprovedShares;
+	private final Long totalPendingForApprovalShares;
+	private final String externalId;
+	private final Long productId;
+	private final String productName;
+	private final String shortProductName;
+	private final ShareAccountStatusEnumData status;
+	private final CurrencyData currency;
+	private final ShareAccountApplicationTimelineData timeline;
+
+	public ShareAccountSummaryData(final Long id, final String accountNo,
+			final String externalId, final Long productId,
+			final String productName, final String shortProductName,
+			final ShareAccountStatusEnumData status,
+			final CurrencyData currency, final Long approvedShares,
+			final Long pendingForApprovalShares,
+			final ShareAccountApplicationTimelineData timeline) {
+		this.id = id;
+		this.accountNo = accountNo;
+		this.externalId = externalId;
+		if(approvedShares == null) {
+			this.totalApprovedShares = new Long(0) ;
+		}else {
+			this.totalApprovedShares = approvedShares;	
+		}
+		if(pendingForApprovalShares == null) {
+			this.totalPendingForApprovalShares = new Long(0) ;
+		}else {
+			this.totalPendingForApprovalShares = pendingForApprovalShares;	
+		}
+		this.productId = productId;
+		this.productName = productName;
+		this.shortProductName = shortProductName;
+		this.status = status;
+		this.currency = currency;
+		this.timeline = timeline;
+	}
+
+    
+    public String getAccountNo() {
+        return this.accountNo;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformServiceJpaRepositoryImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformServiceJpaRepositoryImpl.java
index 5622c8d..339ffd9 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformServiceJpaRepositoryImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformServiceJpaRepositoryImpl.java
@@ -31,6 +31,7 @@ import org.apache.fineract.organisation.monetary.data.CurrencyData;
 import org.apache.fineract.portfolio.accountdetails.data.AccountSummaryCollectionData;
 import org.apache.fineract.portfolio.accountdetails.data.LoanAccountSummaryData;
 import org.apache.fineract.portfolio.accountdetails.data.SavingsAccountSummaryData;
+import org.apache.fineract.portfolio.accountdetails.data.ShareAccountSummaryData;
 import org.apache.fineract.portfolio.client.service.ClientReadPlatformService;
 import org.apache.fineract.portfolio.group.service.GroupReadPlatformService;
 import org.apache.fineract.portfolio.loanaccount.data.LoanApplicationTimelineData;
@@ -39,6 +40,9 @@ import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations;
 import org.apache.fineract.portfolio.savings.data.SavingsAccountApplicationTimelineData;
 import org.apache.fineract.portfolio.savings.data.SavingsAccountStatusEnumData;
 import org.apache.fineract.portfolio.savings.service.SavingsEnumerations;
+import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountApplicationTimelineData;
+import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountStatusEnumData;
+import org.apache.fineract.portfolio.shareaccounts.service.SharesEnumerations;
 import org.joda.time.LocalDate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.jdbc.core.JdbcTemplate;
@@ -68,7 +72,8 @@ public class AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou
         final String savingswhereClause = " where sa.client_id = ? order by sa.status_enum ASC, sa.account_no ASC";
         final List<LoanAccountSummaryData> loanAccounts = retrieveLoanAccountDetails(loanwhereClause, new Object[] { clientId });
         final List<SavingsAccountSummaryData> savingsAccounts = retrieveAccountDetails(savingswhereClause, new Object[] { clientId });
-        return new AccountSummaryCollectionData(loanAccounts, savingsAccounts);
+        final List<ShareAccountSummaryData> shareAccounts = retrieveShareAccountDetails(clientId) ;
+        return new AccountSummaryCollectionData(loanAccounts, savingsAccounts, shareAccounts);
     }
 
     @Override
@@ -121,6 +126,108 @@ public class AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou
         return this.jdbcTemplate.query(savingsSql, savingsAccountSummaryDataMapper, inputs);
     }
 
+    private List<ShareAccountSummaryData> retrieveShareAccountDetails(final Long clientId) {
+    	final ShareAccountSummaryDataMapper mapper = new ShareAccountSummaryDataMapper() ;
+    	final String query = "select " + mapper.schema() + " where sa.client_id = ?" ;
+    	  return this.jdbcTemplate.query(query, mapper, new Object [] {clientId});
+    }
+    
+    private final static class ShareAccountSummaryDataMapper implements RowMapper<ShareAccountSummaryData> {
+
+    	private final String schema ;
+    	
+    	ShareAccountSummaryDataMapper() {
+    		final StringBuffer buff = new StringBuffer()
+    		.append("sa.id as id, sa.external_id as externalId, sa.status_enum as statusEnum, ")
+    		.append("sa.account_no as accountNo, sa.total_approved_shares as approvedShares, sa.total_pending_shares as pendingShares, ")
+    		.append("sa.savings_account_id as savingsAccountNo, sa.minimum_active_period_frequency as minimumactivePeriod,")
+    		.append("sa.minimum_active_period_frequency_enum as minimumactivePeriodEnum,") 
+    		.append("sa.lockin_period_frequency as lockinPeriod, sa.lockin_period_frequency_enum as lockinPeriodEnum, ")
+    		.append("sa.submitted_date as submittedDate, sbu.username as submittedByUsername, ")
+    		.append("sbu.firstname as submittedByFirstname, sbu.lastname as submittedByLastname, ") 
+    		.append("sa.rejected_date as rejectedDate, rbu.username as rejectedByUsername, ")
+    		.append("rbu.firstname as rejectedByFirstname, rbu.lastname as rejectedByLastname, ")
+    		.append("sa.approved_date as approvedDate, abu.username as approvedByUsername, ")
+    		.append("abu.firstname as approvedByFirstname, abu.lastname as approvedByLastname, ")
+    		.append("sa.activated_date as activatedDate, avbu.username as activatedByUsername, ")
+    		.append("avbu.firstname as activatedByFirstname, avbu.lastname as activatedByLastname, ")
+    		.append("sa.closed_date as closedDate, cbu.username as closedByUsername, ")
+    		.append("cbu.firstname as closedByFirstname, cbu.lastname as closedByLastname, ")
+    		.append("sa.currency_code as currencyCode, sa.currency_digits as currencyDigits, sa.currency_multiplesof as inMultiplesOf, ")
+    		.append("curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, ")
+    		.append("curr.display_symbol as currencyDisplaySymbol, sa.product_id as productId, p.name as productName, p.short_name as shortProductName ")
+    		.append("from m_share_account sa ")
+    		.append("join m_share_product as p on p.id = sa.product_id ")
+    		.append("join m_currency curr on curr.code = sa.currency_code ")
+    		.append("left join m_appuser sbu on sbu.id = sa.submitted_userid ")
+    		.append("left join m_appuser rbu on rbu.id = sa.rejected_userid ")
+    		.append("left join m_appuser abu on abu.id = sa.approved_userid ")
+    		.append("left join m_appuser avbu on rbu.id = sa.activated_userid ")
+    		.append("left join m_appuser cbu on cbu.id = sa.closed_userid ") ;
+    		schema = buff.toString() ;
+		}
+		@Override
+		public ShareAccountSummaryData mapRow(ResultSet rs, int rowNum)
+				throws SQLException {
+
+            final Long id = JdbcSupport.getLong(rs, "id");
+            final String accountNo = rs.getString("accountNo");
+            final Long approvedShares = JdbcSupport.getLong(rs, "approvedShares");
+            final Long pendingShares = JdbcSupport.getLong(rs, "pendingShares");
+            final String externalId = rs.getString("externalId");
+            final Long productId = JdbcSupport.getLong(rs, "productId");
+            final String productName = rs.getString("productName");
+            final String shortProductName = rs.getString("shortProductName");
+            final Integer statusId = JdbcSupport.getInteger(rs, "statusEnum");
+            final ShareAccountStatusEnumData status = SharesEnumerations.status(statusId) ;
+            final String currencyCode = rs.getString("currencyCode");
+            final String currencyName = rs.getString("currencyName");
+            final String currencyNameCode = rs.getString("currencyNameCode");
+            final String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
+            final Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits");
+            final Integer inMultiplesOf = JdbcSupport.getInteger(rs, "inMultiplesOf");
+            final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDigits, inMultiplesOf,
+                    currencyDisplaySymbol, currencyNameCode);
+
+            final LocalDate submittedOnDate = JdbcSupport.getLocalDate(rs, "submittedDate");
+            final String submittedByUsername = rs.getString("submittedByUsername");
+            final String submittedByFirstname = rs.getString("submittedByFirstname");
+            final String submittedByLastname = rs.getString("submittedByLastname");
+
+            final LocalDate rejectedOnDate = JdbcSupport.getLocalDate(rs, "rejectedDate");
+            final String rejectedByUsername = rs.getString("rejectedByUsername");
+            final String rejectedByFirstname = rs.getString("rejectedByFirstname");
+            final String rejectedByLastname = rs.getString("rejectedByLastname");
+
+            final LocalDate approvedOnDate = JdbcSupport.getLocalDate(rs, "approvedDate");
+            final String approvedByUsername = rs.getString("approvedByUsername");
+            final String approvedByFirstname = rs.getString("approvedByFirstname");
+            final String approvedByLastname = rs.getString("approvedByLastname");
+
+            final LocalDate activatedOnDate = JdbcSupport.getLocalDate(rs, "activatedDate");
+            final String activatedByUsername = rs.getString("activatedByUsername");
+            final String activatedByFirstname = rs.getString("activatedByFirstname");
+            final String activatedByLastname = rs.getString("activatedByLastname");
+
+            final LocalDate closedOnDate = JdbcSupport.getLocalDate(rs, "closedDate");
+            final String closedByUsername = rs.getString("closedByUsername");
+            final String closedByFirstname = rs.getString("closedByFirstname");
+            final String closedByLastname = rs.getString("closedByLastname");
+
+            final ShareAccountApplicationTimelineData timeline = new ShareAccountApplicationTimelineData(submittedOnDate,
+                    submittedByUsername, submittedByFirstname, submittedByLastname, rejectedOnDate, rejectedByUsername,
+                    rejectedByFirstname, rejectedByLastname, approvedOnDate, approvedByUsername, approvedByFirstname, approvedByLastname, activatedOnDate,
+                    activatedByUsername, activatedByFirstname, activatedByLastname, closedOnDate, closedByUsername, closedByFirstname,
+                    closedByLastname);
+
+            return new ShareAccountSummaryData(id, accountNo, externalId, productId, productName, shortProductName, status, currency,
+                    approvedShares, pendingShares, timeline);
+        }
+    	
+		public String schema() {
+			return this.schema ;
+		}
+    }
     private static final class SavingsAccountSummaryDataMapper implements RowMapper<SavingsAccountSummaryData> {
 
         final String schemaSql;

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/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 b20a19b..56df39f 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
@@ -19,7 +19,6 @@
 package org.apache.fineract.portfolio.accounts.api;
 
 import java.util.Collection;
-import java.util.HashSet;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
@@ -44,7 +43,6 @@ import org.apache.fineract.infrastructure.security.service.PlatformSecurityConte
 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.accounts.service.AccountsCommandsService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Scope;
@@ -79,15 +77,30 @@ public class AccountsApiResource {
     }
     
     @GET
+    @Path("template")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    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());
+    }
+    
+    @GET
     @Path("{accountId}")
     @Consumes({ MediaType.APPLICATION_JSON })
     @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 ;
-        AccountReadPlatformService service = (AccountReadPlatformService) this.applicationContext.getBean(serviceName) ;
-        AccountData data = service.retrieveOne(accountId) ;
         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());
     }
     
@@ -118,12 +131,12 @@ public class AccountsApiResource {
     @Consumes({ MediaType.APPLICATION_JSON })
     @Produces({ MediaType.APPLICATION_JSON })
     public String handleCommands(@PathParam("type") final String accountType, @PathParam("accountId") final Long accountId, @QueryParam("command") final String commandParam,
-            @Context final UriInfo uriInfo, final String apiRequestBodyAsJson) {
-        String serviceName = accountType.toUpperCase()+AccountsApiConstants.ACCOUNT_COMMANDSERVICE ;
-        AccountsCommandsService service = (AccountsCommandsService) this.applicationContext.getBean(serviceName) ;
-        final Object obj = service.handleCommand(accountId, commandParam, apiRequestBodyAsJson) ;
-        final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
-        return this.toApiObjectJsonSerializer.serialize(settings, obj, new HashSet<String>());
+            final String apiRequestBodyAsJson) {
+        CommandWrapper commandWrapper = null;
+        this.platformSecurityContext.authenticatedUser();
+        commandWrapper = new CommandWrapperBuilder().createAccountCommand(accountType, accountId, commandParam).withJson(apiRequestBodyAsJson).build();
+        final CommandProcessingResult commandProcessingResult = this.commandsSourceWritePlatformService.logCommandSource(commandWrapper);
+        return this.toApiJsonSerializer.serialize(commandProcessingResult);
     }
     
     @PUT

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/constants/ShareAccountApiConstants.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/constants/ShareAccountApiConstants.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/constants/ShareAccountApiConstants.java
index 3de0f73..bbfe50e 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/constants/ShareAccountApiConstants.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/constants/ShareAccountApiConstants.java
@@ -18,60 +18,97 @@
  */
 package org.apache.fineract.portfolio.accounts.constants;
 
-
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
 
 public interface ShareAccountApiConstants {
 
-    //Command Strings
-    String APPROVE_COMMAND = "approve" ;
-    String REJECT_COMMAND = "reject" ;
-    String APPLY_ADDITIONALSHARES_COMMAND = "applyadditionalshares" ;
-    String APPROVE_ADDITIONSHARES_COMMAND = "approveadditionalshares" ;
-    String REJECT_ADDITIONSHARES_COMMAND = "rejectadditionalshares" ;
-    
-    //
-    String id_paramname = "id" ;
-    
-    String clientid_paramname = "clientId" ;
-    
-    String productid_paramname = "productId" ;
-    
-    String submitteddate_paramname = "submittedDate" ;
-    
-    String approveddate_paramname = "approvedDate" ;
-    
-    String fieldofferid_paramname = "fieldOfficerId" ;
-    
-    String externalid_paramname = "externalId" ;
-    
-    String currency_paramname = "currencyCode" ;
-    
-    String digitsafterdecimal_paramname = "digitsAfterDecimal" ;
-    
-    String inmultiplesof_paramname = "inMultiplesOf" ;
-    
-    String purchasedshares_paramname = "purchasedShares" ;
-    
-    String additionalshares_paramname = "additionalShares" ;
-    
-    String suspenseaccount_paramname = "suspenseAccount" ;
-    
-    String equityaccount_paramname = "equityAccount" ;
-    
-    String savingsaccountid_paramname = "savingsAccountId" ;
-    
-    String lockperiod_paramname = "lockPeriod" ;
-    
-    String minimumactiveperiodfordividends_paramname = "minimumActivePeriodForDividends" ;
-    
-    String allowdividendcalculationforinactiveclients_paramname = "allowDividendCalculationForInactiveClients" ;
-    
-    String charges_paramname = "charges" ; 
-    
-    String purchaseddate_paramname = "purchasedDate" ;
-    
-    String numberofshares_paramname = "numberOfShares" ;
-    
-    String purchasedprice_paramname = "purchasedPrice" ;
-    
+	public static final String amountParamName = "amount";
+	public static final String dateFormatParamName = "dateFormat";
+	public static final String dueAsOfDateParamName = "dueDate";
+	public static final String feeIntervalParamName = "feeInterval";
+	public static final String feeOnMonthDayParamName = "feeOnMonthDay";
+	public static final String localeParamName = "locale";
+
+	// Command Strings
+	String APPROVE_COMMAND = "approve";
+	String REJECT_COMMAND = "reject";
+	String APPLY_ADDITIONALSHARES_COMMAND = "applyadditionalshares";
+	String APPROVE_ADDITIONSHARES_COMMAND = "approveadditionalshares";
+	String REJECT_ADDITIONSHARES_COMMAND = "rejectadditionalshares";
+
+	//
+	String locale_paramname = "locale" ;
+	
+	String dateformat_paramname = "dateFormat" ;
+	
+	String id_paramname = "id";
+
+	String clientid_paramname = "clientId";
+
+	String productid_paramname = "productId";
+
+	String submitteddate_paramname = "submittedDate";
+
+	String approveddate_paramname = "approvedDate";
+
+	String activatedate_paramname = "activatedDate" ;
+	
+	String fieldofferid_paramname = "fieldOfficerId";
+
+	String externalid_paramname = "externalId";
+
+	String currency_paramname = "currencyCode";
+
+	String digitsafterdecimal_paramname = "digitsAfterDecimal";
+
+	String inmultiplesof_paramname = "inMultiplesOf";
+
+	String requestedshares_paramname = "requestedShares";
+
+	String savingsaccountid_paramname = "savingsAccountId";
+
+	String lockinperiod_paramname = "lockinPeriodFrequency";
+
+	String lockperiodfrequencytype_paramname = "lockinPeriodFrequencyType";
+
+	String minimumactiveperiod_paramname = "minimumActivePeriod";
+
+	String minimumactiveperiodfrequencytype_paramname = "minimumActivePeriodFrequencyType";
+
+	String allowdividendcalculationforinactiveclients_paramname = "allowDividendCalculationForInactiveClients";
+
+	String charges_paramname = "charges";
+
+	String applicationdate_param = "applicationDate";
+
+	String purchaseddate_paramname = "purchasedDate";
+
+	String numberofshares_paramname = "numberOfShares";
+
+	String purchasedprice_paramname = "unitPrice";
+	
+	String note_paramname = "note" ;
+	
+	public String requesteddate_paramname = "requestedDate" ;
+	
+	public String additionalshares_paramname = "additionalshares" ;
+	
+	public String closeddate_paramname = "closedDate" ;
+	
+	Set<String> supportedParameters = new HashSet<>(Arrays.asList(locale_paramname, dateformat_paramname, id_paramname,clientid_paramname, productid_paramname,
+	        submitteddate_paramname,approveddate_paramname, externalid_paramname, currency_paramname, digitsafterdecimal_paramname,
+	        inmultiplesof_paramname, requestedshares_paramname,savingsaccountid_paramname,lockinperiod_paramname,
+	        lockperiodfrequencytype_paramname,minimumactiveperiod_paramname, minimumactiveperiodfrequencytype_paramname,
+	        allowdividendcalculationforinactiveclients_paramname, charges_paramname, applicationdate_param,
+	        purchaseddate_paramname,numberofshares_paramname,purchasedprice_paramname));
+
+	Set<String> approvalParameters = new HashSet<>(Arrays.asList(locale_paramname, dateformat_paramname, approveddate_paramname, note_paramname));
+	
+	Set<String> activateParameters = new HashSet<>(Arrays.asList(locale_paramname, dateformat_paramname, activatedate_paramname));
+	
+	Set<String> closeParameters = new HashSet<>(Arrays.asList(locale_paramname, dateformat_paramname, closeddate_paramname, note_paramname));
+	
+	Set<String> addtionalSharesParameters = new HashSet<>(Arrays.asList(locale_paramname, requesteddate_paramname, requestedshares_paramname, purchasedprice_paramname, dateformat_paramname));
 }

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/data/PurchasedSharesData.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/data/PurchasedSharesData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/data/PurchasedSharesData.java
deleted file mode 100644
index 28414aa..0000000
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/data/PurchasedSharesData.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * 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.accounts.data;
-
-import java.math.BigDecimal;
-import java.util.Date;
-
-
-public class PurchasedSharesData {
-
-    private final Date purchasedDate ;
-    
-    private final Long numberOfShares ;
-    
-    private final BigDecimal purchasedPrice ;
-    
-    private final String status ;
-    
-    public PurchasedSharesData(final Date purchasedDate, final Long numberOfShares, final BigDecimal purchasedPrice, final String status) {
-        this.purchasedDate = purchasedDate ;
-        this.numberOfShares = numberOfShares ;
-        this.purchasedPrice = purchasedPrice ;
-        this.status = status ;
-    }
-
-    
-    public Date getPurchasedDate() {
-        return this.purchasedDate;
-    }
-
-    
-    public Long getNumberOfShares() {
-        return this.numberOfShares;
-    }
-
-    
-    public BigDecimal getPurchasedPrice() {
-        return this.purchasedPrice;
-    }
-    
-    public String getStatus() {
-        return this.status ;
-    }
-}


Mime
View raw message