fineract-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nazeer1100...@apache.org
Subject [2/3] incubator-fineract git commit: Issue fixes on shares and dividends reported by QA
Date Wed, 20 Apr 2016 05:30:49 GMT
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/60588a78/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/serialization/ShareAccountDataSerializer.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/serialization/ShareAccountDataSerializer.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/serialization/ShareAccountDataSerializer.java
index 13c7b4d..1e63050 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/serialization/ShareAccountDataSerializer.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/serialization/ShareAccountDataSerializer.java
@@ -49,7 +49,6 @@ import org.apache.fineract.portfolio.client.domain.Client;
 import org.apache.fineract.portfolio.client.domain.ClientRepositoryWrapper;
 import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
 import org.apache.fineract.portfolio.loanproduct.exception.InvalidCurrencyException;
-import org.apache.fineract.portfolio.savings.SavingsApiConstants;
 import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
 import org.apache.fineract.portfolio.savings.domain.SavingsAccountRepositoryWrapper;
 import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccount;
@@ -87,9 +86,8 @@ public class ShareAccountDataSerializer {
 
     @Autowired
     public ShareAccountDataSerializer(final PlatformSecurityContext platformSecurityContext, final FromJsonHelper fromApiJsonHelper,
-            final ChargeRepositoryWrapper chargeRepository,
-            final SavingsAccountRepositoryWrapper savingsAccountRepositoryWrapper, final ClientRepositoryWrapper clientRepositoryWrapper,
-            final ShareProductRepositoryWrapper shareProductRepository) {
+            final ChargeRepositoryWrapper chargeRepository, final SavingsAccountRepositoryWrapper savingsAccountRepositoryWrapper,
+            final ClientRepositoryWrapper clientRepositoryWrapper, final ShareProductRepositoryWrapper shareProductRepository) {
         this.platformSecurityContext = platformSecurityContext;
         this.fromApiJsonHelper = fromApiJsonHelper;
         this.chargeRepository = chargeRepository;
@@ -117,7 +115,7 @@ public class ShareAccountDataSerializer {
         baseDataValidator.reset().parameter(ShareAccountApiConstants.submitteddate_paramname).value(submittedDate).notNull();
 
         final String externalId = this.fromApiJsonHelper.extractStringNamed(ShareAccountApiConstants.externalid_paramname, element);
-        baseDataValidator.reset().parameter(ShareAccountApiConstants.externalid_paramname).value(externalId).notNull();
+        // baseDataValidator.reset().parameter(ShareAccountApiConstants.externalid_paramname).value(externalId).notNull();
 
         Long savingsAccountId = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.savingsaccountid_paramname, element);
         baseDataValidator.reset().parameter(ShareAccountApiConstants.savingsaccountid_paramname).value(savingsAccountId).notNull()
@@ -126,25 +124,16 @@ public class ShareAccountDataSerializer {
         final Long requestedShares = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.requestedshares_paramname, element);
         baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname).value(requestedShares).notNull()
                 .longGreaterThanZero();
-        boolean allowed = shareProduct.isSharesAllowed(requestedShares) ;
-        if(!allowed) {
-            baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname).value(requestedShares).failWithCode("differ.from.productdefinition", "Out of range");;
+        if(requestedShares < shareProduct.getMinimumClientShares()) {
+            baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname).value(requestedShares)
+            .failWithCode("client.can.not.purchase.shares.lessthan.product.definition", "Client can not purchase shares less than product definition");
         }
         
-        /*Long subscribedShares = shareProduct.getSubscribedShares() ;
-        if(subscribedShares == null) subscribedShares = new Long(0) ;
-        Long totalShares = shareProduct.getTotalShares() ;
-        Long issuedShares = shareProduct.getSharesIssued() ;
-        if(issuedShares == null) issuedShares = totalShares ;
-        if((subscribedShares+requestedShares) > issuedShares) {
-            throw new IssueableSharesExceededException() ;
-        }
-        shareProduct.addSubscribedShares(requestedShares);*/
+        if(requestedShares > shareProduct.getMaximumClientShares()) {
+            baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname).value(requestedShares)
+            .failWithCode("client.can.not.purchase.shares.morethan.product.definition", "Client can not purchase shares more than product definition");
+        }
         
-        /*BigDecimal unitPrice = this.fromApiJsonHelper.extractBigDecimalNamed(ShareAccountApiConstants.purchasedprice_paramname, element,
-                locale);
-        baseDataValidator.reset().parameter(ShareAccountApiConstants.purchasedprice_paramname).value(unitPrice).notNull().positiveAmount();*/
-
         LocalDate applicationDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.applicationdate_param, element);
         baseDataValidator.reset().parameter(ShareAccountApiConstants.applicationdate_param).value(applicationDate).notNull();
 
@@ -185,7 +174,7 @@ public class ShareAccountDataSerializer {
         String accountNo = null;
         Long approvedShares = null;
         Long pendingShares = requestedShares;
-        BigDecimal unitPrice = shareProduct.deriveMarketPrice(applicationDate.toDate()) ;
+        BigDecimal unitPrice = shareProduct.deriveMarketPrice(applicationDate.toDate());
         ShareAccountTransaction transaction = new ShareAccountTransaction(applicationDate.toDate(), requestedShares, unitPrice);
         Set<ShareAccountTransaction> sharesPurchased = new HashSet<>();
         sharesPurchased.add(transaction);
@@ -204,28 +193,28 @@ public class ShareAccountDataSerializer {
                 charge.update(account);
             }
         }
-        createChargeTransaction(account, transaction);
+        createChargeTransaction(account);
         return account;
     }
 
-    private void createChargeTransaction(ShareAccount account, final ShareAccountTransaction transaction) {
+    private void createChargeTransaction(ShareAccount account) {
         BigDecimal totalChargeAmount = BigDecimal.ZERO;
         Set<ShareAccountCharge> charges = account.getCharges();
         Date currentDate = DateUtils.getLocalDateOfTenant().toDate();
         for (ShareAccountCharge charge : charges) {
-            if (charge.isShareAccountActivation()) {
-                charge.deriveChargeAmount(totalChargeAmount) ;
+            if (charge.isActive() && charge.isShareAccountActivation()) {
+                charge.deriveChargeAmount(totalChargeAmount);
                 ShareAccountTransaction chargeTransaction = ShareAccountTransaction.createChargeTransaction(currentDate, charge);
                 ShareAccountChargePaidBy paidBy = new ShareAccountChargePaidBy(chargeTransaction, charge, charge.percentageOrAmount());
                 chargeTransaction.addShareAccountChargePaidBy(paidBy);
                 account.addChargeTransaction(chargeTransaction);
             }
         }
-       
+
         Set<ShareAccountTransaction> pendingApprovalTransaction = account.getPendingForApprovalSharePurchaseTransactions();
         for (ShareAccountTransaction pending : pendingApprovalTransaction) {
             for (ShareAccountCharge charge : charges) {
-                if (charge.isSharesPurchaseCharge()) {
+                if (charge.isActive() && charge.isSharesPurchaseCharge()) {
                     BigDecimal amount = charge.deriveChargeAmount(pending.amount());
                     ShareAccountChargePaidBy paidBy = new ShareAccountChargePaidBy(pending, charge, amount);
                     pending.addShareAccountChargePaidBy(paidBy);
@@ -245,7 +234,7 @@ public class ShareAccountDataSerializer {
         final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
         final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("sharesaccount");
         JsonElement element = jsonCommand.parsedJson();
-        ShareProduct shareProduct = account.getShareProduct() ;
+        ShareProduct shareProduct = account.getShareProduct();
         final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(element.getAsJsonObject());
         if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.productid_paramname, element)) {
             final Long productId = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.productid_paramname, element);
@@ -266,7 +255,7 @@ public class ShareAccountDataSerializer {
 
         if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.externalid_paramname, element)) {
             final String externalId = this.fromApiJsonHelper.extractStringNamed(ShareAccountApiConstants.externalid_paramname, element);
-            baseDataValidator.reset().parameter(ShareAccountApiConstants.externalid_paramname).value(externalId).notNull();
+            // baseDataValidator.reset().parameter(ShareAccountApiConstants.externalid_paramname).value(externalId).notNull();
             if (account.setExternalId(externalId)) {
                 actualChanges.put(ShareAccountApiConstants.externalid_paramname, externalId);
             }
@@ -274,25 +263,51 @@ public class ShareAccountDataSerializer {
 
         if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.savingsaccountid_paramname, element)) {
             Long savingsAccountId = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.savingsaccountid_paramname, element);
-            SavingsAccount savingsAccount = this.savingsAccountRepositoryWrapper.findOneWithNotFoundDetection(savingsAccountId);
-            if (account.setSavingsAccount(savingsAccount)) {
-                actualChanges.put(ShareAccountApiConstants.savingsaccountid_paramname, savingsAccount);
+            baseDataValidator.reset().parameter(ShareAccountApiConstants.savingsaccountid_paramname).value(savingsAccountId).notNull()
+            .longGreaterThanZero();
+            if(savingsAccountId != null) {
+                SavingsAccount savingsAccount = this.savingsAccountRepositoryWrapper.findOneWithNotFoundDetection(savingsAccountId);
+                if (account.setSavingsAccount(savingsAccount)) {
+                    actualChanges.put(ShareAccountApiConstants.savingsaccountid_paramname, savingsAccount.getId());
+                }    
+            }
+        }
+
+        if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.requestedshares_paramname, element)
+                || this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.charges_paramname, element)) {
+            Set<ShareAccountTransaction> transactions = account.getShareAccountTransactions();
+            List<Long> reveralIds = new ArrayList<>();
+            for (ShareAccountTransaction transaction : transactions) {
+                reveralIds.add(transaction.getId());
             }
+            actualChanges.put("reversalIds", reveralIds);
+            account.removeTransactions();
+            account.removeCharges();
         }
 
         if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.requestedshares_paramname, element)) {
             Long requestedShares = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.requestedshares_paramname, element);
-            /*BigDecimal unitPrice = this.fromApiJsonHelper.extractBigDecimalNamed(ShareAccountApiConstants.purchasedprice_paramname,
-                    element, locale);*/
+            /*
+             * BigDecimal unitPrice =
+             * this.fromApiJsonHelper.extractBigDecimalNamed
+             * (ShareAccountApiConstants.purchasedprice_paramname, element,
+             * locale);
+             */
             Date applicationDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.applicationdate_param, element)
                     .toDate();
-            BigDecimal unitPrice = shareProduct.deriveMarketPrice(applicationDate) ;
-            ShareAccountTransaction purchased = new ShareAccountTransaction(applicationDate, requestedShares, unitPrice);
-            account.updateRequestedShares(purchased);
-            actualChanges.put(ShareAccountApiConstants.requestedshares_paramname, purchased);
-            boolean allowed = shareProduct.isSharesAllowed(requestedShares) ;
-            if(!allowed) {
-                baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname).value(requestedShares).failWithCode("differ.from.productdefinition", "Out of range");;
+            BigDecimal unitPrice = shareProduct.deriveMarketPrice(applicationDate);
+            ShareAccountTransaction transaction = new ShareAccountTransaction(applicationDate, requestedShares, unitPrice);
+            account.addTransaction(transaction);
+            actualChanges.put(ShareAccountApiConstants.requestedshares_paramname, "Transaction");
+            
+            if(requestedShares < shareProduct.getMinimumClientShares()) {
+                baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname).value(requestedShares)
+                .failWithCode("client.can.not.purchase.shares.lessthan.product.definition", "Client can not purchase shares less than product definition");
+            }
+            
+            if(requestedShares > shareProduct.getMaximumClientShares()) {
+                baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname).value(requestedShares)
+                .failWithCode("client.can.not.purchase.shares.morethan.product.definition", "Client can not purchase shares more than product definition");
             }
         }
 
@@ -340,13 +355,19 @@ public class ShareAccountDataSerializer {
         }
         if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.charges_paramname, element)) {
             shareProduct = account.getShareProduct();
-            Set<ShareAccountCharge> updatedCharges = assembleListOfAccountChargesforUpdate(account, element, shareProduct.getCurrency()
-                    .getCode());
-            if (!updatedCharges.isEmpty()) {
-                actualChanges.put(ShareAccountApiConstants.charges_paramname, new HashSet<ShareAccountCharge>());
+            final MonetaryCurrency currency = shareProduct.getCurrency();
+            Set<ShareAccountCharge> charges = assembleListOfAccountCharges(element, currency.getCode());
+            if (charges != null) {
+                for (ShareAccountCharge charge : charges) {
+                    charge.update(account);
+                }
+                account.addCharges(charges);
+                if (!charges.isEmpty()) {
+                    actualChanges.put(ShareAccountApiConstants.charges_paramname, new HashSet<ShareAccountCharge>());
+                }
             }
-
         }
+        createChargeTransaction(account);
         if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
         return actualChanges;
     }
@@ -366,30 +387,57 @@ public class ShareAccountDataSerializer {
             final DateTimeFormatter formatter = DateTimeFormat.forPattern(jsonCommand.dateFormat()).withLocale(jsonCommand.extractLocale());
             final String submittalDateAsString = formatter.print(submittalDate);
             baseDataValidator.reset().parameter(ShareAccountApiConstants.approveddate_paramname).value(submittalDateAsString)
-                    .failWithCodeNoParameterAddedToErrorCode("cannot.be.before.submittal.date");
+                    .failWithCodeNoParameterAddedToErrorCode("approved.date.cannot.be.before.submitted.date");
+        }
+        
+        Set<ShareAccountTransaction> transactions = account.getShareAccountTransactions() ;
+        for(ShareAccountTransaction transaction: transactions) {
+            if(transaction.isActive() && transaction.isPendingForApprovalTransaction()) {
+                validateTotalSubsribedShares(account, transaction, baseDataValidator) ;
+            }
         }
+        
         if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
         
         AppUser approvedUser = this.platformSecurityContext.authenticatedUser();
-        account.approve(approvedDate.toDate(), approvedUser);    
+        account.approve(approvedDate.toDate(), approvedUser);
         actualChanges.put(ShareAccountApiConstants.id_paramname, account.getId());
         updateTotalChargeDerived(account);
         return actualChanges;
     }
 
+    private void validateTotalSubsribedShares(final ShareAccount account, final ShareAccountTransaction transaction, final  DataValidatorBuilder baseDataValidator) {
+        Long totalSubsribedShares = account.getShareProduct().getSubscribedShares() ;
+        Long requested = new Long(0) ;
+        if(transaction.isActive() && transaction.isPendingForApprovalTransaction()) {
+           requested +=transaction.getTotalShares() ;
+        }
+        Long totalSharesIssuable = account.getShareProduct().getSharesIssued() ;
+        if(totalSharesIssuable == null) totalSharesIssuable = account.getShareProduct().getTotalShares() ;
+        if(totalSubsribedShares == null) totalSubsribedShares = new Long(0) ;
+        if((totalSubsribedShares+requested) > totalSharesIssuable) {
+            baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname).value(requested)
+            .failWithCodeNoParameterAddedToErrorCode("shares.requested.can.not.be.approved.exceeding.totalshares.issuable");
+        }
+    }
     private void updateTotalChargeDerived(final ShareAccount shareAccount) {
         // Set<ShareAccountCharge> charges = shareAccount.getCharges() ;
         Set<ShareAccountTransaction> transactions = shareAccount.getShareAccountTransactions();
         for (ShareAccountTransaction transaction : transactions) {
-            Set<ShareAccountChargePaidBy> paidBySet = transaction.getChargesPaidBy();
-            if (paidBySet != null && !paidBySet.isEmpty()) {
-                for (ShareAccountChargePaidBy chargePaidBy : paidBySet) {
-                    ShareAccountCharge charge = chargePaidBy.getCharge();
-                    if (charge.isSharesPurchaseCharge()) {
-                        Money money = Money.of(shareAccount.getCurrency(), chargePaidBy.getAmount());
-                        charge.updatePaidAmountBy(money);
+            if (transaction.isActive()) {
+                Set<ShareAccountChargePaidBy> paidBySet = transaction.getChargesPaidBy();
+                if (paidBySet != null && !paidBySet.isEmpty()) {
+                    for (ShareAccountChargePaidBy chargePaidBy : paidBySet) {
+                        ShareAccountCharge charge = chargePaidBy.getCharge();
+                        if (charge.isActive() && charge.isSharesPurchaseCharge()) {
+                            Money money = Money.of(shareAccount.getCurrency(), chargePaidBy.getAmount());
+                            charge.updatePaidAmountBy(money);
+                        }
                     }
                 }
+                if (!transaction.isChargeTransaction()) {
+                    transaction.addAmountPaid(transaction.chargeAmount());
+                }
             }
         }
     }
@@ -397,19 +445,54 @@ public class ShareAccountDataSerializer {
     public Map<String, Object> validateAndUndoApprove(JsonCommand jsonCommand, ShareAccount account) {
         Map<String, Object> actualChanges = new HashMap<>();
         if (StringUtils.isBlank(jsonCommand.json())) { throw new InvalidJsonException(); }
-        //final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
-        //this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, jsonCommand.json(), ShareAccountApiConstants.activateParameters);
-        //final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
-        //final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("sharesaccount");
-        //JsonElement element = jsonCommand.parsedJson();
-        //String notes = this.fromApiJsonHelper.extractStringNamed(ShareAccountApiConstants.note_paramname, element);
+        // final Type typeOfMap = new TypeToken<Map<String, Object>>()
+        // {}.getType();
+        // this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap,
+        // jsonCommand.json(), ShareAccountApiConstants.activateParameters);
+        // final List<ApiParameterError> dataValidationErrors = new
+        // ArrayList<>();
+        // final DataValidatorBuilder baseDataValidator = new
+        // DataValidatorBuilder(dataValidationErrors).resource("sharesaccount");
+        // JsonElement element = jsonCommand.parsedJson();
+        // String notes =
+        // this.fromApiJsonHelper.extractStringNamed(ShareAccountApiConstants.note_paramname,
+        // element);
         // baseDataValidator.reset().parameter(ShareAccountApiConstants.approveddate_paramname).validateDateAfter(account.get)
-        //AppUser approvedUser = this.platformSecurityContext.authenticatedUser();
+        // AppUser approvedUser =
+        // this.platformSecurityContext.authenticatedUser();
         account.undoApprove();
+        updateTotalChargeDerivedForUndoApproval(account) ;
         actualChanges.put(ShareAccountApiConstants.charges_paramname, Boolean.TRUE);
         return actualChanges;
     }
 
+    private void updateTotalChargeDerivedForUndoApproval(final ShareAccount shareAccount) {
+        Set<ShareAccountTransaction> purchaseTransactions = shareAccount.getPendingForApprovalSharePurchaseTransactions() ;
+        //we will have only 1 purchase transaction. Take that
+        ShareAccountTransaction purchaseTransaction = null ;
+        for (ShareAccountTransaction transaction : purchaseTransactions) {
+            purchaseTransaction = transaction ;
+        }
+        BigDecimal transactionAmount = BigDecimal.ZERO ;
+        if(purchaseTransaction != null) {
+            transactionAmount = purchaseTransaction.amount().subtract(purchaseTransaction.chargeAmount()) ;
+        }
+         Set<ShareAccountCharge> charges = shareAccount.getCharges() ;
+         for(ShareAccountCharge charge: charges) {
+             if(charge.isActive() && charge.isSharesPurchaseCharge()) {
+                 charge.update(transactionAmount, charge.percentageOrAmount()) ;
+                 charge.deriveChargeAmount(transactionAmount);
+             }
+         }
+        Set<ShareAccountTransaction> transactions = shareAccount.getShareAccountTransactions();
+        for (ShareAccountTransaction transaction : transactions) {
+            if (transaction.isActive()) {
+                if (!transaction.isChargeTransaction()) {
+                    transaction.resetAmountPaid();
+                }
+            }
+        }
+    }
     @SuppressWarnings("unused")
     public Map<String, Object> validateAndReject(JsonCommand jsonCommand, ShareAccount account) {
         Map<String, Object> actualChanges = new HashMap<>();
@@ -449,10 +532,17 @@ public class ShareAccountDataSerializer {
     private void handlechargesOnActivation(final ShareAccount account) {
         Set<ShareAccountCharge> charges = account.getCharges();
         for (ShareAccountCharge charge : charges) {
-            if (charge.isShareAccountActivation()) {
+            if (charge.isActive() && charge.isShareAccountActivation()) {
                 charge.markAsFullyPaid();
             }
         }
+
+        Set<ShareAccountTransaction> transactions = account.getChargeTransactions();
+        for (ShareAccountTransaction transaction : transactions) {
+            if (transaction.isChargeTransaction()) {
+                transaction.updateAmountPaid(transaction.amount());
+            }
+        }
     }
 
     private Set<ShareAccountCharge> assembleListOfAccountCharges(final JsonElement element, final String currencyCode) {
@@ -484,49 +574,6 @@ public class ShareAccountDataSerializer {
         return charges;
     }
 
-    private Set<ShareAccountCharge> assembleListOfAccountChargesforUpdate(final ShareAccount account, final JsonElement element,
-            final String currencyCode) {
-        Set<ShareAccountCharge> updated = new HashSet<>();
-        if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.charges_paramname, element)) {
-            JsonArray chargesArray = this.fromApiJsonHelper.extractJsonArrayNamed(ShareAccountApiConstants.charges_paramname, element);
-            if (chargesArray != null) {
-                for (int i = 0; i < chargesArray.size(); i++) {
-                    final JsonObject jsonObject = chargesArray.get(i).getAsJsonObject();
-                    if (jsonObject.has("id")) {
-                        final Long id = jsonObject.get("id").getAsLong();
-                        final Long chargeId = jsonObject.get("chargeId").getAsLong();
-                        BigDecimal amount = jsonObject.get("amount").getAsBigDecimal();
-                        final Charge charge = this.chargeRepository.findOneWithNotFoundDetection(chargeId);
-                        if (!currencyCode.equals(charge.getCurrencyCode())) {
-                            final String errorMessage = "Charge and Share Account must have the same currency.";
-                            throw new InvalidCurrencyException("charge", "attach.to.share.account", errorMessage);
-                        }
-                        ShareAccountCharge updatedCharge = account.updateShareCharge(id, chargeId, amount);
-                        updated.add(updatedCharge);
-                    } else {
-                        if (jsonObject.has("chargeId")) {
-                            final Long id = jsonObject.get("chargeId").getAsLong();
-                            BigDecimal amount = jsonObject.get("amount").getAsBigDecimal();
-                            final Charge charge = this.chargeRepository.findOneWithNotFoundDetection(id);
-                            if (!currencyCode.equals(charge.getCurrencyCode())) {
-                                final String errorMessage = "Charge and Share Account must have the same currency.";
-                                throw new InvalidCurrencyException("charge", "attach.to.share.account", errorMessage);
-                            }
-                            ChargeTimeType chargeTime = ChargeTimeType.fromInt(charge.getChargeTimeType());
-                            ChargeCalculationType chargeCalculation = ChargeCalculationType.fromInt(charge.getChargeCalculation());
-                            Boolean status = Boolean.TRUE;
-                            ShareAccountCharge accountCharge = ShareAccountCharge.createNewWithoutShareAccount(charge, amount, chargeTime,
-                                    chargeCalculation, status);
-                            account.addShareAccountCharge(accountCharge);
-                            updated.add(accountCharge);
-                        }
-                    }
-                }
-            }
-        }
-        return updated;
-    }
-
     private PeriodFrequencyType extractPeriodType(String paramName, final JsonElement element) {
         PeriodFrequencyType frequencyType = PeriodFrequencyType.INVALID;
         frequencyType = PeriodFrequencyType.fromInt(this.fromApiJsonHelper.extractIntegerWithLocaleNamed(paramName, element));
@@ -546,15 +593,33 @@ public class ShareAccountDataSerializer {
         baseDataValidator.reset().parameter(ShareAccountApiConstants.requesteddate_paramname).value(requestedDate).notNull();
         final Long sharesRequested = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.requestedshares_paramname, element);
         baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname).value(sharesRequested).notNull();
-        ShareProduct shareProduct = account.getShareProduct() ;
-        if(sharesRequested != null) {
-            boolean allowed = shareProduct.isSharesAllowed(sharesRequested) ;
-            if(!allowed) {
-                baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname).value(sharesRequested).failWithCode("differ.from.productdefinition", "Out of range");;
-            }    
+        ShareProduct shareProduct = account.getShareProduct();
+        if (sharesRequested != null) {
+            Long totalSharesAfterapproval = account.getTotalApprovedShares() + sharesRequested;
+            if(totalSharesAfterapproval > shareProduct.getMaximumClientShares()) {
+                baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname).value(sharesRequested)
+                .failWithCode("exceeding.maximum.limit.defined.in.the.shareproduct", "Existing and requested shares count is more than product definition");
+            }
+        }
+        boolean isTransactionBeforeExistingTransactions = false ;
+        Set<ShareAccountTransaction> transactions = account.getShareAccountTransactions() ;
+        for(ShareAccountTransaction transaction: transactions) {
+            if(!transaction.isChargeTransaction()) {
+                LocalDate transactionDate = new LocalDate(transaction.getPurchasedDate()) ;
+                if(requestedDate.isBefore(transactionDate)) {
+                    isTransactionBeforeExistingTransactions = true ;
+                    break ;
+                }    
+            }
         }
+        if(isTransactionBeforeExistingTransactions) {
+            baseDataValidator.reset().parameter(ShareAccountApiConstants.requesteddate_paramname)
+            .value(requestedDate)
+            .failWithCodeNoParameterAddedToErrorCode("purchase.transaction.date.cannot.be.before.existing.transactions");
+        }
+        
         if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
-        final BigDecimal unitPrice = shareProduct.deriveMarketPrice(requestedDate.toDate()) ;
+        final BigDecimal unitPrice = shareProduct.deriveMarketPrice(requestedDate.toDate());
         ShareAccountTransaction purchaseTransaction = new ShareAccountTransaction(requestedDate.toDate(), sharesRequested, unitPrice);
         account.addAdditionalPurchasedShares(purchaseTransaction);
         handleAdditionalSharesChargeTransactions(account, purchaseTransaction);
@@ -566,7 +631,7 @@ public class ShareAccountDataSerializer {
         Set<ShareAccountCharge> charges = account.getCharges();
         BigDecimal totalChargeAmount = BigDecimal.ZERO;
         for (ShareAccountCharge charge : charges) {
-            if (charge.isSharesPurchaseCharge()) {
+            if (charge.isActive() && charge.isSharesPurchaseCharge()) {
                 BigDecimal amount = charge.updateChargeDetailsForAdditionalSharesRequest(purchaseTransaction.amount());
                 ShareAccountChargePaidBy paidBy = new ShareAccountChargePaidBy(purchaseTransaction, charge, amount);
                 purchaseTransaction.addShareAccountChargePaidBy(paidBy);
@@ -588,20 +653,21 @@ public class ShareAccountDataSerializer {
         final ArrayList<Long> purchasedShares = new ArrayList<>();
         if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.requestedshares_paramname, element)) {
             JsonArray array = this.fromApiJsonHelper.extractJsonArrayNamed(ShareAccountApiConstants.requestedshares_paramname, element);
-            long totalShares = 0 ;
+            long totalShares = 0;
             for (JsonElement arrayElement : array) {
                 final Long purchasedSharesId = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.id_paramname, arrayElement);
-                baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname).value(purchasedSharesId).notBlank() ;
+                baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname).value(purchasedSharesId).notBlank();
                 ShareAccountTransaction transaction = account.retrievePurchasedShares(purchasedSharesId);
                 if (transaction != null) {
-                    totalShares+=transaction.getTotalShares().longValue() ;
+                    validateTotalSubsribedShares(account, transaction, baseDataValidator) ;
+                    totalShares += transaction.getTotalShares().longValue();
                     transaction.approve();
                     updateTotalChargeDerivedForAdditonalShares(account, transaction);
                 }
                 purchasedShares.add(purchasedSharesId);
             }
-            if(totalShares > 0) {
-                account.updateApprovedShares(new Long(totalShares)) ;    
+            if (totalShares > 0) {
+                account.updateApprovedShares(new Long(totalShares));
             }
         }
         if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
@@ -614,11 +680,14 @@ public class ShareAccountDataSerializer {
         if (paidBySet != null && !paidBySet.isEmpty()) {
             for (ShareAccountChargePaidBy chargePaidBy : paidBySet) {
                 ShareAccountCharge charge = chargePaidBy.getCharge();
-                if (charge.isSharesPurchaseCharge()) {
+                if (charge.isActive() && charge.isSharesPurchaseCharge()) {
                     Money money = Money.of(shareAccount.getCurrency(), chargePaidBy.getAmount());
                     charge.updatePaidAmountBy(money);
                 }
             }
+            if (!transaction.isChargeTransaction()) {
+                transaction.addAmountPaid(transaction.chargeAmount());
+            }
         }
     }
 
@@ -631,20 +700,20 @@ public class ShareAccountDataSerializer {
         JsonElement element = jsonCommand.parsedJson();
         final ArrayList<Long> purchasedShares = new ArrayList<>();
         if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.requestedshares_paramname, element)) {
-            long totalShares = 0 ;
+            long totalShares = 0;
             JsonArray array = this.fromApiJsonHelper.extractJsonArrayNamed(ShareAccountApiConstants.requestedshares_paramname, element);
             for (JsonElement arrayElement : array) {
                 final Long purchasedSharesId = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.id_paramname, arrayElement);
                 ShareAccountTransaction shares = account.retrievePurchasedShares(purchasedSharesId);
                 if (shares != null) {
                     shares.reject();
-                    updateTotalChargeDerivedForAdditonalSharesReject(account, shares) ;
-                    totalShares +=shares.getTotalShares().longValue() ;
+                    updateTotalChargeDerivedForAdditonalSharesReject(account, shares);
+                    totalShares += shares.getTotalShares().longValue();
                 }
                 purchasedShares.add(purchasedSharesId);
             }
-            if(totalShares > 0) {
-                account.removePendingShares(new Long(totalShares)) ;
+            if (totalShares > 0) {
+                account.removePendingShares(new Long(totalShares));
             }
         }
         actualChanges.put(ShareAccountApiConstants.requestedshares_paramname, purchasedShares);
@@ -656,14 +725,17 @@ public class ShareAccountDataSerializer {
         if (paidBySet != null && !paidBySet.isEmpty()) {
             for (ShareAccountChargePaidBy chargePaidBy : paidBySet) {
                 ShareAccountCharge charge = chargePaidBy.getCharge();
-                if (charge.isSharesPurchaseCharge()) {
+                if (charge.isActive() && charge.isSharesPurchaseCharge()) {
                     Money money = Money.of(shareAccount.getCurrency(), chargePaidBy.getAmount());
                     charge.updatePaidAmountBy(money);
                 }
             }
+            if (!transaction.isChargeTransaction()) {
+                transaction.addAmountPaid(transaction.chargeAmount());
+            }
         }
     }
-    
+
     public Map<String, Object> validateAndRedeemShares(JsonCommand jsonCommand, ShareAccount account) {
         Map<String, Object> actualChanges = new HashMap<>();
         if (StringUtils.isBlank(jsonCommand.json())) { throw new InvalidJsonException(); }
@@ -683,19 +755,116 @@ public class ShareAccountDataSerializer {
         final BigDecimal unitPrice = this.fromApiJsonHelper.extractBigDecimalNamed(ShareAccountApiConstants.purchasedprice_paramname,
                 element, locale);
         baseDataValidator.reset().parameter(ShareAccountApiConstants.purchasedprice_paramname).value(unitPrice).notNull().positiveAmount();
+        boolean isTransactionBeforeExistingTransactions = false ;
+        Set<ShareAccountTransaction> transactions = account.getShareAccountTransactions() ;
+        for(ShareAccountTransaction transaction: transactions) {
+            if(!transaction.isChargeTransaction()) {
+                LocalDate transactionDate = new LocalDate(transaction.getPurchasedDate()) ;
+                if(requestedDate.isBefore(transactionDate)) {
+                    isTransactionBeforeExistingTransactions = true ;
+                    break ;
+                }    
+            }
+        }
+        if(isTransactionBeforeExistingTransactions) {
+            baseDataValidator.reset().parameter(ShareAccountApiConstants.requesteddate_paramname)
+            .value(requestedDate)
+            .failWithCodeNoParameterAddedToErrorCode("redeem.transaction.date.cannot.be.before.existing.transactions");
+        }
+        if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
+        
         ShareAccountTransaction transaction = ShareAccountTransaction.createRedeemTransaction(requestedDate.toDate(), sharesRequested,
                 unitPrice);
         account.addAdditionalPurchasedShares(transaction);
         actualChanges.put(ShareAccountApiConstants.requestedshares_paramname, transaction);
+        validateRedeemRequest(account, transaction, baseDataValidator, dataValidationErrors) ;
         handleRedeemSharesChargeTransactions(account, transaction);
         return actualChanges;
     }
-
+    
+    private void validateRedeemRequest(final ShareAccount account, ShareAccountTransaction redeemTransaction,
+            final DataValidatorBuilder baseDataValidator,  final List<ApiParameterError> dataValidationErrors ) {
+        
+        if (account.getTotalApprovedShares() < redeemTransaction.getTotalShares()) {
+            baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname)
+                    .value(redeemTransaction.getTotalShares())
+                    .failWithCodeNoParameterAddedToErrorCode("cannot.be.redeemed.due.to.insufficient.shares");
+        }
+        if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
+        
+        LocalDate redeemDate = new LocalDate(redeemTransaction.getPurchasedDate());
+        final Integer lockinPeriod = account.getLockinPeriodFrequency();
+        final PeriodFrequencyType periodType = account.getLockinPeriodFrequencyType();
+        if (lockinPeriod == null && periodType == null) { return; }
+        Long totalSharesCanBeRedeemed = new Long(0);
+        Long totalSharesPurchasedBeforeRedeem = new Long(0) ;
+        boolean isPurchaseTransactionExist = false ;
+        
+        Set<ShareAccountTransaction> transactions = account.getShareAccountTransactions();
+        for (ShareAccountTransaction transaction : transactions) {
+            if (transaction.isActive() && !transaction.isChargeTransaction()) {
+                LocalDate purchaseDate = new LocalDate(transaction.getPurchasedDate());
+                LocalDate lockinDate = deriveLockinPeriodDuration(lockinPeriod, periodType, purchaseDate);
+                if (!lockinDate.isAfter(redeemDate)) {
+                    if (transaction.isPurchasTransaction()) {
+                        totalSharesCanBeRedeemed += transaction.getTotalShares();
+                    } else if (transaction.isRedeemTransaction()) {
+                        totalSharesCanBeRedeemed -= transaction.getTotalShares();
+                    }
+                }
+                
+                if(!purchaseDate.isAfter(redeemDate)) {
+                    isPurchaseTransactionExist = true ;
+                    if (transaction.isPurchasTransaction()) {
+                        totalSharesPurchasedBeforeRedeem += transaction.getTotalShares();
+                    } else if (transaction.isRedeemTransaction()) {
+                        totalSharesPurchasedBeforeRedeem -= transaction.getTotalShares();
+                    }
+                }
+            }
+        }
+        if(!isPurchaseTransactionExist) {
+            baseDataValidator.reset().parameter(ShareAccountApiConstants.requesteddate_paramname)
+            .value(redeemDate)
+            .failWithCodeNoParameterAddedToErrorCode("no.purchase.transaction.found.before.redeem.date");
+        }else if (totalSharesPurchasedBeforeRedeem < redeemTransaction.getTotalShares()) {
+            baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname)
+            .value(redeemTransaction.getTotalShares())
+            .failWithCodeNoParameterAddedToErrorCode("cannot.be.redeemed.due.to.insufficient.shares.for.this.redeem.date");
+        }else if (totalSharesCanBeRedeemed < redeemTransaction.getTotalShares()) {
+            baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname)
+                    .value(redeemTransaction.getTotalShares())
+                    .failWithCodeNoParameterAddedToErrorCode("cannot.be.redeemed.due.to.lockinperiod");
+        }
+        if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
+    }
+    
+    private LocalDate deriveLockinPeriodDuration(final Integer lockinPeriod, final PeriodFrequencyType periodType, LocalDate purchaseDate) {
+        LocalDate lockinDate = null ;
+        switch(periodType) {
+            case INVALID: //It never comes in to this state.
+                break ;
+            case DAYS:
+                lockinDate = purchaseDate.plusDays(lockinPeriod) ;
+                break ;
+            case WEEKS:
+                lockinDate = purchaseDate.plusWeeks(lockinPeriod) ;
+                break ;
+            case MONTHS:
+                lockinDate = purchaseDate.plusMonths(lockinPeriod) ;
+                break ;
+            case YEARS:
+                lockinDate = purchaseDate.plusYears(lockinPeriod) ;
+                break ;
+        }
+        return lockinDate ;
+    }
+    
     private void handleRedeemSharesChargeTransactions(final ShareAccount account, final ShareAccountTransaction transaction) {
         Set<ShareAccountCharge> charges = account.getCharges();
         BigDecimal totalChargeAmount = BigDecimal.ZERO;
         for (ShareAccountCharge charge : charges) {
-            if (charge.isSharesRedeemCharge()) {
+            if (charge.isActive() && charge.isSharesRedeemCharge()) {
                 BigDecimal amount = charge.updateChargeDetailsForAdditionalSharesRequest(transaction.amount());
                 ShareAccountChargePaidBy paidBy = new ShareAccountChargePaidBy(transaction, charge, amount);
                 transaction.addShareAccountChargePaidBy(paidBy);
@@ -707,16 +876,15 @@ public class ShareAccountDataSerializer {
         if (paidBySet != null && !paidBySet.isEmpty()) {
             for (ShareAccountChargePaidBy chargePaidBy : paidBySet) {
                 ShareAccountCharge charge = chargePaidBy.getCharge();
-                if (charge.isSharesRedeemCharge()) {
+                if (charge.isActive() && charge.isSharesRedeemCharge()) {
                     Money money = Money.of(account.getCurrency(), chargePaidBy.getAmount());
                     charge.updatePaidAmountBy(money);
                 }
             }
         }
-        
-       // transaction.adjustRedeemAmount();
+        transaction.addAmountPaid(transaction.chargeAmount());
     }
-    
+
     public Map<String, Object> validateAndClose(JsonCommand jsonCommand, ShareAccount account) {
         Map<String, Object> actualChanges = new HashMap<>();
         if (StringUtils.isBlank(jsonCommand.json())) { throw new InvalidJsonException(); }
@@ -727,15 +895,35 @@ public class ShareAccountDataSerializer {
         JsonElement element = jsonCommand.parsedJson();
         LocalDate closedDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.closeddate_paramname, element);
         baseDataValidator.reset().parameter(ShareAccountApiConstants.approveddate_paramname).value(closedDate).notNull();
+        boolean isTransactionBeforeExistingTransactions = false ;
+        Set<ShareAccountTransaction> transactions = account.getShareAccountTransactions() ;
+        for(ShareAccountTransaction transaction: transactions) {
+            if(!transaction.isChargeTransaction()) {
+                LocalDate transactionDate = new LocalDate(transaction.getPurchasedDate()) ;
+                if(closedDate.isBefore(transactionDate)) {
+                    isTransactionBeforeExistingTransactions = true ;
+                    break ;
+                }    
+            }
+        }
+        if(isTransactionBeforeExistingTransactions) {
+            baseDataValidator.reset().parameter(ShareAccountApiConstants.closeddate_paramname)
+            .value(closedDate)
+            .failWithCodeNoParameterAddedToErrorCode("share.account.cannot.be.closed.before.existing.transactions");
+        }
+        
+        if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
+        
         AppUser approvedUser = this.platformSecurityContext.authenticatedUser();
-        final BigDecimal unitPrice = account.getShareProduct().deriveMarketPrice(DateUtils.getDateOfTenant()) ;
-        ShareAccountTransaction transaction = ShareAccountTransaction.createRedeemTransaction(closedDate.toDate(), account.getTotalApprovedShares(), unitPrice) ;
+        final BigDecimal unitPrice = account.getShareProduct().deriveMarketPrice(DateUtils.getDateOfTenant());
+        ShareAccountTransaction transaction = ShareAccountTransaction.createRedeemTransaction(closedDate.toDate(),
+                account.getTotalApprovedShares(), unitPrice);
         account.addAdditionalPurchasedShares(transaction);
         account.close(closedDate.toDate(), approvedUser);
-        handleRedeemSharesChargeTransactions(account, transaction) ;
+        handleRedeemSharesChargeTransactions(account, transaction);
         actualChanges.put(ShareAccountApiConstants.requestedshares_paramname, transaction);
         updateTotalChargeDerived(account);
-        if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
+       
         return actualChanges;
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/60588a78/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/PurchasedSharesReadPlatformService.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/PurchasedSharesReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/PurchasedSharesReadPlatformService.java
index 4f3b401..1f608bf 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/PurchasedSharesReadPlatformService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/PurchasedSharesReadPlatformService.java
@@ -20,9 +20,9 @@ package org.apache.fineract.portfolio.shareaccounts.service;
 
 import java.util.Collection;
 
-import org.apache.fineract.portfolio.shareaccounts.data.PurchasedSharesData;
+import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountTransactionData;
 
 public interface PurchasedSharesReadPlatformService {
 
-	public Collection<PurchasedSharesData> retrievePurchasedShares(final Long accountId) ;
+	public Collection<ShareAccountTransactionData> retrievePurchasedShares(final Long accountId) ;
 }

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/60588a78/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/PurchasedSharesReadPlatformServiceImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/PurchasedSharesReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/PurchasedSharesReadPlatformServiceImpl.java
index 5aa7f73..195e6d8 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/PurchasedSharesReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/PurchasedSharesReadPlatformServiceImpl.java
@@ -26,7 +26,7 @@ import java.util.Collection;
 import org.apache.fineract.infrastructure.core.data.EnumOptionData;
 import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
-import org.apache.fineract.portfolio.shareaccounts.data.PurchasedSharesData;
+import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountTransactionData;
 import org.joda.time.LocalDate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.jdbc.core.JdbcTemplate;
@@ -44,26 +44,27 @@ public class PurchasedSharesReadPlatformServiceImpl implements
 		this.jdbcTemplate = new JdbcTemplate(dataSource) ;
 	}
 	@Override
-	public Collection<PurchasedSharesData> retrievePurchasedShares(
+	public Collection<ShareAccountTransactionData> retrievePurchasedShares(
 			Long accountId) {
 		PurchasedSharesDataRowMapper mapper = new PurchasedSharesDataRowMapper() ;
-		final String sql = "select " + mapper.schema() + " where saps.account_id=?";
+		final String sql = "select " + mapper.schema() + " where saps.account_id=? and saps.is_active = 1";
 		return this.jdbcTemplate.query(sql, mapper, new Object[] { accountId});
 	}
 
-	private final static class PurchasedSharesDataRowMapper implements RowMapper<PurchasedSharesData> {
+	private final static class PurchasedSharesDataRowMapper implements RowMapper<ShareAccountTransactionData> {
 
 		private final String schema ;
 		
 		public PurchasedSharesDataRowMapper() {
 			StringBuffer buff = new StringBuffer()
 			.append("saps.id, saps.account_id, saps.transaction_date, saps.total_shares, saps.unit_price, ")
-			.append("saps.status_enum, saps.type_enum, saps.amount, saps.charge_amount as chargeamount ")
+			.append("saps.status_enum, saps.type_enum, saps.amount, saps.charge_amount as chargeamount, ")
+			.append("saps.amount_paid as amountPaid")
 			.append(" from m_share_account_transactions saps ");
 			schema = buff.toString() ;
 		}
 		@Override
-		public PurchasedSharesData mapRow(ResultSet rs, int rowNum)
+		public ShareAccountTransactionData mapRow(ResultSet rs, int rowNum)
 				throws SQLException {
 			final Long id = rs.getLong("id") ;
 			final Long accountId = rs.getLong("account_id") ;
@@ -76,7 +77,9 @@ public class PurchasedSharesReadPlatformServiceImpl implements
 			final EnumOptionData typeEnum = SharesEnumerations.purchasedSharesEnum(type) ;
 			final BigDecimal amount = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amount") ;
 			final BigDecimal chargeAmount = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "chargeamount") ;
-			return new PurchasedSharesData(id,accountId, purchasedDate, numberOfShares, purchasedPrice, statusEnum, typeEnum, amount, chargeAmount);
+			final BigDecimal amountPaid = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amountPaid") ;
+			
+			return new ShareAccountTransactionData(id,accountId, purchasedDate, numberOfShares, purchasedPrice, statusEnum, typeEnum, amount, chargeAmount, amountPaid);
 		}
 		
 		public String schema() {

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/60588a78/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountChargeReadPlatformServiceImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountChargeReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountChargeReadPlatformServiceImpl.java
index b4ddd96..66fb61e 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountChargeReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountChargeReadPlatformServiceImpl.java
@@ -80,6 +80,7 @@ public class ShareAccountChargeReadPlatformServiceImpl implements
 					.append("sc.charge_calculation_enum as chargeCalculation, c.is_active as isActive, ")
 					.append("c.currency_code as currencyCode, oc.name as currencyName, ")
 					.append("oc.decimal_places as currencyDecimalPlaces, oc.currency_multiplesof as inMultiplesOf, oc.display_symbol as currencyDisplaySymbol, ")
+					.append("sc.charge_amount_or_percentage, ")
 					.append("oc.internationalized_name_code as currencyNameCode from m_charge c ")
 					.append("join m_organisation_currency oc on c.currency_code = oc.code ")
 					.append("join m_share_account_charge sc on sc.charge_id = c.id ");
@@ -132,13 +133,14 @@ public class ShareAccountChargeReadPlatformServiceImpl implements
 			final EnumOptionData chargeCalculationType = ChargeEnumerations
 					.chargeCalculationType(chargeCalculation);
 			final Boolean isActive = rs.getBoolean("isActive");
-
+			final BigDecimal chargeamountorpercentage = rs.getBigDecimal("charge_amount_or_percentage") ;
+			
 			final Collection<ChargeData> chargeOptions = null;
 			return new ShareAccountChargeData(id, chargeId, accountId, name,
 					currency, amount, amountPaid, amountWaived,
 					amountWrittenOff, amountOutstanding, chargeTimeType,
 					chargeCalculationType, percentageOf,
-					amountPercentageAppliedTo, chargeOptions, isActive);
+					amountPercentageAppliedTo, chargeOptions, isActive, chargeamountorpercentage);
 		}
 
 		public String schema() {

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/60588a78/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountReadPlatformServiceImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountReadPlatformServiceImpl.java
index 3635aaa..90ab5b0 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountReadPlatformServiceImpl.java
@@ -42,9 +42,10 @@ import org.apache.fineract.portfolio.client.service.ClientReadPlatformService;
 import org.apache.fineract.portfolio.products.constants.ProductsApiConstants;
 import org.apache.fineract.portfolio.products.data.ProductData;
 import org.apache.fineract.portfolio.products.service.ProductReadPlatformService;
+import org.apache.fineract.portfolio.savings.DepositAccountType;
 import org.apache.fineract.portfolio.savings.data.SavingsAccountData;
 import org.apache.fineract.portfolio.savings.service.SavingsAccountReadPlatformService;
-import org.apache.fineract.portfolio.shareaccounts.data.PurchasedSharesData;
+import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountTransactionData;
 import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountApplicationTimelineData;
 import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountDividendData;
 import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountStatusEnumData;
@@ -114,7 +115,7 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat
             final Collection<EnumOptionData> minimumActivePeriodFrequencyTypeOptions = this.shareProductDropdownReadPlatformService
                     .retrieveMinimumActivePeriodFrequencyTypeOptions();
             final Collection<SavingsAccountData> clientSavingsAccounts = this.savingsAccountReadPlatformService
-                    .retrieveAllForLookup(clientId);
+                    .retrieveActiveForLookup(clientId, DepositAccountType.SAVINGS_DEPOSIT, productData.getCurrency().code());
             toReturn = new ShareAccountData(client.id(), client.displayName(), productData.getCurrency(), charges, marketPrice,
                     minimumActivePeriodFrequencyTypeOptions, lockinPeriodFrequencyTypeOptions, clientSavingsAccounts, productData.getNominaltShares());
         } else {
@@ -143,7 +144,7 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat
     @Override
     public ShareAccountData retrieveOne(final Long id, final boolean includeTemplate) {
         Collection<ShareAccountChargeData> charges = this.shareAccountChargeReadPlatformService.retrieveAccountCharges(id, "active");
-        Collection<PurchasedSharesData> purchasedShares = this.purchasedSharesReadPlatformService.retrievePurchasedShares(id);
+        Collection<ShareAccountTransactionData> purchasedShares = this.purchasedSharesReadPlatformService.retrievePurchasedShares(id);
         
         ShareAccountMapper mapper = new ShareAccountMapper(charges, purchasedShares);
         String query = "select " + mapper.schema() + "where sa.id=?";
@@ -161,8 +162,8 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat
             final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = this.shareProductDropdownReadPlatformService
                     .retrieveLockinPeriodFrequencyTypeOptions();
             final Collection<EnumOptionData> minimumActivePeriodFrequencyTypeOptions = lockinPeriodFrequencyTypeOptions;
-            final Collection<SavingsAccountData> clientSavingsAccounts = this.savingsAccountReadPlatformService.retrieveAllForLookup(data
-                    .getClientId());
+            final Collection<SavingsAccountData> clientSavingsAccounts = this.savingsAccountReadPlatformService
+                    .retrieveActiveForLookup(data.getClientId(), DepositAccountType.SAVINGS_DEPOSIT, productData.getCurrency().code());
             Collection<ProductData> productOptions = service.retrieveAllForLookup();
             final Collection<ChargeData> chargeOptions = this.chargeReadPlatformService.retrieveSharesApplicableCharges();
             data = ShareAccountData.template(data, productOptions, chargeOptions, clientSavingsAccounts, lockinPeriodFrequencyTypeOptions,
@@ -224,11 +225,11 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat
     private final static class ShareAccountMapper implements RowMapper<ShareAccountData> {
 
         private final Collection<ShareAccountChargeData> charges;
-        private final Collection<PurchasedSharesData> purchasedShares;
+        private final Collection<ShareAccountTransactionData> purchasedShares;
 
         private final String schema;
 
-        public ShareAccountMapper(final Collection<ShareAccountChargeData> charges, final Collection<PurchasedSharesData> purchasedShares) {
+        public ShareAccountMapper(final Collection<ShareAccountChargeData> charges, final Collection<ShareAccountTransactionData> purchasedShares) {
             this.charges = charges;
             this.purchasedShares = purchasedShares;
             StringBuffer buff = new StringBuffer()
@@ -392,7 +393,7 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat
             final Boolean allowdividendsforinactiveclients = null;
 
             final Collection<ShareAccountChargeData> charges = null;
-            final Collection<PurchasedSharesData> purchasedSharesData = new ArrayList<>();
+            final Collection<ShareAccountTransactionData> purchasedSharesData = new ArrayList<>();
             final Integer lockinPeriod = null;
             final EnumOptionData lockPeriodTypeEnum = null;
             final Integer minimumActivePeriod = null;
@@ -418,19 +419,21 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat
         }
     }
 
-    private final static class PurchasedSharesDataRowMapper implements RowMapper<PurchasedSharesData> {
+    private final static class PurchasedSharesDataRowMapper implements RowMapper<ShareAccountTransactionData> {
 
         private final String schema;
 
         public PurchasedSharesDataRowMapper() {
             StringBuffer buff = new StringBuffer()
                     .append("saps.id as purchasedId, saps.account_id as accountId, saps.transaction_date as transactionDate, saps.total_shares as purchasedShares, saps.unit_price as unitPrice, ")
-                    .append("saps.status_enum as purchaseStatus, saps.type_enum as purchaseType, saps.amount as amount, saps.charge_amount as chargeamount ");
+                    .append("saps.status_enum as purchaseStatus, saps.type_enum as purchaseType, saps.amount as amount, saps.charge_amount as chargeamount, ")
+                    .append("saps.amount_paid as amountPaid ");
+            
             schema = buff.toString();
         }
 
         @Override
-        public PurchasedSharesData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException {
+        public ShareAccountTransactionData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException {
             final Long id = rs.getLong("purchasedId");
             final Long accountId = rs.getLong("accountId");
             final LocalDate transactionDate = new LocalDate(rs.getDate("transactionDate"));
@@ -442,8 +445,9 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat
             final EnumOptionData typeEnum = SharesEnumerations.purchasedSharesEnum(type);
             final BigDecimal amount = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "amount");
             final BigDecimal chargeAmount = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "chargeamount");
-            return new PurchasedSharesData(id, accountId, transactionDate, numberOfShares, purchasedPrice, statusEnum, typeEnum, amount,
-                    chargeAmount);
+            final BigDecimal amountPaid = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "amountPaid");
+            return new ShareAccountTransactionData(id, accountId, transactionDate, numberOfShares, purchasedPrice, statusEnum, typeEnum, amount,
+                    chargeAmount, amountPaid);
         }
 
         public String schema() {

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/60588a78/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountWritePlatformServiceJpaRepositoryImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountWritePlatformServiceJpaRepositoryImpl.java
index daad3be..e97f6e3 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountWritePlatformServiceJpaRepositoryImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountWritePlatformServiceJpaRepositoryImpl.java
@@ -18,7 +18,9 @@
  */
 package org.apache.fineract.portfolio.shareaccounts.service;
 
+import java.math.BigDecimal;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -32,6 +34,7 @@ import org.apache.fineract.infrastructure.accountnumberformat.domain.EntityAccou
 import org.apache.fineract.infrastructure.core.api.JsonCommand;
 import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
 import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
+import org.apache.fineract.infrastructure.core.service.DateUtils;
 import org.apache.fineract.organisation.monetary.data.CurrencyData;
 import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
 import org.apache.fineract.portfolio.accounts.constants.ShareAccountApiConstants;
@@ -42,6 +45,8 @@ import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccountChargePaid
 import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccountRepositoryWrapper;
 import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccountTransaction;
 import org.apache.fineract.portfolio.shareaccounts.serialization.ShareAccountDataSerializer;
+import org.apache.fineract.portfolio.shareproducts.domain.ShareProduct;
+import org.apache.fineract.portfolio.shareproducts.domain.ShareProductRepositoryWrapper;
 import org.joda.time.LocalDate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.dao.DataIntegrityViolationException;
@@ -54,6 +59,8 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA
 
     private final ShareAccountRepositoryWrapper shareAccountRepository;
 
+    private final ShareProductRepositoryWrapper shareProductRepository ;
+    
     private final AccountNumberGenerator accountNumberGenerator;
 
     private final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository;
@@ -62,12 +69,14 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA
 
     @Autowired
     public ShareAccountWritePlatformServiceJpaRepositoryImpl(final ShareAccountDataSerializer accountDataSerializer,
-            final ShareAccountRepositoryWrapper shareAccountRepository,
+            final ShareAccountRepositoryWrapper shareAccountRepository, 
+            final ShareProductRepositoryWrapper shareProductRepository,
             final AccountNumberGenerator accountNumberGenerator,
             final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository,
             final JournalEntryWritePlatformService journalEntryWritePlatformService) {
         this.accountDataSerializer = accountDataSerializer;
         this.shareAccountRepository = shareAccountRepository;
+        this.shareProductRepository = shareProductRepository ;
         this.accountNumberGenerator = accountNumberGenerator;
         this.accountNumberFormatRepository = accountNumberFormatRepository;
         this.journalEntryWritePlatformService = journalEntryWritePlatformService;
@@ -79,7 +88,6 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA
             ShareAccount account = this.accountDataSerializer.validateAndCreate(jsonCommand);
             this.shareAccountRepository.save(account);
             generateAccountNumber(account);
-            //this.shareProductRepository.save(account.getShareProduct()); //subscribed shares is increased
             journalEntryWritePlatformService.createJournalEntriesForShares(populateJournalEntries(account,
                     account.getPendingForApprovalSharePurchaseTransactions()));
             return new CommandProcessingResultBuilder() //
@@ -126,7 +134,16 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA
             final ShareAccountTransactionEnumData typeEnum = new ShareAccountTransactionEnumData(type.longValue(), null, null);
             transactionDto.put("status", statusEnum);
             transactionDto.put("type", typeEnum);
-            transactionDto.put("amount", transaction.amount());
+            if(transaction.isPurchaseRejectedTransaction() || transaction.isRedeemTransaction()) {
+                BigDecimal amount = transaction.amount() ;
+                if(transaction.chargeAmount() != null) {
+                    amount = amount.add(transaction.chargeAmount()) ;
+                }
+                transactionDto.put("amount", amount);
+            }else {
+                transactionDto.put("amount", transaction.amount());    
+            }
+            
             transactionDto.put("chargeAmount", transaction.chargeAmount());
             transactionDto.put("paymentTypeId", null); // FIXME::make it cash
                                                        // payment
@@ -147,14 +164,24 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA
         return accountingBridgeData;
     }
 
+    @SuppressWarnings("unchecked")
     @Override
     public CommandProcessingResult updateShareAccount(Long accountId, JsonCommand jsonCommand) {
         try {
+            Date transactionDate = DateUtils.getDateOfTenant();
             ShareAccount account = this.shareAccountRepository.findOneWithNotFoundDetection(accountId);
             Map<String, Object> changes = this.accountDataSerializer.validateAndUpdate(jsonCommand, account);
             if (!changes.isEmpty()) {
                 this.shareAccountRepository.save(account);
             }
+            // since we are reverting all journal entries we need to add journal
+            // entries for application request
+            if (changes.containsKey("reversalIds")) {
+                ArrayList<Long> reversalIds = (ArrayList<Long>) changes.get("reversalIds");
+                this.journalEntryWritePlatformService.revertShareAccountJournalEntries(reversalIds, transactionDate);
+                journalEntryWritePlatformService.createJournalEntriesForShares(populateJournalEntries(account,
+                        account.getPendingForApprovalSharePurchaseTransactions()));
+            }
             return new CommandProcessingResultBuilder() //
                     .withCommandId(jsonCommand.commandId()) //
                     .withEntityId(accountId) //
@@ -205,8 +232,21 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA
             if (!changes.isEmpty()) {
                 this.shareAccountRepository.save(account);
             }
-            this.journalEntryWritePlatformService.createJournalEntriesForShares(populateJournalEntries(account,
-                    account.getShareAccountTransactions()));
+            Set<ShareAccountTransaction> transactions = account.getShareAccountTransactions();
+            Set<ShareAccountTransaction> journalTransactions = new HashSet<>();
+            Long totalSubsribedShares = new Long(0) ;
+            
+            for (ShareAccountTransaction transaction : transactions) {
+                if (transaction.isActive() && transaction.isPurchasTransaction()) {
+                    journalTransactions.add(transaction);
+                    totalSubsribedShares += transaction.getTotalShares() ;
+                }
+            }
+            ShareProduct shareProduct = account.getShareProduct() ;
+            shareProduct.addSubscribedShares(totalSubsribedShares);
+            this.shareProductRepository.save(shareProduct);
+            
+            this.journalEntryWritePlatformService.createJournalEntriesForShares(populateJournalEntries(account, journalTransactions));
             return new CommandProcessingResultBuilder() //
                     .withCommandId(jsonCommand.commandId()) //
                     .withEntityId(accountId) //
@@ -226,8 +266,14 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA
             if (!changes.isEmpty()) {
                 this.shareAccountRepository.save(account);
             }
-            this.journalEntryWritePlatformService.createJournalEntriesForShares(populateJournalEntries(account,
-                    account.getShareAccountTransactions()));
+            Set<ShareAccountTransaction> transactions = account.getShareAccountTransactions();
+            Set<ShareAccountTransaction> journalTransactions = new HashSet<>();
+            for (ShareAccountTransaction transaction : transactions) {
+                if (transaction.isActive() && !transaction.isChargeTransaction()) {
+                    journalTransactions.add(transaction);
+                }
+            }
+            this.journalEntryWritePlatformService.createJournalEntriesForShares(populateJournalEntries(account, journalTransactions));
             return new CommandProcessingResultBuilder() //
                     .withCommandId(jsonCommand.commandId()) //
                     .withEntityId(accountId) //
@@ -247,11 +293,18 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA
             if (!changes.isEmpty()) {
                 this.shareAccountRepository.save(account);
             }
-            /*
-             * this.journalEntryWritePlatformService.createJournalEntriesForShares
-             * (populateJournalEntries(account,
-             * account.getShareAccountTransactions()));
-             */
+            
+            Set<ShareAccountTransaction> transactions = account.getShareAccountTransactions() ;
+            ArrayList<Long> journalEntryTransactions = new ArrayList<>() ;
+            for(ShareAccountTransaction transaction: transactions) {
+                if(transaction.isActive() && !transaction.isChargeTransaction()){
+                    journalEntryTransactions.add(transaction.getId()) ;
+                }
+            }
+            Date transactionDate = DateUtils.getDateOfTenant();
+            this.journalEntryWritePlatformService.revertShareAccountJournalEntries(journalEntryTransactions, transactionDate);
+            journalEntryWritePlatformService.createJournalEntriesForShares(populateJournalEntries(account,
+                    account.getPendingForApprovalSharePurchaseTransactions()));
             return new CommandProcessingResultBuilder() //
                     .withCommandId(jsonCommand.commandId()) //
                     .withEntityId(accountId) //
@@ -285,6 +338,7 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA
         }
     }
 
+    @SuppressWarnings("unchecked")
     @Override
     public CommandProcessingResult approveAdditionalShares(Long accountId, JsonCommand jsonCommand) {
 
@@ -294,14 +348,21 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA
             if (!changes.isEmpty()) {
                 this.shareAccountRepository.save(account);
                 ArrayList<Long> transactionIds = (ArrayList<Long>) changes.get(ShareAccountApiConstants.requestedshares_paramname);
+                Long totalSubscribedShares = new Long(0) ;
                 if (transactionIds != null) {
                     Set<ShareAccountTransaction> transactions = new HashSet<>();
                     for (Long id : transactionIds) {
                         ShareAccountTransaction transaction = account.retrievePurchasedShares(id);
                         transactions.add(transaction);
+                        totalSubscribedShares += transaction.getTotalShares() ;
                     }
                     this.journalEntryWritePlatformService.createJournalEntriesForShares(populateJournalEntries(account, transactions));
                 }
+                if(!totalSubscribedShares.equals(new Long(0))) {
+                    ShareProduct shareProduct = account.getShareProduct() ;
+                    shareProduct.addSubscribedShares(totalSubscribedShares);
+                    this.shareProductRepository.save(shareProduct);
+                }
             }
             return new CommandProcessingResultBuilder() //
                     .withCommandId(jsonCommand.commandId()) //
@@ -314,9 +375,9 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA
         }
     }
 
+    @SuppressWarnings("unchecked")
     @Override
     public CommandProcessingResult rejectAdditionalShares(Long accountId, JsonCommand jsonCommand) {
-
         try {
             ShareAccount account = this.shareAccountRepository.findOneWithNotFoundDetection(accountId);
             Map<String, Object> changes = this.accountDataSerializer.validateAndRejectAddtionalShares(jsonCommand, account);
@@ -352,7 +413,21 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA
                 this.shareAccountRepository.save(account);
                 ShareAccountTransaction transaction = (ShareAccountTransaction) changes
                         .get(ShareAccountApiConstants.requestedshares_paramname);
-                transaction = account.getShareAccountTransaction(transaction);
+                transaction = account.getShareAccountTransaction(transaction); // after
+                                                                               // saving,
+                                                                               // entity
+                                                                               // will
+                                                                               // have
+                                                                               // different
+                                                                               // object.
+                                                                               // So
+                                                                               // need
+                                                                               // to
+                                                                               // retrieve
+                                                                               // to
+                                                                               // get
+                                                                               // the
+                                                                               // id
                 Set<ShareAccountTransaction> transactions = new HashSet<>();
                 transactions.add(transaction);
                 this.journalEntryWritePlatformService.createJournalEntriesForShares(populateJournalEntries(account, transactions));
@@ -398,6 +473,7 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA
             return CommandProcessingResult.empty();
         }
     }
+
     private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) {
 
     }

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/60588a78/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/domain/ShareProduct.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/domain/ShareProduct.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/domain/ShareProduct.java
index 4fee7ef..6cf301e 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/domain/ShareProduct.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/domain/ShareProduct.java
@@ -226,7 +226,10 @@ public class ShareProduct extends AbstractAuditableCustom<AppUser, Long> {
 
     public boolean setTotalIssuedShares(Long totalSharesIssued) {
         boolean returnValue = false;
-        if (!this.totalSharesIssued.equals(totalSharesIssued)) {
+        if(this.totalSharesIssued == null) {
+            this.totalSharesIssued = totalSharesIssued ;
+            returnValue = true ;
+        }else if (!this.totalSharesIssued.equals(totalSharesIssued)) {
             this.totalSharesIssued = totalSharesIssued;
             returnValue = true;
         }
@@ -430,5 +433,16 @@ public class ShareProduct extends AbstractAuditableCustom<AppUser, Long> {
     public Long getSubscribedShares() {
         return this.totalSubscribedShares ;
     }
+ 
+    public Long getMinimumClientShares() {
+        return this.minimumShares ;
+    }
+    
+    public Long getMaximumClientShares() {
+        return this.maximumShares ;
+    }
     
+    public Long getDefaultClientShares() {
+        return this.nominalShares ;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/60588a78/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/exception/ShareAccountsNotFoundException.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/exception/ShareAccountsNotFoundException.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/exception/ShareAccountsNotFoundException.java
new file mode 100644
index 0000000..71b59bc
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/exception/ShareAccountsNotFoundException.java
@@ -0,0 +1,29 @@
+/**
+ * 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.shareproducts.exception;
+
+import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
+
+
+public class ShareAccountsNotFoundException extends AbstractPlatformResourceNotFoundException{
+
+    public ShareAccountsNotFoundException(final Long productId) {
+        super("error.msg.shareproduct.shareaccounts.not.defined", " No Share Accounts found for this prodct " + productId, productId);
+    }
+}


Mime
View raw message