Merge pull request #1528 from nazeer1100126/provision

MIFOSX-2314 MIFOSX-2313 All Provisioning Critical Issues
This commit is contained in:
Adi Narayana Raju
2015-10-29 10:02:45 +05:30
12 changed files with 140 additions and 37 deletions
@@ -38,10 +38,14 @@ public class LoanProductProvisioningEntryData {
private final String liabilityAccountCode ; private final String liabilityAccountCode ;
private final String liabilityAccountName ;
private final Long expenseAccount; private final Long expenseAccount;
private final String expenseAccountCode ; private final String expenseAccountCode ;
private final String expenseAccountName ;
private final Long criteriaId ; private final Long criteriaId ;
public LoanProductProvisioningEntryData(final Long historyId, final Long officeId, final String currencyCode, final Long productId, public LoanProductProvisioningEntryData(final Long historyId, final Long officeId, final String currencyCode, final Long productId,
@@ -62,13 +66,15 @@ public class LoanProductProvisioningEntryData {
this.productName = null ; this.productName = null ;
this.categoryName = null ; this.categoryName = null ;
this.liabilityAccountCode = null ; this.liabilityAccountCode = null ;
this.liabilityAccountName = null ;
this.expenseAccountCode = null ; this.expenseAccountCode = null ;
this.expenseAccountName = null ;
this.criteriaId = criteriaId ; this.criteriaId = criteriaId ;
} }
public LoanProductProvisioningEntryData(final Long historyId, final Long officeId, final String officeName, final String currencyCode, final Long productId, public LoanProductProvisioningEntryData(final Long historyId, final Long officeId, final String officeName, final String currencyCode, final Long productId,
final String productName, final Long categoryId, final String categoryName, final Long overdueInDays, final BigDecimal amountReserved, final String productName, final Long categoryId, final String categoryName, final Long overdueInDays, final BigDecimal amountReserved,
Long liablityAccount, String liabilityAccountName, Long expenseAccount, String expenseAccountName, final Long criteriaId) { Long liablityAccount, String liabilityAccountglCode, String liabilityAccountName, Long expenseAccount, String expenseAccountglCode, String expenseAccountName, final Long criteriaId) {
this.historyId = historyId; this.historyId = historyId;
this.officeId = officeId; this.officeId = officeId;
this.currencyCode = currencyCode; this.currencyCode = currencyCode;
@@ -83,8 +89,10 @@ public class LoanProductProvisioningEntryData {
this.officeName = officeName ; this.officeName = officeName ;
this.productName = productName ; this.productName = productName ;
this.amountreserved = amountReserved ; this.amountreserved = amountReserved ;
this.liabilityAccountCode = liabilityAccountName ; this.liabilityAccountCode = liabilityAccountglCode ;
this.expenseAccountCode = expenseAccountName ; this.liabilityAccountName = liabilityAccountName ;
this.expenseAccountCode = expenseAccountglCode ;
this.expenseAccountName = expenseAccountName ;
this.criteriaId = criteriaId ; this.criteriaId = criteriaId ;
} }
public Long getHistoryId() { public Long getHistoryId() {
@@ -0,0 +1,16 @@
/**
* 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.accounting.provisioning.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
public class NoProvisioningCriteriaDefinitionFound extends AbstractPlatformResourceNotFoundException {
public NoProvisioningCriteriaDefinitionFound() {
super("error.msg.no.provisioning.criteria.definitions.found", "No Provisioning Criteria Definitions are found");
}
}
@@ -54,13 +54,14 @@ public class ProvisioningEntriesReadPlatformServiceImpl implements ProvisioningE
.append(",sch.duedate),0) as numberofdaysoverdue,sch.duedate, pcd.category_id, pcd.provision_percentage,") .append(",sch.duedate),0) as numberofdaysoverdue,sch.duedate, pcd.category_id, pcd.provision_percentage,")
.append("loan.total_outstanding_derived as outstandingbalance, pcd.liability_account, pcd.expense_account from m_loan_repayment_schedule sch") .append("loan.total_outstanding_derived as outstandingbalance, pcd.liability_account, pcd.expense_account from m_loan_repayment_schedule sch")
.append(" LEFT JOIN m_loan loan on sch.loan_id = loan.id") .append(" LEFT JOIN m_loan loan on sch.loan_id = loan.id")
.append(" LEFT JOIN m_loanproduct_provisioning_mapping lpm on lpm.product_id = loan.product_id") .append(" JOIN m_loanproduct_provisioning_mapping lpm on lpm.product_id = loan.product_id")
.append(" LEFT JOIN m_provisioning_criteria_definition pcd on pcd.criteria_id = lpm.criteria_id and ") .append(" JOIN m_provisioning_criteria_definition pcd on pcd.criteria_id = lpm.criteria_id and ")
.append("(pcd.min_age <= GREATEST(datediff(").append(formattedDate).append(",sch.duedate),0) and ") .append("(pcd.min_age <= GREATEST(datediff(").append(formattedDate).append(",sch.duedate),0) and ")
.append("GREATEST(datediff(").append(formattedDate).append(",sch.duedate),0) <= pcd.max_age) ") .append("GREATEST(datediff(").append(formattedDate).append(",sch.duedate),0) <= pcd.max_age) and ")
.append("pcd.criteria_id is not null ")
.append("LEFT JOIN m_client mclient ON mclient.id = loan.client_id ") .append("LEFT JOIN m_client mclient ON mclient.id = loan.client_id ")
.append("LEFT JOIN m_group mgroup ON mgroup.id = loan.group_id ") .append("LEFT JOIN m_group mgroup ON mgroup.id = loan.group_id ")
.append("where loan.loan_status_id=300 and sch.completed_derived=false and provision_percentage is not null ") .append("where loan.loan_status_id=300 and sch.completed_derived=false ")
.append("GROUP BY loan.id order by loan.product_id"); .append("GROUP BY loan.id order by loan.product_id");
} }
@@ -130,8 +131,8 @@ public class ProvisioningEntriesReadPlatformServiceImpl implements ProvisioningE
private final StringBuilder sqlQuery = new StringBuilder() private final StringBuilder sqlQuery = new StringBuilder()
.append("select entry.id, entry.history_id as historyId, office_id, entry.criteria_id as criteriaid, office.name as officename, product.name as productname, entry.product_id, ") .append("select entry.id, entry.history_id as historyId, office_id, entry.criteria_id as criteriaid, office.name as officename, product.name as productname, entry.product_id, ")
.append("category_id, category.category_name, liability.id as liabilityid, liability.gl_code as liabilitycode, ") .append("category_id, category.category_name, liability.id as liabilityid, liability.gl_code as liabilitycode, liability.name as liabilityname, ")
.append("expense.id as expenseid, expense.gl_code as expensecode, entry.currency_code, entry.overdue_in_days, entry.reseve_amount from m_loanproduct_provisioning_entry entry ") .append("expense.id as expenseid, expense.gl_code as expensecode, expense.name as expensename, entry.currency_code, entry.overdue_in_days, entry.reseve_amount from m_loanproduct_provisioning_entry entry ")
.append("left join m_office office ON office.id = entry.office_id ") .append("left join m_office office ON office.id = entry.office_id ")
.append("left join m_product_loan product ON product.id = entry.product_id ") .append("left join m_product_loan product ON product.id = entry.product_id ")
.append("left join m_provision_category category ON category.id = entry.category_id ") .append("left join m_provision_category category ON category.id = entry.category_id ")
@@ -152,12 +153,14 @@ public class ProvisioningEntriesReadPlatformServiceImpl implements ProvisioningE
String categoryName = rs.getString("category_name") ; String categoryName = rs.getString("category_name") ;
BigDecimal amountreserved = rs.getBigDecimal("reseve_amount"); BigDecimal amountreserved = rs.getBigDecimal("reseve_amount");
Long liabilityAccountCode = rs.getLong("liabilityid"); Long liabilityAccountCode = rs.getLong("liabilityid");
String liabilityAccountName = rs.getString("liabilitycode") ; String liabilityAccountglCode = rs.getString("liabilitycode") ;
String expenseAccountName = rs.getString("expensecode") ; String expenseAccountglCode = rs.getString("expensecode") ;
Long expenseAccountCode = rs.getLong("expenseid"); Long expenseAccountCode = rs.getLong("expenseid");
Long criteriaId = rs.getLong("criteriaid") ; Long criteriaId = rs.getLong("criteriaid") ;
String liabilityAccountName = rs.getString("liabilityname") ;
String expenseAccountName = rs.getString("expensename") ;
return new LoanProductProvisioningEntryData(historyId, officeId, officeName, currentcyCode, productId, productName, categoryId, categoryName, overdueDays, amountreserved, return new LoanProductProvisioningEntryData(historyId, officeId, officeName, currentcyCode, productId, productName, categoryId, categoryName, overdueDays, amountreserved,
liabilityAccountCode, liabilityAccountName, expenseAccountCode, expenseAccountName, criteriaId); liabilityAccountCode, liabilityAccountglCode, liabilityAccountName, expenseAccountCode, expenseAccountglCode, expenseAccountName, criteriaId);
} }
public String getSchema() { public String getSchema() {
@@ -20,6 +20,7 @@ import org.mifosplatform.accounting.provisioning.data.ProvisioningEntryData;
import org.mifosplatform.accounting.provisioning.domain.LoanProductProvisioningEntry; import org.mifosplatform.accounting.provisioning.domain.LoanProductProvisioningEntry;
import org.mifosplatform.accounting.provisioning.domain.ProvisioningEntry; import org.mifosplatform.accounting.provisioning.domain.ProvisioningEntry;
import org.mifosplatform.accounting.provisioning.domain.ProvisioningEntryRepository; import org.mifosplatform.accounting.provisioning.domain.ProvisioningEntryRepository;
import org.mifosplatform.accounting.provisioning.exception.NoProvisioningCriteriaDefinitionFound;
import org.mifosplatform.accounting.provisioning.exception.ProvisioningEntryAlreadyCreatedException; import org.mifosplatform.accounting.provisioning.exception.ProvisioningEntryAlreadyCreatedException;
import org.mifosplatform.accounting.provisioning.exception.ProvisioningEntryNotfoundException; import org.mifosplatform.accounting.provisioning.exception.ProvisioningEntryNotfoundException;
import org.mifosplatform.accounting.provisioning.exception.ProvisioningJournalEntriesCannotbeCreatedException; import org.mifosplatform.accounting.provisioning.exception.ProvisioningJournalEntriesCannotbeCreatedException;
@@ -36,8 +37,10 @@ import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.organisation.monetary.domain.MoneyHelper; import org.mifosplatform.organisation.monetary.domain.MoneyHelper;
import org.mifosplatform.organisation.office.domain.Office; import org.mifosplatform.organisation.office.domain.Office;
import org.mifosplatform.organisation.office.domain.OfficeRepository; import org.mifosplatform.organisation.office.domain.OfficeRepository;
import org.mifosplatform.organisation.provisioning.data.ProvisioningCriteriaData;
import org.mifosplatform.organisation.provisioning.domain.ProvisioningCategory; import org.mifosplatform.organisation.provisioning.domain.ProvisioningCategory;
import org.mifosplatform.organisation.provisioning.domain.ProvisioningCategoryRepository; import org.mifosplatform.organisation.provisioning.domain.ProvisioningCategoryRepository;
import org.mifosplatform.organisation.provisioning.service.ProvisioningCriteriaReadPlatformService;
import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct; import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct;
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRepository; import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRepository;
import org.mifosplatform.useradministration.domain.AppUser; import org.mifosplatform.useradministration.domain.AppUser;
@@ -55,6 +58,7 @@ public class ProvisioningEntriesWritePlatformServiceJpaRepositoryImpl implements
private final static Logger logger = LoggerFactory.getLogger(ProvisioningEntriesWritePlatformServiceJpaRepositoryImpl.class); private final static Logger logger = LoggerFactory.getLogger(ProvisioningEntriesWritePlatformServiceJpaRepositoryImpl.class);
private final ProvisioningEntriesReadPlatformService provisioningEntriesReadPlatformService; private final ProvisioningEntriesReadPlatformService provisioningEntriesReadPlatformService;
private final ProvisioningCriteriaReadPlatformService provisioningCriteriaReadPlatformService ;
private final LoanProductRepository loanProductRepository; private final LoanProductRepository loanProductRepository;
private final GLAccountRepository glAccountRepository; private final GLAccountRepository glAccountRepository;
private final OfficeRepository officeRepository; private final OfficeRepository officeRepository;
@@ -64,16 +68,18 @@ public class ProvisioningEntriesWritePlatformServiceJpaRepositoryImpl implements
private final JournalEntryWritePlatformService journalEntryWritePlatformService; private final JournalEntryWritePlatformService journalEntryWritePlatformService;
private final ProvisioningEntriesDefinitionJsonDeserializer fromApiJsonDeserializer; private final ProvisioningEntriesDefinitionJsonDeserializer fromApiJsonDeserializer;
private final FromJsonHelper fromApiJsonHelper; private final FromJsonHelper fromApiJsonHelper;
@Autowired @Autowired
public ProvisioningEntriesWritePlatformServiceJpaRepositoryImpl( public ProvisioningEntriesWritePlatformServiceJpaRepositoryImpl(
final ProvisioningEntriesReadPlatformService provisioningEntriesReadPlatformService, final ProvisioningEntriesReadPlatformService provisioningEntriesReadPlatformService,
final ProvisioningCriteriaReadPlatformService provisioningCriteriaReadPlatformService,
final LoanProductRepository loanProductRepository, final GLAccountRepository glAccountRepository, final LoanProductRepository loanProductRepository, final GLAccountRepository glAccountRepository,
final OfficeRepository officeRepository, final ProvisioningCategoryRepository provisioningCategoryRepository, final OfficeRepository officeRepository, final ProvisioningCategoryRepository provisioningCategoryRepository,
final PlatformSecurityContext platformSecurityContext, final ProvisioningEntryRepository provisioningEntryRepository, final PlatformSecurityContext platformSecurityContext, final ProvisioningEntryRepository provisioningEntryRepository,
final JournalEntryWritePlatformService journalEntryWritePlatformService, final JournalEntryWritePlatformService journalEntryWritePlatformService,
final ProvisioningEntriesDefinitionJsonDeserializer fromApiJsonDeserializer, final FromJsonHelper fromApiJsonHelper) { final ProvisioningEntriesDefinitionJsonDeserializer fromApiJsonDeserializer, final FromJsonHelper fromApiJsonHelper) {
this.provisioningEntriesReadPlatformService = provisioningEntriesReadPlatformService; this.provisioningEntriesReadPlatformService = provisioningEntriesReadPlatformService;
this.provisioningCriteriaReadPlatformService = provisioningCriteriaReadPlatformService ;
this.loanProductRepository = loanProductRepository; this.loanProductRepository = loanProductRepository;
this.glAccountRepository = glAccountRepository; this.glAccountRepository = glAccountRepository;
this.officeRepository = officeRepository; this.officeRepository = officeRepository;
@@ -102,7 +108,12 @@ public class ProvisioningEntriesWritePlatformServiceJpaRepositoryImpl implements
this.journalEntryWritePlatformService.revertProvisioningJournalEntries(requestedEntry.getCreatedDate(), this.journalEntryWritePlatformService.revertProvisioningJournalEntries(requestedEntry.getCreatedDate(),
existingEntryData.getId(), PortfolioProductType.PROVISIONING.getValue()); existingEntryData.getId(), PortfolioProductType.PROVISIONING.getValue());
} }
requestedEntry.setJournalEntryCreated(Boolean.TRUE); if(requestedEntry.getLoanProductProvisioningEntries() == null || requestedEntry.getLoanProductProvisioningEntries().size() == 0) {
requestedEntry.setJournalEntryCreated(Boolean.FALSE);
}else {
requestedEntry.setJournalEntryCreated(Boolean.TRUE);
}
this.provisioningEntryRepository.save(requestedEntry); this.provisioningEntryRepository.save(requestedEntry);
this.journalEntryWritePlatformService.createProvisioningJournalEntries(requestedEntry); this.journalEntryWritePlatformService.createProvisioningJournalEntries(requestedEntry);
} }
@@ -144,6 +155,10 @@ public class ProvisioningEntriesWritePlatformServiceJpaRepositoryImpl implements
Date createdDate = parseDate(command); Date createdDate = parseDate(command);
boolean addJournalEntries = isJournalEntriesRequired(command); boolean addJournalEntries = isJournalEntriesRequired(command);
try { try {
Collection<ProvisioningCriteriaData> criteriaCollection = this.provisioningCriteriaReadPlatformService.retrieveAllProvisioningCriterias() ;
if(criteriaCollection == null || criteriaCollection.size() == 0){
throw new NoProvisioningCriteriaDefinitionFound() ;
}
ProvisioningEntry requestedEntry = createProvsioningEntry(createdDate, addJournalEntries); ProvisioningEntry requestedEntry = createProvsioningEntry(createdDate, addJournalEntries);
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(requestedEntry.getId()).build(); return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(requestedEntry.getId()).build();
} catch (DataIntegrityViolationException dve) { } catch (DataIntegrityViolationException dve) {
@@ -501,6 +501,24 @@ public class DataValidatorBuilder {
return this; return this;
} }
public DataValidatorBuilder longGreaterThanNumber(String paramName, Long number, int index) {
if (this.value == null && this.ignoreNullValue) { return this; }
if (this.value != null) {
final Long longValue = Long.valueOf(this.value.toString());
if (longValue < number + 1) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".not.greater.than.specified.").append(paramName).append(".at Index.").append(index);
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" must be greater than ").append(number);
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, longValue, number);
this.dataValidationErrors.add(error);
}
}
return this;
}
public DataValidatorBuilder arrayNotEmpty() { public DataValidatorBuilder arrayNotEmpty() {
if (this.value == null && this.ignoreNullValue) { return this; } if (this.value == null && this.ignoreNullValue) { return this; }
@@ -17,13 +17,15 @@ public final class ProvisioningCriteriaDefinitionData implements Comparable<Prov
private final Long maxAge; private final Long maxAge;
private final BigDecimal provisioningPercentage; private final BigDecimal provisioningPercentage;
private final Long liabilityAccount; private final Long liabilityAccount;
private final Long expenseAccount;
private final String liabilityCode; private final String liabilityCode;
private final String liabilityName ;
private final Long expenseAccount;
private final String expenseCode; private final String expenseCode;
private final String expenseName ;
public ProvisioningCriteriaDefinitionData(Long id, Long categoryId, String categoryName, Long minAge, Long maxAge, public ProvisioningCriteriaDefinitionData(Long id, Long categoryId, String categoryName, Long minAge, Long maxAge,
BigDecimal provisioningPercentage, Long liabilityAccount, Long expenseAccount, final String liabilityCode, BigDecimal provisioningPercentage, Long liabilityAccount, final String liabilityCode, String liabilityName, Long expenseAccount,
final String expenseCode) { final String expenseCode, final String expenseName) {
this.id = id; this.id = id;
this.categoryId = categoryId; this.categoryId = categoryId;
this.minAge = minAge; this.minAge = minAge;
@@ -34,11 +36,12 @@ public final class ProvisioningCriteriaDefinitionData implements Comparable<Prov
this.categoryName = categoryName; this.categoryName = categoryName;
this.liabilityCode = liabilityCode; this.liabilityCode = liabilityCode;
this.expenseCode = expenseCode; this.expenseCode = expenseCode;
this.liabilityName = liabilityName ;
this.expenseName = expenseName ;
} }
public static ProvisioningCriteriaDefinitionData template(Long categoryId, String categoryName) { public static ProvisioningCriteriaDefinitionData template(Long categoryId, String categoryName) {
return new ProvisioningCriteriaDefinitionData(null, categoryId, categoryName, null, null, null, null, null, null, null); return new ProvisioningCriteriaDefinitionData(null, categoryId, categoryName, null, null, null, null, null, null, null, null, null);
} }
public Long getId() { public Long getId() {
@@ -75,4 +75,9 @@ public class ProvisioningCriteriaDefinition extends AbstractPersistable<Long> {
this.liabilityAccount = lia ; this.liabilityAccount = lia ;
this.expenseAccount = exp ; this.expenseAccount = exp ;
} }
public boolean isOverlapping(ProvisioningCriteriaDefinition def) {
return this.minimumAge <= def.maximumAge && def.minimumAge <= this.maximumAge;
}
} }
@@ -0,0 +1,15 @@
/**
* 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.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
public class ProvisioningCriteriaOverlappingDefinitionException extends AbstractPlatformResourceNotFoundException {
public ProvisioningCriteriaOverlappingDefinitionException() {
super("error.msg.provisioning.criteria.definitions.are.overlapping", "Provisioning Criteria definitions are overlapping ");
}
}
@@ -87,30 +87,31 @@ public class ProvisioningCriteriaDefinitionJsonDeserializer implements Provision
.longGreaterThanZero(); .longGreaterThanZero();
Long minimumAge = this.fromApiJsonHelper.extractLongNamed(ProvisioningCriteriaConstants.JSON_MINIMUM_AGE_PARAM, jsonObject); Long minimumAge = this.fromApiJsonHelper.extractLongNamed(ProvisioningCriteriaConstants.JSON_MINIMUM_AGE_PARAM, jsonObject);
baseDataValidator.reset().parameter(ProvisioningCriteriaConstants.JSON_PROVISIONING_DEFINITIONS_PARAM) baseDataValidator.reset().parameter(ProvisioningCriteriaConstants.JSON_MINIMUM_AGE_PARAM)
.parameterAtIndexArray(ProvisioningCriteriaConstants.JSON_MINIMUM_AGE_PARAM, i + 1).value(minimumAge).notNull() .parameterAtIndexArray(ProvisioningCriteriaConstants.JSON_MINIMUM_AGE_PARAM, i + 1).value(minimumAge).notNull()
.longZeroOrGreater() ; .longZeroOrGreater() ;
Long maximumAge = this.fromApiJsonHelper.extractLongNamed(ProvisioningCriteriaConstants.JSON_MAXIMUM_AGE_PARAM, jsonObject); Long maximumAge = this.fromApiJsonHelper.extractLongNamed(ProvisioningCriteriaConstants.JSON_MAXIMUM_AGE_PARAM, jsonObject);
baseDataValidator.reset().parameter(ProvisioningCriteriaConstants.JSON_PROVISIONING_DEFINITIONS_PARAM) baseDataValidator.reset().parameter(ProvisioningCriteriaConstants.JSON_MAXIMUM_AGE_PARAM)
.parameterAtIndexArray(ProvisioningCriteriaConstants.JSON_MAXIMUM_AGE_PARAM, i + 1).value(maximumAge).notNull() .parameterAtIndexArray(ProvisioningCriteriaConstants.JSON_MAXIMUM_AGE_PARAM, i + 1).value(maximumAge).notNull()
.longZeroOrGreater(); .longGreaterThanNumber(ProvisioningCriteriaConstants.JSON_MINIMUM_AGE_PARAM, minimumAge, (i+1));
BigDecimal provisioningpercentage = this.fromApiJsonHelper.extractBigDecimalNamed( BigDecimal provisioningpercentage = this.fromApiJsonHelper.extractBigDecimalNamed(
ProvisioningCriteriaConstants.JSON_PROVISIONING_PERCENTAGE_PARAM, jsonObject, locale); ProvisioningCriteriaConstants.JSON_PROVISIONING_PERCENTAGE_PARAM, jsonObject, locale);
baseDataValidator.reset().parameter(ProvisioningCriteriaConstants.JSON_PROVISIONING_DEFINITIONS_PARAM) baseDataValidator.reset().parameter(ProvisioningCriteriaConstants.JSON_PROVISIONING_PERCENTAGE_PARAM)
.parameterAtIndexArray(ProvisioningCriteriaConstants.JSON_PROVISIONING_PERCENTAGE_PARAM, i + 1).value(provisioningpercentage) .parameterAtIndexArray(ProvisioningCriteriaConstants.JSON_PROVISIONING_PERCENTAGE_PARAM, i + 1).value(provisioningpercentage)
.notNull().zeroOrPositiveAmount(); .notNull().zeroOrPositiveAmount();
Long liabilityAccountId = this.fromApiJsonHelper.extractLongNamed(ProvisioningCriteriaConstants.JSON_LIABILITY_ACCOUNT_PARAM, Long liabilityAccountId = this.fromApiJsonHelper.extractLongNamed(ProvisioningCriteriaConstants.JSON_LIABILITY_ACCOUNT_PARAM,
jsonObject); jsonObject);
baseDataValidator.reset().parameter(ProvisioningCriteriaConstants.JSON_PROVISIONING_DEFINITIONS_PARAM) baseDataValidator.reset().parameter(ProvisioningCriteriaConstants.JSON_LIABILITY_ACCOUNT_PARAM)
.parameterAtIndexArray(ProvisioningCriteriaConstants.JSON_LIABILITY_ACCOUNT_PARAM, i + 1).value(liabilityAccountId) .parameterAtIndexArray(ProvisioningCriteriaConstants.JSON_LIABILITY_ACCOUNT_PARAM, i + 1).value(liabilityAccountId)
.notNull().longGreaterThanZero() ; .notNull().longGreaterThanZero() ;
Long expenseAccountId = this.fromApiJsonHelper.extractLongNamed(ProvisioningCriteriaConstants.JSON_EXPENSE_ACCOUNT_PARAM, Long expenseAccountId = this.fromApiJsonHelper.extractLongNamed(ProvisioningCriteriaConstants.JSON_EXPENSE_ACCOUNT_PARAM,
jsonObject); jsonObject);
baseDataValidator.reset().parameter(ProvisioningCriteriaConstants.JSON_PROVISIONING_DEFINITIONS_PARAM) baseDataValidator.reset().parameter(ProvisioningCriteriaConstants.JSON_EXPENSE_ACCOUNT_PARAM)
.parameterAtIndexArray(ProvisioningCriteriaConstants.JSON_EXPENSE_ACCOUNT_PARAM, i + 1).value(expenseAccountId).notNull() .parameterAtIndexArray(ProvisioningCriteriaConstants.JSON_EXPENSE_ACCOUNT_PARAM, i + 1).value(expenseAccountId).notNull()
.longGreaterThanZero() ; .longGreaterThanZero() ;
} }
@@ -179,10 +180,10 @@ public class ProvisioningCriteriaDefinitionJsonDeserializer implements Provision
.longZeroOrGreater() ; .longZeroOrGreater() ;
Long maximumAge = this.fromApiJsonHelper.extractLongNamed(ProvisioningCriteriaConstants.JSON_MAXIMUM_AGE_PARAM, jsonObject); Long maximumAge = this.fromApiJsonHelper.extractLongNamed(ProvisioningCriteriaConstants.JSON_MAXIMUM_AGE_PARAM, jsonObject);
baseDataValidator.reset().parameter(ProvisioningCriteriaConstants.JSON_PROVISIONING_DEFINITIONS_PARAM) baseDataValidator.reset().parameter(ProvisioningCriteriaConstants.JSON_MAXIMUM_AGE_PARAM)
.parameterAtIndexArray(ProvisioningCriteriaConstants.JSON_MAXIMUM_AGE_PARAM, i + 1).value(maximumAge).notNull() .parameterAtIndexArray(ProvisioningCriteriaConstants.JSON_MAXIMUM_AGE_PARAM, i + 1).value(maximumAge).notNull()
.longZeroOrGreater(); .longGreaterThanNumber(ProvisioningCriteriaConstants.JSON_MINIMUM_AGE_PARAM, minimumAge, (i+1));
BigDecimal provisioningpercentage = this.fromApiJsonHelper.extractBigDecimalNamed( BigDecimal provisioningpercentage = this.fromApiJsonHelper.extractBigDecimalNamed(
ProvisioningCriteriaConstants.JSON_PROVISIONING_PERCENTAGE_PARAM, jsonObject, locale); ProvisioningCriteriaConstants.JSON_PROVISIONING_PERCENTAGE_PARAM, jsonObject, locale);
baseDataValidator.reset().parameter(ProvisioningCriteriaConstants.JSON_PROVISIONING_DEFINITIONS_PARAM) baseDataValidator.reset().parameter(ProvisioningCriteriaConstants.JSON_PROVISIONING_DEFINITIONS_PARAM)
@@ -23,6 +23,7 @@ import org.mifosplatform.organisation.provisioning.domain.ProvisioningCategory;
import org.mifosplatform.organisation.provisioning.domain.ProvisioningCategoryRepository; import org.mifosplatform.organisation.provisioning.domain.ProvisioningCategoryRepository;
import org.mifosplatform.organisation.provisioning.domain.ProvisioningCriteria; import org.mifosplatform.organisation.provisioning.domain.ProvisioningCriteria;
import org.mifosplatform.organisation.provisioning.domain.ProvisioningCriteriaDefinition; 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.LoanProduct;
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRepository; import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRepository;
import org.mifosplatform.useradministration.domain.AppUser; import org.mifosplatform.useradministration.domain.AppUser;
@@ -68,6 +69,19 @@ public class ProvisioningCriteriaAssembler {
return loanProducts ; 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) { public ProvisioningCriteria fromParsedJson(final JsonElement jsonElement) {
ProvisioningCriteria provisioningCriteria = createCriteria(jsonElement); ProvisioningCriteria provisioningCriteria = createCriteria(jsonElement);
final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(jsonElement.getAsJsonObject()); final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(jsonElement.getAsJsonObject());
@@ -82,7 +96,7 @@ public class ProvisioningCriteriaAssembler {
provisioningCriteria); provisioningCriteria);
criteriaDefinitions.add(provisioningCriteriaData); criteriaDefinitions.add(provisioningCriteriaData);
} }
validateRange(criteriaDefinitions) ;
Set<LoanProductProvisionCriteria> mapping = new HashSet<>(); Set<LoanProductProvisionCriteria> mapping = new HashSet<>();
for (LoanProduct loanProduct : loanProducts) { for (LoanProduct loanProduct : loanProducts) {
mapping.add(new LoanProductProvisionCriteria(provisioningCriteria, loanProduct)); mapping.add(new LoanProductProvisionCriteria(provisioningCriteria, loanProduct));
@@ -117,7 +117,8 @@ public class ProvisioningCriteriaReadPlatformServiceImpl implements Provisioning
private final StringBuilder sqlQuery = new StringBuilder() private final StringBuilder sqlQuery = new StringBuilder()
.append("pc.id, pc.criteria_id, pc.category_id, mpc.category_name, pc.min_age, pc.max_age, ") .append("pc.id, pc.criteria_id, pc.category_id, mpc.category_name, pc.min_age, pc.max_age, ")
.append("pc.provision_percentage, pc.liability_account, pc.expense_account, lia.gl_code as liabilitycode, expe.gl_code as expensecode ") .append("pc.provision_percentage, pc.liability_account, pc.expense_account, lia.gl_code as liabilitycode, expe.gl_code as expensecode, ")
.append("lia.name as liabilityname, expe.name as expensename ")
.append("from m_provisioning_criteria_definition as pc ") .append("from m_provisioning_criteria_definition as pc ")
.append("LEFT JOIN acc_gl_account lia ON lia.id = pc.liability_account ") .append("LEFT JOIN acc_gl_account lia ON lia.id = pc.liability_account ")
.append("LEFT JOIN acc_gl_account expe ON expe.id = pc.expense_account ") .append("LEFT JOIN acc_gl_account expe ON expe.id = pc.expense_account ")
@@ -134,12 +135,14 @@ public class ProvisioningCriteriaReadPlatformServiceImpl implements Provisioning
Long maxAge = rs.getLong("max_age"); Long maxAge = rs.getLong("max_age");
BigDecimal provisioningPercentage = rs.getBigDecimal("provision_percentage"); BigDecimal provisioningPercentage = rs.getBigDecimal("provision_percentage");
Long liabilityAccount = rs.getLong("liability_account"); Long liabilityAccount = rs.getLong("liability_account");
Long expenseAccount = rs.getLong("expense_account");
String liabilityAccountCode = rs.getString("liabilitycode"); String liabilityAccountCode = rs.getString("liabilitycode");
String liabilityAccountName = rs.getString("liabilityname") ;
Long expenseAccount = rs.getLong("expense_account");
String expenseAccountCode = rs.getString("expensecode"); String expenseAccountCode = rs.getString("expensecode");
String expenseAccountName = rs.getString("expensename") ;
return new ProvisioningCriteriaDefinitionData(id, categoryId, categoryName, minAge, maxAge, provisioningPercentage, return new ProvisioningCriteriaDefinitionData(id, categoryId, categoryName, minAge, maxAge, provisioningPercentage,
liabilityAccount, expenseAccount, liabilityAccountCode, expenseAccountCode); liabilityAccount, liabilityAccountCode, liabilityAccountName, expenseAccount, expenseAccountCode, expenseAccountName);
} }
public String schema() { public String schema() {
@@ -123,9 +123,11 @@ public class ProvisioningCriteriaWritePlatformServiceJpaRepositoryImpl implement
GLAccount liabilityAccount = glAccountRepository.findOne(liabilityAccountId); GLAccount liabilityAccount = glAccountRepository.findOne(liabilityAccountId);
GLAccount expenseAccount = glAccountRepository.findOne(expenseAccountId); GLAccount expenseAccount = glAccountRepository.findOne(expenseAccountId);
String categoryName = null ; String categoryName = null ;
String liabilityAccountName = null ;
String expenseAccountName = null ;
ProvisioningCriteriaDefinitionData data = new ProvisioningCriteriaDefinitionData(id, categoryId, ProvisioningCriteriaDefinitionData data = new ProvisioningCriteriaDefinitionData(id, categoryId,
categoryName, minimumAge, maximumAge, provisioningpercentage, categoryName, minimumAge, maximumAge, provisioningpercentage,
liabilityAccount.getId(), expenseAccount.getId(), liabilityAccount.getGlCode(), expenseAccount.getGlCode()) ; liabilityAccount.getId(), liabilityAccount.getGlCode(), liabilityAccountName, expenseAccount.getId(), expenseAccount.getGlCode(), expenseAccountName) ;
provisioningCriteria.update(data, liabilityAccount, expenseAccount) ; provisioningCriteria.update(data, liabilityAccount, expenseAccount) ;
} }
} }
@@ -143,7 +145,7 @@ public class ProvisioningCriteriaWritePlatformServiceJpaRepositoryImpl implement
+ name + "` already exists", "category name", name); + name + "` already exists", "category name", name);
} }
logger.error(dve.getMessage(), dve); logger.error(dve.getMessage(), dve);
throw new PlatformDataIntegrityException("error.msg.charge.unknown.data.integrity.issue", throw new PlatformDataIntegrityException("error.msg.provisioning.unknown.data.integrity.issue",
"Unknown data integrity issue with resource: " + realCause.getMessage()); "Unknown data integrity issue with resource: " + realCause.getMessage());
} }
} }