IDEMPIERE-4824 Boolean Logic Expression Enhancements (#748)
* IDEMPIERE-4824 Boolean Logic Expression Enhancements Fix comparison operator not working for timestamp value
This commit is contained in:
parent
c33d0528a7
commit
10812c486d
|
@ -25,6 +25,8 @@
|
|||
package org.idempiere.expression.logic;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.compiere.util.Evaluatee;
|
||||
|
@ -88,18 +90,35 @@ public class EvaluationVisitor extends SimpleBooleanBaseVisitor<Object> {
|
|||
return super.visit(ctx.expression());
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@Override
|
||||
public Object visitComparatorExpression(SimpleBooleanParser.ComparatorExpressionContext ctx) {
|
||||
if (ctx.op.EQ() != null) {
|
||||
return isEqual(ctx);
|
||||
} else if (ctx.op.LE() != null) {
|
||||
return asBigDecimal(ctx.left).compareTo(asBigDecimal(ctx.right)) <= 0;
|
||||
Comparable leftValue = asComparable(ctx.left);
|
||||
Comparable rightValue = asComparable(ctx.right);
|
||||
if (leftValue == null || rightValue == null)
|
||||
return Boolean.FALSE;
|
||||
return leftValue.compareTo(rightValue) <= 0;
|
||||
} else if (ctx.op.GE() != null) {
|
||||
return asBigDecimal(ctx.left).compareTo(asBigDecimal(ctx.right)) >= 0;
|
||||
Comparable leftValue = asComparable(ctx.left);
|
||||
Comparable rightValue = asComparable(ctx.right);
|
||||
if (leftValue == null || rightValue == null)
|
||||
return Boolean.FALSE;
|
||||
return leftValue.compareTo(rightValue) >= 0;
|
||||
} else if (ctx.op.LT() != null) {
|
||||
return asBigDecimal(ctx.left).compareTo(asBigDecimal(ctx.right)) < 0;
|
||||
Comparable leftValue = asComparable(ctx.left);
|
||||
Comparable rightValue = asComparable(ctx.right);
|
||||
if (leftValue == null || rightValue == null)
|
||||
return Boolean.FALSE;
|
||||
return leftValue.compareTo(rightValue) < 0;
|
||||
} else if (ctx.op.GT() != null) {
|
||||
return asBigDecimal(ctx.left).compareTo(asBigDecimal(ctx.right)) > 0;
|
||||
Comparable leftValue = asComparable(ctx.left);
|
||||
Comparable rightValue = asComparable(ctx.right);
|
||||
if (leftValue == null || rightValue == null)
|
||||
return Boolean.FALSE;
|
||||
return leftValue.compareTo(rightValue) > 0;
|
||||
} else if (ctx.op.NE() != null) {
|
||||
return !(isEqual(ctx));
|
||||
} else if (ctx.op.RE() != null) {
|
||||
|
@ -215,13 +234,35 @@ public class EvaluationVisitor extends SimpleBooleanBaseVisitor<Object> {
|
|||
return (boolean) visit(ctx);
|
||||
}
|
||||
|
||||
private BigDecimal asBigDecimal(SimpleBooleanParser.ExpressionContext ctx) {
|
||||
private static final Pattern jdbcTimestampPattern = Pattern.compile(".*[-].*[-].*[:].*[:].*");
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private Comparable asComparable(SimpleBooleanParser.ExpressionContext ctx) {
|
||||
Object value = visit(ctx);
|
||||
if (value instanceof String)
|
||||
return new BigDecimal((String)value);
|
||||
else if (value instanceof BigDecimal)
|
||||
if (value instanceof String) {
|
||||
String s = (String) value;
|
||||
if (Util.isEmpty(s, true))
|
||||
return null;
|
||||
|
||||
Matcher matcher = jdbcTimestampPattern.matcher(s);
|
||||
if (matcher.matches()) {
|
||||
try {
|
||||
return Timestamp.valueOf(s);
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
try {
|
||||
return new BigDecimal(s);
|
||||
} catch (Exception e) {}
|
||||
} else if (value instanceof BigDecimal) {
|
||||
return (BigDecimal)value;
|
||||
} else if (value instanceof Timestamp) {
|
||||
return (Timestamp)value;
|
||||
}
|
||||
|
||||
//fall back to comparable and string
|
||||
if (value instanceof Comparable)
|
||||
return (Comparable)value;
|
||||
else
|
||||
return new BigDecimal(value.toString());
|
||||
return value.toString();
|
||||
}
|
||||
}
|
|
@ -33,6 +33,7 @@ import static org.junit.jupiter.api.Assertions.fail;
|
|||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -44,6 +45,7 @@ import org.compiere.util.DB;
|
|||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Evaluatee;
|
||||
import org.compiere.util.LegacyLogicEvaluator;
|
||||
import org.compiere.util.TimeUtil;
|
||||
import org.idempiere.expression.logic.LogicEvaluator;
|
||||
import org.idempiere.test.AbstractTestCase;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -492,6 +494,32 @@ public class LogicExpressionTest extends AbstractTestCase {
|
|||
assertTrue(exceptions.isEmpty(), "Found " + exceptions.size() + " logic expression with invalid syntax in AD");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDateExpression() {
|
||||
String expr = "@DateAcct@<@DateOrdered@";
|
||||
Timestamp today = TimeUtil.getDay(System.currentTimeMillis());
|
||||
|
||||
Env.setContext(Env.getCtx(), "DateAcct", (Timestamp)null);
|
||||
Env.setContext(Env.getCtx(), "DateOrdered", (Timestamp)null);
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "DateAcct", today);
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "DateOrdered", today);
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "DateAcct", TimeUtil.addDays(today, -1));
|
||||
assertTrue(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
|
||||
Env.setContext(Env.getCtx(), "DateAcct", (Timestamp)null);
|
||||
Env.setContext(Env.getCtx(), "DateOrdered", (Timestamp)null);
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "DateAcct", today);
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "DateOrdered", today);
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "DateAcct", TimeUtil.addDays(today, -1));
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
}
|
||||
|
||||
private static class ContextEvaluatee implements Evaluatee {
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue