diff --git a/migration/iD10/oracle/202210311420_IDEMPIERE-5468.sql b/migration/iD10/oracle/202210311420_IDEMPIERE-5468.sql
new file mode 100644
index 0000000000..4e636ce2b8
--- /dev/null
+++ b/migration/iD10/oracle/202210311420_IDEMPIERE-5468.sql
@@ -0,0 +1,26 @@
+-- IDEMPIERE-5468
+SELECT register_migration_script('202210311420_IDEMPIERE-5468.sql') FROM dual;
+
+SET SQLBLANKLINES ON
+SET DEFINE OFF
+
+-- Oct 31, 2022, 2:20:52 PM BRT
+INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,Description,PrintName,EntityType,AD_Element_UU) VALUES (203724,0,0,'Y',TO_TIMESTAMP('2022-10-31 14:20:51','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2022-10-31 14:20:51','YYYY-MM-DD HH24:MI:SS'),100,'IsNotClause','Not Clause','Indicates if a chosen multiple component value must be negate','Not Clause','D','d50d4b2c-6ba8-4165-859e-9e307d6b1421')
+;
+
+-- Oct 31, 2022, 2:22:00 PM BRT
+INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,AD_Table_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (215631,0,'Not Clause','Indicates if a chosen multiple component value must be negate',283,'IsNotClause','N',1,'N','N','Y','N','N',0,'N',20,0,0,'Y',TO_TIMESTAMP('2022-10-31 14:22:00','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2022-10-31 14:22:00','YYYY-MM-DD HH24:MI:SS'),100,203724,'Y','N','D','N','N','N','Y','cf018b7d-a0bd-4500-b9fc-ec57ef490418','Y',0,'N','N','N','N')
+;
+
+-- Oct 31, 2022, 2:22:06 PM BRT
+ALTER TABLE AD_PInstance_Para ADD IsNotClause CHAR(1) DEFAULT 'N' CHECK (IsNotClause IN ('Y','N')) NOT NULL
+;
+
+-- Oct 31, 2022, 2:23:59 PM BRT
+ALTER TABLE AD_PInstance_Para MODIFY IsNotClause CHAR(1) DEFAULT 'N'
+;
+
+-- Oct 31, 2022, 2:28:32 PM BRT
+INSERT INTO AD_Field (AD_Field_ID,Name,Description,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan) VALUES (207410,'Not Clause','Indicates if a chosen multiple component value must be negate',664,215631,'Y',1,140,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2022-10-31 14:28:32','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2022-10-31 14:28:32','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','8fa2857f-38a3-4f31-bff6-d6baa56ea352','Y',140,2,2)
+;
+
diff --git a/migration/iD10/oracle/202211301704_IDEMPIERE-5468.sql b/migration/iD10/oracle/202211301704_IDEMPIERE-5468.sql
new file mode 100644
index 0000000000..f6fc2b9e28
--- /dev/null
+++ b/migration/iD10/oracle/202211301704_IDEMPIERE-5468.sql
@@ -0,0 +1,22 @@
+-- IDEMPIERE-5468
+SELECT register_migration_script('202211301704_IDEMPIERE-5468.sql') FROM dual;
+
+SET SQLBLANKLINES ON
+SET DEFINE OFF
+
+-- Nov 30, 2022, 5:04:32 PM BRT
+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','Include selected values',0,0,'Y',TO_TIMESTAMP('2022-11-30 17:04:32','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2022-11-30 17:04:32','YYYY-MM-DD HH24:MI:SS'),100,1000000,'IncludeSelectedValues','U','9794b1f5-cd91-4d8d-95ba-a2f53eca1af5')
+;
+
+-- Nov 30, 2022, 5:04:49 PM BRT
+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','Exclude selected values',0,0,'Y',TO_TIMESTAMP('2022-11-30 17:04:49','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2022-11-30 17:04:49','YYYY-MM-DD HH24:MI:SS'),100,1000001,'ExcludeSelectedValues','U','439b142f-26ab-4224-8e38-d42fc3757750')
+;
+
+-- Nov 30, 2022, 5:04:54 PM BRT
+UPDATE AD_Message SET EntityType='D',Updated=TO_TIMESTAMP('2022-11-30 17:04:54','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=1000001
+;
+
+-- Nov 30, 2022, 5:05:08 PM BRT
+UPDATE AD_Message SET EntityType='D',Updated=TO_TIMESTAMP('2022-11-30 17:05:08','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=1000000
+;
+
diff --git a/migration/iD10/postgresql/202210311420_IDEMPIERE-5468.sql b/migration/iD10/postgresql/202210311420_IDEMPIERE-5468.sql
new file mode 100644
index 0000000000..f2d68e1fec
--- /dev/null
+++ b/migration/iD10/postgresql/202210311420_IDEMPIERE-5468.sql
@@ -0,0 +1,23 @@
+-- IDEMPIERE-5468
+SELECT register_migration_script('202210311420_IDEMPIERE-5468.sql') FROM dual;
+
+-- Oct 31, 2022, 2:20:52 PM BRT
+INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,Description,PrintName,EntityType,AD_Element_UU) VALUES (203724,0,0,'Y',TO_TIMESTAMP('2022-10-31 14:20:51','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2022-10-31 14:20:51','YYYY-MM-DD HH24:MI:SS'),100,'IsNotClause','Not Clause','Indicates if a chosen multiple component value must be negate','Not Clause','D','d50d4b2c-6ba8-4165-859e-9e307d6b1421')
+;
+
+-- Oct 31, 2022, 2:22:00 PM BRT
+INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,AD_Table_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (215631,0,'Not Clause','Indicates if a chosen multiple component value must be negate',283,'IsNotClause','N',1,'N','N','Y','N','N',0,'N',20,0,0,'Y',TO_TIMESTAMP('2022-10-31 14:22:00','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2022-10-31 14:22:00','YYYY-MM-DD HH24:MI:SS'),100,203724,'Y','N','D','N','N','N','Y','cf018b7d-a0bd-4500-b9fc-ec57ef490418','Y',0,'N','N','N','N')
+;
+
+-- Oct 31, 2022, 2:22:06 PM BRT
+ALTER TABLE AD_PInstance_Para ADD COLUMN IsNotClause CHAR(1) DEFAULT 'N' CHECK (IsNotClause IN ('Y','N')) NOT NULL
+;
+
+-- Oct 31, 2022, 2:23:59 PM BRT
+INSERT INTO t_alter_column values('ad_pinstance_para','IsNotClause','CHAR(1)',null,'N')
+;
+
+-- Oct 31, 2022, 2:28:32 PM BRT
+INSERT INTO AD_Field (AD_Field_ID,Name,Description,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan) VALUES (207410,'Not Clause','Indicates if a chosen multiple component value must be negate',664,215631,'Y',1,140,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2022-10-31 14:28:32','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2022-10-31 14:28:32','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','8fa2857f-38a3-4f31-bff6-d6baa56ea352','Y',140,2,2)
+;
+
diff --git a/migration/iD10/postgresql/202211301704_IDEMPIERE-5468.sql b/migration/iD10/postgresql/202211301704_IDEMPIERE-5468.sql
new file mode 100644
index 0000000000..e69184da91
--- /dev/null
+++ b/migration/iD10/postgresql/202211301704_IDEMPIERE-5468.sql
@@ -0,0 +1,19 @@
+-- IDEMPIERE-5468
+SELECT register_migration_script('202211301704_IDEMPIERE-5468.sql') FROM dual;
+
+-- Nov 30, 2022, 5:04:32 PM BRT
+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','Include selected values',0,0,'Y',TO_TIMESTAMP('2022-11-30 17:04:32','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2022-11-30 17:04:32','YYYY-MM-DD HH24:MI:SS'),100,1000000,'IncludeSelectedValues','U','9794b1f5-cd91-4d8d-95ba-a2f53eca1af5')
+;
+
+-- Nov 30, 2022, 5:04:49 PM BRT
+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','Exclude selected values',0,0,'Y',TO_TIMESTAMP('2022-11-30 17:04:49','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2022-11-30 17:04:49','YYYY-MM-DD HH24:MI:SS'),100,1000001,'ExcludeSelectedValues','U','439b142f-26ab-4224-8e38-d42fc3757750')
+;
+
+-- Nov 30, 2022, 5:04:54 PM BRT
+UPDATE AD_Message SET EntityType='D',Updated=TO_TIMESTAMP('2022-11-30 17:04:54','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=1000001
+;
+
+-- Nov 30, 2022, 5:05:08 PM BRT
+UPDATE AD_Message SET EntityType='D',Updated=TO_TIMESTAMP('2022-11-30 17:05:08','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=1000000
+;
+
diff --git a/org.adempiere.base/src/org/compiere/db/AdempiereDatabase.java b/org.adempiere.base/src/org/compiere/db/AdempiereDatabase.java
index 64b3309c19..b6661bb2ff 100644
--- a/org.adempiere.base/src/org/compiere/db/AdempiereDatabase.java
+++ b/org.adempiere.base/src/org/compiere/db/AdempiereDatabase.java
@@ -348,6 +348,14 @@ public interface AdempiereDatabase
*/
public String intersectClauseForCSV(String columnName, String csv);
+ /**
+ * @param columnName
+ * @param csv comma separated value
+ * @param isNotClause
+ * @return subset sql clause
+ */
+ public String intersectClauseForCSV(String columnName, String csv, boolean isNotClause);
+
/**
* Quote column name if necessary (usually to avoid conflict with reserved keywords)
* @param columnName
diff --git a/org.adempiere.base/src/org/compiere/model/I_AD_PInstance_Para.java b/org.adempiere.base/src/org/compiere/model/I_AD_PInstance_Para.java
index 33e93f43fc..c23c6543ee 100644
--- a/org.adempiere.base/src/org/compiere/model/I_AD_PInstance_Para.java
+++ b/org.adempiere.base/src/org/compiere/model/I_AD_PInstance_Para.java
@@ -22,7 +22,7 @@ import org.compiere.util.KeyNamePair;
/** Generated Interface for AD_PInstance_Para
* @author iDempiere (generated)
- * @version Release 9
+ * @version Release 10
*/
public interface I_AD_PInstance_Para
{
@@ -44,8 +44,8 @@ public interface I_AD_PInstance_Para
/** Column name AD_Client_ID */
public static final String COLUMNNAME_AD_Client_ID = "AD_Client_ID";
- /** Get Client.
- * Client/Tenant for this installation.
+ /** Get Tenant.
+ * Tenant for this installation.
*/
public int getAD_Client_ID();
@@ -53,12 +53,12 @@ public interface I_AD_PInstance_Para
public static final String COLUMNNAME_AD_Org_ID = "AD_Org_ID";
/** Set Organization.
- * Organizational entity within client
+ * Organizational entity within tenant
*/
public void setAD_Org_ID (int AD_Org_ID);
/** Get Organization.
- * Organizational entity within client
+ * Organizational entity within tenant
*/
public int getAD_Org_ID();
@@ -137,14 +137,18 @@ public interface I_AD_PInstance_Para
*/
public boolean isActive();
- /** Column name ParameterName */
- public static final String COLUMNNAME_ParameterName = "ParameterName";
+ /** Column name IsNotClause */
+ public static final String COLUMNNAME_IsNotClause = "IsNotClause";
- /** Set Parameter Name */
- public void setParameterName (String ParameterName);
+ /** Set Is not clause.
+ * Indicates if a chosen multiple component value must be negate
+ */
+ public void setIsNotClause (boolean IsNotClause);
- /** Get Parameter Name */
- public String getParameterName();
+ /** Get Is not clause.
+ * Indicates if a chosen multiple component value must be negate
+ */
+ public boolean isNotClause();
/** Column name P_Date */
public static final String COLUMNNAME_P_Date = "P_Date";
@@ -224,6 +228,15 @@ public interface I_AD_PInstance_Para
*/
public String getP_String_To();
+ /** Column name ParameterName */
+ public static final String COLUMNNAME_ParameterName = "ParameterName";
+
+ /** Set Parameter Name */
+ public void setParameterName (String ParameterName);
+
+ /** Get Parameter Name */
+ public String getParameterName();
+
/** Column name SeqNo */
public static final String COLUMNNAME_SeqNo = "SeqNo";
diff --git a/org.adempiere.base/src/org/compiere/model/MQuery.java b/org.adempiere.base/src/org/compiere/model/MQuery.java
index 8d868411c2..cc0070382e 100644
--- a/org.adempiere.base/src/org/compiere/model/MQuery.java
+++ b/org.adempiere.base/src/org/compiere/model/MQuery.java
@@ -93,7 +93,8 @@ public class MQuery implements Serializable, Cloneable
+ "ip.P_Number,ip.P_Number_To," // 4..5
+ "ip.P_Date,ip.P_Date_To, ip.Info,ip.Info_To, " // 6..9
+ "pp.Name, pp.IsRange, pp.AD_Reference_ID, pp.Query, " // 10..13
- + "pp.AD_Process_ID, pp.AD_Process_Para_ID " // 14..15
+ + "pp.AD_Process_ID, pp.AD_Process_Para_ID, " // 14..15
+ + "ip.IsNotClause "
+ "FROM AD_PInstance_Para ip, AD_PInstance i, AD_Process_Para pp "
+ "WHERE i.AD_PInstance_ID=ip.AD_PInstance_ID"
+ " AND pp.AD_Process_ID=i.AD_Process_ID"
@@ -105,7 +106,8 @@ public class MQuery implements Serializable, Cloneable
SQL = "SELECT ip.ParameterName,ip.P_String,ip.P_String_To, ip.P_Number,ip.P_Number_To,"
+ "ip.P_Date,ip.P_Date_To, ip.Info,ip.Info_To, "
+ "ppt.Name, pp.IsRange, pp.AD_Reference_ID, pp.Query, "
- + "pp.AD_Process_ID, pp.AD_Process_Para_ID "
+ + "pp.AD_Process_ID, pp.AD_Process_Para_ID, "
+ + "ip.IsNotClause "
+ "FROM AD_PInstance_Para ip, AD_PInstance i, AD_Process_Para pp, AD_Process_Para_Trl ppt "
+ "WHERE i.AD_PInstance_ID=ip.AD_PInstance_ID"
+ " AND pp.AD_Process_ID=i.AD_Process_ID"
@@ -163,10 +165,12 @@ public class MQuery implements Serializable, Cloneable
Reference_ID = udpp.getAD_Reference_ID();
String P_Query = rs.getString(13);
+ boolean isNotClause = "Y".equals(rs.getString(16));
//
if (s_log.isLoggable(Level.FINE)) s_log.fine(ParameterName + " S=" + P_String + "-" + P_String_To
+ ", N=" + P_Number + "-" + P_Number_To + ", D=" + P_Date + "-" + P_Date_To
- + "; Name=" + Name + ", Info=" + Info + "-" + Info_To + ", Range=" + isRange);
+ + "; Name=" + Name + ", Info=" + Info + "-" + Info_To + ", Range=" + isRange
+ + ", Not Clause=" + isNotClause);
//
//custom query or column not exists - render as report parameters
if (!Util.isEmpty(P_Query) || (table != null && table.getColumn(ParameterName) == null))
@@ -185,17 +189,17 @@ public class MQuery implements Serializable, Cloneable
String columnName = TableName + "." + ParameterName;
int cnt = DB.getSQLValueEx(null, "SELECT Count(*) From AD_Column WHERE IsActive='Y' AND AD_Client_ID=0 AND Upper(ColumnName)=? AND AD_Reference_ID=?", ParameterName.toUpperCase(), DisplayType.ChosenMultipleSelectionList);
if (cnt > 0)
- query.addRestriction(DB.intersectClauseForCSV(columnName, P_String), MQuery.EQUAL, Name, Info);
+ query.addRestriction(DB.intersectClauseForCSV(columnName, P_String, isNotClause), isNotClause ? MQuery.NOT_EQUAL : MQuery.EQUAL, Name, Info);
else
- query.addRestriction(DB.inClauseForCSV(columnName, P_String), MQuery.EQUAL, Name, Info);
+ query.addRestriction(DB.inClauseForCSV(columnName, P_String, isNotClause), isNotClause ? MQuery.NOT_EQUAL : MQuery.EQUAL, Name, Info);
}
else if (Reference_ID == DisplayType.ChosenMultipleSelectionTable || Reference_ID == DisplayType.ChosenMultipleSelectionSearch)
{
String columnName = TableName + "." + ParameterName;
if (columnName.endsWith("_ID"))
- query.addRestriction(DB.inClauseForCSV(columnName, P_String), MQuery.EQUAL, Name, Info);
+ query.addRestriction(DB.inClauseForCSV(columnName, P_String, isNotClause), isNotClause ? MQuery.NOT_EQUAL : MQuery.EQUAL, Name, Info);
else
- query.addRestriction(DB.intersectClauseForCSV(columnName, P_String), MQuery.EQUAL, Name, Info);
+ query.addRestriction(DB.intersectClauseForCSV(columnName, P_String, isNotClause), isNotClause ? MQuery.NOT_EQUAL : MQuery.EQUAL, Name, Info);
}
else
{
diff --git a/org.adempiere.base/src/org/compiere/model/X_AD_PInstance_Para.java b/org.adempiere.base/src/org/compiere/model/X_AD_PInstance_Para.java
index da58e2df2d..ad3b66db46 100644
--- a/org.adempiere.base/src/org/compiere/model/X_AD_PInstance_Para.java
+++ b/org.adempiere.base/src/org/compiere/model/X_AD_PInstance_Para.java
@@ -26,7 +26,7 @@ import org.compiere.util.KeyNamePair;
/** Generated Model for AD_PInstance_Para
* @author iDempiere (generated)
- * @version Release 9 - $Id$ */
+ * @version Release 10 - $Id$ */
@org.adempiere.base.Model(table="AD_PInstance_Para")
public class X_AD_PInstance_Para extends PO implements I_AD_PInstance_Para, I_Persistent
{
@@ -34,7 +34,7 @@ public class X_AD_PInstance_Para extends PO implements I_AD_PInstance_Para, I_Pe
/**
*
*/
- private static final long serialVersionUID = 20220116L;
+ private static final long serialVersionUID = 20221028L;
/** Standard Constructor */
public X_AD_PInstance_Para (Properties ctx, int AD_PInstance_Para_ID, String trxName)
@@ -43,6 +43,8 @@ public class X_AD_PInstance_Para extends PO implements I_AD_PInstance_Para, I_Pe
/** if (AD_PInstance_Para_ID == 0)
{
setAD_PInstance_ID (0);
+ setIsNotClause (false);
+// N
setSeqNo (0);
} */
}
@@ -54,6 +56,8 @@ public class X_AD_PInstance_Para extends PO implements I_AD_PInstance_Para, I_Pe
/** if (AD_PInstance_Para_ID == 0)
{
setAD_PInstance_ID (0);
+ setIsNotClause (false);
+// N
setSeqNo (0);
} */
}
@@ -160,29 +164,29 @@ public class X_AD_PInstance_Para extends PO implements I_AD_PInstance_Para, I_Pe
return (String)get_Value(COLUMNNAME_Info_To);
}
- /** Set Parameter Name.
- @param ParameterName Parameter Name
+ /** Set Is not clause.
+ @param IsNotClause Indicates if a chosen multiple component value must be negate
*/
- public void setParameterName (String ParameterName)
+ public void setIsNotClause (boolean IsNotClause)
{
- set_Value (COLUMNNAME_ParameterName, ParameterName);
+ set_Value (COLUMNNAME_IsNotClause, Boolean.valueOf(IsNotClause));
}
- /** Get Parameter Name.
- @return Parameter Name */
- public String getParameterName()
+ /** Get Is not clause.
+ @return Indicates if a chosen multiple component value must be negate
+ */
+ public boolean isNotClause()
{
- return (String)get_Value(COLUMNNAME_ParameterName);
+ Object oo = get_Value(COLUMNNAME_IsNotClause);
+ if (oo != null)
+ {
+ if (oo instanceof Boolean)
+ return ((Boolean)oo).booleanValue();
+ return "Y".equals(oo);
+ }
+ return false;
}
- /** Get Record ID/ColumnName
- @return ID/ColumnName pair
- */
- public KeyNamePair getKeyNamePair()
- {
- return new KeyNamePair(get_ID(), getParameterName());
- }
-
/** Set Process Date.
@param P_Date Process Parameter
*/
@@ -285,6 +289,29 @@ public class X_AD_PInstance_Para extends PO implements I_AD_PInstance_Para, I_Pe
return (String)get_Value(COLUMNNAME_P_String_To);
}
+ /** Set Parameter Name.
+ @param ParameterName Parameter Name
+ */
+ public void setParameterName (String ParameterName)
+ {
+ set_Value (COLUMNNAME_ParameterName, ParameterName);
+ }
+
+ /** Get Parameter Name.
+ @return Parameter Name */
+ public String getParameterName()
+ {
+ return (String)get_Value(COLUMNNAME_ParameterName);
+ }
+
+ /** Get Record ID/ColumnName
+ @return ID/ColumnName pair
+ */
+ public KeyNamePair getKeyNamePair()
+ {
+ return new KeyNamePair(get_ID(), getParameterName());
+ }
+
/** Set Sequence.
@param SeqNo Method of ordering records; lowest number comes first
*/
diff --git a/org.adempiere.base/src/org/compiere/process/ProcessInfoParameter.java b/org.adempiere.base/src/org/compiere/process/ProcessInfoParameter.java
index 44c212c599..6d2674909c 100644
--- a/org.adempiere.base/src/org/compiere/process/ProcessInfoParameter.java
+++ b/org.adempiere.base/src/org/compiere/process/ProcessInfoParameter.java
@@ -52,12 +52,27 @@ public class ProcessInfoParameter implements Serializable
* @param info_To to info
*/
public ProcessInfoParameter (String parameterName, Object parameter, Object parameter_To, String info, String info_To)
+ {
+ this(parameterName, parameter, parameter_To, info, info_To, false);
+ } // ProcessInfoParameter
+
+ /**
+ * Construct Parameter
+ * @param parameterName parameter name
+ * @param parameter parameter
+ * @param parameter_To to parameter
+ * @param info info
+ * @param info_To to info
+ * @param isNotClause is not clause
+ */
+ public ProcessInfoParameter (String parameterName, Object parameter, Object parameter_To, String info, String info_To, boolean isNotClause)
{
setParameterName (parameterName);
setParameter (parameter);
setParameter_To (parameter_To);
setInfo (info);
setInfo_To (info_To);
+ setIsNotClause(isNotClause);
} // ProcessInfoParameter
private String m_ParameterName;
@@ -65,6 +80,7 @@ public class ProcessInfoParameter implements Serializable
private Object m_Parameter_To;
private String m_Info = "";
private String m_Info_To = "";
+ private boolean m_IsNotClause;
/**
* String Representation
@@ -261,6 +277,14 @@ public class ProcessInfoParameter implements Serializable
{
return m_ParameterName;
}
+
+ /**
+ * Method isNotClause
+ * @return boolean
+ */
+ public boolean isNotClause() {
+ return m_IsNotClause;
+ }
/**
* Method setInfo
@@ -312,6 +336,14 @@ public class ProcessInfoParameter implements Serializable
{
m_ParameterName = ParameterName;
}
+
+ /**
+ * Method setIsNotClause
+ * @param IsNotClause boolean
+ */
+ public void setIsNotClause(boolean IsNotClause) {
+ this.m_IsNotClause = IsNotClause;
+ }
/**
* Return the value of the parameter as a comma separated integer string. Validate every value is an integer and throws NumberFormatException if one of the value is not a valid integer.
diff --git a/org.adempiere.base/src/org/compiere/process/ProcessInfoUtil.java b/org.adempiere.base/src/org/compiere/process/ProcessInfoUtil.java
index c240156410..2a3bc8bc35 100644
--- a/org.adempiere.base/src/org/compiere/process/ProcessInfoUtil.java
+++ b/org.adempiere.base/src/org/compiere/process/ProcessInfoUtil.java
@@ -187,7 +187,8 @@ public class ProcessInfoUtil
String sql = "SELECT p.ParameterName," // 1
+ " p.P_String,p.P_String_To, p.P_Number,p.P_Number_To," // 2/3 4/5
+ " p.P_Date,p.P_Date_To, p.Info,p.Info_To, " // 6/7 8/9
- + " i.AD_Client_ID, i.AD_Org_ID, i.AD_User_ID " // 10..12
+ + " i.AD_Client_ID, i.AD_Org_ID, i.AD_User_ID, " // 10..12
+ + " p.IsNotClause " // 13
+ "FROM AD_PInstance_Para p"
+ " INNER JOIN AD_PInstance i ON (p.AD_PInstance_ID=i.AD_PInstance_ID) "
+ "WHERE p.AD_PInstance_ID=? "
@@ -221,7 +222,8 @@ public class ProcessInfoUtil
String Info = rs.getString(8);
String Info_To = rs.getString(9);
//
- list.add (new ProcessInfoParameter(ParameterName, Parameter, Parameter_To, Info, Info_To));
+ boolean isNotClause = "Y".equals(rs.getString(13));
+ list.add (new ProcessInfoParameter(ParameterName, Parameter, Parameter_To, Info, Info_To, isNotClause));
//
if (pi.getAD_Client_ID() == null)
pi.setAD_Client_ID (rs.getInt(10));
diff --git a/org.adempiere.base/src/org/compiere/util/DB.java b/org.adempiere.base/src/org/compiere/util/DB.java
index 5adbeec3c7..c78fec4ee7 100644
--- a/org.adempiere.base/src/org/compiere/util/DB.java
+++ b/org.adempiere.base/src/org/compiere/util/DB.java
@@ -2602,15 +2602,32 @@ public final class DB
return ProxyFactory.newCPreparedStatement(resultSetType, resultSetConcurrency, sql, trxName);
}
+
/**
* @param columnName
* @param csv comma separated value
* @return IN clause
*/
public static String inClauseForCSV(String columnName, String csv)
+ {
+ return inClauseForCSV(columnName, csv, false);
+ }
+
+ /**
+ * @param columnName
+ * @param csv comma separated value
+ * @param isNotClause
+ * @return IN clause
+ */
+ public static String inClauseForCSV(String columnName, String csv, boolean isNotClause)
{
StringBuilder builder = new StringBuilder();
- builder.append(columnName).append(" IN (");
+ builder.append(columnName);
+
+ if(isNotClause)
+ builder.append(" NOT ");
+
+ builder.append(" IN (");
String[] values = csv.split("[,]");
for(int i = 0; i < values.length; i++)
{
@@ -2653,7 +2670,18 @@ public final class DB
*/
public static String intersectClauseForCSV(String columnName, String csv)
{
- return getDatabase().intersectClauseForCSV(columnName, csv);
+ return intersectClauseForCSV(columnName, csv, false);
+ }
+ /**
+ *
+ * @param columnName
+ * @param csv
+ * @param isNotClause
+ * @return intersect sql clause
+ */
+ public static String intersectClauseForCSV(String columnName, String csv, boolean isNotClause)
+ {
+ return getDatabase().intersectClauseForCSV(columnName, csv, isNotClause);
}
/**
diff --git a/org.adempiere.base/src/org/compiere/util/DisplayType.java b/org.adempiere.base/src/org/compiere/util/DisplayType.java
index 1bddb96e4e..8a6abe5b4f 100644
--- a/org.adempiere.base/src/org/compiere/util/DisplayType.java
+++ b/org.adempiere.base/src/org/compiere/util/DisplayType.java
@@ -503,6 +503,20 @@ public final class DisplayType
return false;
}
+ /**
+ *
+ * @param displayType
+ * @return true if displayType is a ChosenMultipleSelection
+ */
+ public static boolean isChosenMultipleSelection(int displayType)
+ {
+ if (displayType == ChosenMultipleSelectionList || displayType == ChosenMultipleSelectionSearch
+ || displayType == ChosenMultipleSelectionTable)
+ return true;
+ else
+ return false;
+ }
+
/**************************************************************************
* Return Format for numeric DisplayType
* @param displayType Display Type (default Number)
diff --git a/org.adempiere.report.jasper/src/org/adempiere/report/jasper/ReportStarter.java b/org.adempiere.report.jasper/src/org/adempiere/report/jasper/ReportStarter.java
index 0d9c3a8f3f..494f0b2f7b 100644
--- a/org.adempiere.report.jasper/src/org/adempiere/report/jasper/ReportStarter.java
+++ b/org.adempiere.report.jasper/src/org/adempiere/report/jasper/ReportStarter.java
@@ -1013,6 +1013,7 @@ public class ReportStarter implements ProcessCall, ClientProcess
.append(",").append(X_AD_PInstance_Para.COLUMNNAME_P_Date_To)
.append(",").append(X_AD_PInstance_Para.COLUMNNAME_Info)
.append(",").append(X_AD_PInstance_Para.COLUMNNAME_Info_To)
+ .append(",").append(X_AD_PInstance_Para.COLUMNNAME_IsNotClause)
.append(" FROM ").append(X_AD_PInstance_Para.Table_Name)
.append(" WHERE ").append(X_AD_PInstance_Para.COLUMNNAME_AD_PInstance_ID+"=?");
PreparedStatement pstmt = null;
@@ -1067,8 +1068,10 @@ public class ReportStarter implements ProcessCall, ClientProcess
// Add parameter info - teo_sarca FR [ 2581145 ]
String info = rs.getString(8);
String infoTo = rs.getString(9);
+ String isNotClause = rs.getString(10);
params.put(name+"_Info1", (info != null ? info : ""));
params.put(name+"_Info2", (infoTo != null ? infoTo : ""));
+ params.put(name+"_NOT", isNotClause);
}
}
catch (SQLException e)
diff --git a/org.adempiere.ui.zk/WEB-INF/src/metainfo/zk/lang-addon.xml b/org.adempiere.ui.zk/WEB-INF/src/metainfo/zk/lang-addon.xml
index 9705b859aa..eb25926ccf 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/metainfo/zk/lang-addon.xml
+++ b/org.adempiere.ui.zk/WEB-INF/src/metainfo/zk/lang-addon.xml
@@ -57,6 +57,6 @@ Copyright (C) 2007 Ashley G Ramdass (ADempiere WebUI).
-
+
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessParameterPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessParameterPanel.java
index 0c00dab058..3117ea991b 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessParameterPanel.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessParameterPanel.java
@@ -28,6 +28,7 @@ import java.util.logging.Level;
import org.adempiere.webui.Extensions;
import org.adempiere.webui.LayoutUtils;
+import org.adempiere.webui.component.Button;
import org.adempiere.webui.component.Column;
import org.adempiere.webui.component.Columns;
import org.adempiere.webui.component.EditorBox;
@@ -47,6 +48,7 @@ import org.adempiere.webui.editor.WebEditorFactory;
import org.adempiere.webui.event.ContextMenuListener;
import org.adempiere.webui.event.ValueChangeEvent;
import org.adempiere.webui.event.ValueChangeListener;
+import org.adempiere.webui.factory.ButtonFactory;
import org.adempiere.webui.session.SessionManager;
import org.adempiere.webui.util.ZKUpdateUtil;
import org.adempiere.webui.window.DateRangeButton;
@@ -425,10 +427,10 @@ public class ProcessParameterPanel extends Panel implements
div.appendChild(label.getDecorator());
row.appendChild(div);
//
+ Div box = new Div();
+ box.setStyle("display: flex; align-items: center;");
+ ZKUpdateUtil.setWidth(box, "100%");
if (voF.isRange) {
- Div box = new Div();
- box.setStyle("display: flex; align-items: center;");
- ZKUpdateUtil.setWidth(box, "100%");
box.appendChild(editor.getComponent());
ZKUpdateUtil.setWidth((HtmlBasedComponent) editor.getComponent(), "49%");
//
@@ -470,11 +472,23 @@ public class ProcessParameterPanel extends Panel implements
box.appendChild(dateRangeButton);
}
} else {
- row.appendChild(editor.getComponent());
+ box.appendChild(editor.getComponent());
m_mFields2.add(null);
m_wEditors2.add(null);
m_separators.add(null);
+ if(DisplayType.isChosenMultipleSelection(mField.getDisplayType())) {
+ Button bNegate = ButtonFactory.createButton("", null, null);
+ bNegate.setTooltiptext(Msg.translate(Env.getCtx(), "IncludeSelectedValues"));
+ bNegate.setIconSclass("z-icon-IncludeSelected");
+ bNegate.setSclass("btn-negate btn-negate-include");
+ bNegate.setAttribute("isSelected", false);
+ bNegate.setVisible(false);
+ bNegate.addActionListener(this);
+ box.appendChild(bNegate);
+ editor.getComponent().setAttribute("isNotClause", bNegate);
+ }
}
+ row.appendChild(box);
} // createField
private void setEditorPlaceHolder(WEditor editor, String msg) {
@@ -590,6 +604,10 @@ public class ProcessParameterPanel extends Panel implements
MPInstancePara para = params[i];
if ( mField.getColumnName().equals(para.getParameterName()) )
{
+ Button bNegate = null;
+ if(editor.getComponent() != null)
+ bNegate = (Button) editor.getComponent().getAttribute("isNotClause");
+
if (para.getP_Date() != null || para.getP_Date_To() != null )
{
editor.setValue(para.getP_Date());
@@ -624,6 +642,23 @@ public class ProcessParameterPanel extends Panel implements
valueChange(changeEvent);
}
+ if(bNegate != null) {
+ if(para.isNotClause()) {
+ bNegate.setTooltiptext(Msg.translate(Env.getCtx(), "ExcludeSelectedValues"));
+ bNegate.setIconSclass("z-icon-ExcludeSelected");
+ bNegate.setSclass("btn-negate btn-negate-exclude");
+ bNegate.setAttribute("isSelected", true);
+ }
+ else {
+ bNegate.setTooltiptext(Msg.translate(Env.getCtx(), "IncludeSelectedValues"));
+ bNegate.setIconSclass("z-icon-IncludeSelected");
+ bNegate.setSclass("btn-negate btn-negate-include");
+ bNegate.setAttribute("isSelected", false);
+ }
+
+ if(editor.getValue() != null)
+ bNegate.setVisible(true);
+ }
log.fine(para.toString());
break;
}
@@ -726,6 +761,14 @@ public class ProcessParameterPanel extends Panel implements
GridField mField = (GridField) m_mFields.get(i);
para.setParameterName(mField.getColumnName());
+ Button bNegate = null;
+ if(editor.getComponent() != null)
+ bNegate = (Button)editor.getComponent().getAttribute("isNotClause");
+
+ if(bNegate != null) {
+ para.setIsNotClause((boolean)bNegate.getAttribute("isSelected"));
+ }
+
// Date
if (result instanceof Timestamp || result2 instanceof Timestamp) {
if (result instanceof Timestamp)
@@ -918,7 +961,39 @@ public class ProcessParameterPanel extends Panel implements
dynamicDisplay();
}
else if (event.getName().equals("onPostEditorValueChange")) {
- onPostEditorValueChange((WEditor)event.getData());
+ WEditor editor = (WEditor)event.getData();
+ onPostEditorValueChange(editor);
+ if(editor.getComponent() != null) {
+ Button bNegate = (Button) editor.getComponent().getAttribute("isNotClause");
+ if (bNegate != null) {
+ if (editor.getValue() != null) {
+ bNegate.setVisible(true);
+ } else {
+ bNegate.setVisible(false);
+ bNegate.setAttribute("isSelected", false);
+ bNegate.setTooltiptext(Msg.translate(Env.getCtx(), "IncludeSelectedValues"));
+ bNegate.setIconSclass("z-icon-IncludeSelected");
+ bNegate.setSclass("btn-negate btn-negate-include");
+ }
+ }
+ }
+ }
+ else if (event.getName().equals(Events.ON_CLICK)) {
+ if(event.getTarget() instanceof Button) {
+ Button bNegate = (Button)event.getTarget();
+ boolean isSelected = !(boolean)bNegate.getAttribute("isSelected");
+ if(isSelected) {
+ bNegate.setTooltiptext(Msg.translate(Env.getCtx(), "ExcludeSelectedValues"));
+ bNegate.setIconSclass("z-icon-ExcludeSelected");
+ bNegate.setSclass("btn-negate btn-negate-exclude");
+ }
+ else {
+ bNegate.setTooltiptext(Msg.translate(Env.getCtx(), "IncludeSelectedValues"));
+ bNegate.setIconSclass("z-icon-IncludeSelected");
+ bNegate.setSclass("btn-negate btn-negate-include");
+ }
+ bNegate.setAttribute("isSelected", isSelected);
+ }
}
}
@@ -1009,6 +1084,13 @@ public class ProcessParameterPanel extends Panel implements
m_separators.get(i).setVisible(true);
m_wEditors2.get(i).setVisible(true);
}
+
+ Button bNegate = null;
+ if(editor.getComponent() != null)
+ bNegate = (Button) editor.getComponent().getAttribute("isNotClause");
+ if(bNegate != null) {
+ bNegate.setVisible(true);
+ }
}
boolean rw = mField.isEditablePara(true); // r/w - check if field is Editable
editor.setReadWrite(rw);
@@ -1026,6 +1108,13 @@ public class ProcessParameterPanel extends Panel implements
m_separators.get(i).setVisible(false);
m_wEditors2.get(i).setVisible(false);
}
+
+ Button bNegate = null;
+ if(editor.getComponent() != null)
+ bNegate = (Button) editor.getComponent().getAttribute("isNotClause");
+ if(bNegate != null) {
+ bNegate.setVisible(false);
+ }
}
editor.setMandatory(mField.isMandatory(true));
editor.updateStyle();
diff --git a/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/css/fragment/button.css.dsp b/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/css/fragment/button.css.dsp
index 5cf2102cfd..3378df75c1 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/css/fragment/button.css.dsp
+++ b/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/css/fragment/button.css.dsp
@@ -138,4 +138,29 @@
}
.btn-cancel.z-button [class^="z-icon-"]:before {
color: red;
-}
\ No newline at end of file
+}
+
+.btn-negate.z-button {
+ background: none;
+ border: none;
+ margin: 0px !important;
+ padding: 0px;
+ min-width: 16px;
+ width: 16px;
+ height: 10px;
+ min-height:10px;
+ font-size: 14px;
+ font-weight: lighter;
+ position: absolute;
+ top: 5px;
+ right: 25px;
+}
+.btn-negate.z-button:active, .btn-negate.z-button:focus {
+ border: none;
+ box-shadow: none;
+}
+.btn-negate.z-button [class^="z-icon-"] {
+ font-size: 14px;
+ padding: 0px;
+ line-height: 14px;
+}
diff --git a/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/css/fragment/font-icons.css.dsp b/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/css/fragment/font-icons.css.dsp
index d5a8d2ce3d..6c7526590c 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/css/fragment/font-icons.css.dsp
+++ b/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/css/fragment/font-icons.css.dsp
@@ -66,6 +66,9 @@
color: yellow;
font-family: FontAwesome;
}
+.z-icon-ExcludeSelected:before {
+ content: "\f05e";
+}
.z-icon-Expand:before {
content: "\f0d7";
}
@@ -117,6 +120,9 @@
.z-icon-Import:before {
content: "\f0ee";
}
+.z-icon-IncludeSelected:before {
+ content: "\f05d";
+}
.z-icon-Info:before {
content: "\f0eb";
}
diff --git a/org.compiere.db.oracle.provider/src/org/compiere/db/DB_Oracle.java b/org.compiere.db.oracle.provider/src/org/compiere/db/DB_Oracle.java
index 8be02c361c..6ad62abea2 100644
--- a/org.compiere.db.oracle.provider/src/org/compiere/db/DB_Oracle.java
+++ b/org.compiere.db.oracle.provider/src/org/compiere/db/DB_Oracle.java
@@ -962,17 +962,26 @@ public class DB_Oracle implements AdempiereDatabase
return builder.toString();
}
-
+
@Override
public String intersectClauseForCSV(String columnName, String csv) {
+ return intersectClauseForCSV(columnName, csv, false);
+ }
+
+ @Override
+ public String intersectClauseForCSV(String columnName, String csv, boolean isNotClause) {
StringBuilder builder = new StringBuilder();
builder.append("toTableOfVarchar2(")
.append(columnName)
.append(")");
builder.append(" MULTISET INTERSECT ")
.append("toTableOfVarchar2(")
- .append(DB.TO_STRING(csv))
- .append(") IS NOT EMPTY");
+ .append(DB.TO_STRING(csv)).append(") IS ");
+
+ if(!isNotClause)
+ builder.append("NOT ");
+
+ builder.append("EMPTY");
return builder.toString();
}
diff --git a/org.compiere.db.postgresql.provider/src/org/compiere/db/DB_PostgreSQL.java b/org.compiere.db.postgresql.provider/src/org/compiere/db/DB_PostgreSQL.java
index 1b93587680..eb0999152c 100755
--- a/org.compiere.db.postgresql.provider/src/org/compiere/db/DB_PostgreSQL.java
+++ b/org.compiere.db.postgresql.provider/src/org/compiere/db/DB_PostgreSQL.java
@@ -1049,14 +1049,21 @@ public class DB_PostgreSQL implements AdempiereDatabase
@Override
public String intersectClauseForCSV(String columnName, String csv) {
+ return intersectClauseForCSV(columnName, csv, false);
+ }
+
+ @Override
+ public String intersectClauseForCSV(String columnName, String csv, boolean isNotClause) {
StringBuilder builder = new StringBuilder();
- builder.append("string_to_array(")
+ if(isNotClause)
+ builder.append("NOT");
+ builder.append("(string_to_array(")
.append(columnName)
.append(",',')");
builder.append(" && "); //intersect
builder.append("string_to_array(")
.append(DB.TO_STRING(csv))
- .append(",',')");
+ .append(",','))");
return builder.toString();
}