/** * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mifosplatform.organisation.provisioning.service; import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Set; import org.joda.time.DateTime; import org.mifosplatform.accounting.glaccount.domain.GLAccount; import org.mifosplatform.accounting.glaccount.domain.GLAccountRepository; import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.organisation.provisioning.constants.ProvisioningCriteriaConstants; import org.mifosplatform.organisation.provisioning.domain.LoanProductProvisionCriteria; import org.mifosplatform.organisation.provisioning.domain.ProvisioningCategory; import org.mifosplatform.organisation.provisioning.domain.ProvisioningCategoryRepository; import org.mifosplatform.organisation.provisioning.domain.ProvisioningCriteria; import org.mifosplatform.organisation.provisioning.domain.ProvisioningCriteriaDefinition; import org.mifosplatform.organisation.provisioning.exception.ProvisioningCriteriaOverlappingDefinitionException; import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct; import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRepository; import org.mifosplatform.useradministration.domain.AppUser; 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; @Service public class ProvisioningCriteriaAssembler { private final FromJsonHelper fromApiJsonHelper; private final ProvisioningCategoryRepository provisioningCategoryRepository; private final LoanProductRepository loanProductRepository; private final GLAccountRepository glAccountRepository; private final PlatformSecurityContext platformSecurityContext; @Autowired public ProvisioningCriteriaAssembler(final FromJsonHelper fromApiJsonHelper, final ProvisioningCategoryRepository provisioningCategoryRepository, final LoanProductRepository loanProductRepository, final GLAccountRepository glAccountRepository, final PlatformSecurityContext platformSecurityContext) { this.fromApiJsonHelper = fromApiJsonHelper; this.provisioningCategoryRepository = provisioningCategoryRepository; this.loanProductRepository = loanProductRepository; this.glAccountRepository = glAccountRepository; this.platformSecurityContext = platformSecurityContext; } public List<LoanProduct> parseLoanProducts(final JsonElement jsonElement) { List<LoanProduct> loanProducts = new ArrayList<>(); if (fromApiJsonHelper.parameterExists(ProvisioningCriteriaConstants.JSON_LOANPRODUCTS_PARAM, jsonElement)) { JsonArray jsonloanProducts = this.fromApiJsonHelper.extractJsonArrayNamed(ProvisioningCriteriaConstants.JSON_LOANPRODUCTS_PARAM, jsonElement); for (JsonElement element : jsonloanProducts) { Long productId = this.fromApiJsonHelper.extractLongNamed("id", element.getAsJsonObject()); loanProducts.add(loanProductRepository.findOne(productId)); } } else { loanProducts = loanProductRepository.findAll(); } return loanProducts ; } private void validateRange(Set<ProvisioningCriteriaDefinition> criteriaDefinitions) { List<ProvisioningCriteriaDefinition> def = new ArrayList<>() ; def.addAll(criteriaDefinitions) ; for (int i = 0; i < def.size(); i++) { for (int j = i + 1; j < def.size(); j++) { if (def.get(i).isOverlapping(def.get(j))) { throw new ProvisioningCriteriaOverlappingDefinitionException() ; } } } } public ProvisioningCriteria fromParsedJson(final JsonElement jsonElement) { ProvisioningCriteria provisioningCriteria = createCriteria(jsonElement); final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(jsonElement.getAsJsonObject()); List<LoanProduct> loanProducts = parseLoanProducts(jsonElement) ; Set<ProvisioningCriteriaDefinition> criteriaDefinitions = new HashSet<>(); JsonArray jsonProvisioningCriteria = this.fromApiJsonHelper.extractJsonArrayNamed( ProvisioningCriteriaConstants.JSON_PROVISIONING_DEFINITIONS_PARAM, jsonElement); for (JsonElement element : jsonProvisioningCriteria) { JsonObject jsonObject = element.getAsJsonObject(); ProvisioningCriteriaDefinition provisioningCriteriaData = createProvisioningCriteriaDefinitions(jsonObject, locale, provisioningCriteria); criteriaDefinitions.add(provisioningCriteriaData); } validateRange(criteriaDefinitions) ; Set<LoanProductProvisionCriteria> mapping = new HashSet<>(); for (LoanProduct loanProduct : loanProducts) { mapping.add(new LoanProductProvisionCriteria(provisioningCriteria, loanProduct)); } provisioningCriteria.setProvisioningCriteriaDefinitions(criteriaDefinitions); provisioningCriteria.setLoanProductProvisioningCriteria(mapping); return provisioningCriteria; } private ProvisioningCriteria createCriteria(final JsonElement jsonElement) { final String criteriaName = this.fromApiJsonHelper.extractStringNamed(ProvisioningCriteriaConstants.JSON_CRITERIANAME_PARAM, jsonElement); AppUser modifiedBy = null; DateTime modifiedOn = null; ProvisioningCriteria criteria = new ProvisioningCriteria(criteriaName, platformSecurityContext.authenticatedUser(), new DateTime(), modifiedBy, modifiedOn); return criteria; } private ProvisioningCriteriaDefinition createProvisioningCriteriaDefinitions(JsonObject jsonObject, Locale locale, ProvisioningCriteria criteria) { Long categoryId = this.fromApiJsonHelper.extractLongNamed(ProvisioningCriteriaConstants.JSON_CATEOGRYID_PARAM, jsonObject); Long minimumAge = this.fromApiJsonHelper.extractLongNamed(ProvisioningCriteriaConstants.JSON_MINIMUM_AGE_PARAM, jsonObject); Long maximumAge = this.fromApiJsonHelper.extractLongNamed(ProvisioningCriteriaConstants.JSON_MAXIMUM_AGE_PARAM, jsonObject); BigDecimal provisioningpercentage = this.fromApiJsonHelper.extractBigDecimalNamed(ProvisioningCriteriaConstants.JSON_PROVISIONING_PERCENTAGE_PARAM, jsonObject, locale); Long liabilityAccountId = this.fromApiJsonHelper.extractLongNamed(ProvisioningCriteriaConstants.JSON_LIABILITY_ACCOUNT_PARAM, jsonObject); Long expenseAccountId = this.fromApiJsonHelper.extractLongNamed(ProvisioningCriteriaConstants.JSON_EXPENSE_ACCOUNT_PARAM, jsonObject); ProvisioningCategory provisioningCategory = provisioningCategoryRepository.findOne(categoryId); GLAccount liabilityAccount = glAccountRepository.findOne(liabilityAccountId); GLAccount expenseAccount = glAccountRepository.findOne(expenseAccountId); return ProvisioningCriteriaDefinition.newPrivisioningCriteria(criteria, provisioningCategory, minimumAge, maximumAge, provisioningpercentage, liabilityAccount, expenseAccount); } }