blob: 8186fa27eac2db1b09244184b06ec74f0a6f7672 [file] [log] [blame]
/**
* 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.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.apache.fineract.accounting.glaccount.domain.GLAccount;
import org.apache.fineract.accounting.glaccount.domain.GLAccountRepository;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.organisation.provisioning.constants.ProvisioningCriteriaConstants;
import org.apache.fineract.organisation.provisioning.domain.LoanProductProvisionCriteria;
import org.apache.fineract.organisation.provisioning.domain.ProvisioningCategory;
import org.apache.fineract.organisation.provisioning.domain.ProvisioningCategoryRepository;
import org.apache.fineract.organisation.provisioning.domain.ProvisioningCriteria;
import org.apache.fineract.organisation.provisioning.domain.ProvisioningCriteriaDefinition;
import org.apache.fineract.organisation.provisioning.exception.ProvisioningCriteriaOverlappingDefinitionException;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRepository;
import org.apache.fineract.useradministration.domain.AppUser;
import org.joda.time.DateTime;
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);
}
}