Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding organisation start in global configuartion #12

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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));

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@
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;
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;
Expand Down Expand Up @@ -71,6 +73,11 @@ public void validateForUpdate(final JsonCommand command) {
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).ignoreIfNull();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing is being validated? looks like missing validation

}

if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -63,4 +64,8 @@ public interface ConfigurationDomainService {
int getRoundingMode();

boolean isBackdatePenaltiesEnabled();

boolean isOrganisationstartDateEnable();

Date retriveOrganisationStartDate();
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -214,4 +215,18 @@ public boolean isBackdatePenaltiesEnabled() {
return property.isEnabled();
}

@Override
public boolean isOrganisationstartDateEnable() {
final String propertyName = "organisation-start-date";
final GlobalConfigurationProperty property = this.globalConfigurationRepository.findOneByNameWithNotFoundDetection(propertyName);
return property.isEnabled();
}

@Override
public Date retriveOrganisationStartDate() {
final String propertyName = "organisation-start-date";
final GlobalConfigurationProperty property = this.globalConfigurationRepository.findOneByNameWithNotFoundDetection(propertyName);
return property.getDateValue();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
package org.apache.fineract.infrastructure.configuration.domain;

import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

Expand All @@ -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;
Expand All @@ -53,15 +57,17 @@ protected GlobalConfigurationProperty() {
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;
}
Expand All @@ -73,6 +79,10 @@ public boolean isEnabled() {
public Long getValue() {
return this.value;
}

public Date getDateValue(){
return this.dateValue;
}

public boolean updateTo(final boolean value) {
final boolean updated = this.enabled != value;
Expand Down Expand Up @@ -100,6 +110,13 @@ public Map<String, Object> update(final JsonCommand command) {
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)) {
Expand All @@ -112,7 +129,7 @@ public Map<String, Object> update(final JsonCommand command) {
}

public static GlobalConfigurationProperty newSurveyConfiguration(final String name) {
return new GlobalConfigurationProperty(name, false, null, null, false);
return new GlobalConfigurationProperty(name, false, null, null, null, false);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;

@Service
Expand All @@ -52,7 +53,7 @@ public GlobalConfigurationData retrieveGlobalConfiguration(final boolean survey)

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 ";
Expand All @@ -71,7 +72,7 @@ public GlobalConfigurationPropertyData retrieveGlobalConfiguration(Long configId

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 });
Expand All @@ -88,10 +89,11 @@ public GlobalConfigurationPropertyData mapRow(final ResultSet rs, @SuppressWarni
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);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -437,6 +438,8 @@ public void reverseTransfer(final LoanTransaction loanTransaction) {
@Override
public void recalculateAccruals(Loan loan) {
LocalDate accruedTill = loan.getAccruedTill();
boolean isOrganisationDateEnabled = this.configurationDomainService.isOrganisationstartDateEnable();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make the API as Enabled.... it is better for readability

Date organisationStartDate = this.configurationDomainService.retriveOrganisationStartDate();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do this only when Start Date is enabled.... one DB query can be avoided....
Also it is better to keep API spellings clean

if (!loan.isPeriodicAccrualAccountingEnabledOnLoanProduct() || !loan.repaymentScheduleDetail().isInterestRecalculationEnabled()
|| accruedTill == null || loan.isNpa() || !loan.status().isActive()) { return; }
Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas = new ArrayList<>();
Expand All @@ -454,7 +457,7 @@ public void recalculateAccruals(Loan loan) {
Set<LoanCharge> loanCharges = loan.charges();

for (LoanRepaymentScheduleInstallment installment : installments) {
if (!accruedTill.isBefore(installment.getDueDate())
if (isOrganisationDateEnabled && new LocalDate(organisationStartDate).isBefore(installment.getDueDate()) && !accruedTill.isBefore(installment.getDueDate())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If organisationStartDate is not enabled.... this value might be null.... is this scenario tested?

|| (accruedTill.isAfter(installment.getFromDate()) && !accruedTill.isAfter(installment.getDueDate()))) {
BigDecimal dueDateFeeIncome = BigDecimal.ZERO;
BigDecimal dueDatePenaltyIncome = BigDecimal.ZERO;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
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;
Expand Down Expand Up @@ -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,
Expand All @@ -160,7 +162,8 @@ public LoanReadPlatformServiceImpl(final PlatformSecurityContext context, final
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;
Expand All @@ -180,6 +183,7 @@ public LoanReadPlatformServiceImpl(final PlatformSecurityContext context, final
this.loanRepaymentScheduleTransactionProcessorFactory = loanRepaymentScheduleTransactionProcessorFactory;
this.floatingRatesReadPlatformService = floatingRatesReadPlatformService;
this.loanUtilService = loanUtilService;
this.configurationDomainService = configurationDomainService;
}

@Override
Expand Down Expand Up @@ -1559,34 +1563,42 @@ public LoanTermVariationsData mapRow(final ResultSet rs, @SuppressWarnings("unus
public Collection<LoanScheduleAccrualData> retriveScheduleAccrualData() {

LoanScheduleAccrualMapper mapper = new LoanScheduleAccrualMapper();
final Date organisationStartDate = this.configurationDomainService.retriveOrganisationStartDate();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens when organisationStartDate is disabled?

final StringBuilder sqlBuilder = new StringBuilder(400);
sqlBuilder
.append("select ")
.append(mapper.schema())
.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)));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens when organisationStartDate is disabled?


return this.namedParameterJdbcTemplate.query(sqlBuilder.toString(), paramMap, mapper);
}

@Override
public Collection<LoanScheduleAccrualData> retrivePeriodicAccrualData(final LocalDate tillDate) {

LoanSchedulePeriodicAccrualMapper mapper = new LoanSchedulePeriodicAccrualMapper();
final Date organisationStartDate = this.configurationDomainService.retriveOrganisationStartDate();
final StringBuilder sqlBuilder = new StringBuilder(400);
sqlBuilder
.append("select ")
.append(mapper.schema())
.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);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE `c_configuration`
ADD COLUMN `date_value` DATE NULL DEFAULT NULL AFTER `value`;