You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by na...@apache.org on 2016/04/20 07:30:49 UTC
[2/3] incubator-fineract git commit: Issue fixes on shares and
dividends reported by QA
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);
+ }
+}