public Map validateAndUpdate()

in fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/serialization/ShareAccountDataSerializer.java [264:454]


    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 LocalDate submittedDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.submitteddate_paramname,
                    element);
            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);
            baseDataValidator.reset().parameter(ShareAccountApiConstants.savingsaccountid_paramname).value(savingsAccountId).notNull()
                    .longGreaterThanZero();
            if (savingsAccountId != null) {
                if (!this.savingsAccountReadPlatformService.isAccountBelongsToClient(account.getClientId(), savingsAccountId,
                        DepositAccountType.SAVINGS_DEPOSIT, shareProduct.getCurrency().getCode())) {
                    throw new SavingsAccountNotFoundException(savingsAccountId);
                }
                SavingsAccount savingsAccount = this.savingsAccountRepositoryWrapper.findOneWithNotFoundDetection(savingsAccountId);
                if (account.setSavingsAccount(savingsAccount)) {
                    actualChanges.put(ShareAccountApiConstants.savingsaccountid_paramname, savingsAccount.getId());
                }
            }
        }

        LocalDate existingApplicationDate = null;
        List<ShareAccountTransaction> purchaseTransactionsList = new ArrayList<>();
        Set<ShareAccountCharge> chargesList = new HashSet<>();

        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) {
                if (transaction.isActive()) {
                    reveralIds.add(transaction.getId());
                    transaction.setActive(false);
                    if (!transaction.isChargeTransaction()) {
                        existingApplicationDate = transaction.getPurchasedDate();
                        ShareAccountTransaction newtransaction = new ShareAccountTransaction(transaction.getPurchasedDate(),
                                transaction.getTotalShares(), transaction.getPurchasePrice());
                        purchaseTransactionsList.add(newtransaction);
                    }
                }
            }

            actualChanges.put("reversalIds", reveralIds);
            Set<ShareAccountCharge> charges = account.getCharges();
            for (ShareAccountCharge charge : charges) {
                if (charge.isActive()) {
                    charge.setActive(false);
                    ChargeTimeType chargeTime = null;
                    ChargeCalculationType chargeCalculation = null;
                    Boolean status = Boolean.TRUE;
                    ShareAccountCharge accountCharge = ShareAccountCharge.createNewWithoutShareAccount(charge.getCharge(),
                            charge.percentageOrAmount(), chargeTime, chargeCalculation, status);
                    chargesList.add(accountCharge);
                }
            }
        }

        if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.requestedshares_paramname, element)) {
            Long requestedShares = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.requestedshares_paramname, element);
            baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname).value(requestedShares).notNull();
            LocalDate applicationDate = null;
            purchaseTransactionsList.clear();
            if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.applicationdate_param, element)) {
                applicationDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.applicationdate_param, element);
                baseDataValidator.reset().parameter(ShareAccountApiConstants.applicationdate_param).value(applicationDate).notNull();
            } else {
                applicationDate = existingApplicationDate;
            }
            BigDecimal unitPrice = shareProduct.deriveMarketPrice(applicationDate);
            ShareAccountTransaction transaction = new ShareAccountTransaction(applicationDate, requestedShares, unitPrice);
            purchaseTransactionsList.add(transaction);
            actualChanges.put(ShareAccountApiConstants.requestedshares_paramname, "Transaction");

            if (shareProduct.getMinimumClientShares() != null && 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 (shareProduct.getMaximumClientShares() != null && 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");
            }
        }

        if (!purchaseTransactionsList.isEmpty()) {
            ShareAccountTransaction transaction = purchaseTransactionsList.get(0);
            account.addTransaction(transaction);
            account.setTotalPendingShares(transaction.getTotalShares());
        }

        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();
            final MonetaryCurrency currency = shareProduct.getCurrency();
            chargesList = assembleListOfAccountCharges(element, currency.getCode());
            if (chargesList != null) {
                if (!chargesList.isEmpty()) {
                    actualChanges.put(ShareAccountApiConstants.charges_paramname, new HashSet<ShareAccountCharge>());
                }
            }
        }
        if (chargesList != null && !chargesList.isEmpty()) {
            for (ShareAccountCharge charge : chargesList) {
                charge.update(account);
            }
            account.addCharges(chargesList);
        }

        createChargeTransaction(account);
        if (!dataValidationErrors.isEmpty()) {
            throw new PlatformApiDataValidationException(dataValidationErrors);
        }
        return actualChanges;
    }