http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/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 new file mode 100644 index 0000000..13c7b4d --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/serialization/ShareAccountDataSerializer.java @@ -0,0 +1,741 @@ +/** + * 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.shareaccounts.serialization; + +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.apache.fineract.infrastructure.core.api.JsonCommand; +import org.apache.fineract.infrastructure.core.data.ApiParameterError; +import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder; +import org.apache.fineract.infrastructure.core.exception.InvalidJsonException; +import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException; +import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper; +import org.apache.fineract.infrastructure.core.service.DateUtils; +import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; +import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; +import org.apache.fineract.organisation.monetary.domain.Money; +import org.apache.fineract.portfolio.accounts.constants.ShareAccountApiConstants; +import org.apache.fineract.portfolio.charge.domain.Charge; +import org.apache.fineract.portfolio.charge.domain.ChargeCalculationType; +import org.apache.fineract.portfolio.charge.domain.ChargeRepositoryWrapper; +import org.apache.fineract.portfolio.charge.domain.ChargeTimeType; +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; +import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccountCharge; +import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccountChargePaidBy; +import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccountTransaction; +import org.apache.fineract.portfolio.shareproducts.domain.ShareProduct; +import org.apache.fineract.portfolio.shareproducts.domain.ShareProductRepositoryWrapper; +import org.apache.fineract.useradministration.domain.AppUser; +import org.joda.time.LocalDate; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.reflect.TypeToken; + +@Service +public class ShareAccountDataSerializer { + + private final PlatformSecurityContext platformSecurityContext; + + private final FromJsonHelper fromApiJsonHelper; + + private final ChargeRepositoryWrapper chargeRepository; + + private final SavingsAccountRepositoryWrapper savingsAccountRepositoryWrapper; + + private final ClientRepositoryWrapper clientRepositoryWrapper; + + private final ShareProductRepositoryWrapper shareProductRepository; + + @Autowired + public ShareAccountDataSerializer(final PlatformSecurityContext platformSecurityContext, final FromJsonHelper fromApiJsonHelper, + final ChargeRepositoryWrapper chargeRepository, + final SavingsAccountRepositoryWrapper savingsAccountRepositoryWrapper, final ClientRepositoryWrapper clientRepositoryWrapper, + final ShareProductRepositoryWrapper shareProductRepository) { + this.platformSecurityContext = platformSecurityContext; + this.fromApiJsonHelper = fromApiJsonHelper; + this.chargeRepository = chargeRepository; + this.savingsAccountRepositoryWrapper = savingsAccountRepositoryWrapper; + this.clientRepositoryWrapper = clientRepositoryWrapper; + this.shareProductRepository = shareProductRepository; + } + + public ShareAccount validateAndCreate(JsonCommand jsonCommand) { + + if (StringUtils.isBlank(jsonCommand.json())) { throw new InvalidJsonException(); } + final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType(); + this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, jsonCommand.json(), ShareAccountApiConstants.supportedParameters); + + final List<ApiParameterError> dataValidationErrors = new ArrayList<>(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("sharesaccount"); + JsonElement element = jsonCommand.parsedJson(); + + final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(element.getAsJsonObject()); + final Long clientId = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.clientid_paramname, element); + final Long productId = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.productid_paramname, element); + ShareProduct shareProduct = this.shareProductRepository.findOneWithNotFoundDetection(productId); + final LocalDate submittedDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.submitteddate_paramname, + element); + 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(); + + Long savingsAccountId = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.savingsaccountid_paramname, element); + baseDataValidator.reset().parameter(ShareAccountApiConstants.savingsaccountid_paramname).value(savingsAccountId).notNull() + .longGreaterThanZero(); + + 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");; + } + + /*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);*/ + + /*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(); + + Boolean allowdividendsForInactiveClients = this.fromApiJsonHelper.extractBooleanNamed( + ShareAccountApiConstants.allowdividendcalculationforinactiveclients_paramname, element); + + Integer minimumActivePeriod = this.fromApiJsonHelper.extractIntegerNamed(ShareAccountApiConstants.minimumactiveperiod_paramname, + element, locale); + PeriodFrequencyType minimumActivePeriodEnum = extractPeriodType( + ShareAccountApiConstants.minimumactiveperiodfrequencytype_paramname, element); + + if (minimumActivePeriod != null) { + baseDataValidator.reset().parameter(ShareAccountApiConstants.minimumactiveperiodfrequencytype_paramname) + .value(minimumActivePeriodEnum.getValue()).integerSameAsNumber(PeriodFrequencyType.DAYS.getValue()); + } + + Integer lockinPeriod = this.fromApiJsonHelper.extractIntegerNamed(ShareAccountApiConstants.lockinperiod_paramname, element, locale); + PeriodFrequencyType lockPeriodEnum = extractPeriodType(ShareAccountApiConstants.lockperiodfrequencytype_paramname, element); + + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); } + + Client client = this.clientRepositoryWrapper.findOneWithNotFoundDetection(clientId); + SavingsAccount savingsAccount = this.savingsAccountRepositoryWrapper.findOneWithNotFoundDetection(savingsAccountId); + final MonetaryCurrency currency = shareProduct.getCurrency(); + Set<ShareAccountCharge> charges = assembleListOfAccountCharges(element, currency.getCode()); + + AppUser submittedBy = platformSecurityContext.authenticatedUser(); + AppUser approvedBy = null; + Date approvedDate = null; + AppUser rejectedBy = null; + Date rejectedDate = null; + AppUser activatedBy = null; + Date activatedDate = null; + AppUser closedBy = null; + Date closedDate = null; + AppUser modifiedBy = null; + Date modifiedDate = null; + String accountNo = null; + Long approvedShares = null; + Long pendingShares = requestedShares; + BigDecimal unitPrice = shareProduct.deriveMarketPrice(applicationDate.toDate()) ; + ShareAccountTransaction transaction = new ShareAccountTransaction(applicationDate.toDate(), requestedShares, unitPrice); + Set<ShareAccountTransaction> sharesPurchased = new HashSet<>(); + sharesPurchased.add(transaction); + + ShareAccount account = new ShareAccount(client, shareProduct, externalId, currency, savingsAccount, accountNo, approvedShares, + pendingShares, sharesPurchased, allowdividendsForInactiveClients, lockinPeriod, lockPeriodEnum, minimumActivePeriod, + minimumActivePeriodEnum, charges, submittedBy, submittedDate.toDate(), approvedBy, approvedDate, rejectedBy, rejectedDate, + activatedBy, activatedDate, closedBy, closedDate, modifiedBy, modifiedDate); + + for (ShareAccountTransaction pur : sharesPurchased) { + pur.setShareAccount(account); + } + + if (charges != null) { + for (ShareAccountCharge charge : charges) { + charge.update(account); + } + } + createChargeTransaction(account, transaction); + return account; + } + + private void createChargeTransaction(ShareAccount account, final ShareAccountTransaction transaction) { + BigDecimal totalChargeAmount = BigDecimal.ZERO; + Set<ShareAccountCharge> charges = account.getCharges(); + Date currentDate = DateUtils.getLocalDateOfTenant().toDate(); + for (ShareAccountCharge charge : charges) { + if (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()) { + BigDecimal amount = charge.deriveChargeAmount(pending.amount()); + ShareAccountChargePaidBy paidBy = new ShareAccountChargePaidBy(pending, charge, amount); + pending.addShareAccountChargePaidBy(paidBy); + totalChargeAmount = totalChargeAmount.add(amount); + } + } + pending.updateChargeAmount(totalChargeAmount); + } + } + + public Map<String, Object> validateAndUpdate(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.supportedParameters); + + final List<ApiParameterError> dataValidationErrors = new ArrayList<>(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("sharesaccount"); + JsonElement element = jsonCommand.parsedJson(); + 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); + shareProduct = this.shareProductRepository.findOneWithNotFoundDetection(productId); + if (account.setShareProduct(shareProduct)) { + actualChanges.put(ShareAccountApiConstants.productid_paramname, productId); + } + } + + if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.submitteddate_paramname, element)) { + final Date submittedDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.submitteddate_paramname, + element).toDate(); + baseDataValidator.reset().parameter(ShareAccountApiConstants.submitteddate_paramname).value(submittedDate).notNull(); + if (account.setSubmittedDate(submittedDate)) { + actualChanges.put(ShareAccountApiConstants.submitteddate_paramname, submittedDate); + } + } + + 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(); + if (account.setExternalId(externalId)) { + actualChanges.put(ShareAccountApiConstants.externalid_paramname, externalId); + } + } + + 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); + } + } + + 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);*/ + 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");; + } + } + + if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.allowdividendcalculationforinactiveclients_paramname, element)) { + Boolean allowdividendsForInactiveClients = this.fromApiJsonHelper.extractBooleanNamed( + ShareAccountApiConstants.allowdividendcalculationforinactiveclients_paramname, element); + if (account.setAllowDividendCalculationForInactiveClients(allowdividendsForInactiveClients)) { + actualChanges.put(ShareAccountApiConstants.allowdividendcalculationforinactiveclients_paramname, + allowdividendsForInactiveClients); + } + } + + if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.lockinperiod_paramname, element)) { + final Integer lockinperiod = this.fromApiJsonHelper.extractIntegerNamed(ShareAccountApiConstants.lockinperiod_paramname, + element, locale); + baseDataValidator.reset().parameter(ShareAccountApiConstants.lockinperiod_paramname).value(lockinperiod).notNull(); + if (account.setLockPeriod(lockinperiod)) { + actualChanges.put(ShareAccountApiConstants.lockinperiod_paramname, lockinperiod); + } + } + + if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.lockperiodfrequencytype_paramname, element)) { + PeriodFrequencyType lockPeriod = extractPeriodType(ShareAccountApiConstants.lockperiodfrequencytype_paramname, element); + if (account.setLockPeriodFrequencyEnum(lockPeriod)) { + actualChanges.put(ShareAccountApiConstants.lockperiodfrequencytype_paramname, lockPeriod); + } + } + + if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.minimumactiveperiod_paramname, element)) { + final Integer minimumActivePeriod = this.fromApiJsonHelper.extractIntegerNamed( + ShareAccountApiConstants.minimumactiveperiod_paramname, element, locale); + baseDataValidator.reset().parameter(ShareAccountApiConstants.minimumactiveperiod_paramname).value(minimumActivePeriod) + .notNull(); + if (account.setminimumActivePeriod(minimumActivePeriod)) { + actualChanges.put(ShareAccountApiConstants.minimumactiveperiod_paramname, minimumActivePeriod); + } + } + + if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.minimumactiveperiodfrequencytype_paramname, element)) { + PeriodFrequencyType minimumActivePeriod = extractPeriodType( + ShareAccountApiConstants.minimumactiveperiodfrequencytype_paramname, element); + if (account.setminimumActivePeriodTypeEnum(minimumActivePeriod)) { + actualChanges.put(ShareAccountApiConstants.minimumactiveperiodfrequencytype_paramname, minimumActivePeriod); + } + } + 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>()); + } + + } + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); } + return actualChanges; + } + + @SuppressWarnings("null") + public Map<String, Object> validateAndApprove(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.approvalParameters); + final List<ApiParameterError> dataValidationErrors = new ArrayList<>(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("sharesaccount"); + JsonElement element = jsonCommand.parsedJson(); + LocalDate approvedDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.approveddate_paramname, element); + final LocalDate submittalDate = new LocalDate(account.getSubmittedDate()); + if (approvedDate != null && approvedDate.isBefore(submittalDate)) { + 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"); + } + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); } + + AppUser approvedUser = this.platformSecurityContext.authenticatedUser(); + account.approve(approvedDate.toDate(), approvedUser); + actualChanges.put(ShareAccountApiConstants.id_paramname, account.getId()); + updateTotalChargeDerived(account); + return actualChanges; + } + + 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); + } + } + } + } + } + + public Map<String, Object> validateAndUndoApprove(JsonCommand jsonCommand, ShareAccount account) { + Map<String, Object> actualChanges = new HashMap<>(); + if (StringUtils.isBlank(jsonCommand.json())) { throw new InvalidJsonException(); } + //final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType(); + //this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, jsonCommand.json(), ShareAccountApiConstants.activateParameters); + //final List<ApiParameterError> dataValidationErrors = new ArrayList<>(); + //final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("sharesaccount"); + //JsonElement element = jsonCommand.parsedJson(); + //String notes = this.fromApiJsonHelper.extractStringNamed(ShareAccountApiConstants.note_paramname, element); + // baseDataValidator.reset().parameter(ShareAccountApiConstants.approveddate_paramname).validateDateAfter(account.get) + //AppUser approvedUser = this.platformSecurityContext.authenticatedUser(); + account.undoApprove(); + actualChanges.put(ShareAccountApiConstants.charges_paramname, Boolean.TRUE); + return actualChanges; + } + + @SuppressWarnings("unused") + public Map<String, Object> validateAndReject(JsonCommand jsonCommand, ShareAccount account) { + Map<String, Object> actualChanges = new HashMap<>(); + AppUser rejectedUser = this.platformSecurityContext.authenticatedUser(); + Date rejectedDate = DateUtils.getDateOfTenant(); + account.reject(rejectedDate, rejectedUser); + actualChanges.put(ShareAccountApiConstants.charges_paramname, Boolean.TRUE); + return actualChanges; + } + + @SuppressWarnings("null") + public Map<String, Object> validateAndActivate(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(); + LocalDate activatedDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.activatedate_paramname, element); + baseDataValidator.reset().parameter(ShareAccountApiConstants.activatedate_paramname).value(activatedDate).notNull(); + final LocalDate approvedDate = new LocalDate(account.getApprovedDate()); + if (activatedDate != null && activatedDate.isBefore(approvedDate)) { + final DateTimeFormatter formatter = DateTimeFormat.forPattern(jsonCommand.dateFormat()).withLocale(jsonCommand.extractLocale()); + final String submittalDateAsString = formatter.print(approvedDate); + baseDataValidator.reset().parameter(ShareAccountApiConstants.activatedate_paramname).value(submittalDateAsString) + .failWithCodeNoParameterAddedToErrorCode("cannot.be.before.approved.date"); + } + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); } + AppUser approvedUser = this.platformSecurityContext.authenticatedUser(); + account.activate(activatedDate.toDate(), approvedUser); + handlechargesOnActivation(account); + actualChanges.put(ShareAccountApiConstants.charges_paramname, activatedDate.toDate()); + return actualChanges; + } + + private void handlechargesOnActivation(final ShareAccount account) { + Set<ShareAccountCharge> charges = account.getCharges(); + for (ShareAccountCharge charge : charges) { + if (charge.isShareAccountActivation()) { + charge.markAsFullyPaid(); + } + } + } + + private Set<ShareAccountCharge> assembleListOfAccountCharges(final JsonElement element, final String currencyCode) { + final Set<ShareAccountCharge> charges = 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("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 = null; + ChargeCalculationType chargeCalculation = null; + Boolean status = Boolean.TRUE; + ShareAccountCharge accountCharge = ShareAccountCharge.createNewWithoutShareAccount(charge, amount, chargeTime, + chargeCalculation, status); + charges.add(accountCharge); + } + } + } + } + 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)); + return frequencyType; + } + + public Map<String, Object> validateAndApplyAddtionalShares(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.addtionalSharesParameters); + final List<ApiParameterError> dataValidationErrors = new ArrayList<>(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("sharesaccount"); + JsonElement element = jsonCommand.parsedJson(); + LocalDate requestedDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.requesteddate_paramname, element); + baseDataValidator.reset().parameter(ShareAccountApiConstants.requesteddate_paramname).value(requestedDate).notNull(); + final Long sharesRequested = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.requestedshares_paramname, element); + 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");; + } + } + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); } + final BigDecimal unitPrice = shareProduct.deriveMarketPrice(requestedDate.toDate()) ; + ShareAccountTransaction purchaseTransaction = new ShareAccountTransaction(requestedDate.toDate(), sharesRequested, unitPrice); + account.addAdditionalPurchasedShares(purchaseTransaction); + handleAdditionalSharesChargeTransactions(account, purchaseTransaction); + actualChanges.put(ShareAccountApiConstants.additionalshares_paramname, purchaseTransaction); + return actualChanges; + } + + private void handleAdditionalSharesChargeTransactions(final ShareAccount account, final ShareAccountTransaction purchaseTransaction) { + Set<ShareAccountCharge> charges = account.getCharges(); + BigDecimal totalChargeAmount = BigDecimal.ZERO; + for (ShareAccountCharge charge : charges) { + if (charge.isSharesPurchaseCharge()) { + BigDecimal amount = charge.updateChargeDetailsForAdditionalSharesRequest(purchaseTransaction.amount()); + ShareAccountChargePaidBy paidBy = new ShareAccountChargePaidBy(purchaseTransaction, charge, amount); + purchaseTransaction.addShareAccountChargePaidBy(paidBy); + totalChargeAmount = totalChargeAmount.add(amount); + } + } + purchaseTransaction.updateChargeAmount(totalChargeAmount); + } + + public Map<String, Object> validateAndApproveAddtionalShares(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.addtionalSharesParameters); + final List<ApiParameterError> dataValidationErrors = new ArrayList<>(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("sharesaccount"); + JsonElement element = jsonCommand.parsedJson(); + 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 ; + for (JsonElement arrayElement : array) { + final Long purchasedSharesId = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.id_paramname, arrayElement); + baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname).value(purchasedSharesId).notBlank() ; + ShareAccountTransaction transaction = account.retrievePurchasedShares(purchasedSharesId); + if (transaction != null) { + totalShares+=transaction.getTotalShares().longValue() ; + transaction.approve(); + updateTotalChargeDerivedForAdditonalShares(account, transaction); + } + purchasedShares.add(purchasedSharesId); + } + if(totalShares > 0) { + account.updateApprovedShares(new Long(totalShares)) ; + } + } + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); } + actualChanges.put(ShareAccountApiConstants.requestedshares_paramname, purchasedShares); + return actualChanges; + } + + private void updateTotalChargeDerivedForAdditonalShares(final ShareAccount shareAccount, final ShareAccountTransaction transaction) { + 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); + } + } + } + } + + public Map<String, Object> validateAndRejectAddtionalShares(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.addtionalSharesParameters); + JsonElement element = jsonCommand.parsedJson(); + final ArrayList<Long> purchasedShares = new ArrayList<>(); + if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.requestedshares_paramname, element)) { + 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() ; + } + purchasedShares.add(purchasedSharesId); + } + if(totalShares > 0) { + account.removePendingShares(new Long(totalShares)) ; + } + } + actualChanges.put(ShareAccountApiConstants.requestedshares_paramname, purchasedShares); + return actualChanges; + } + + private void updateTotalChargeDerivedForAdditonalSharesReject(final ShareAccount shareAccount, final ShareAccountTransaction transaction) { + 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); + } + } + } + } + + public Map<String, Object> validateAndRedeemShares(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.addtionalSharesParameters); + final List<ApiParameterError> dataValidationErrors = new ArrayList<>(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("sharesaccount"); + JsonElement element = jsonCommand.parsedJson(); + LocalDate requestedDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.requesteddate_paramname, element); + baseDataValidator.reset().parameter(ShareAccountApiConstants.requesteddate_paramname).value(requestedDate).notNull(); + final Long sharesRequested = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.requestedshares_paramname, element); + baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname).value(sharesRequested).notNull() + .longGreaterThanZero(); + + final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(element.getAsJsonObject()); + final BigDecimal unitPrice = this.fromApiJsonHelper.extractBigDecimalNamed(ShareAccountApiConstants.purchasedprice_paramname, + element, locale); + baseDataValidator.reset().parameter(ShareAccountApiConstants.purchasedprice_paramname).value(unitPrice).notNull().positiveAmount(); + ShareAccountTransaction transaction = ShareAccountTransaction.createRedeemTransaction(requestedDate.toDate(), sharesRequested, + unitPrice); + account.addAdditionalPurchasedShares(transaction); + actualChanges.put(ShareAccountApiConstants.requestedshares_paramname, transaction); + handleRedeemSharesChargeTransactions(account, transaction); + return actualChanges; + } + + 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()) { + BigDecimal amount = charge.updateChargeDetailsForAdditionalSharesRequest(transaction.amount()); + ShareAccountChargePaidBy paidBy = new ShareAccountChargePaidBy(transaction, charge, amount); + transaction.addShareAccountChargePaidBy(paidBy); + totalChargeAmount = totalChargeAmount.add(amount); + } + } + transaction.deductChargesFromTotalAmount(totalChargeAmount); + Set<ShareAccountChargePaidBy> paidBySet = transaction.getChargesPaidBy(); + if (paidBySet != null && !paidBySet.isEmpty()) { + for (ShareAccountChargePaidBy chargePaidBy : paidBySet) { + ShareAccountCharge charge = chargePaidBy.getCharge(); + if (charge.isSharesRedeemCharge()) { + Money money = Money.of(account.getCurrency(), chargePaidBy.getAmount()); + charge.updatePaidAmountBy(money); + } + } + } + + // transaction.adjustRedeemAmount(); + } + + public Map<String, Object> validateAndClose(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.closeParameters); + final List<ApiParameterError> dataValidationErrors = new ArrayList<>(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("sharesaccount"); + JsonElement element = jsonCommand.parsedJson(); + LocalDate closedDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.closeddate_paramname, element); + baseDataValidator.reset().parameter(ShareAccountApiConstants.approveddate_paramname).value(closedDate).notNull(); + AppUser approvedUser = this.platformSecurityContext.authenticatedUser(); + 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) ; + 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/08c553f9/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 new file mode 100644 index 0000000..4f3b401 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/PurchasedSharesReadPlatformService.java @@ -0,0 +1,28 @@ +/** + * 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.shareaccounts.service; + +import java.util.Collection; + +import org.apache.fineract.portfolio.shareaccounts.data.PurchasedSharesData; + +public interface PurchasedSharesReadPlatformService { + + public Collection<PurchasedSharesData> retrievePurchasedShares(final Long accountId) ; +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/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 new file mode 100644 index 0000000..5aa7f73 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/PurchasedSharesReadPlatformServiceImpl.java @@ -0,0 +1,86 @@ +/** + * 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.shareaccounts.service; + +import java.math.BigDecimal; +import java.sql.ResultSet; +import java.sql.SQLException; +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.joda.time.LocalDate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Service; + +@Service +public class PurchasedSharesReadPlatformServiceImpl implements + PurchasedSharesReadPlatformService { + + private final JdbcTemplate jdbcTemplate; + + @Autowired + public PurchasedSharesReadPlatformServiceImpl(final RoutingDataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource) ; + } + @Override + public Collection<PurchasedSharesData> retrievePurchasedShares( + Long accountId) { + PurchasedSharesDataRowMapper mapper = new PurchasedSharesDataRowMapper() ; + final String sql = "select " + mapper.schema() + " where saps.account_id=?"; + return this.jdbcTemplate.query(sql, mapper, new Object[] { accountId}); + } + + private final static class PurchasedSharesDataRowMapper implements RowMapper<PurchasedSharesData> { + + 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(" from m_share_account_transactions saps "); + schema = buff.toString() ; + } + @Override + public PurchasedSharesData mapRow(ResultSet rs, int rowNum) + throws SQLException { + final Long id = rs.getLong("id") ; + final Long accountId = rs.getLong("account_id") ; + final LocalDate purchasedDate = new LocalDate(rs.getDate("transaction_date")) ; + final Long numberOfShares = JdbcSupport.getLong(rs, "total_shares") ; + final BigDecimal purchasedPrice = rs.getBigDecimal("unit_price") ; + final Integer status = rs.getInt("status_enum") ; + final EnumOptionData statusEnum = SharesEnumerations.purchasedSharesEnum(status) ; + final Integer type = rs.getInt("type_enum") ; + 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); + } + + public String schema() { + return this.schema ; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountChargeReadPlatformService.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountChargeReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountChargeReadPlatformService.java new file mode 100644 index 0000000..af23abe --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountChargeReadPlatformService.java @@ -0,0 +1,28 @@ +/** + * 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.shareaccounts.service; + +import java.util.Collection; + +import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountChargeData; + +public interface ShareAccountChargeReadPlatformService { + + Collection<ShareAccountChargeData> retrieveAccountCharges(final Long accountId, final String status) ; +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/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 new file mode 100644 index 0000000..b4ddd96 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountChargeReadPlatformServiceImpl.java @@ -0,0 +1,148 @@ +/** + * 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.shareaccounts.service; + +import java.math.BigDecimal; +import java.sql.ResultSet; +import java.sql.SQLException; +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.organisation.monetary.data.CurrencyData; +import org.apache.fineract.portfolio.charge.data.ChargeData; +import org.apache.fineract.portfolio.charge.service.ChargeEnumerations; +import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountChargeData; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Service; + +@Service +public class ShareAccountChargeReadPlatformServiceImpl implements + ShareAccountChargeReadPlatformService { + + private final JdbcTemplate jdbcTemplate; + + @Autowired + public ShareAccountChargeReadPlatformServiceImpl( + final RoutingDataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + @Override + public Collection<ShareAccountChargeData> retrieveAccountCharges( + Long accountId, String status) { + final ShareAccountChargeMapper rm = new ShareAccountChargeMapper(); + final StringBuilder sqlBuilder = new StringBuilder(); + sqlBuilder.append("select ").append(rm.schema()) + .append(" where sc.account_id=? "); + if (status.equalsIgnoreCase("active")) { + sqlBuilder.append(" and sc.is_active = 1 "); + } else if (status.equalsIgnoreCase("inactive")) { + sqlBuilder.append(" and sc.is_active = 0 "); + } + sqlBuilder.append(" order by sc.charge_time_enum ASC"); + + return this.jdbcTemplate.query(sqlBuilder.toString(), rm, + new Object[] { accountId }); + } + + private final static class ShareAccountChargeMapper implements + RowMapper<ShareAccountChargeData> { + + private final String schema; + + public ShareAccountChargeMapper() { + StringBuffer buff = new StringBuffer() + .append("sc.id as id, c.id as chargeId, sc.account_id as accountId, c.name as name, ") + .append("sc.amount as amountDue, sc.amount_paid_derived as amountPaid, ") + .append("sc.amount_waived_derived as amountWaived, sc.amount_writtenoff_derived as amountWrittenOff, ") + .append("sc.amount_outstanding_derived as amountOutstanding, sc.calculation_percentage as percentageOf, ") + .append("sc.calculation_on_amount as amountPercentageAppliedTo, sc.charge_time_enum as chargeTime, ") + .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("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 "); + + schema = buff.toString(); + } + + @Override + public ShareAccountChargeData mapRow(ResultSet rs, int rowNum) + throws SQLException { + final Long id = rs.getLong("id"); + final Long chargeId = rs.getLong("chargeId"); + final Long accountId = rs.getLong("accountId"); + final String name = rs.getString("name"); + final BigDecimal amount = rs.getBigDecimal("amountDue"); + final BigDecimal amountPaid = JdbcSupport + .getBigDecimalDefaultToZeroIfNull(rs, "amountPaid"); + final BigDecimal amountWaived = JdbcSupport + .getBigDecimalDefaultToZeroIfNull(rs, "amountWaived"); + final BigDecimal amountWrittenOff = JdbcSupport + .getBigDecimalDefaultToZeroIfNull(rs, "amountWrittenOff"); + final BigDecimal amountOutstanding = rs + .getBigDecimal("amountOutstanding"); + + final BigDecimal percentageOf = JdbcSupport + .getBigDecimalDefaultToZeroIfNull(rs, "percentageOf"); + final BigDecimal amountPercentageAppliedTo = JdbcSupport + .getBigDecimalDefaultToZeroIfNull(rs, + "amountPercentageAppliedTo"); + + final String currencyCode = rs.getString("currencyCode"); + final String currencyName = rs.getString("currencyName"); + final String currencyNameCode = rs.getString("currencyNameCode"); + final String currencyDisplaySymbol = rs + .getString("currencyDisplaySymbol"); + final Integer currencyDecimalPlaces = JdbcSupport.getInteger(rs, + "currencyDecimalPlaces"); + final Integer inMultiplesOf = JdbcSupport.getInteger(rs, + "inMultiplesOf"); + + final CurrencyData currency = new CurrencyData(currencyCode, + currencyName, currencyDecimalPlaces, inMultiplesOf, + currencyDisplaySymbol, currencyNameCode); + + final int chargeTime = rs.getInt("chargeTime"); + final EnumOptionData chargeTimeType = ChargeEnumerations + .chargeTimeType(chargeTime); + + final int chargeCalculation = rs.getInt("chargeCalculation"); + final EnumOptionData chargeCalculationType = ChargeEnumerations + .chargeCalculationType(chargeCalculation); + final Boolean isActive = rs.getBoolean("isActive"); + + final Collection<ChargeData> chargeOptions = null; + return new ShareAccountChargeData(id, chargeId, accountId, name, + currency, amount, amountPaid, amountWaived, + amountWrittenOff, amountOutstanding, chargeTimeType, + chargeCalculationType, percentageOf, + amountPercentageAppliedTo, chargeOptions, isActive); + } + + public String schema() { + return this.schema; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountCommandsServiceImpl.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountCommandsServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountCommandsServiceImpl.java new file mode 100644 index 0000000..6f56afa --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountCommandsServiceImpl.java @@ -0,0 +1,85 @@ +/** + * 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.shareaccounts.service; + +import org.apache.fineract.infrastructure.core.api.JsonCommand; +import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; +import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper; +import org.apache.fineract.portfolio.accounts.constants.ShareAccountApiConstants; +import org.apache.fineract.portfolio.accounts.service.AccountsCommandsService; +import org.apache.fineract.portfolio.shareaccounts.serialization.ShareAccountDataSerializer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.google.gson.JsonElement; + +@Service(value = "SHAREACCOUNT_COMMANDSERVICE") +public class ShareAccountCommandsServiceImpl implements AccountsCommandsService { + + private final FromJsonHelper fromApiJsonHelper; + + private final ShareAccountDataSerializer shareAccountDataSerializer ; + + @Autowired + public ShareAccountCommandsServiceImpl(final FromJsonHelper fromApiJsonHelper, + final ShareAccountDataSerializer shareAccountDataSerializer) { + this.fromApiJsonHelper = fromApiJsonHelper; + this.shareAccountDataSerializer = shareAccountDataSerializer ; + } + + @Override + public Object handleCommand(Long accountId, String command, String jsonBody) { + final JsonElement parsedCommand = this.fromApiJsonHelper.parse(jsonBody); + final JsonCommand jsonCommand = JsonCommand.from(jsonBody, parsedCommand, this.fromApiJsonHelper, null, null, null, null, null, + null, null, null, null, null); + if(ShareAccountApiConstants.APPROVE_COMMAND.equals(command)){ + return approveShareAccount(accountId, jsonCommand) ; + }if(ShareAccountApiConstants.REJECT_COMMAND.equals(command)){ + return rejectShareAccount(accountId, jsonCommand) ; + }else if(ShareAccountApiConstants.APPLY_ADDITIONALSHARES_COMMAND.equals(command)) { + return applyAdditionalShares(accountId, jsonCommand) ; + }else if(ShareAccountApiConstants.APPROVE_ADDITIONSHARES_COMMAND.equals(command)) { + return approveAdditionalShares(accountId, jsonCommand) ; + }else if(ShareAccountApiConstants.REJECT_ADDITIONSHARES_COMMAND.equals(command)) { + return rejectAdditionalShares(accountId, jsonCommand) ; + } + + return CommandProcessingResult.empty(); + } + + public Object approveShareAccount(Long accountId, JsonCommand jsonCommand) { + return null ; + } + + public Object rejectShareAccount(Long accountId, JsonCommand jsonCommand) { + return null ; + } + + public Object applyAdditionalShares(Long accountId, JsonCommand jsonCommand) { + return null ; + } + + public Object approveAdditionalShares(Long accountId, JsonCommand jsonCommand) { + return null ; + } + + public Object rejectAdditionalShares(Long accountId, JsonCommand jsonCommand) { + return null ; + } +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountDividendReadPlatformService.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountDividendReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountDividendReadPlatformService.java new file mode 100644 index 0000000..bacf6db --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountDividendReadPlatformService.java @@ -0,0 +1,34 @@ +/** + * 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.shareaccounts.service; + +import java.util.List; +import java.util.Map; + +import org.apache.fineract.infrastructure.core.service.Page; +import org.apache.fineract.infrastructure.core.service.SearchParameters; +import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountDividendData; + +public interface ShareAccountDividendReadPlatformService { + + List<Map<String, Object>> retriveDividendDetailsForPostDividents(); + + Page<ShareAccountDividendData> retriveAll(Long payoutDetailId, SearchParameters searchParameters); + +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountDividendReadPlatformServiceImpl.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountDividendReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountDividendReadPlatformServiceImpl.java new file mode 100644 index 0000000..1be1eac --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountDividendReadPlatformServiceImpl.java @@ -0,0 +1,140 @@ +/** + * 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.shareaccounts.service; + +import java.math.BigDecimal; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.fineract.infrastructure.core.data.EnumOptionData; +import org.apache.fineract.infrastructure.core.domain.JdbcSupport; +import org.apache.fineract.infrastructure.core.service.Page; +import org.apache.fineract.infrastructure.core.service.PaginationHelper; +import org.apache.fineract.infrastructure.core.service.RoutingDataSource; +import org.apache.fineract.infrastructure.core.service.SearchParameters; +import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountDividendData; +import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountData; +import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccountDividendStatusType; +import org.apache.fineract.portfolio.shareproducts.domain.ShareProductDividendStatusType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Service; + +@Service +public class ShareAccountDividendReadPlatformServiceImpl implements ShareAccountDividendReadPlatformService { + + private final JdbcTemplate jdbcTemplate; + private final PaginationHelper<ShareAccountDividendData> paginationHelper = new PaginationHelper<>(); + + @Autowired + public ShareAccountDividendReadPlatformServiceImpl(final RoutingDataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + @Override + public List<Map<String, Object>> retriveDividendDetailsForPostDividents() { + StringBuilder sb = new StringBuilder(); + sb.append("select "); + sb.append(" sadd.id as id, "); + sb.append(" sa.savings_account_id as savingsAccountId "); + sb.append(" from m_share_account_dividend_details sadd"); + sb.append(" inner join m_share_product_dividend_pay_out spdpo on spdpo.id = sadd.dividend_pay_out_id "); + sb.append(" inner join m_share_account sa on sa.id = sadd.account_id "); + sb.append(" where spdpo.status = ? and sadd.status = ?"); + return this.jdbcTemplate.queryForList(sb.toString(), ShareProductDividendStatusType.APPROVED.getValue(), + ShareAccountDividendStatusType.INITIATED.getValue()); + } + + @Override + public Page<ShareAccountDividendData> retriveAll(final Long payoutDetailId, final SearchParameters searchParameters) { + ShareAccountDividendMapper shareAccountDividendMapper = new ShareAccountDividendMapper(); + final StringBuilder sqlBuilder = new StringBuilder(200); + sqlBuilder.append("select SQL_CALC_FOUND_ROWS "); + sqlBuilder.append(shareAccountDividendMapper.schema()); + sqlBuilder.append(" where sadd.dividend_pay_out_id = ? "); + List<Object> params = new ArrayList<>(2); + params.add(payoutDetailId); + if (searchParameters.getAccountNo() != null) { + sqlBuilder.append(" and sa.account_no = ? "); + params.add(searchParameters.getAccountNo()); + } + if (searchParameters.isOrderByRequested()) { + sqlBuilder.append(" order by ").append(searchParameters.getOrderBy()); + + if (searchParameters.isSortOrderProvided()) { + sqlBuilder.append(' ').append(searchParameters.getSortOrder()); + } + } + + if (searchParameters.isLimited()) { + sqlBuilder.append(" limit ").append(searchParameters.getLimit()); + if (searchParameters.isOffset()) { + sqlBuilder.append(" offset ").append(searchParameters.getOffset()); + } + } + + final String sqlCountRows = "SELECT FOUND_ROWS()"; + Object[] paramsObj = params.toArray(); + return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), paramsObj, + shareAccountDividendMapper); + } + + private static final class ShareAccountDividendMapper implements RowMapper<ShareAccountDividendData> { + + private final String sql; + + public ShareAccountDividendMapper() { + StringBuilder sb = new StringBuilder(); + sb.append(" sadd.id as id, sadd.amount as amount,"); + sb.append(" sadd.status as status, sadd.savings_transaction_id as savingsTransactionId,"); + sb.append(" sa.id as accountId,sa.account_no as accountNumber, "); + sb.append(" mc.id as clientId,mc.display_name as clientName "); + sb.append(" from m_share_account_dividend_details sadd"); + sb.append(" inner join m_share_account sa on sa.id = sadd.account_id "); + sb.append(" inner join m_client mc on mc.id=sa.client_id "); + sql = sb.toString(); + } + + public String schema() { + return this.sql; + } + + @Override + public ShareAccountDividendData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException { + final Long id = rs.getLong("id"); + final BigDecimal amount = rs.getBigDecimal("amount"); + final Integer status = JdbcSupport.getInteger(rs, "status"); + final EnumOptionData statusEnum = SharesEnumerations.ShareAccountDividendStatusEnum(status); + final Long savingsTransactionId = JdbcSupport.getLong(rs, "savingsTransactionId"); + + final Long accounId = rs.getLong("accountId"); + final String accountNumber = rs.getString("accountNumber"); + final String clientName = rs.getString("clientName"); + final Long clientId = rs.getLong("clientId"); + final ShareAccountData accountData = ShareAccountData.lookup(accounId, accountNumber, clientId, clientName); + return new ShareAccountDividendData(id, accountData, amount, statusEnum, savingsTransactionId); + } + + } + +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/08c553f9/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountReadPlatformService.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountReadPlatformService.java new file mode 100644 index 0000000..06cdf62 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountReadPlatformService.java @@ -0,0 +1,41 @@ +/** + * 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.shareaccounts.service; + +import java.util.Collection; +import java.util.Set; + +import org.apache.fineract.portfolio.accounts.service.AccountReadPlatformService; +import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountData; +import org.joda.time.LocalDate; + +public interface ShareAccountReadPlatformService extends AccountReadPlatformService { + + @Override + public ShareAccountData retrieveTemplate(final Long clientId, final Long productId); + + @Override + public ShareAccountData retrieveOne(Long id, boolean includeTemplate); + + @Override + public Set<String> getResponseDataParams(); + + Collection<ShareAccountData> retrieveAllShareAccountDataForDividends(Long productId, boolean fetchInActiveAccounts, LocalDate startDate); + +}