Shares And Dividends Implementation

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

Branch: refs/heads/develop
Commit: 08c553f9fcb47137464d7fb66a644aa8bf3ccdac
Parents: 9fedac2
Author: Nazeer Hussain Shaik <nazeer.sh...@confluxtechnologies.com>
Authored: Wed Apr 13 16:34:38 2016 +0530
Committer: Nazeer Hussain Shaik <nazeer.sh...@confluxtechnologies.com>
Committed: Wed Apr 13 16:34:38 2016 +0530

----------------------------------------------------------------------
 .../accounting/common/AccountingConstants.java  |  64 +-
 .../AccountingDropdownReadPlatformService.java  |   2 +
 ...countingDropdownReadPlatformServiceImpl.java |  11 +
 .../FinancialActivityAccountDataValidator.java  |   6 +-
 .../accounting/journalentry/data/SharesDTO.java | 101 +++
 .../journalentry/data/SharesTransactionDTO.java |  94 +++
 .../journalentry/domain/JournalEntry.java       |  21 +-
 .../service/AccountingProcessorForShares.java   |  27 +
 .../AccountingProcessorForSharesFactory.java    |  48 ++
 .../service/AccountingProcessorHelper.java      | 220 +++++-
 .../CashBasedAccountingProcessorForSavings.java |   6 +
 .../CashBasedAccountingProcessorForShares.java  | 129 ++++
 .../JournalEntryWritePlatformService.java       |   2 +
 ...ryWritePlatformServiceJpaRepositoryImpl.java |  59 +-
 .../domain/PortfolioProductType.java            |   7 +-
 ...GLAccountMappingFromApiJsonDeserializer.java |  47 +-
 ...ctToGLAccountMappingReadPlatformService.java |   6 +
 ...GLAccountMappingReadPlatformServiceImpl.java |  48 ++
 ...tToGLAccountMappingWritePlatformService.java |   5 +
 ...LAccountMappingWritePlatformServiceImpl.java |  81 +-
 .../ShareProductToGLAccountMappingHelper.java   | 204 +++++
 .../commands/service/CommandWrapperBuilder.java |  72 +-
 .../domain/EntityAccountType.java               |   2 +-
 .../core/service/SearchParameters.java          |  85 ++-
 .../domain/FineractEntityAccessType.java        |   2 +-
 .../entityaccess/domain/FineractEntityType.java |  11 +-
 .../infrastructure/jobs/service/JobName.java    |  23 +-
 .../TellerWritePlatformServiceJpaImpl.java      |   5 +-
 .../data/AccountSummaryCollectionData.java      |  21 +-
 .../data/ShareAccountSummaryData.java           |  73 ++
 ...ilsReadPlatformServiceJpaRepositoryImpl.java | 109 ++-
 .../accounts/api/AccountsApiResource.java       |  33 +-
 .../constants/ShareAccountApiConstants.java     | 143 ++--
 .../accounts/data/PurchasedSharesData.java      |  60 --
 .../accounts/data/ShareAccountData.java         |  99 ---
 .../accounts/data/ShareChargeData.java          |  32 -
 .../accounts/domain/PurchasedShares.java        |  93 ---
 .../portfolio/accounts/domain/ShareAccount.java | 333 ---------
 .../accounts/domain/ShareAccountCharge.java     |  65 --
 .../accounts/domain/ShareAccountRepository.java |  27 -
 .../domain/ShareAccountTempRepository.java      |  56 --
 .../CreateShareAccountCommandHandler.java       |  47 --
 .../UpdateShareAccountCommandHandler.java       |  47 --
 .../ShareAccountDataSerializer.java             | 333 ---------
 .../service/AccountReadPlatformService.java     |  12 +-
 .../ShareAccountCommandsServiceImpl.java        | 136 ----
 .../ShareAccountReadPlatformServiceImpl.java    |  53 --
 .../ShareAccountWritePlatformService.java       |  30 -
 ...ntWritePlatformServiceJpaRepositoryImpl.java |  85 ---
 .../portfolio/charge/data/ChargeData.java       |  45 +-
 .../charge/domain/ChargeAppliesTo.java          |  13 +-
 .../charge/domain/ChargeCalculationType.java    |   8 +
 .../portfolio/charge/domain/ChargeTimeType.java |  46 +-
 ...untChargeWithoutMandatoryFieldException.java |  34 +
 ...efinitionCommandFromApiJsonDeserializer.java |  32 +-
 .../ChargeDropdownReadPlatformService.java      |   4 +
 .../ChargeDropdownReadPlatformServiceImpl.java  |  12 +
 .../charge/service/ChargeEnumerations.java      |  13 +
 .../service/ChargeReadPlatformService.java      |   6 +
 .../service/ChargeReadPlatformServiceImpl.java  |  29 +-
 .../client/api/ClientsApiResource.java          |   2 +-
 .../client/domain/AccountNumberGenerator.java   |  11 +-
 .../LoanChargeReadPlatformServiceImpl.java      |   5 +-
 .../products/api/ProductsApiResource.java       |  90 +--
 .../service/ProductReadPlatformService.java     |   7 +-
 .../savings/SavingsAccountTransactionType.java  |  10 +-
 .../data/SavingsAccountTransactionEnumData.java |   6 +
 .../savings/domain/SavingsAccount.java          |  13 +-
 .../domain/SavingsAccountDomainService.java     |   2 +
 .../domain/SavingsAccountDomainServiceJpa.java  |  31 +-
 .../domain/SavingsAccountTransaction.java       |  26 +-
 ...SavingsAccountTransactionSummaryWrapper.java |   4 +-
 ...ngsAccountChargeReadPlatformServiceImpl.java |  25 +-
 .../savings/service/SavingsEnumerations.java    |   4 +
 .../shareaccounts/data/PurchasedSharesData.java |  78 ++
 .../ShareAccountApplicationTimelineData.java    | 108 +++
 .../data/ShareAccountChargeData.java            |  95 +++
 .../shareaccounts/data/ShareAccountData.java    | 247 +++++++
 .../data/ShareAccountDividendData.java          |  64 ++
 .../data/ShareAccountStatusEnumData.java        |  52 ++
 .../data/ShareAccountTransactionEnumData.java   |  83 +++
 .../domain/PurchasedSharesStatusType.java       |  80 ++
 .../shareaccounts/domain/ShareAccount.java      | 526 +++++++++++++
 .../domain/ShareAccountCharge.java              | 444 +++++++++++
 .../domain/ShareAccountChargePaidBy.java        |  77 ++
 .../domain/ShareAccountDividendDetails.java     |  64 ++
 .../domain/ShareAccountDividendRepository.java  |  27 +
 .../domain/ShareAccountDividendStatusType.java  |  57 ++
 .../domain/ShareAccountRepository.java          |  27 +
 .../domain/ShareAccountRepositoryWrapper.java   |  49 ++
 .../domain/ShareAccountStatusType.java          | 100 +++
 .../domain/ShareAccountTransaction.java         | 209 ++++++
 .../IssueableSharesExceededException.java       |  31 +
 .../ActivateShareAccountCommandHandler.java     |  47 ++
 .../ApplyAddtionalSharesCommandHandler.java     |  47 ++
 .../ApproveAddtionalSharesCommandHandler.java   |  47 ++
 .../ApproveShareAccountCommandHandler.java      |  47 ++
 .../CloseShareAccountCommandHandler.java        |  47 ++
 .../CreateShareAccountCommandHandler.java       |  47 ++
 .../handler/RedeemSharesCommandHandler.java     |  47 ++
 .../RejectAddtionalSharesCommandHandler.java    |  47 ++
 .../RejectShareAccountCommandHandler.java       |  47 ++
 .../UndoApproveShareAccountCommandHandler.java  |  47 ++
 .../UpdateShareAccountCommandHandler.java       |  47 ++
 .../ShareAccountDataSerializer.java             | 741 +++++++++++++++++++
 .../PurchasedSharesReadPlatformService.java     |  28 +
 .../PurchasedSharesReadPlatformServiceImpl.java |  86 +++
 .../ShareAccountChargeReadPlatformService.java  |  28 +
 ...areAccountChargeReadPlatformServiceImpl.java | 148 ++++
 .../ShareAccountCommandsServiceImpl.java        |  85 +++
 ...ShareAccountDividendReadPlatformService.java |  34 +
 ...eAccountDividendReadPlatformServiceImpl.java | 140 ++++
 .../ShareAccountReadPlatformService.java        |  41 +
 .../ShareAccountReadPlatformServiceImpl.java    | 482 ++++++++++++
 .../service/ShareAccountSchedularService.java   |  27 +
 .../ShareAccountSchedularServiceImpl.java       |  61 ++
 .../ShareAccountWritePlatformService.java       |  49 ++
 ...ntWritePlatformServiceJpaRepositoryImpl.java | 404 ++++++++++
 .../service/SharesEnumerations.java             | 196 +++++
 .../shareproducts/SharePeriodFrequencyType.java |  85 +++
 .../api/ShareDividendApiResource.java           | 153 ++++
 .../constants/ShareProductApiConstants.java     |  83 +++
 .../shareproducts/data/ShareProductData.java    | 339 +++++++++
 .../data/ShareProductDividendPayOutData.java    |  56 ++
 .../data/ShareProductMarketPriceData.java       |  49 ++
 .../shareproducts/domain/ShareProduct.java      | 434 +++++++++++
 .../ShareProductDividendPayOutDetails.java      | 101 +++
 .../domain/ShareProductDividendStatusType.java  |  62 ++
 ...eProductDividentPayOutDetailsRepository.java |  27 +
 ...tDividentPayOutDetailsRepositoryWrapper.java |  51 ++
 .../domain/ShareProductMarketPrice.java         |  77 ++
 .../domain/ShareProductRepository.java          |  27 +
 .../domain/ShareProductRepositoryWrapper.java   |  50 ++
 .../exception/DividendNotFoundException.java    |  28 +
 .../exception/DividentProcessingException.java  |  29 +
 ...proveShareProductDividendCommandHandler.java |  47 ++
 .../CreateShareProductCommandHandler.java       |  47 ++
 ...reateShareProductDividendCommandHandler.java |  47 ++
 ...eleteShareProductDividendCommandHandler.java |  47 ++
 .../UpdateShareProductCommandHandler.java       |  47 ++
 .../ShareProductDataSerializer.java             | 460 ++++++++++++
 .../ShareProductCommandsServiceImpl.java        |  59 ++
 .../service/ShareProductDividendAssembler.java  | 131 ++++
 ...ShareProductDividendReadPlatformService.java |  29 +
 ...eProductDividendReadPlatformServiceImpl.java | 128 ++++
 ...ShareProductDropdownReadPlatformService.java |  30 +
 ...eProductDropdownReadPlatformServiceImpl.java |  53 ++
 .../ShareProductReadPlatformServiceImpl.java    | 283 +++++++
 .../ShareProductWritePlatformService.java       |  35 +
 ...ctWritePlatformServiceJpaRepositoryImpl.java | 190 +++++
 .../constants/ShareProductApiConstants.java     |  52 --
 .../portfolio/shares/data/DividendsData.java    |  49 --
 .../shares/data/ProductDividendsData.java       |  65 --
 .../shares/data/ShareMarketPriceData.java       |  42 --
 .../portfolio/shares/data/ShareProductData.java | 160 ----
 .../shares/domain/ShareMarketPrice.java         |  65 --
 .../portfolio/shares/domain/ShareProduct.java   | 363 ---------
 .../shares/domain/ShareProductRepository.java   |  27 -
 .../domain/ShareProductTempRepository.java      |  79 --
 .../CreateShareProductCommandHandler.java       |  47 --
 .../UpdateShareProductCommandHandler.java       |  47 --
 .../ShareProductDataSerializer.java             | 341 ---------
 .../ShareProductCommandsServiceImpl.java        | 105 ---
 .../ShareProductReadPlatformServiceImpl.java    |  64 --
 .../ShareProductWritePlatformService.java       |  30 -
 ...ctWritePlatformServiceJpaRepositoryImpl.java |  90 ---
 .../service/ScheduledJobRunnerService.java      |   2 +
 .../service/ScheduledJobRunnerServiceImpl.java  |  40 +-
 .../migrations/core_db/V299__share_products.sql | 194 +++++
 169 files changed, 10980 insertions(+), 3404 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/accounting/common/AccountingConstants.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/common/AccountingConstants.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/common/AccountingConstants.java
index 03ca3c6..01a6510 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/common/AccountingConstants.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/common/AccountingConstants.java
@@ -234,10 +234,10 @@ public class AccountingConstants {
     }
 
     public static enum FINANCIAL_ACTIVITY {
-        ASSET_TRANSFER(100, "assetTransfer", GLAccountType.ASSET), 
LIABILITY_TRANSFER(200, "liabilityTransfer", GLAccountType.LIABILITY),
-        CASH_AT_MAINVAULT (101, "cashAtMainVault", GLAccountType.ASSET),
-        CASH_AT_TELLER (102, "cashAtTeller", 
GLAccountType.ASSET),OPENING_BALANCES_TRANSFER_CONTRA 
(300,"openingBalancesTransferContra",GLAccountType.EQUITY),
-        ASSET_FUND_SOURCE(103, "fundSource", GLAccountType.ASSET);
+        ASSET_TRANSFER(100, "assetTransfer", GLAccountType.ASSET), 
LIABILITY_TRANSFER(200, "liabilityTransfer", GLAccountType.LIABILITY), 
CASH_AT_MAINVAULT(
+                101, "cashAtMainVault", GLAccountType.ASSET), 
CASH_AT_TELLER(102, "cashAtTeller", GLAccountType.ASSET), 
OPENING_BALANCES_TRANSFER_CONTRA(
+                300, "openingBalancesTransferContra", GLAccountType.EQUITY), 
ASSET_FUND_SOURCE(103, "fundSource", GLAccountType.ASSET), PAYABLE_DIVIDENDS(
+                201, "payableDividends", GLAccountType.LIABILITY);
 
         private final Integer value;
         private final String code;
@@ -305,6 +305,62 @@ public class AccountingConstants {
         }
     }
 
+    /*** Accounting placeholders for cash based accounting for Share products 
***/
+    public static enum CASH_ACCOUNTS_FOR_SHARES {
+        SHARES_REFERENCE(1), SHARES_SUSPENSE(2), INCOME_FROM_FEES(3), 
SHARES_EQUITY(4);
+
+        private final Integer value;
+
+        private CASH_ACCOUNTS_FOR_SHARES(final Integer value) {
+            this.value = value;
+        }
+
+        @Override
+        public String toString() {
+            return name().toString().replaceAll("_", " ");
+        }
+
+        public Integer getValue() {
+            return this.value;
+        }
+
+        private static final Map<Integer, CASH_ACCOUNTS_FOR_SHARES> 
intToEnumMap = new HashMap<>();
+        static {
+            for (final CASH_ACCOUNTS_FOR_SHARES type : 
CASH_ACCOUNTS_FOR_SHARES.values()) {
+                intToEnumMap.put(type.value, type);
+            }
+        }
+
+        public static CASH_ACCOUNTS_FOR_SHARES fromInt(final int i) {
+            final CASH_ACCOUNTS_FOR_SHARES type = 
intToEnumMap.get(Integer.valueOf(i));
+            return type;
+        }
+    }
+
+    /***
+     * Enum of all accounting related input parameter names used while
+     * creating/updating a savings product
+     ***/
+    public static enum SHARES_PRODUCT_ACCOUNTING_PARAMS {
+        SHARES_REFERENCE("shareReferenceId"), 
SHARES_SUSPENSE("shareSuspenseId"), INCOME_FROM_FEES("incomeFromFeeAccountId"), 
SHARES_EQUITY(
+                "shareEquityId");
+
+        private final String value;
+
+        private SHARES_PRODUCT_ACCOUNTING_PARAMS(final String value) {
+            this.value = value;
+        }
+
+        @Override
+        public String toString() {
+            return name().toString().replaceAll("_", " ");
+        }
+
+        public String getValue() {
+            return this.value;
+        }
+    }
+
     public static final String ASSESTS_TAG_OPTION_CODE_NAME = 
"AssetAccountTags";
     public static final String LIABILITIES_TAG_OPTION_CODE_NAME = 
"LiabilityAccountTags";
     public static final String EQUITY_TAG_OPTION_CODE_NAME = 
"EquityAccountTags";

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/accounting/common/AccountingDropdownReadPlatformService.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/common/AccountingDropdownReadPlatformService.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/common/AccountingDropdownReadPlatformService.java
index a8ce5d1..8c9aa31 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/common/AccountingDropdownReadPlatformService.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/common/AccountingDropdownReadPlatformService.java
@@ -41,5 +41,7 @@ public interface AccountingDropdownReadPlatformService {
     public Map<String, List<GLAccountData>> 
retrieveAccountMappingOptionsForCharges();
 
     public Map<String, List<GLAccountData>> retrieveAccountMappingOptions();
+    
+    public Map<String, List<GLAccountData>> 
retrieveAccountMappingOptionsForShareProducts();
 
 }
\ 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/common/AccountingDropdownReadPlatformServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/common/AccountingDropdownReadPlatformServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/common/AccountingDropdownReadPlatformServiceImpl.java
index 87c6b28..66ce192 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/common/AccountingDropdownReadPlatformServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/common/AccountingDropdownReadPlatformServiceImpl.java
@@ -147,4 +147,15 @@ public class AccountingDropdownReadPlatformServiceImpl 
implements AccountingDrop
         return accountOptions;
     }
 
+    @Override
+    public Map<String, List<GLAccountData>> 
retrieveAccountMappingOptionsForShareProducts() {
+        boolean includeAssetAccounts = true;
+        boolean includeIncomeAccounts = true;
+        boolean includeExpenseAccounts = false;
+        boolean includeLiabilityAccounts = true;
+        boolean includeEquityAccounts = true;
+        return retrieveAccountMappingOptions(includeAssetAccounts, 
includeIncomeAccounts, includeExpenseAccounts, includeLiabilityAccounts,
+                includeEquityAccounts);
+    }
+
 }
\ 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/financialactivityaccount/serialization/FinancialActivityAccountDataValidator.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/serialization/FinancialActivityAccountDataValidator.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/serialization/FinancialActivityAccountDataValidator.java
index 104b3c8..810de31 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/serialization/FinancialActivityAccountDataValidator.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/serialization/FinancialActivityAccountDataValidator.java
@@ -68,7 +68,8 @@ public final class FinancialActivityAccountDataValidator {
         
baseDataValidator.reset().parameter(paramNameForFinancialActivity).value(financialActivityId).notNull().isOneOfTheseValues(
                 FINANCIAL_ACTIVITY.ASSET_TRANSFER.getValue(), 
FINANCIAL_ACTIVITY.LIABILITY_TRANSFER.getValue(),
                 FINANCIAL_ACTIVITY.CASH_AT_MAINVAULT.getValue(), 
FINANCIAL_ACTIVITY.CASH_AT_TELLER.getValue(),
-                
FINANCIAL_ACTIVITY.OPENING_BALANCES_TRANSFER_CONTRA.getValue(), 
FINANCIAL_ACTIVITY.ASSET_FUND_SOURCE.getValue());
+                
FINANCIAL_ACTIVITY.OPENING_BALANCES_TRANSFER_CONTRA.getValue(), 
FINANCIAL_ACTIVITY.ASSET_FUND_SOURCE.getValue(),
+                FINANCIAL_ACTIVITY.PAYABLE_DIVIDENDS.getValue());
 
         final Long glAccountId = 
this.fromApiJsonHelper.extractLongNamed(paramNameForGLAccount, element);
         
baseDataValidator.reset().parameter(paramNameForGLAccount).value(glAccountId).notNull().integerGreaterThanZero();
@@ -94,7 +95,8 @@ public final class FinancialActivityAccountDataValidator {
                     element);
             
baseDataValidator.reset().parameter(paramNameForFinancialActivity).value(financialActivityId).ignoreIfNull().isOneOfTheseValues(
                     FINANCIAL_ACTIVITY.ASSET_TRANSFER.getValue(), 
FINANCIAL_ACTIVITY.LIABILITY_TRANSFER.getValue(),
-                    
FINANCIAL_ACTIVITY.OPENING_BALANCES_TRANSFER_CONTRA.getValue(), 
FINANCIAL_ACTIVITY.ASSET_FUND_SOURCE.getValue());
+                    
FINANCIAL_ACTIVITY.OPENING_BALANCES_TRANSFER_CONTRA.getValue(), 
FINANCIAL_ACTIVITY.ASSET_FUND_SOURCE.getValue(),
+                    FINANCIAL_ACTIVITY.PAYABLE_DIVIDENDS.getValue());
         }
 
         if (this.fromApiJsonHelper.parameterExists(paramNameForGLAccount, 
element)) {

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/SharesDTO.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/SharesDTO.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/SharesDTO.java
new file mode 100644
index 0000000..28cbb7f
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/SharesDTO.java
@@ -0,0 +1,101 @@
+/**
+ * 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.journalentry.data;
+
+import java.util.List;
+
+public class SharesDTO {
+
+    private Long shareAccountId;
+    private Long shareProductId;
+    private Long officeId;
+    private String currencyCode;
+    private boolean cashBasedAccountingEnabled;
+    private boolean accrualBasedAccountingEnabled;
+    private List<SharesTransactionDTO> newTransactions;
+
+    public SharesDTO(final Long shareAccountId, final Long shareProductId, 
final Long officeId, final String currencyCode,
+            final boolean cashBasedAccountingEnabled, final boolean 
accrualBasedAccountingEnabled,
+            final List<SharesTransactionDTO> newTransactions) {
+        this.shareAccountId = shareAccountId;
+        this.shareProductId = shareProductId;
+        this.officeId = officeId;
+        this.cashBasedAccountingEnabled = cashBasedAccountingEnabled;
+        this.accrualBasedAccountingEnabled = accrualBasedAccountingEnabled;
+        this.newTransactions = newTransactions;
+        this.currencyCode = currencyCode;
+    }
+
+    public Long getOfficeId() {
+        return this.officeId;
+    }
+
+    public void setOfficeId(final Long officeId) {
+        this.officeId = officeId;
+    }
+
+    public boolean isCashBasedAccountingEnabled() {
+        return this.cashBasedAccountingEnabled;
+    }
+
+    public void setCashBasedAccountingEnabled(final boolean 
cashBasedAccountingEnabled) {
+        this.cashBasedAccountingEnabled = cashBasedAccountingEnabled;
+    }
+
+    public boolean isAccrualBasedAccountingEnabled() {
+        return this.accrualBasedAccountingEnabled;
+    }
+
+    public void setAccrualBasedAccountingEnabled(final boolean 
accrualBasedAccountingEnabled) {
+        this.accrualBasedAccountingEnabled = accrualBasedAccountingEnabled;
+    }
+
+    public String getCurrencyCode() {
+        return this.currencyCode;
+    }
+
+    public void setCurrencyCode(final String currencyCode) {
+        this.currencyCode = currencyCode;
+    }
+
+    public Long getShareAccountId() {
+        return this.shareAccountId;
+    }
+
+    public void setShareAccountId(Long shareAccountId) {
+        this.shareAccountId = shareAccountId;
+    }
+
+    public Long getShareProductId() {
+        return this.shareProductId;
+    }
+
+    public void setShareProductId(Long shareProductId) {
+        this.shareProductId = shareProductId;
+    }
+
+    public List<SharesTransactionDTO> getNewTransactions() {
+        return this.newTransactions;
+    }
+
+    public void setNewTransactions(List<SharesTransactionDTO> newTransactions) 
{
+        this.newTransactions = newTransactions;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/SharesTransactionDTO.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/SharesTransactionDTO.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/SharesTransactionDTO.java
new file mode 100644
index 0000000..a4871bd
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/SharesTransactionDTO.java
@@ -0,0 +1,94 @@
+/**
+ * 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.journalentry.data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+import 
org.apache.fineract.portfolio.shareaccounts.data.ShareAccountTransactionEnumData;
+
+public class SharesTransactionDTO {
+
+    private final Long officeId;
+    private final String transactionId;
+    private final Date transactionDate;
+    private final Long paymentTypeId;
+    private final ShareAccountTransactionEnumData transactionType;
+    private final ShareAccountTransactionEnumData transactionStatus;
+
+    private final BigDecimal amount;
+
+    /*** Breakup of amounts **/
+    private final BigDecimal chargeAmount;
+
+    /** Breakdowns of fees and penalties this Transaction pays **/
+    private final List<ChargePaymentDTO> feePayments;
+
+    public SharesTransactionDTO(final Long officeId, final Long paymentTypeId, 
final String transactionId, final Date transactionDate,
+            final ShareAccountTransactionEnumData transactionType, 
ShareAccountTransactionEnumData transactionStatus,
+            final BigDecimal amount, final BigDecimal chargeAmount, final 
List<ChargePaymentDTO> feePayments) {
+        this.paymentTypeId = paymentTypeId;
+        this.transactionId = transactionId;
+        this.transactionDate = transactionDate;
+        this.amount = amount;
+        this.chargeAmount = chargeAmount;
+        this.transactionType = transactionType;
+        this.transactionStatus = transactionStatus;
+        this.feePayments = feePayments;
+        this.officeId = officeId;
+    }
+
+    public Long getOfficeId() {
+        return this.officeId;
+    }
+
+    public String getTransactionId() {
+        return this.transactionId;
+    }
+
+    public Date getTransactionDate() {
+        return this.transactionDate;
+    }
+
+    public Long getPaymentTypeId() {
+        return this.paymentTypeId;
+    }
+
+    public ShareAccountTransactionEnumData getTransactionType() {
+        return this.transactionType;
+    }
+
+    public BigDecimal getAmount() {
+        return this.amount;
+    }
+
+    public List<ChargePaymentDTO> getFeePayments() {
+        return this.feePayments;
+    }
+
+    public ShareAccountTransactionEnumData getTransactionStatus() {
+        return this.transactionStatus;
+    }
+
+    public BigDecimal getChargeAmount() {
+        return this.chargeAmount;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntry.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntry.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntry.java
index 341baf2..3e499d1 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntry.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntry.java
@@ -78,6 +78,9 @@ public class JournalEntry extends 
AbstractAuditableCustom<AppUser, Long> {
     @JoinColumn(name = "client_transaction_id", nullable = false)
     private ClientTransaction clientTransaction;
 
+    @Column(name = "share_transaction_id", nullable = true)
+    private Long shareTransactionId;
+
     @Column(name = "reversed", nullable = false)
     private boolean reversed = false;
 
@@ -110,10 +113,10 @@ public class JournalEntry extends 
AbstractAuditableCustom<AppUser, Long> {
             final String currencyCode, final String transactionId, final 
boolean manualEntry, final Date transactionDate,
             final JournalEntryType journalEntryType, final BigDecimal amount, 
final String description, final Integer entityType,
             final Long entityId, final String referenceNumber, final 
LoanTransaction loanTransaction,
-            final SavingsAccountTransaction savingsTransaction, final 
ClientTransaction clientTransaction) {
+            final SavingsAccountTransaction savingsTransaction, final 
ClientTransaction clientTransaction, Long shareTransactionId) {
         return new JournalEntry(office, paymentDetail, glAccount, 
currencyCode, transactionId, manualEntry, transactionDate,
                 journalEntryType.getValue(), amount, description, entityType, 
entityId, referenceNumber, loanTransaction,
-                savingsTransaction, clientTransaction);
+                savingsTransaction, clientTransaction, shareTransactionId);
     }
 
     protected JournalEntry() {
@@ -124,7 +127,7 @@ public class JournalEntry extends 
AbstractAuditableCustom<AppUser, Long> {
             final String transactionId, final boolean manualEntry, final Date 
transactionDate, final Integer type, final BigDecimal amount,
             final String description, final Integer entityType, final Long 
entityId, final String referenceNumber,
             final LoanTransaction loanTransaction, final 
SavingsAccountTransaction savingsTransaction,
-            final ClientTransaction clientTransaction) {
+            final ClientTransaction clientTransaction, final Long 
shareTransactionId) {
         this.office = office;
         this.glAccount = glAccount;
         this.reversalJournalEntry = null;
@@ -143,6 +146,7 @@ public class JournalEntry extends 
AbstractAuditableCustom<AppUser, Long> {
         this.savingsTransaction = savingsTransaction;
         this.clientTransaction = clientTransaction;
         this.paymentDetail = paymentDetail;
+        this.shareTransactionId = shareTransactionId;
     }
 
     public boolean isDebitEntry() {
@@ -206,11 +210,16 @@ public class JournalEntry extends 
AbstractAuditableCustom<AppUser, Long> {
     }
 
     public Long getEntityId() {
-        return this.entityId ;
+        return this.entityId;
     }
-    
+
     public Integer getEntityType() {
-        return this.entityType ;
+        return this.entityType;
     }
+
     
+    public Long getShareTransactionId() {
+        return this.shareTransactionId;
+    }
+
 }
\ 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/journalentry/service/AccountingProcessorForShares.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorForShares.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorForShares.java
new file mode 100644
index 0000000..a8f5e83
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorForShares.java
@@ -0,0 +1,27 @@
+/**
+ * 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.journalentry.service;
+
+import org.apache.fineract.accounting.journalentry.data.SharesDTO;
+
+public interface AccountingProcessorForShares {
+
+    void createJournalEntriesForShares(SharesDTO sharesDTO);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorForSharesFactory.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorForSharesFactory.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorForSharesFactory.java
new file mode 100644
index 0000000..a59fd40
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorForSharesFactory.java
@@ -0,0 +1,48 @@
+/**
+ * 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.journalentry.service;
+
+import org.apache.fineract.accounting.journalentry.data.SharesDTO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AccountingProcessorForSharesFactory {
+
+    private final ApplicationContext applicationContext;
+
+    @Autowired
+    public AccountingProcessorForSharesFactory(final ApplicationContext 
applicationContext) {
+        this.applicationContext = applicationContext;
+    }
+
+    public AccountingProcessorForShares determineProcessor(final SharesDTO 
sharesDTO) {
+
+        AccountingProcessorForShares accountingProcessorForShares = null;
+
+        if (sharesDTO.isCashBasedAccountingEnabled()) {
+            accountingProcessorForShares = 
this.applicationContext.getBean("cashBasedAccountingProcessorForShares",
+                    AccountingProcessorForShares.class);
+        }
+
+        return accountingProcessorForShares;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java
index fb9c799..ec2c0dd 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java
@@ -31,6 +31,7 @@ import 
org.apache.fineract.accounting.closure.domain.GLClosureRepository;
 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.FINANCIAL_ACTIVITY;
 import 
org.apache.fineract.accounting.financialactivityaccount.domain.FinancialActivityAccount;
 import 
org.apache.fineract.accounting.financialactivityaccount.domain.FinancialActivityAccountRepositoryWrapper;
@@ -44,6 +45,8 @@ import 
org.apache.fineract.accounting.journalentry.data.LoanTransactionDTO;
 import org.apache.fineract.accounting.journalentry.data.SavingsDTO;
 import org.apache.fineract.accounting.journalentry.data.SavingsTransactionDTO;
 import org.apache.fineract.accounting.journalentry.data.TaxPaymentDTO;
+import org.apache.fineract.accounting.journalentry.data.SharesDTO;
+import org.apache.fineract.accounting.journalentry.data.SharesTransactionDTO;
 import org.apache.fineract.accounting.journalentry.domain.JournalEntry;
 import 
org.apache.fineract.accounting.journalentry.domain.JournalEntryRepository;
 import org.apache.fineract.accounting.journalentry.domain.JournalEntryType;
@@ -69,6 +72,7 @@ import 
org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
 import 
org.apache.fineract.portfolio.savings.data.SavingsAccountTransactionEnumData;
 import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransaction;
 import 
org.apache.fineract.portfolio.savings.domain.SavingsAccountTransactionRepository;
+import 
org.apache.fineract.portfolio.shareaccounts.data.ShareAccountTransactionEnumData;
 import org.joda.time.LocalDate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -80,6 +84,7 @@ public class AccountingProcessorHelper {
     public static final String SAVINGS_TRANSACTION_IDENTIFIER = "S";
     public static final String CLIENT_TRANSACTION_IDENTIFIER = "C";
     public static final String PROVISIONING_TRANSACTION_IDENTIFIER = "P";
+    public static final String SHARE_TRANSACTION_IDENTIFIER = "SH";
     private final JournalEntryRepository glJournalEntryRepository;
     private final ProductToGLAccountMappingRepository accountMappingRepository;
     private final FinancialActivityAccountRepositoryWrapper 
financialActivityAccountRepository;
@@ -244,6 +249,51 @@ public class AccountingProcessorHelper {
                 accrualBasedAccountingEnabled, newSavingsTransactions);
     }
 
+    public SharesDTO populateSharesDtoFromMap(final Map<String, Object> 
accountingBridgeData, final boolean cashBasedAccountingEnabled,
+            final boolean accrualBasedAccountingEnabled) {
+        final Long shareAccountId = (Long) 
accountingBridgeData.get("shareAccountId");
+        final Long shareProductId = (Long) 
accountingBridgeData.get("shareProductId");
+        final Long officeId = (Long) accountingBridgeData.get("officeId");
+        final CurrencyData currencyData = (CurrencyData) 
accountingBridgeData.get("currency");
+        final List<SharesTransactionDTO> newTransactions = new ArrayList<>();
+
+        @SuppressWarnings("unchecked")
+        final List<Map<String, Object>> newTransactionsMap = (List<Map<String, 
Object>>) accountingBridgeData.get("newTransactions");
+
+        for (final Map<String, Object> map : newTransactionsMap) {
+            final Long transactionOfficeId = (Long) map.get("officeId");
+            final String transactionId = ((Long) map.get("id")).toString();
+            final Date transactionDate = ((LocalDate) 
map.get("date")).toDate();
+            final ShareAccountTransactionEnumData transactionType = 
(ShareAccountTransactionEnumData) map.get("type");
+            final ShareAccountTransactionEnumData transactionStatus = 
(ShareAccountTransactionEnumData) map.get("status");
+            final BigDecimal amount = (BigDecimal) map.get("amount");
+            final BigDecimal chargeAmount = (BigDecimal) 
map.get("chargeAmount");
+            final Long paymentTypeId = (Long) map.get("paymentTypeId");
+
+            final List<ChargePaymentDTO> feePayments = new ArrayList<>();
+            // extract charge payment details (if exists)
+            if (map.containsKey("chargesPaid")) {
+                @SuppressWarnings("unchecked")
+                final List<Map<String, Object>> chargesPaidData = 
(List<Map<String, Object>>) map.get("chargesPaid");
+                for (final Map<String, Object> chargePaid : chargesPaidData) {
+                    final Long chargeId = (Long) chargePaid.get("chargeId");
+                    final Long loanChargeId = (Long) 
chargePaid.get("sharesChargeId");
+                    final BigDecimal chargeAmountPaid = (BigDecimal) 
chargePaid.get("amount");
+                    final ChargePaymentDTO chargePaymentDTO = new 
ChargePaymentDTO(chargeId, loanChargeId, chargeAmountPaid);
+                    feePayments.add(chargePaymentDTO);
+                }
+            }
+            final SharesTransactionDTO transaction = new 
SharesTransactionDTO(transactionOfficeId, paymentTypeId, transactionId,
+                    transactionDate, transactionType, transactionStatus, 
amount, chargeAmount, feePayments);
+
+            newTransactions.add(transaction);
+
+        }
+
+        return new SharesDTO(shareAccountId, shareProductId, officeId, 
currencyData.code(), cashBasedAccountingEnabled,
+                accrualBasedAccountingEnabled, newTransactions);
+    }
+
     public ClientTransactionDTO populateClientTransactionDtoFromMap(final 
Map<String, Object> accountingBridgeData) {
 
         final Long transactionOfficeId = (Long) 
accountingBridgeData.get("officeId");
@@ -745,6 +795,7 @@ public class AccountingProcessorHelper {
         SavingsAccountTransaction savingsAccountTransaction = null;
         ClientTransaction clientTransaction = null;
         final PaymentDetail paymentDetail = null;
+        final Long shareTransactionId = null;
 
         clientTransaction = 
this.clientTransactionRepository.findOneWithNotFoundDetection(clientId, 
transactionId);
 
@@ -752,7 +803,7 @@ public class AccountingProcessorHelper {
         modifiedTransactionId = CLIENT_TRANSACTION_IDENTIFIER + transactionId;
         final JournalEntry journalEntry = JournalEntry.createNew(office, 
paymentDetail, account, currencyCode, modifiedTransactionId,
                 manualEntry, transactionDate, JournalEntryType.CREDIT, amount, 
null, PortfolioProductType.CLIENT.getValue(), clientId,
-                null, loanTransaction, savingsAccountTransaction, 
clientTransaction);
+                null, loanTransaction, savingsAccountTransaction, 
clientTransaction, shareTransactionId);
         this.glJournalEntryRepository.saveAndFlush(journalEntry);
     }
 
@@ -762,6 +813,7 @@ public class AccountingProcessorHelper {
         LoanTransaction loanTransaction = null;
         SavingsAccountTransaction savingsAccountTransaction = null;
         ClientTransaction clientTransaction = null;
+        final Long shareTransactionId = null;
         final PaymentDetail paymentDetail = null;
         String modifiedTransactionId = transactionId;
         if (StringUtils.isNumeric(transactionId)) {
@@ -771,7 +823,7 @@ public class AccountingProcessorHelper {
         }
         final JournalEntry journalEntry = JournalEntry.createNew(office, 
paymentDetail, account, currencyCode, modifiedTransactionId,
                 manualEntry, transactionDate, JournalEntryType.CREDIT, amount, 
null, PortfolioProductType.SAVING.getValue(), savingsId,
-                null, loanTransaction, savingsAccountTransaction, 
clientTransaction);
+                null, loanTransaction, savingsAccountTransaction, 
clientTransaction, shareTransactionId);
         this.glJournalEntryRepository.saveAndFlush(journalEntry);
     }
 
@@ -782,6 +834,7 @@ public class AccountingProcessorHelper {
         SavingsAccountTransaction savingsAccountTransaction = null;
         ClientTransaction clientTransaction = null;
         final PaymentDetail paymentDetail = null;
+        final Long shareTransactionId = null;
         String modifiedTransactionId = transactionId;
         if (StringUtils.isNumeric(transactionId)) {
             long id = Long.parseLong(transactionId);
@@ -790,7 +843,7 @@ public class AccountingProcessorHelper {
         }
         final JournalEntry journalEntry = JournalEntry.createNew(office, 
paymentDetail, account, currencyCode, modifiedTransactionId,
                 manualEntry, transactionDate, JournalEntryType.CREDIT, amount, 
null, PortfolioProductType.LOAN.getValue(), loanId, null,
-                loanTransaction, savingsAccountTransaction, clientTransaction);
+                loanTransaction, savingsAccountTransaction, clientTransaction, 
shareTransactionId);
         this.glJournalEntryRepository.saveAndFlush(journalEntry);
     }
 
@@ -800,12 +853,12 @@ public class AccountingProcessorHelper {
         SavingsAccountTransaction savingsAccountTransaction = null;
         ClientTransaction clientTransaction = null;
         PaymentDetail paymentDetail = null;
+        final Long shareTransactionId = null;
         final boolean manualEntry = false;
         String modifiedTransactionId = PROVISIONING_TRANSACTION_IDENTIFIER + 
provisioningentryId;
         final JournalEntry journalEntry = JournalEntry.createNew(office, 
paymentDetail, account, currencyCode, modifiedTransactionId,
                 manualEntry, transactionDate, JournalEntryType.DEBIT, amount, 
null, PortfolioProductType.PROVISIONING.getValue(),
-                provisioningentryId, null, loanTransaction, 
savingsAccountTransaction, clientTransaction);
-
+                provisioningentryId, null, loanTransaction, 
savingsAccountTransaction, clientTransaction, shareTransactionId);
         this.glJournalEntryRepository.saveAndFlush(journalEntry);
     }
 
@@ -815,11 +868,12 @@ public class AccountingProcessorHelper {
         SavingsAccountTransaction savingsAccountTransaction = null;
         ClientTransaction clientTransaction = null;
         PaymentDetail paymentDetail = null;
+        final Long shareTransactionId = null;
         final boolean manualEntry = false;
         String modifiedTransactionId = PROVISIONING_TRANSACTION_IDENTIFIER + 
provisioningentryId;
         final JournalEntry journalEntry = JournalEntry.createNew(office, 
paymentDetail, account, currencyCode, modifiedTransactionId,
                 manualEntry, transactionDate, JournalEntryType.CREDIT, amount, 
null, PortfolioProductType.PROVISIONING.getValue(),
-                provisioningentryId, null, loanTransaction, 
savingsAccountTransaction, clientTransaction);
+                provisioningentryId, null, loanTransaction, 
savingsAccountTransaction, clientTransaction, shareTransactionId);
         this.glJournalEntryRepository.saveAndFlush(journalEntry);
     }
 
@@ -830,6 +884,7 @@ public class AccountingProcessorHelper {
         SavingsAccountTransaction savingsAccountTransaction = null;
         ClientTransaction clientTransaction = null;
         final PaymentDetail paymentDetail = null;
+        final Long shareTransactionId = null;
         String modifiedTransactionId = transactionId;
         if (StringUtils.isNumeric(transactionId)) {
             long id = Long.parseLong(transactionId);
@@ -838,7 +893,7 @@ public class AccountingProcessorHelper {
         }
         final JournalEntry journalEntry = JournalEntry.createNew(office, 
paymentDetail, account, currencyCode, modifiedTransactionId,
                 manualEntry, transactionDate, JournalEntryType.DEBIT, amount, 
null, PortfolioProductType.LOAN.getValue(), loanId, null,
-                loanTransaction, savingsAccountTransaction, clientTransaction);
+                loanTransaction, savingsAccountTransaction, clientTransaction, 
shareTransactionId);
         this.glJournalEntryRepository.saveAndFlush(journalEntry);
     }
 
@@ -849,6 +904,7 @@ public class AccountingProcessorHelper {
         SavingsAccountTransaction savingsAccountTransaction = null;
         ClientTransaction clientTransaction = null;
         final PaymentDetail paymentDetail = null;
+        final Long shareTransactionId = null;
         String modifiedTransactionId = transactionId;
         if (StringUtils.isNumeric(transactionId)) {
             long id = Long.parseLong(transactionId);
@@ -857,7 +913,7 @@ public class AccountingProcessorHelper {
         }
         final JournalEntry journalEntry = JournalEntry.createNew(office, 
paymentDetail, account, currencyCode, modifiedTransactionId,
                 manualEntry, transactionDate, JournalEntryType.DEBIT, amount, 
null, PortfolioProductType.SAVING.getValue(), savingsId,
-                null, loanTransaction, savingsAccountTransaction, 
clientTransaction);
+                null, loanTransaction, savingsAccountTransaction, 
clientTransaction, shareTransactionId);
         this.glJournalEntryRepository.saveAndFlush(journalEntry);
     }
 
@@ -868,6 +924,7 @@ public class AccountingProcessorHelper {
         LoanTransaction loanTransaction = null;
         SavingsAccountTransaction savingsAccountTransaction = null;
         final PaymentDetail paymentDetail = null;
+        final Long shareTransactionId = null;
 
         clientTransaction = 
this.clientTransactionRepository.findOneWithNotFoundDetection(clientId, 
transactionId);
         String modifiedTransactionId = transactionId.toString();
@@ -875,10 +932,113 @@ public class AccountingProcessorHelper {
 
         final JournalEntry journalEntry = JournalEntry.createNew(office, 
paymentDetail, account, currencyCode, modifiedTransactionId,
                 manualEntry, transactionDate, JournalEntryType.DEBIT, amount, 
null, PortfolioProductType.CLIENT.getValue(), clientId, null,
-                loanTransaction, savingsAccountTransaction, clientTransaction);
+                loanTransaction, savingsAccountTransaction, clientTransaction, 
shareTransactionId);
         this.glJournalEntryRepository.saveAndFlush(journalEntry);
     }
 
+    public void createJournalEntriesForShares(final Office office, final 
String currencyCode, final int accountTypeToDebitId,
+            final int accountTypeToCreditId, final Long shareProductId, final 
Long paymentTypeId, final Long shareAccountId,
+            final String transactionId, final Date transactionDate, final 
BigDecimal amount) {
+        createDebitJournalEntryForShares(office, currencyCode, 
accountTypeToDebitId, shareProductId, paymentTypeId, shareAccountId,
+                transactionId, transactionDate, amount);
+        createCreditJournalEntryForShares(office, currencyCode, 
accountTypeToCreditId, shareProductId, paymentTypeId, shareAccountId,
+                transactionId, transactionDate, amount);
+    }
+
+    public void createDebitJournalEntryForShares(final Office office, final 
String currencyCode, final int accountTypeToDebitId,
+            final Long shareProductId, final Long paymentTypeId, final Long 
shareAccountId, final String transactionId,
+            final Date transactionDate, final BigDecimal amount) {
+        final GLAccount debitAccount = 
getLinkedGLAccountForShareProduct(shareProductId, accountTypeToDebitId, 
paymentTypeId);
+        createDebitJournalEntryForShares(office, currencyCode, debitAccount, 
shareAccountId, transactionId, transactionDate, amount);
+    }
+
+    public void createCreditJournalEntryForShares(final Office office, final 
String currencyCode, final int accountTypeToCreditId,
+            final Long shareProductId, final Long paymentTypeId, final Long 
shareAccountId, final String transactionId,
+            final Date transactionDate, final BigDecimal amount) {
+        final GLAccount creditAccount = 
getLinkedGLAccountForShareProduct(shareProductId, accountTypeToCreditId, 
paymentTypeId);
+        createCreditJournalEntryForShares(office, currencyCode, creditAccount, 
shareAccountId, transactionId, transactionDate, amount);
+    }
+
+    public void createCashBasedJournalEntriesForSharesCharges(final Office 
office, final String currencyCode,
+            final CASH_ACCOUNTS_FOR_SHARES accountTypeToBeDebited, final 
CASH_ACCOUNTS_FOR_SHARES accountTypeToBeCredited,
+            final Long shareProductId, final Long paymentTypeId, final Long 
shareAccountId, final String transactionId,
+            final Date transactionDate, final BigDecimal totalAmount, final 
List<ChargePaymentDTO> chargePaymentDTOs) {
+
+        createDebitJournalEntryForShares(office, currencyCode, 
accountTypeToBeDebited.getValue(), shareProductId, paymentTypeId,
+                shareAccountId, transactionId, transactionDate, totalAmount);
+        createCashBasedJournalEntryForSharesCharges(office, currencyCode, 
accountTypeToBeCredited, shareProductId, shareAccountId,
+                transactionId, transactionDate, totalAmount, 
chargePaymentDTOs);
+    }
+
+    public void createCashBasedJournalEntryForSharesCharges(final Office 
office, final String currencyCode,
+            final CASH_ACCOUNTS_FOR_SHARES accountTypeToBeCredited, final Long 
shareProductId, final Long shareAccountId,
+            final String transactionId, final Date transactionDate, final 
BigDecimal totalAmount,
+            final List<ChargePaymentDTO> chargePaymentDTOs) {
+        final Map<GLAccount, BigDecimal> creditDetailsMap = new 
LinkedHashMap<>();
+        for (final ChargePaymentDTO chargePaymentDTO : chargePaymentDTOs) {
+            final GLAccount chargeSpecificAccount = 
getLinkedGLAccountForShareCharges(shareProductId, 
accountTypeToBeCredited.getValue(),
+                    chargePaymentDTO.getChargeId());
+            BigDecimal chargeSpecificAmount = chargePaymentDTO.getAmount();
+
+            // adjust net credit amount if the account is already present in 
the
+            // map
+            if (creditDetailsMap.containsKey(chargeSpecificAccount)) {
+                final BigDecimal existingAmount = 
creditDetailsMap.get(chargeSpecificAccount);
+                chargeSpecificAmount = 
chargeSpecificAmount.add(existingAmount);
+            }
+            creditDetailsMap.put(chargeSpecificAccount, chargeSpecificAmount);
+        }
+
+        BigDecimal totalCreditedAmount = BigDecimal.ZERO;
+        for (final Map.Entry<GLAccount, BigDecimal> entry : 
creditDetailsMap.entrySet()) {
+            final GLAccount account = entry.getKey();
+            final BigDecimal amount = entry.getValue();
+            totalCreditedAmount = totalCreditedAmount.add(amount);
+            createCreditJournalEntryForShares(office, currencyCode, account, 
shareAccountId, transactionId, transactionDate, amount);
+        }
+        if (totalAmount.compareTo(totalCreditedAmount) != 0) { throw new 
PlatformDataIntegrityException(
+                "Recent Portfolio changes w.r.t Charges for shares have Broken 
the accounting code",
+                "Recent Portfolio changes w.r.t Charges for shares have Broken 
the accounting code"); }
+    }
+
+    private void createDebitJournalEntryForShares(final Office office, final 
String currencyCode, final GLAccount account,
+            final Long shareAccountId, final String transactionId, final Date 
transactionDate, final BigDecimal amount) {
+        final boolean manualEntry = false;
+        LoanTransaction loanTransaction = null;
+        SavingsAccountTransaction savingsAccountTransaction = null;
+        ClientTransaction clientTransaction = null;
+        final PaymentDetail paymentDetail = null;
+        Long shareTransactionId = null;
+        String modifiedTransactionId = transactionId;
+        if (StringUtils.isNumeric(transactionId)) {
+            shareTransactionId = Long.parseLong(transactionId);
+            modifiedTransactionId = SHARE_TRANSACTION_IDENTIFIER + 
transactionId;
+        }
+        final JournalEntry journalEntry = JournalEntry.createNew(office, 
paymentDetail, account, currencyCode, modifiedTransactionId,
+                manualEntry, transactionDate, JournalEntryType.DEBIT, amount, 
null, PortfolioProductType.SHARES.getValue(), shareAccountId,
+                null, loanTransaction, savingsAccountTransaction, 
clientTransaction, shareTransactionId);
+        this.glJournalEntryRepository.save(journalEntry);
+    }
+
+    private void createCreditJournalEntryForShares(final Office office, final 
String currencyCode, final GLAccount account,
+            final Long shareAccountId, final String transactionId, final Date 
transactionDate, final BigDecimal amount) {
+        final boolean manualEntry = false;
+        LoanTransaction loanTransaction = null;
+        SavingsAccountTransaction savingsAccountTransaction = null;
+        ClientTransaction clientTransaction = null;
+        Long shareTransactionId = null;
+        final PaymentDetail paymentDetail = null;
+        String modifiedTransactionId = transactionId;
+        if (StringUtils.isNumeric(transactionId)) {
+            shareTransactionId = Long.parseLong(transactionId);
+            modifiedTransactionId = SHARE_TRANSACTION_IDENTIFIER + 
transactionId;
+        }
+        final JournalEntry journalEntry = JournalEntry.createNew(office, 
paymentDetail, account, currencyCode, modifiedTransactionId,
+                manualEntry, transactionDate, JournalEntryType.CREDIT, amount, 
null, PortfolioProductType.SHARES.getValue(),
+                shareAccountId, null, loanTransaction, 
savingsAccountTransaction, clientTransaction, shareTransactionId);
+        this.glJournalEntryRepository.save(journalEntry);
+    }
+
     private GLAccount getLinkedGLAccountForLoanProduct(final Long 
loanProductId, final int accountMappingTypeId, final Long paymentTypeId) {
         GLAccount glAccount = null;
         if (isOrganizationAccount(accountMappingTypeId)) {
@@ -984,6 +1144,48 @@ public class AccountingProcessorHelper {
         return glAccount;
     }
 
+    private GLAccount getLinkedGLAccountForShareProduct(final Long 
shareProductId, final int accountMappingTypeId, final Long paymentTypeId) {
+        GLAccount glAccount = null;
+        if (isOrganizationAccount(accountMappingTypeId)) {
+            FinancialActivityAccount financialActivityAccount = 
this.financialActivityAccountRepository
+                    
.findByFinancialActivityTypeWithNotFoundDetection(accountMappingTypeId);
+            glAccount = financialActivityAccount.getGlAccount();
+        } else {
+            ProductToGLAccountMapping accountMapping = 
this.accountMappingRepository.findCoreProductToFinAccountMapping(shareProductId,
+                    PortfolioProductType.SHARES.getValue(), 
accountMappingTypeId);
+
+            if (accountMappingTypeId == 
CASH_ACCOUNTS_FOR_SHARES.SHARES_REFERENCE.getValue()) {
+                final ProductToGLAccountMapping 
paymentChannelSpecificAccountMapping = this.accountMappingRepository
+                        
.findByProductIdAndProductTypeAndFinancialAccountTypeAndPaymentTypeId(shareProductId,
+                                PortfolioProductType.SHARES.getValue(), 
accountMappingTypeId, paymentTypeId);
+                if (paymentChannelSpecificAccountMapping != null) {
+                    accountMapping = paymentChannelSpecificAccountMapping;
+                }
+            }
+            glAccount = accountMapping.getGlAccount();
+        }
+        return glAccount;
+    }
+
+    private GLAccount getLinkedGLAccountForShareCharges(final Long 
shareProductId, final int accountMappingTypeId, final Long chargeId) {
+        ProductToGLAccountMapping accountMapping = 
this.accountMappingRepository.findCoreProductToFinAccountMapping(shareProductId,
+                PortfolioProductType.SHARES.getValue(), accountMappingTypeId);
+        /*****
+         * Get more specific mappings for Charges and penalties (based on the
+         * actual charge /penalty coupled with the loan product). Note the
+         * income from fees and income from penalties placeholder ID would be
+         * the same for both cash and accrual based accounts
+         *****/
+
+        final ProductToGLAccountMapping chargeSpecificIncomeAccountMapping = 
this.accountMappingRepository
+                
.findByProductIdAndProductTypeAndFinancialAccountTypeAndChargeId(shareProductId,
 PortfolioProductType.SHARES.getValue(),
+                        accountMappingTypeId, chargeId);
+        if (chargeSpecificIncomeAccountMapping != null) {
+            accountMapping = chargeSpecificIncomeAccountMapping;
+        }
+        return accountMapping.getGlAccount();
+    }
+
     private boolean isOrganizationAccount(final int accountMappingTypeId) {
         boolean isOrganizationAccount = false;
         if (FINANCIAL_ACTIVITY.fromInt(accountMappingTypeId) != null) {

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForSavings.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForSavings.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForSavings.java
index 27eb9e8..474f321 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForSavings.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForSavings.java
@@ -124,6 +124,12 @@ public class CashBasedAccountingProcessorForSavings 
implements AccountingProcess
                 }
             }
 
+            /** Handle Deposits and reversals of Dividend pay outs **/
+            else if 
(savingsTransactionDTO.getTransactionType().isDividendPayout()) {
+                
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, 
currencyCode,
+                        FINANCIAL_ACTIVITY.PAYABLE_DIVIDENDS.getValue(), 
CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_CONTROL.getValue(),
+                        savingsProductId, paymentTypeId, savingsId, 
transactionId, transactionDate, amount, isReversal);
+            }
             /** Handle withdrawals and reversals of withdrawals **/
             else if 
(savingsTransactionDTO.getTransactionType().isWithdrawal()) {
                 if (savingsTransactionDTO.isAccountTransfer()) {

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForShares.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForShares.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForShares.java
new file mode 100644
index 0000000..f379ed1
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForShares.java
@@ -0,0 +1,129 @@
+/**
+ * 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.journalentry.service;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.fineract.accounting.closure.domain.GLClosure;
+import 
org.apache.fineract.accounting.common.AccountingConstants.CASH_ACCOUNTS_FOR_SHARES;
+import org.apache.fineract.accounting.journalentry.data.ChargePaymentDTO;
+import org.apache.fineract.accounting.journalentry.data.SharesDTO;
+import org.apache.fineract.accounting.journalentry.data.SharesTransactionDTO;
+import org.apache.fineract.organisation.office.domain.Office;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class CashBasedAccountingProcessorForShares implements 
AccountingProcessorForShares {
+
+    private final AccountingProcessorHelper helper;
+
+    @Autowired
+    public CashBasedAccountingProcessorForShares(final 
AccountingProcessorHelper helper) {
+        this.helper = helper;
+    }
+
+    @Override
+    public void createJournalEntriesForShares(SharesDTO sharesDTO) {
+        final GLClosure latestGLClosure = 
this.helper.getLatestClosureByBranch(sharesDTO.getOfficeId());
+        final Long shareAccountId = sharesDTO.getShareAccountId();
+        final Long shareProductId = sharesDTO.getShareProductId();
+        final String currencyCode = sharesDTO.getCurrencyCode();
+        for (SharesTransactionDTO transactionDTO : 
sharesDTO.getNewTransactions()) {
+            final Date transactionDate = transactionDTO.getTransactionDate();
+            final String transactionId = transactionDTO.getTransactionId();
+            final Office office = 
this.helper.getOfficeById(transactionDTO.getOfficeId());
+            final Long paymentTypeId = transactionDTO.getPaymentTypeId();
+            final BigDecimal amount = transactionDTO.getAmount();
+            final BigDecimal chargeAmount = transactionDTO.getChargeAmount();
+            final List<ChargePaymentDTO> feePayments = 
transactionDTO.getFeePayments();
+
+            this.helper.checkForBranchClosures(latestGLClosure, 
transactionDate);
+
+            if (transactionDTO.getTransactionType().isPurchased()) {
+                createJournalEntriesForPurchase(shareAccountId, 
shareProductId, currencyCode, transactionDTO, transactionDate,
+                        transactionId, office, paymentTypeId, amount, 
chargeAmount, feePayments);
+            } else if (transactionDTO.getTransactionType().isRedeemed() && 
transactionDTO.getTransactionStatus().isApproved()) {
+                createJournalEntriesForRedeem(shareAccountId, shareProductId, 
currencyCode, transactionDate, transactionId, office,
+                        paymentTypeId, amount, chargeAmount, feePayments);
+
+            } else if (transactionDTO.getTransactionType().isChargePayment()) {
+                
this.helper.createCashBasedJournalEntriesForSharesCharges(office, currencyCode, 
CASH_ACCOUNTS_FOR_SHARES.SHARES_REFERENCE,
+                        CASH_ACCOUNTS_FOR_SHARES.INCOME_FROM_FEES, 
shareProductId, paymentTypeId, shareAccountId, transactionId,
+                        transactionDate, amount, feePayments);
+            }
+        }
+
+    }
+
+    public void createJournalEntriesForRedeem(final Long shareAccountId, final 
Long shareProductId, final String currencyCode,
+            final Date transactionDate, final String transactionId, final 
Office office, final Long paymentTypeId, final BigDecimal amount,
+            final BigDecimal chargeAmount, final List<ChargePaymentDTO> 
feePayments) {
+        if (chargeAmount == null || chargeAmount.compareTo(BigDecimal.ZERO) != 
1) {
+            this.helper.createJournalEntriesForShares(office, currencyCode, 
CASH_ACCOUNTS_FOR_SHARES.SHARES_EQUITY.getValue(),
+                    CASH_ACCOUNTS_FOR_SHARES.SHARES_REFERENCE.getValue(), 
shareProductId, paymentTypeId, shareAccountId, transactionId,
+                    transactionDate, amount);
+        } else {
+            this.helper.createDebitJournalEntryForShares(office, currencyCode, 
CASH_ACCOUNTS_FOR_SHARES.SHARES_EQUITY.getValue(),
+                    shareProductId, paymentTypeId, shareAccountId, 
transactionId, transactionDate, amount.add(chargeAmount));
+            this.helper.createCreditJournalEntryForShares(office, 
currencyCode, CASH_ACCOUNTS_FOR_SHARES.SHARES_REFERENCE.getValue(),
+                    shareProductId, paymentTypeId, shareAccountId, 
transactionId, transactionDate, amount);
+            this.helper.createCashBasedJournalEntryForSharesCharges(office, 
currencyCode, CASH_ACCOUNTS_FOR_SHARES.INCOME_FROM_FEES,
+                    shareProductId, shareAccountId, transactionId, 
transactionDate, chargeAmount, feePayments);
+        }
+    }
+
+    public void createJournalEntriesForPurchase(final Long shareAccountId, 
final Long shareProductId, final String currencyCode,
+            SharesTransactionDTO transactionDTO, final Date transactionDate, 
final String transactionId, final Office office,
+            final Long paymentTypeId, final BigDecimal amount, final 
BigDecimal chargeAmount, final List<ChargePaymentDTO> feePayments) {
+        if (transactionDTO.getTransactionStatus().isApplied()) {
+            if (chargeAmount == null || 
chargeAmount.compareTo(BigDecimal.ZERO) != 1) {
+                this.helper.createJournalEntriesForShares(office, 
currencyCode, CASH_ACCOUNTS_FOR_SHARES.SHARES_REFERENCE.getValue(),
+                        CASH_ACCOUNTS_FOR_SHARES.SHARES_SUSPENSE.getValue(), 
shareProductId, paymentTypeId, shareAccountId, transactionId,
+                        transactionDate, amount);
+            } else {
+                this.helper.createDebitJournalEntryForShares(office, 
currencyCode, CASH_ACCOUNTS_FOR_SHARES.SHARES_REFERENCE.getValue(),
+                        shareProductId, paymentTypeId, shareAccountId, 
transactionId, transactionDate, amount);
+                this.helper.createCreditJournalEntryForShares(office, 
currencyCode, CASH_ACCOUNTS_FOR_SHARES.SHARES_SUSPENSE.getValue(),
+                        shareProductId, paymentTypeId, shareAccountId, 
transactionId, transactionDate, amount.subtract(chargeAmount));
+                
this.helper.createCashBasedJournalEntryForSharesCharges(office, currencyCode, 
CASH_ACCOUNTS_FOR_SHARES.INCOME_FROM_FEES,
+                        shareProductId, shareAccountId, transactionId, 
transactionDate, chargeAmount, feePayments);
+            }
+        } else if (transactionDTO.getTransactionStatus().isApproved()) {
+            BigDecimal amountForJE = amount;
+            if (chargeAmount != null && 
chargeAmount.compareTo(BigDecimal.ZERO) == 1) {
+                amountForJE = amount.subtract(chargeAmount);
+            }
+            this.helper.createJournalEntriesForShares(office, currencyCode, 
CASH_ACCOUNTS_FOR_SHARES.SHARES_SUSPENSE.getValue(),
+                    CASH_ACCOUNTS_FOR_SHARES.SHARES_EQUITY.getValue(), 
shareProductId, paymentTypeId, shareAccountId, transactionId,
+                    transactionDate, amountForJE);
+        } else if (transactionDTO.getTransactionStatus().isRejected()) {
+            BigDecimal amountForJE = amount;
+            if (chargeAmount != null && 
chargeAmount.compareTo(BigDecimal.ZERO) == 1) {
+                amountForJE = amount.subtract(chargeAmount);
+            }
+            this.helper.createJournalEntriesForShares(office, currencyCode, 
CASH_ACCOUNTS_FOR_SHARES.SHARES_SUSPENSE.getValue(),
+                    CASH_ACCOUNTS_FOR_SHARES.SHARES_REFERENCE.getValue(), 
shareProductId, paymentTypeId, shareAccountId, transactionId,
+                    transactionDate, amountForJE);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryWritePlatformService.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryWritePlatformService.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryWritePlatformService.java
index 480e722..4428daa 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryWritePlatformService.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryWritePlatformService.java
@@ -42,4 +42,6 @@ public interface JournalEntryWritePlatformService {
     public String revertProvisioningJournalEntries(final Date 
reversalTransactionDate, final Long entityId, final Integer entityType) ;
 
     public String createProvisioningJournalEntries(ProvisioningEntry entry) ;
+
+    void createJournalEntriesForShares(Map<String, Object> 
accountingBridgeData);
 }

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryWritePlatformServiceJpaRepositoryImpl.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryWritePlatformServiceJpaRepositoryImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryWritePlatformServiceJpaRepositoryImpl.java
index 4ac3dc2..aed5f7f 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryWritePlatformServiceJpaRepositoryImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryWritePlatformServiceJpaRepositoryImpl.java
@@ -45,6 +45,7 @@ import 
org.apache.fineract.accounting.journalentry.command.SingleDebitOrCreditEn
 import org.apache.fineract.accounting.journalentry.data.ClientTransactionDTO;
 import org.apache.fineract.accounting.journalentry.data.LoanDTO;
 import org.apache.fineract.accounting.journalentry.data.SavingsDTO;
+import org.apache.fineract.accounting.journalentry.data.SharesDTO;
 import org.apache.fineract.accounting.journalentry.domain.JournalEntry;
 import 
org.apache.fineract.accounting.journalentry.domain.JournalEntryRepository;
 import org.apache.fineract.accounting.journalentry.domain.JournalEntryType;
@@ -94,6 +95,7 @@ public class 
JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
     private final OfficeRepository officeRepository;
     private final AccountingProcessorForLoanFactory 
accountingProcessorForLoanFactory;
     private final AccountingProcessorForSavingsFactory 
accountingProcessorForSavingsFactory;
+    private final AccountingProcessorForSharesFactory 
accountingProcessorForSharesFactory;
     private final AccountingProcessorHelper helper;
     private final JournalEntryCommandFromApiJsonDeserializer 
fromApiJsonDeserializer;
     private final AccountingRuleRepository accountingRuleRepository;
@@ -111,6 +113,7 @@ public class 
JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
             final AccountingProcessorHelper accountingProcessorHelper, final 
AccountingRuleRepository accountingRuleRepository,
             final AccountingProcessorForLoanFactory 
accountingProcessorForLoanFactory,
             final AccountingProcessorForSavingsFactory 
accountingProcessorForSavingsFactory,
+            final AccountingProcessorForSharesFactory 
accountingProcessorForSharesFactory,
             final GLAccountReadPlatformService glAccountReadPlatformService,
             final OrganisationCurrencyRepositoryWrapper 
organisationCurrencyRepository, final PlatformSecurityContext context,
             final PaymentDetailWritePlatformService 
paymentDetailWritePlatformService,
@@ -123,6 +126,7 @@ public class 
JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
         this.glAccountRepository = glAccountRepository;
         this.accountingProcessorForLoanFactory = 
accountingProcessorForLoanFactory;
         this.accountingProcessorForSavingsFactory = 
accountingProcessorForSavingsFactory;
+        this.accountingProcessorForSharesFactory = 
accountingProcessorForSharesFactory;
         this.helper = accountingProcessorHelper;
         this.accountingRuleRepository = accountingRuleRepository;
         this.glAccountReadPlatformService = glAccountReadPlatformService;
@@ -335,13 +339,13 @@ public class 
JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
                         journalEntry.getGlAccount(), 
journalEntry.getCurrencyCode(), reversalTransactionId, manualEntry,
                         journalEntry.getTransactionDate(), 
JournalEntryType.CREDIT, journalEntry.getAmount(), reversalComment, null, null,
                         journalEntry.getReferenceNumber(), 
journalEntry.getLoanTransaction(), journalEntry.getSavingsTransaction(),
-                        journalEntry.getClientTransaction());
+                        journalEntry.getClientTransaction(), 
journalEntry.getShareTransactionId());
             } else {
                 reversalJournalEntry = 
JournalEntry.createNew(journalEntry.getOffice(), 
journalEntry.getPaymentDetails(),
                         journalEntry.getGlAccount(), 
journalEntry.getCurrencyCode(), reversalTransactionId, manualEntry,
                         journalEntry.getTransactionDate(), 
JournalEntryType.DEBIT, journalEntry.getAmount(), reversalComment, null, null,
                         journalEntry.getReferenceNumber(), 
journalEntry.getLoanTransaction(), journalEntry.getSavingsTransaction(),
-                        journalEntry.getClientTransaction());
+                        journalEntry.getClientTransaction(), 
journalEntry.getShareTransactionId());
             }
             // save the reversal entry
             this.glJournalEntryRepository.saveAndFlush(reversalJournalEntry);
@@ -366,13 +370,15 @@ public class 
JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
                         journalEntry.getGlAccount(), 
journalEntry.getCurrencyCode(), journalEntry.getTransactionId(), Boolean.FALSE,
                         reversalTransactionDate, JournalEntryType.CREDIT, 
journalEntry.getAmount(), reversalComment,
                         journalEntry.getEntityType(), 
journalEntry.getEntityId(), journalEntry.getReferenceNumber(),
-                        journalEntry.getLoanTransaction(), 
journalEntry.getSavingsTransaction(), journalEntry.getClientTransaction());
+                        journalEntry.getLoanTransaction(), 
journalEntry.getSavingsTransaction(), journalEntry.getClientTransaction(),
+                        journalEntry.getShareTransactionId());
             } else {
                 reversalJournalEntry = 
JournalEntry.createNew(journalEntry.getOffice(), 
journalEntry.getPaymentDetails(),
                         journalEntry.getGlAccount(), 
journalEntry.getCurrencyCode(), journalEntry.getTransactionId(), Boolean.FALSE,
                         reversalTransactionDate, JournalEntryType.DEBIT, 
journalEntry.getAmount(), reversalComment,
                         journalEntry.getEntityType(), 
journalEntry.getEntityId(), journalEntry.getReferenceNumber(),
-                        journalEntry.getLoanTransaction(), 
journalEntry.getSavingsTransaction(), journalEntry.getClientTransaction());
+                        journalEntry.getLoanTransaction(), 
journalEntry.getSavingsTransaction(), journalEntry.getClientTransaction(),
+                        journalEntry.getShareTransactionId());
             }
             // save the reversal entry
             this.glJournalEntryRepository.save(reversalJournalEntry);
@@ -428,26 +434,26 @@ public class 
JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
                     expenseMap.put(entry.getExpenseAccount(), amount);
                 }
             }
-            createJournalEnry(provisioningEntry.getCreatedDate(), 
provisioningEntry.getId(), key.office, key.currency, liabilityMap, expenseMap);
+            createJournalEnry(provisioningEntry.getCreatedDate(), 
provisioningEntry.getId(), key.office, key.currency, liabilityMap,
+                    expenseMap);
         }
-        return "P"+provisioningEntry.getId() ;
+        return "P" + provisioningEntry.getId();
     }
-    
-    private void createJournalEnry(Date transactionDate, Long entryId, Office 
office, String currencyCode, Map<GLAccount, BigDecimal> liabilityMap,
-            Map<GLAccount, BigDecimal> expenseMap) {
+
+    private void createJournalEnry(Date transactionDate, Long entryId, Office 
office, String currencyCode,
+            Map<GLAccount, BigDecimal> liabilityMap, Map<GLAccount, 
BigDecimal> expenseMap) {
         Set<GLAccount> liabilityAccounts = liabilityMap.keySet();
         for (GLAccount account : liabilityAccounts) {
-            
this.helper.createProvisioningCreditJournalEntry(transactionDate,entryId, 
office, currencyCode, account,
+            this.helper.createProvisioningCreditJournalEntry(transactionDate, 
entryId, office, currencyCode, account,
                     liabilityMap.get(account));
         }
         Set<GLAccount> expenseAccounts = expenseMap.keySet();
         for (GLAccount account : expenseAccounts) {
-            
this.helper.createProvisioningDebitJournalEntry(transactionDate,entryId, 
office, currencyCode, account,
+            this.helper.createProvisioningDebitJournalEntry(transactionDate, 
entryId, office, currencyCode, account,
                     expenseMap.get(account));
         }
     }
-    
-    
+
     private void validateCommentForReversal(final String reversalComment) {
         final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
 
@@ -493,6 +499,23 @@ public class 
JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
 
     }
 
+    @Transactional
+    @Override
+    public void createJournalEntriesForShares(final Map<String, Object> 
accountingBridgeData) {
+
+        final boolean cashBasedAccountingEnabled = (Boolean) 
accountingBridgeData.get("cashBasedAccountingEnabled");
+        final boolean accrualBasedAccountingEnabled = (Boolean) 
accountingBridgeData.get("accrualBasedAccountingEnabled");
+
+        if (cashBasedAccountingEnabled) {
+            final SharesDTO sharesDTO = 
this.helper.populateSharesDtoFromMap(accountingBridgeData, 
cashBasedAccountingEnabled,
+                    accrualBasedAccountingEnabled);
+            final AccountingProcessorForShares accountingProcessorForShares = 
this.accountingProcessorForSharesFactory
+                    .determineProcessor(sharesDTO);
+            
accountingProcessorForShares.createJournalEntriesForShares(sharesDTO);
+        }
+
+    }
+
     private void validateBusinessRulesForJournalEntries(final 
JournalEntryCommand command) {
         /** check if date of Journal entry is valid ***/
         final LocalDate entryLocalDate = command.getTransactionDate();
@@ -539,9 +562,10 @@ public class 
JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
             
this.organisationCurrencyRepository.findOneWithNotFoundDetection(currencyCode);
 
             final ClientTransaction clientTransaction = null;
+            final Long shareTransactionId = null;
             final JournalEntry glJournalEntry = JournalEntry.createNew(office, 
paymentDetail, glAccount, currencyCode, transactionId,
                     manualEntry, transactionDate, type, 
singleDebitOrCreditEntryCommand.getAmount(), comments, null, null, 
referenceNumber,
-                    null, null, clientTransaction);
+                    null, null, clientTransaction, shareTransactionId);
             this.glJournalEntryRepository.saveAndFlush(glJournalEntry);
         }
     }
@@ -648,14 +672,15 @@ public class 
JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
             }
 
             final ClientTransaction clientTransaction = null;
+            final Long shareTransactionId = null;
             final JournalEntry glJournalEntry = JournalEntry.createNew(office, 
null, glAccount, currencyCode, transactionId, manualEntry,
                     transactionDate, type, 
singleDebitOrCreditEntryCommand.getAmount(), comments, null, null, null, null, 
null,
-                    clientTransaction);
+                    clientTransaction, shareTransactionId);
             this.glJournalEntryRepository.saveAndFlush(glJournalEntry);
 
             final JournalEntry contraEntry = JournalEntry.createNew(office, 
null, contraAccount, currencyCode, transactionId, manualEntry,
                     transactionDate, contraType, 
singleDebitOrCreditEntryCommand.getAmount(), comments, null, null, null, null, 
null,
-                    clientTransaction);
+                    clientTransaction, shareTransactionId);
             this.glJournalEntryRepository.saveAndFlush(contraEntry);
         }
     }
@@ -682,7 +707,7 @@ public class 
JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
         final ClientTransactionDTO clientTransactionDTO = 
this.helper.populateClientTransactionDtoFromMap(accountingBridgeData);
         
accountingProcessorForClientTransactions.createJournalEntriesForClientTransaction(clientTransactionDTO);
     }
-    
+
     private class OfficeCurrencyKey {
 
         Office office;

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/PortfolioProductType.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/PortfolioProductType.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/PortfolioProductType.java
index 786699c..f43f7e1 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/PortfolioProductType.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/PortfolioProductType.java
@@ -22,7 +22,8 @@ import java.util.HashMap;
 import java.util.Map;
 
 public enum PortfolioProductType {
-    LOAN(1, "productType.loan"), SAVING(2, "productType.saving"), CLIENT(2, 
"productType.client"), PROVISIONING(3, "productType.provisioning");
+    LOAN(1, "productType.loan"), SAVING(2, "productType.saving"), CLIENT(2, 
"productType.client"), PROVISIONING(3,
+            "productType.provisioning"), SHARES(4, "productType.shares");
 
     private final Integer value;
     private final String code;
@@ -70,4 +71,8 @@ public enum PortfolioProductType {
         return this.value.equals(PortfolioProductType.CLIENT.getValue());
     }
 
+    public boolean isShareProduct() {
+        return this.value.equals(PortfolioProductType.SHARES.getValue());
+    }
+
 }

Reply via email to