adding organisation start in global configuartion

This commit is contained in:
sachinkulkarni12
2016-02-29 12:37:18 +05:30
parent 8d160d3e7d
commit 79fe66e30d
10 changed files with 135 additions and 41 deletions
@@ -26,9 +26,13 @@ public class GlobalConfigurationApiConstant {
public static final String ENABLED = "enabled";
public static final String VALUE = "value";
public static final String DATE_VALUE = "dateValue";
public static final String ID = "id";
public static final String CONFIGURATION_RESOURCE_NAME = "globalConfiguration";
public static final String localeParamName = "locale";
public static final String dateFormatParamName = "dateFormat";
public static final Set<String> UPDATE_CONFIGURATION_DATA_PARAMETERS = new HashSet<>(Arrays.asList(ENABLED, VALUE));
public static final Set<String> UPDATE_CONFIGURATION_DATA_PARAMETERS = new HashSet<>(Arrays.asList(localeParamName, dateFormatParamName,
ENABLED, VALUE, DATE_VALUE));
}
@@ -22,6 +22,7 @@ import static org.apache.fineract.infrastructure.configuration.api.GlobalConfigu
import static org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationApiConstant.ENABLED;
import static org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationApiConstant.UPDATE_CONFIGURATION_DATA_PARAMETERS;
import static org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationApiConstant.VALUE;
import static org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationApiConstant.DATE_VALUE;
import java.lang.reflect.Type;
import java.util.ArrayList;
@@ -29,6 +30,7 @@ import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
@@ -71,6 +73,11 @@ public class GlobalConfigurationDataValidator {
final Long valueStr = this.fromApiJsonHelper.extractLongNamed(VALUE, element);
baseDataValidator.reset().parameter(ENABLED).value(valueStr).zeroOrPositiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(DATE_VALUE, element)) {
final LocalDate dateValue = this.fromApiJsonHelper.extractLocalDateNamed(DATE_VALUE, element);
baseDataValidator.reset().parameter(DATE_VALUE).value(dateValue).notNull();
}
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
@@ -17,6 +17,7 @@
* under the License.
*/
package org.apache.fineract.infrastructure.configuration.data;
import java.util.Date;
/**
* Immutable data object for global configuration property.
@@ -30,26 +31,31 @@ public class GlobalConfigurationPropertyData {
@SuppressWarnings("unused")
private final Long value;
@SuppressWarnings("unused")
private final Date dateValue;
@SuppressWarnings("unused")
private final Long id;
@SuppressWarnings("unused")
private final String description;
@SuppressWarnings("unused")
private final boolean trapDoor;
public GlobalConfigurationPropertyData(final String name, final boolean enabled, final Long value, final String description, final boolean trapDoor) {
public GlobalConfigurationPropertyData(final String name, final boolean enabled, final Long value, final Date dateValue, final String description,
final boolean trapDoor) {
this.name = name;
this.enabled = enabled;
this.value = value;
this.dateValue = dateValue;
this.id = null;
this.description = description;
this.trapDoor = trapDoor;
}
public GlobalConfigurationPropertyData(final String name, final boolean enabled, final Long value, final Long id,
public GlobalConfigurationPropertyData(final String name, final boolean enabled, final Long value, Date dateValue, final Long id,
final String description, final boolean isTrapDoor) {
this.name = name;
this.enabled = enabled;
this.value = value;
this.dateValue = dateValue;
this.id = id;
this.description = description;
this.trapDoor = isTrapDoor;
@@ -18,6 +18,7 @@
*/
package org.apache.fineract.infrastructure.configuration.domain;
import java.util.Date;
import org.apache.fineract.infrastructure.cache.domain.CacheType;
public interface ConfigurationDomainService {
@@ -63,4 +64,8 @@ public interface ConfigurationDomainService {
int getRoundingMode();
boolean isBackdatePenaltiesEnabled();
boolean isOrganisationstartDateEnabled();
Date retrieveOrganisationStartDate();
}
@@ -18,6 +18,7 @@
*/
package org.apache.fineract.infrastructure.configuration.domain;
import java.util.Date;
import org.apache.commons.lang.StringUtils;
import org.apache.fineract.infrastructure.cache.domain.CacheType;
import org.apache.fineract.infrastructure.cache.domain.PlatformCache;
@@ -214,4 +215,18 @@ public class ConfigurationDomainServiceJpa implements ConfigurationDomainService
return property.isEnabled();
}
@Override
public boolean isOrganisationstartDateEnabled() {
final String propertyName = "organisation-start-date";
final GlobalConfigurationProperty property = this.globalConfigurationRepository.findOneByNameWithNotFoundDetection(propertyName);
return property.isEnabled();
}
@Override
public Date retrieveOrganisationStartDate() {
final String propertyName = "organisation-start-date";
final GlobalConfigurationProperty property = this.globalConfigurationRepository.findOneByNameWithNotFoundDetection(propertyName);
return property.getDateValue();
}
}
@@ -18,6 +18,7 @@
*/
package org.apache.fineract.infrastructure.configuration.domain;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -42,6 +43,9 @@ public class GlobalConfigurationProperty extends AbstractPersistable<Long> {
@Column(name = "value", nullable = true)
private Long value;
@Column(name = "date_value", nullable = true)
private Date dateValue;
@Column(name = "description", nullable = true)
private final String description;
@@ -53,15 +57,17 @@ public class GlobalConfigurationProperty extends AbstractPersistable<Long> {
this.name = null;
this.enabled = false;
this.value = null;
this.dateValue = null;
this.description = null;
this.isTrapDoor = false;
}
public GlobalConfigurationProperty(final String name, final boolean enabled, final Long value, final String description,
public GlobalConfigurationProperty(final String name, final boolean enabled, final Long value, final Date dateValue ,final String description,
final boolean isTrapDoor) {
this.name = name;
this.enabled = enabled;
this.value = value;
this.dateValue = dateValue;
this.description = description;
this.isTrapDoor = isTrapDoor;
}
@@ -73,6 +79,10 @@ public class GlobalConfigurationProperty extends AbstractPersistable<Long> {
public Long getValue() {
return this.value;
}
public Date getDateValue(){
return this.dateValue;
}
public boolean updateTo(final boolean value) {
final boolean updated = this.enabled != value;
@@ -100,6 +110,13 @@ public class GlobalConfigurationProperty extends AbstractPersistable<Long> {
actualChanges.put(valueParamName, newValue);
this.value = newValue;
}
final String dateValueParamName = "dateValue";
if(command.isChangeInDateParameterNamed(dateValueParamName, this.dateValue)){
final Date newDateValue = command.DateValueOfParameterNamed(dateValueParamName);
actualChanges.put(dateValueParamName, newDateValue);
this.dateValue = newDateValue;
}
final String passwordPropertyName = "force-password-reset-days";
if (this.name.equalsIgnoreCase(passwordPropertyName)) {
@@ -112,7 +129,7 @@ public class GlobalConfigurationProperty extends AbstractPersistable<Long> {
}
public static GlobalConfigurationProperty newSurveyConfiguration(final String name) {
return new GlobalConfigurationProperty(name, false, null, null, false);
return new GlobalConfigurationProperty(name, false, null, null, null, false);
}
}
@@ -30,6 +30,7 @@ import org.springframework.stereotype.Service;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
@Service
@@ -52,7 +53,7 @@ public class ConfigurationReadPlatformServiceImpl implements ConfigurationReadPl
this.context.authenticatedUser();
String sql = "SELECT c.id, c.name, c.enabled, c.value, c.description, c.is_trap_door FROM c_configuration c ";
String sql = "SELECT c.id, c.name, c.enabled, c.value, c.date_value, c.description, c.is_trap_door FROM c_configuration c ";
if (survey) {
sql += " JOIN x_registered_table on x_registered_table.registered_table_name = c.name ";
@@ -71,7 +72,7 @@ public class ConfigurationReadPlatformServiceImpl implements ConfigurationReadPl
this.context.authenticatedUser();
final String sql = "SELECT c.id, c.name, c.enabled, c.value, c.description, c.is_trap_door FROM "
final String sql = "SELECT c.id, c.name, c.enabled, c.value, c.date_value, c.description, c.is_trap_door FROM "
+ "c_configuration c where c.id=? order by c.id";
final GlobalConfigurationPropertyData globalConfiguration = this.jdbcTemplate.queryForObject(sql, this.rm,
new Object[] { configId });
@@ -88,10 +89,11 @@ public class ConfigurationReadPlatformServiceImpl implements ConfigurationReadPl
final String name = rs.getString("name");
final boolean enabled = rs.getBoolean("enabled");
final Long value = rs.getLong("value");
final Date dateValue = rs.getDate("date_value");
final String description = rs.getString("description");
final Long id = rs.getLong("id");
final boolean isTrapDoor = rs.getBoolean("is_trap_door");
return new GlobalConfigurationPropertyData(name, enabled, value, id, description, isTrapDoor);
return new GlobalConfigurationPropertyData(name, enabled, value, dateValue, id, description, isTrapDoor);
}
}
@@ -19,6 +19,7 @@
package org.apache.fineract.portfolio.loanaccount.domain;
import java.math.BigDecimal;
import java.util.Date;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -437,6 +438,12 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
@Override
public void recalculateAccruals(Loan loan) {
LocalDate accruedTill = loan.getAccruedTill();
boolean isOrganisationDateEnabled = this.configurationDomainService.isOrganisationstartDateEnabled();
Date organisationStartDate = new Date();
if(isOrganisationDateEnabled){
organisationStartDate = this.configurationDomainService.retrieveOrganisationStartDate();
}
if (!loan.isPeriodicAccrualAccountingEnabledOnLoanProduct() || !loan.repaymentScheduleDetail().isInterestRecalculationEnabled()
|| accruedTill == null || loan.isNpa() || !loan.status().isActive()) { return; }
Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas = new ArrayList<>();
@@ -454,33 +461,9 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
Set<LoanCharge> loanCharges = loan.charges();
for (LoanRepaymentScheduleInstallment installment : installments) {
if (!accruedTill.isBefore(installment.getDueDate())
|| (accruedTill.isAfter(installment.getFromDate()) && !accruedTill.isAfter(installment.getDueDate()))) {
BigDecimal dueDateFeeIncome = BigDecimal.ZERO;
BigDecimal dueDatePenaltyIncome = BigDecimal.ZERO;
LocalDate chargesTillDate = installment.getDueDate();
if (!accruedTill.isAfter(installment.getDueDate())) {
chargesTillDate = accruedTill;
}
for (final LoanCharge loanCharge : loanCharges) {
if (loanCharge.isDueForCollectionFromAndUpToAndIncluding(installment.getFromDate(), chargesTillDate)) {
if (loanCharge.isFeeCharge()) {
dueDateFeeIncome = dueDateFeeIncome.add(loanCharge.amount());
} else if (loanCharge.isPenaltyCharge()) {
dueDatePenaltyIncome = dueDatePenaltyIncome.add(loanCharge.amount());
}
}
}
LoanScheduleAccrualData accrualData = new LoanScheduleAccrualData(loanId, officeId, installment.getInstallmentNumber(),
accrualStartDate, repaymentFrequency, repayEvery, installment.getDueDate(), installment.getFromDate(),
installment.getId(), loanProductId, installment.getInterestCharged(currency).getAmount(), installment
.getFeeChargesCharged(currency).getAmount(), installment.getPenaltyChargesCharged(currency).getAmount(),
installment.getInterestAccrued(currency).getAmount(), installment.getFeeAccrued(currency).getAmount(), installment
.getPenaltyAccrued(currency).getAmount(), currencyData, interestCalculatedFrom, installment
.getInterestWaived(currency).getAmount());
loanScheduleAccrualDatas.add(accrualData);
if(!isOrganisationDateEnabled || new LocalDate(organisationStartDate).isBefore(installment.getDueDate())){
generateLoanScheduleAccrualData(accruedTill, loanScheduleAccrualDatas, loanId, officeId, accrualStartDate, repaymentFrequency,
repayEvery, interestCalculatedFrom, loanProductId, currency, currencyData, loanCharges, installment);
}
}
@@ -493,6 +476,41 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
}
}
private void generateLoanScheduleAccrualData(final LocalDate accruedTill, final Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas,
final Long loanId, Long officeId, final LocalDate accrualStartDate, final PeriodFrequencyType repaymentFrequency, final Integer repayEvery,
final LocalDate interestCalculatedFrom, final Long loanProductId, final MonetaryCurrency currency, final CurrencyData currencyData,
final Set<LoanCharge> loanCharges, final LoanRepaymentScheduleInstallment installment) {
if (!accruedTill.isBefore(installment.getDueDate())
|| (accruedTill.isAfter(installment.getFromDate()) && !accruedTill.isAfter(installment.getDueDate()))) {
BigDecimal dueDateFeeIncome = BigDecimal.ZERO;
BigDecimal dueDatePenaltyIncome = BigDecimal.ZERO;
LocalDate chargesTillDate = installment.getDueDate();
if (!accruedTill.isAfter(installment.getDueDate())) {
chargesTillDate = accruedTill;
}
for (final LoanCharge loanCharge : loanCharges) {
if (loanCharge.isDueForCollectionFromAndUpToAndIncluding(installment.getFromDate(), chargesTillDate)) {
if (loanCharge.isFeeCharge()) {
dueDateFeeIncome = dueDateFeeIncome.add(loanCharge.amount());
} else if (loanCharge.isPenaltyCharge()) {
dueDatePenaltyIncome = dueDatePenaltyIncome.add(loanCharge.amount());
}
}
}
LoanScheduleAccrualData accrualData = new LoanScheduleAccrualData(loanId, officeId, installment.getInstallmentNumber(),
accrualStartDate, repaymentFrequency, repayEvery, installment.getDueDate(), installment.getFromDate(),
installment.getId(), loanProductId, installment.getInterestCharged(currency).getAmount(), installment
.getFeeChargesCharged(currency).getAmount(), installment.getPenaltyChargesCharged(currency).getAmount(),
installment.getInterestAccrued(currency).getAmount(), installment.getFeeAccrued(currency).getAmount(), installment
.getPenaltyAccrued(currency).getAmount(), currencyData, interestCalculatedFrom, installment
.getInterestWaived(currency).getAmount());
loanScheduleAccrualDatas.add(accrualData);
}
}
private void updateLoanTransaction(final Long loanTransactionId, final LoanTransaction newLoanTransaction) {
final AccountTransferTransaction transferTransaction = this.accountTransferRepository.findByToLoanTransactionId(loanTransactionId);
if (transferTransaction != null) {
@@ -35,6 +35,7 @@ import org.apache.commons.lang.StringUtils;
import org.apache.fineract.accounting.common.AccountingRuleType;
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
import org.apache.fineract.infrastructure.codes.service.CodeValueReadPlatformService;
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
import org.apache.fineract.infrastructure.core.service.DateUtils;
@@ -148,6 +149,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
private final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory;
private final FloatingRatesReadPlatformService floatingRatesReadPlatformService;
private final LoanUtilService loanUtilService;
private final ConfigurationDomainService configurationDomainService;
@Autowired
public LoanReadPlatformServiceImpl(final PlatformSecurityContext context, final LoanRepository loanRepository,
@@ -160,7 +162,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
final CalendarReadPlatformService calendarReadPlatformService, final StaffReadPlatformService staffReadPlatformService,
final PaymentTypeReadPlatformService paymentTypeReadPlatformService,
final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory,
final FloatingRatesReadPlatformService floatingRatesReadPlatformService, final LoanUtilService loanUtilService) {
final FloatingRatesReadPlatformService floatingRatesReadPlatformService, final LoanUtilService loanUtilService,
final ConfigurationDomainService configurationDomainService) {
this.context = context;
this.loanRepository = loanRepository;
this.loanTransactionRepository = loanTransactionRepository;
@@ -180,6 +183,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
this.loanRepaymentScheduleTransactionProcessorFactory = loanRepaymentScheduleTransactionProcessorFactory;
this.floatingRatesReadPlatformService = floatingRatesReadPlatformService;
this.loanUtilService = loanUtilService;
this.configurationDomainService = configurationDomainService;
}
@Override
@@ -1559,6 +1563,10 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
public Collection<LoanScheduleAccrualData> retriveScheduleAccrualData() {
LoanScheduleAccrualMapper mapper = new LoanScheduleAccrualMapper();
Date organisationStartDate = this.configurationDomainService.retrieveOrganisationStartDate();
if(organisationStartDate == null){
organisationStartDate = new Date();
}
final StringBuilder sqlBuilder = new StringBuilder(400);
sqlBuilder
.append("select ")
@@ -1566,15 +1574,23 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
.append(" where ((ls.fee_charges_amount <> if(ls.accrual_fee_charges_derived is null,0, ls.accrual_fee_charges_derived))")
.append(" or ( ls.penalty_charges_amount <> if(ls.accrual_penalty_charges_derived is null,0,ls.accrual_penalty_charges_derived))")
.append(" or ( ls.interest_amount <> if(ls.accrual_interest_derived is null,0,ls.accrual_interest_derived)))")
.append(" and loan.loan_status_id=? and mpl.accounting_type=? and loan.is_npa=0 and ls.duedate <= CURDATE() order by loan.id,ls.duedate");
return this.jdbcTemplate.query(sqlBuilder.toString(), mapper, new Object[] { LoanStatus.ACTIVE.getValue(),
AccountingRuleType.ACCRUAL_PERIODIC.getValue() });
.append(" and ls.duedate > :organisationstartdate and loan.loan_status_id=:active and mpl.accounting_type=:type and loan.is_npa=0 and ls.duedate <= CURDATE() order by loan.id,ls.duedate");
Map<String, Object> paramMap = new HashMap<>(3);
paramMap.put("active", LoanStatus.ACTIVE.getValue());
paramMap.put("type", AccountingRuleType.ACCRUAL_PERIODIC.getValue());
paramMap.put("organisationstartdate", formatter.print(new LocalDate(organisationStartDate)));
return this.namedParameterJdbcTemplate.query(sqlBuilder.toString(), paramMap, mapper);
}
@Override
public Collection<LoanScheduleAccrualData> retrivePeriodicAccrualData(final LocalDate tillDate) {
LoanSchedulePeriodicAccrualMapper mapper = new LoanSchedulePeriodicAccrualMapper();
Date organisationStartDate = this.configurationDomainService.retrieveOrganisationStartDate();
if(organisationStartDate == null){
organisationStartDate = new Date();
}
final StringBuilder sqlBuilder = new StringBuilder(400);
sqlBuilder
.append("select ")
@@ -1582,11 +1598,13 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
.append(" where ((ls.fee_charges_amount <> if(ls.accrual_fee_charges_derived is null,0, ls.accrual_fee_charges_derived))")
.append(" or (ls.penalty_charges_amount <> if(ls.accrual_penalty_charges_derived is null,0,ls.accrual_penalty_charges_derived))")
.append(" or (ls.interest_amount <> if(ls.accrual_interest_derived is null,0,ls.accrual_interest_derived)))")
.append(" and loan.loan_status_id=:active and mpl.accounting_type=:type and loan.is_npa=0 and (ls.duedate <= :tilldate or (ls.duedate > :tilldate and ls.fromdate < :tilldate)) order by loan.id,ls.duedate");
Map<String, Object> paramMap = new HashMap<>(3);
.append(" and loan.loan_status_id=:active and mpl.accounting_type=:type and ls.duedate > :organisationstartdate and (loan.closedon_date <= :tilldate or loan.closedon_date is null)")
.append(" and loan.is_npa=0 and (ls.duedate <= :tilldate or (ls.duedate > :tilldate and ls.fromdate < :tilldate)) order by loan.id,ls.duedate");
Map<String, Object> paramMap = new HashMap<>(4);
paramMap.put("active", LoanStatus.ACTIVE.getValue());
paramMap.put("type", AccountingRuleType.ACCRUAL_PERIODIC.getValue());
paramMap.put("tilldate", formatter.print(tillDate));
paramMap.put("organisationstartdate", formatter.print(new LocalDate(organisationStartDate)));
return this.namedParameterJdbcTemplate.query(sqlBuilder.toString(), paramMap, mapper);
}
@@ -0,0 +1,2 @@
ALTER TABLE `c_configuration`
ADD COLUMN `date_value` DATE NULL DEFAULT NULL AFTER `value`;