RuleProcessor.java
package com.tradecloud.repository.workload.impl;
import com.tradecloud.domain.base.utils.DateUtils;
import com.tradecloud.domain.workload.DateFilter;
import com.tradecloud.domain.workload.DateFormulaOperator;
import com.tradecloud.domain.workload.WorkLoadAllocation;
import com.tradecloud.domain.workload.WorkLoadRule;
import org.hibernate.Session;
import org.hibernate.query.NativeQuery;
import org.hibernate.transform.Transformers;
import org.hibernate.type.StandardBasicTypes;
import java.util.*;
public abstract class RuleProcessor {
private Session session;
public RuleProcessor(Session session) {
this.session = session;
}
private static final Map<DateFormulaOperator, String> OPERATOR_MAP = Map.of(
DateFormulaOperator.EQUAL_TO, "= date(:dateV)",
DateFormulaOperator.LESS_THAN, "< date(:dateV)",
DateFormulaOperator.GREATER_THAN, "> date(:dateV)",
DateFormulaOperator.GREATER_THAN_OR_EQUAL_TO, ">= date(:dateV)",
DateFormulaOperator.LESS_THAN_OR_EQUAL_TO, "<= date(:dateV)"
);
public List<Map<String, String>> findAllByRule(WorkLoadRule rule) {
String baseTable = getBaseTable();
String joinClause = getJoinClause(rule);
// Get the column name for filtering
String dateColumn = getDateColumn(rule.getDateFilter());
if (dateColumn == null) {
return Collections.emptyList();
}
// Construct the query
String sql = String.format(
getQuery(),
dateFilterStringMap().get(rule.getPriorityDateFilter()) ,baseTable, joinClause, dateColumn
);
sql = addDateFilter(rule, sql);
sql += getExcludeFilter();
sql = filterByRuleAttribute(rule, sql);
sql = addServiceProvideFilter(rule, sql);
sql = addPaymentTermFilter(rule, sql);
if(rule.getModeOfTransport()!=null) {
sql = addShippingModeFilter(rule, sql);
}
if(rule.getOrderStates()!=null && !rule.getOrderStates().isEmpty()){
sql = addOrderStatesFilter(rule, sql);
}
// Execute the query
NativeQuery nativeQuery = session
.createNativeQuery(sql);
Date formulaDate = DateUtils.getStartOfDay(DateUtils.addDays(new Date(), rule.getDateFormulaValue()));
nativeQuery.setParameter("dateV", formulaDate);
if(rule.getServiceProviderType()!=null && rule.getServiceProvider()!=null){
nativeQuery = nativeQuery.setParameter("sp_id", rule.getServiceProvider().getId());
}
if(rule.getModeOfTransport()!=null) {
nativeQuery.setParameter("shippingMode",rule.getModeOfTransport().name());
}
if(rule.getOrderStates()!=null && !rule.getOrderStates().isEmpty()){
nativeQuery.setParameterList("orderStates",rule.getOrderStates().stream().map(orderState -> orderState.name()).toList());
}
if(rule.getPaymentTerm()!=null){
nativeQuery.setParameter("paymentTerm",rule.getPaymentTerm().getCode());
}
return nativeQuery
.addScalar("id", StandardBasicTypes.STRING)
.addScalar("reference", StandardBasicTypes.STRING)
.addScalar("supplier", StandardBasicTypes.STRING)
.addScalar("number", StandardBasicTypes.STRING)
.addScalar("ruledate", StandardBasicTypes.STRING)
.addScalar("state", StandardBasicTypes.STRING)
.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP)
.list();
}
protected abstract String addPaymentTermFilter(WorkLoadRule rule, String sql);
protected abstract String addOrderStatesFilter(WorkLoadRule rule, String sql);
private String getDateColumn(DateFilter dateFilter) {
String dateColumn = Optional.ofNullable(dateFilterStringMap().get(dateFilter))
.filter(s -> !s.isBlank())
.map(s -> String.format("date(%s)", s))
.orElseThrow(() -> new IllegalArgumentException(
"No date column mapping found for filter: " + dateFilter
));
return dateColumn;
}
protected abstract String addShippingModeFilter(WorkLoadRule rule, String sql);
protected abstract String getQuery();
protected abstract String getExcludeFilter();
protected abstract String getBaseTable();
protected abstract Map<DateFilter, String> dateFilterStringMap();
protected abstract String addServiceProvideFilter(WorkLoadRule rule, String sql);
protected abstract String filterByRuleAttribute(WorkLoadRule rule, String sql);
private String addDateFilter(WorkLoadRule workLoadRule, String sql) {
String operator = OPERATOR_MAP.get(workLoadRule.getDateFormulaOperator());
if (operator == null) {
throw new IllegalStateException("Cannot process date formula operation: " + workLoadRule.getDateFormulaOperator());
}
return sql + operator;
}
protected abstract String getJoinClause(WorkLoadRule rule);
public List<Map<String, String>> findPriorityAttr(WorkLoadAllocation workLoadAllocation) {
WorkLoadRule workLoadRule = workLoadAllocation.getWorkLoadRule();
String sql = getPriorityFieldsSql(workLoadRule);
NativeQuery nativeQuery = session
.createNativeQuery(String.format(sql, getDateColumn(workLoadRule.getPriorityDateFilter())));
nativeQuery.setParameter("entityId", workLoadAllocation.getEntityId());
return nativeQuery
.addScalar("priorityDate", StandardBasicTypes.STRING)
.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP)
.list();
}
protected abstract String getPriorityFieldsSql(WorkLoadRule rule);
}