FINERACT-1724 Improve cashier data validator

This commit is contained in:
Peter Bagrij
2023-12-11 10:38:53 +01:00
committed by Adam Saghy
parent 6dbab1737e
commit fb492b8172
2 changed files with 42 additions and 24 deletions
@@ -21,13 +21,15 @@ package org.apache.fineract.organisation.teller.data;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.util.HashMap;
import java.util.Map;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.infrastructure.core.service.MathUtil;
import org.apache.fineract.infrastructure.core.service.SearchParameters;
import org.apache.fineract.organisation.teller.domain.Cashier;
import org.apache.fineract.organisation.teller.domain.Teller;
import org.apache.fineract.organisation.teller.exception.CashierAlreadyAlloacated;
import org.apache.fineract.organisation.teller.exception.CashierAlreadyAllocated;
import org.apache.fineract.organisation.teller.exception.CashierDateRangeOutOfTellerDateRangeException;
import org.apache.fineract.organisation.teller.exception.CashierInsufficientAmountException;
import org.apache.fineract.organisation.teller.service.TellerManagementReadPlatformService;
@@ -36,19 +38,19 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Component;
@Component
public class CashierTransactionDataValidator {
private final TellerManagementReadPlatformService tellerManagementReadPlatformService;
private final JdbcTemplate jdbcTemplate;
private final NamedParameterJdbcTemplate jdbcTemplate;
private static final Logger LOG = LoggerFactory.getLogger(CashierTransactionDataValidator.class);
@Autowired
public CashierTransactionDataValidator(final TellerManagementReadPlatformService tellerManagementReadPlatformService,
final JdbcTemplate jdbcTemplate) {
final NamedParameterJdbcTemplate jdbcTemplate) {
this.tellerManagementReadPlatformService = tellerManagementReadPlatformService;
this.jdbcTemplate = jdbcTemplate;
}
@@ -80,25 +82,35 @@ public class CashierTransactionDataValidator {
final LocalDate endDate = cashier.getEndDate();
final LocalDate tellerFromDate = teller.getStartDate();
final LocalDate tellerEndDate = teller.getEndDate();
// to validate cashier date range in range of teller date range
// Validate cashier date range in range of teller date range
if (DateUtils.isBefore(fromDate, tellerFromDate) || DateUtils.isBefore(endDate, tellerFromDate)
|| (tellerEndDate != null && (DateUtils.isAfter(fromDate, tellerEndDate) || DateUtils.isAfter(endDate, tellerEndDate)))) {
throw new CashierDateRangeOutOfTellerDateRangeException();
}
// to validate cashier has not been assigned for same duration
String sql = "select count(*) from m_cashiers c where c.staff_id = " + staffId + " AND " + "(('" + fromDate
+ "' BETWEEN c.start_date AND c.end_date OR '" + endDate + "' BETWEEN c.start_date AND c.end_date )"
+ " OR ( c.start_date BETWEEN '" + fromDate + "' AND '" + endDate + "' OR c.end_date BETWEEN '" + fromDate + "' AND '"
+ endDate + "'))";
// Validate cashier has not been assigned for the same duration
String sql = "SELECT COUNT(*) FROM m_cashiers c WHERE c.staff_id = :staffId AND "
+ "((:fromDate BETWEEN c.start_date AND c.end_date OR :endDate BETWEEN c.start_date AND c.end_date) "
+ "OR (c.start_date BETWEEN :fromDate AND :endDate OR c.end_date BETWEEN :fromDate AND :endDate))";
if (!cashier.getIsFullDay()) {
String startTime = cashier.getStartTime();
String endTime = cashier.getEndTime();
sql = sql + " AND ( Time(c.start_time) BETWEEN TIME('" + startTime + "') and TIME('" + endTime
+ "') or Time(c.end_time) BETWEEN TIME('" + startTime + "') and TIME('" + endTime + "')) ";
sql += " AND (TIME(c.start_time) BETWEEN TIME(:startTime) AND TIME(:endTime) "
+ "OR TIME(c.end_time) BETWEEN TIME(:startTime) AND TIME(:endTime))";
}
int count = this.jdbcTemplate.queryForObject(sql, Integer.class); // NOSONAR
if (count > 0) {
throw new CashierAlreadyAlloacated();
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("staffId", staffId);
paramMap.put("fromDate", fromDate);
paramMap.put("endDate", endDate);
if (!cashier.getIsFullDay()) {
paramMap.put("startTime", cashier.getStartTime());
paramMap.put("endTime", cashier.getEndTime());
}
Integer count = jdbcTemplate.queryForObject(sql, paramMap, Integer.class);
if (count != null && count > 0) {
throw new CashierAlreadyAllocated();
}
}
@@ -106,12 +118,18 @@ public class CashierTransactionDataValidator {
LocalDate tenantDate = DateUtils.getLocalDateOfTenant();
OffsetDateTime tenantDateTime = DateUtils.getOffsetDateTimeOfTenant();
if (user.getStaff() != null) {
String sql = "select c.id from m_cashiers c where c.staff_id = " + user.getStaff().getId() + " AND (case when c.full_day then '"
+ tenantDate + "' BETWEEN c.start_date AND c.end_date else ('" + tenantDate
+ "' BETWEEN c.start_date AND c.end_date and TIME('" + tenantDateTime
+ "') BETWEEN TIME(c.start_time) AND TIME(c.end_time)) end)";
String sql = "SELECT c.id FROM m_cashiers c WHERE c.staff_id = :staffId "
+ "AND (CASE WHEN c.full_day THEN :tenantDate BETWEEN c.start_date AND c.end_date "
+ "ELSE (:tenantDate BETWEEN c.start_date AND c.end_date AND "
+ "TIME(:tenantDateTime) BETWEEN TIME(c.start_time) AND TIME(c.end_time)) END)";
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("staffId", user.getStaff().getId());
paramMap.put("tenantDate", tenantDate);
paramMap.put("tenantDateTime", tenantDateTime);
try {
Long cashierId = this.jdbcTemplate.queryForObject(sql, Long.class); // NOSONAR
Long cashierId = jdbcTemplate.queryForObject(sql, paramMap, Long.class);
validateSettleCashAndCashOutTransactions(cashierId, currencyCode, transactionAmount);
} catch (EmptyResultDataAccessException e) {
LOG.error("Problem occurred in validateOnLoanDisbursal function", e);
@@ -21,9 +21,9 @@ package org.apache.fineract.organisation.teller.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
@SuppressWarnings("serial")
public class CashierAlreadyAlloacated extends AbstractPlatformDomainRuleException {
public class CashierAlreadyAllocated extends AbstractPlatformDomainRuleException {
public CashierAlreadyAlloacated() {
public CashierAlreadyAllocated() {
super("cashier.already.allocated.for.given.data.and.time.exception", "Cashier already allocated for given date and time range.");
}