IDEMPIERE-4470 Window Advanced Search - New operator types: AND Not, Or Not (#850)

* IDEMPIERE-4470 Window Advanced Search - New operator types: AND Not, Or Not

Based on pull request 170
Co-authored-by: Igor Pojzl <igor.pojzl@cloudempiere.com>

* IDEMPIERE-4470 Window Advanced Search - New operator types: AND Not, Or Not

Rename migration scripts as suggested by Heng Sin
This commit is contained in:
Carlos Ruiz 2021-09-03 16:20:50 +02:00 committed by GitHub
parent 88e0f55b9d
commit 39ad82ebf0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 137 additions and 24 deletions

View File

@ -0,0 +1,14 @@
SET SQLBLANKLINES ON
SET DEFINE OFF
-- IDEMPIERE-4364 - Advanced Search - Allow select column from window tabs.
-- Jul 17, 2020, 9:33:17 AM CEST
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','AND NOT',0,0,'Y',TO_DATE('2020-07-17 09:33:17','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2020-07-17 09:33:17','YYYY-MM-DD HH24:MI:SS'),100,200621,'ANDNOT','D','edddd9d0-bfc5-44b9-bba8-cfa4e5ab8d2a')
;
-- Jul 17, 2020, 9:35:20 AM CEST
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','OR NOT',0,0,'Y',TO_DATE('2020-07-17 09:35:20','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2020-07-17 09:35:20','YYYY-MM-DD HH24:MI:SS'),100,200622,'ORNOT','D','dc113e24-35bc-4736-8de0-22a036e9f01b')
;
SELECT register_migration_script('202007171100_IDEMPIERE-4364.sql') FROM dual
;

View File

@ -46,7 +46,6 @@ UPDATE AD_Field SET SeqNo=170,IsDisplayed='Y', Updated=getDate(), UpdatedBy=100
UPDATE AD_Field SET DisplayLogic='@DataType@=S', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2021-03-07 21:09:10','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206602 UPDATE AD_Field SET DisplayLogic='@DataType@=S', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2021-03-07 21:09:10','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206602
; ;
SELECT register_migration_script('202103081000_IDEMPIERE-4724.sql') FROM dual SELECT register_migration_script('202109031531_IDEMPIERE-4470.sql') FROM dual
; ;

View File

@ -0,0 +1,11 @@
-- IDEMPIERE-4364 - Advanced Search - Allow select column from window tabs.
-- Jul 17, 2020, 9:33:17 AM CEST
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','AND NOT',0,0,'Y',TO_TIMESTAMP('2020-07-17 09:33:17','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2020-07-17 09:33:17','YYYY-MM-DD HH24:MI:SS'),100,200621,'ANDNOT','D','edddd9d0-bfc5-44b9-bba8-cfa4e5ab8d2a')
;
-- Jul 17, 2020, 9:35:20 AM CEST
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','OR NOT',0,0,'Y',TO_TIMESTAMP('2020-07-17 09:35:20','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2020-07-17 09:35:20','YYYY-MM-DD HH24:MI:SS'),100,200622,'ORNOT','D','dc113e24-35bc-4736-8de0-22a036e9f01b')
;
SELECT register_migration_script('202007171100_IDEMPIERE-4364.sql') FROM dual
;

View File

@ -43,7 +43,6 @@ UPDATE AD_Field SET SeqNo=170,IsDisplayed='Y', Updated=statement_timestamp(), Up
UPDATE AD_Field SET DisplayLogic='@DataType@=S', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2021-03-07 21:09:10','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206602 UPDATE AD_Field SET DisplayLogic='@DataType@=S', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2021-03-07 21:09:10','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206602
; ;
SELECT register_migration_script('202103081000_IDEMPIERE-4724.sql') FROM dual SELECT register_migration_script('202109031531_IDEMPIERE-4470.sql') FROM dual
; ;

View File

@ -55,7 +55,7 @@ public class MQuery implements Serializable, Cloneable
/** /**
* *
*/ */
private static final long serialVersionUID = -8412818805510431201L; private static final long serialVersionUID = 4726305684993324747L;
/** /**
* Get Query from Parameter * Get Query from Parameter
@ -659,6 +659,24 @@ public class MQuery implements Serializable, Cloneable
m_list.add(r); m_list.add(r);
} // addRestriction } // addRestriction
/*************************************************************************
* Add Restriction
* @param ColumnName ColumnName
* @param Operator Operator, e.g. = != ..
* @param Code Code, e.g 0, All%
* @param InfoName Display Name
* @param InfoDisplay Display of Code (Lookup)
* @param andOrCondition AND/OR/AND NOT/OR NOT - concatenation of parenthesis
* @param depth ( = no open brackets )
*/
public void addRestriction (String ColumnName, String Operator,
Object Code, String InfoName, String InfoDisplay, String andOrCondition, int depth)
{
Restriction r = new Restriction (ColumnName, Operator,
Code, InfoName, InfoDisplay, andOrCondition, depth);
m_list.add(r);
} // addRestriction
/************************************************************************* /*************************************************************************
* Add Restriction * Add Restriction
* @param ColumnName ColumnName * @param ColumnName ColumnName
@ -717,9 +735,29 @@ public class MQuery implements Serializable, Cloneable
public void addRangeRestriction (String ColumnName, public void addRangeRestriction (String ColumnName,
Object Code, Object Code_to, Object Code, Object Code_to,
String InfoName, String InfoDisplay, String InfoDisplay_to, boolean andCondition, int depth) String InfoName, String InfoDisplay, String InfoDisplay_to, boolean andCondition, int depth)
{
addRangeRestriction(ColumnName,
Code, Code_to,
InfoName, InfoDisplay, InfoDisplay_to, andCondition ? "AND" : "OR", depth);
}
/**
* Add Range Restriction (BETWEEN)
* @param ColumnName ColumnName
* @param Code Code, e.g 0, All%
* @param Code_to Code, e.g 0, All%
* @param InfoName Display Name
* @param InfoDisplay Display of Code (Lookup)
* @param InfoDisplay_to Display of Code (Lookup)
* @param andOrCondition AND/OR/AND NOT/OR NOT - concatenation of parenthesis
* @param depth ( = no open brackets )
*/
public void addRangeRestriction (String ColumnName,
Object Code, Object Code_to,
String InfoName, String InfoDisplay, String InfoDisplay_to, String andOrCondition, int depth)
{ {
Restriction r = new Restriction (ColumnName, Code, Code_to, Restriction r = new Restriction (ColumnName, Code, Code_to,
InfoName, InfoDisplay, InfoDisplay_to, andCondition, depth); InfoName, InfoDisplay, InfoDisplay_to, andOrCondition, depth);
m_list.add(r); m_list.add(r);
} // addRestriction } // addRestriction
@ -842,7 +880,7 @@ public class MQuery implements Serializable, Cloneable
{ {
Restriction r = (Restriction)m_list.get(i); Restriction r = (Restriction)m_list.get(i);
if (i != 0) if (i != 0)
sb.append(r.andCondition ? " AND " : " OR "); sb.append(" ").append(r.andOrCondition).append(" ");
for ( ; currentDepth < r.joinDepth; currentDepth++ ) for ( ; currentDepth < r.joinDepth; currentDepth++ )
{ {
sb.append('('); sb.append('(');
@ -890,7 +928,7 @@ public class MQuery implements Serializable, Cloneable
sb.append(')'); sb.append(')');
} }
if (i != 0) if (i != 0)
sb.append(r.andCondition ? " AND " : " OR "); sb.append(" ").append(r.andOrCondition).append(" ");
// //
sb.append(r.getInfoName()) sb.append(r.getInfoName())
.append(r.getInfoOperator()) .append(r.getInfoOperator())
@ -1211,9 +1249,29 @@ class Restriction implements Serializable
* @param code Code, e.g 0, All% * @param code Code, e.g 0, All%
* @param infoName Display Name * @param infoName Display Name
* @param infoDisplay Display of Code (Lookup) * @param infoDisplay Display of Code (Lookup)
* @param andCondition true->AND false->OR
* @param depth number of parenthesis
*/ */
Restriction (String columnName, String operator, Restriction (String columnName, String operator,
Object code, String infoName, String infoDisplay, boolean andCondition, int depth) Object code, String infoName, String infoDisplay, boolean andCondition, int depth)
{
this(columnName, operator, code, infoName, infoDisplay,
andCondition ? "AND" : "OR",
depth);
}
/**
* Restriction
* @param columnName ColumnName
* @param operator Operator, e.g. = != ..
* @param code Code, e.g 0, All%
* @param infoName Display Name
* @param infoDisplay Display of Code (Lookup)
* @param andOrCondition AND/OR/AND NOT/OR NOT - concatenation of parenthesis
* @param depth number of parenthesis
*/
Restriction (String columnName, String operator,
Object code, String infoName, String infoDisplay, String andOrCondition, int depth)
{ {
this.ColumnName = columnName.trim(); this.ColumnName = columnName.trim();
if (infoName != null) if (infoName != null)
@ -1222,7 +1280,7 @@ class Restriction implements Serializable
InfoName = ColumnName; InfoName = ColumnName;
this.andCondition = andCondition; this.andOrCondition = andOrCondition;
this.joinDepth = depth < 0 ? 0 : depth; this.joinDepth = depth < 0 ? 0 : depth;
// //
@ -1258,12 +1316,33 @@ class Restriction implements Serializable
* @param infoName Display Name * @param infoName Display Name
* @param infoDisplay Display of Code (Lookup) * @param infoDisplay Display of Code (Lookup)
* @param infoDisplay_to Display of Code (Lookup) * @param infoDisplay_to Display of Code (Lookup)
* @param andCondition true->AND false->OR
* @param depth number of parenthesis
*/ */
Restriction (String columnName, Restriction (String columnName,
Object code, Object code_to, Object code, Object code_to,
String infoName, String infoDisplay, String infoDisplay_to, boolean andCondition, int depth) String infoName, String infoDisplay, String infoDisplay_to, boolean andCondition, int depth)
{ {
this (columnName, MQuery.BETWEEN, code, infoName, infoDisplay, andCondition, depth); this(columnName, code, code_to,
infoName, infoDisplay, infoDisplay_to, andCondition ? "AND" : "OR", depth);
}
/**
* Range Restriction (BETWEEN)
* @param columnName ColumnName
* @param code Code, e.g 0, All%
* @param code_to Code, e.g 0, All%
* @param infoName Display Name
* @param infoDisplay Display of Code (Lookup)
* @param infoDisplay_to Display of Code (Lookup)
* @param andOrCondition AND/OR/AND NOT/OR NOT - concatenation of parenthesis
* @param depth number of parenthesis
*/
Restriction (String columnName,
Object code, Object code_to,
String infoName, String infoDisplay, String infoDisplay_to, String andOrCondition, int depth)
{
this (columnName, MQuery.BETWEEN, code, infoName, infoDisplay, andOrCondition, depth);
// Code_to // Code_to
Code_to = code_to; Code_to = code_to;
@ -1284,11 +1363,24 @@ class Restriction implements Serializable
/** /**
* Create Restriction with direct WHERE clause * Create Restriction with direct WHERE clause
* @param whereClause SQL WHERE Clause * @param whereClause SQL WHERE Clause
* @param andCondition true->AND false->OR
* @param depth number of parenthesis
*/ */
Restriction (String whereClause, boolean andCondition, int depth) Restriction (String whereClause, boolean andCondition, int depth)
{
this(whereClause, andCondition ? "AND" : "OR", depth);
}
/**
* Create Restriction with direct WHERE clause
* @param whereClause SQL WHERE Clause
* @param andOrCondition AND/OR/AND NOT/OR NOT - concatenation of parenthesis
* @param depth number of parenthesis
*/
Restriction (String whereClause, String andOrCondition, int depth)
{ {
DirectWhereClause = whereClause; DirectWhereClause = whereClause;
this.andCondition = andCondition; this.andOrCondition = andOrCondition;
this.joinDepth = depth; this.joinDepth = depth;
} // Restriction } // Restriction
@ -1309,7 +1401,7 @@ class Restriction implements Serializable
/** Info To */ /** Info To */
protected String InfoDisplay_to; protected String InfoDisplay_to;
/** And/Or Condition */ /** And/Or Condition */
protected boolean andCondition = true; protected String andOrCondition = "AND";
/** And/Or condition nesting depth ( = number of open brackets at and/or) */ /** And/Or condition nesting depth ( = number of open brackets at and/or) */
protected int joinDepth = 0; protected int joinDepth = 0;

View File

@ -1041,11 +1041,13 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
setValues(listColumn, listOperator, fields); setValues(listColumn, listOperator, fields);
// And Or // And / Or / And Not / Or Not
ValueNamePair[] andOr = new ValueNamePair[] { ValueNamePair[] andOr = new ValueNamePair[] {
new ValueNamePair ("", ""), new ValueNamePair ("", ""),
new ValueNamePair ("AND", Msg.getMsg(Env.getCtx(),"AND")), new ValueNamePair ("AND", Msg.getMsg(Env.getCtx(),"AND")),
new ValueNamePair ("OR", Msg.getMsg(Env.getCtx(),"OR")) new ValueNamePair ("OR", Msg.getMsg(Env.getCtx(),"OR")),
new ValueNamePair ("AND NOT", Msg.getMsg(Env.getCtx(),"ANDNOT")),
new ValueNamePair ("OR NOT", Msg.getMsg(Env.getCtx(),"ORNOT"))
}; };
for (ValueNamePair item: andOr) for (ValueNamePair item: andOr)
@ -1845,10 +1847,6 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
// And Or // And Or
Listbox listAndOr = (Listbox)row.getFellow("listAndOr"+row.getId()); Listbox listAndOr = (Listbox)row.getFellow("listAndOr"+row.getId());
String andOr = listAndOr.getSelectedItem().getValue().toString(); String andOr = listAndOr.getSelectedItem().getValue().toString();
boolean and = true;
if ( rowIndex > 1 ) {
and = !"OR".equals(andOr);
}
// Op // Op
Combobox op = (Combobox)row.getFellow("listOperator"+row.getId()); Combobox op = (Combobox)row.getFellow("listOperator"+row.getId());
if (op == null) if (op == null)
@ -1880,7 +1878,7 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
if(Operator.equals(MQuery.NULL) || Operator.equals(MQuery.NOT_NULL)) if(Operator.equals(MQuery.NULL) || Operator.equals(MQuery.NOT_NULL))
{ {
m_query.addRestriction(ColumnSQL, Operator, null, m_query.addRestriction(ColumnSQL, Operator, null,
infoName, null, and, openBrackets); infoName, null, andOr, openBrackets);
appendCode(code, ColumnName, Operator, "", "", andOr, lBrackets, rBrackets); appendCode(code, ColumnName, Operator, "", "", andOr, lBrackets, rBrackets);
} }
continue; continue;
@ -1924,26 +1922,26 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
if (parsedValue2 == null) if (parsedValue2 == null)
continue; continue;
m_query.addRangeRestriction(ColumnSQL, parsedValue, parsedValue2, m_query.addRangeRestriction(ColumnSQL, parsedValue, parsedValue2,
infoName, infoDisplay, infoDisplay_to, and, openBrackets); infoName, infoDisplay, infoDisplay_to, andOr, openBrackets);
} }
else if (isProductCategoryField && MQuery.OPERATORS[MQuery.EQUAL_INDEX].getValue().equals(Operator)) { else if (isProductCategoryField && MQuery.OPERATORS[MQuery.EQUAL_INDEX].getValue().equals(Operator)) {
if (!(parsedValue instanceof Integer)) { if (!(parsedValue instanceof Integer)) {
continue; continue;
} }
m_query.addRestriction(getSubCategoryWhereClause(field, ((Integer) parsedValue).intValue()), and, openBrackets); m_query.addRestriction(getSubCategoryWhereClause(field, ((Integer) parsedValue).intValue()), andOr, openBrackets);
} }
else if ((field.getDisplayType()==DisplayType.ChosenMultipleSelectionList||field.getDisplayType()==DisplayType.ChosenMultipleSelectionSearch||field.getDisplayType()==DisplayType.ChosenMultipleSelectionTable) && else if ((field.getDisplayType()==DisplayType.ChosenMultipleSelectionList||field.getDisplayType()==DisplayType.ChosenMultipleSelectionSearch||field.getDisplayType()==DisplayType.ChosenMultipleSelectionTable) &&
(MQuery.OPERATORS[MQuery.EQUAL_INDEX].getValue().equals(Operator) || MQuery.OPERATORS[MQuery.NOT_EQUAL_INDEX].getValue().equals(Operator))) (MQuery.OPERATORS[MQuery.EQUAL_INDEX].getValue().equals(Operator) || MQuery.OPERATORS[MQuery.NOT_EQUAL_INDEX].getValue().equals(Operator)))
{ {
String clause = DB.intersectClauseForCSV(ColumnSQL, parsedValue.toString()); String clause = DB.intersectClauseForCSV(ColumnSQL, parsedValue.toString());
if (MQuery.OPERATORS[MQuery.EQUAL_INDEX].getValue().equals(Operator)) if (MQuery.OPERATORS[MQuery.EQUAL_INDEX].getValue().equals(Operator))
m_query.addRestriction(clause, and, openBrackets); m_query.addRestriction(clause, andOr, openBrackets);
else else
m_query.addRestriction("NOT (" + clause + ")", and, openBrackets); m_query.addRestriction("NOT (" + clause + ")", andOr, openBrackets);
} }
else else
m_query.addRestriction(ColumnSQL, Operator, parsedValue, m_query.addRestriction(ColumnSQL, Operator, parsedValue,
infoName, infoDisplay, and, openBrackets); infoName, infoDisplay, andOr, openBrackets);
appendCode(code, ColumnName, Operator, value != null ? value.toString() : "", value2 != null ? value2.toString() : "", andOr, lBrackets, rBrackets); appendCode(code, ColumnName, Operator, value != null ? value.toString() : "", value2 != null ? value2.toString() : "", andOr, lBrackets, rBrackets);
} }