IDEMPIERE-5468 - Negate option in parameter panel when component is a Chosen Multiple Selection (#1567)

* # IDEMPIERE-5468 - implement negate option for chosen multiple selection components as process parameter

* # IDEMPIERE-5468 - Negate option in parameter panel when component is a Chosen Multiple Selection

* IDEMPIERE-5468 - ui improvements

* IDEMPIERE-5468 - adding old method signature

* IDEMPIERE-5468 - fix method comment

* # IDEMPIERE-5468 - fix missing methods

* IDEMPIERE-5468 - applying hengsins suggestion and translating tooltips
This commit is contained in:
matheus-marcelinux 2022-12-01 02:20:25 -03:00 committed by GitHub
parent e723456063
commit ac81f3529b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 409 additions and 52 deletions

View File

@ -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)
;

View File

@ -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
;

View File

@ -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)
;

View File

@ -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
;

View File

@ -348,6 +348,14 @@ public interface AdempiereDatabase
*/ */
public String intersectClauseForCSV(String columnName, String csv); 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) * Quote column name if necessary (usually to avoid conflict with reserved keywords)
* @param columnName * @param columnName

View File

@ -22,7 +22,7 @@ import org.compiere.util.KeyNamePair;
/** Generated Interface for AD_PInstance_Para /** Generated Interface for AD_PInstance_Para
* @author iDempiere (generated) * @author iDempiere (generated)
* @version Release 9 * @version Release 10
*/ */
public interface I_AD_PInstance_Para public interface I_AD_PInstance_Para
{ {
@ -44,8 +44,8 @@ public interface I_AD_PInstance_Para
/** Column name AD_Client_ID */ /** Column name AD_Client_ID */
public static final String COLUMNNAME_AD_Client_ID = "AD_Client_ID"; public static final String COLUMNNAME_AD_Client_ID = "AD_Client_ID";
/** Get Client. /** Get Tenant.
* Client/Tenant for this installation. * Tenant for this installation.
*/ */
public int getAD_Client_ID(); 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"; public static final String COLUMNNAME_AD_Org_ID = "AD_Org_ID";
/** Set Organization. /** Set Organization.
* Organizational entity within client * Organizational entity within tenant
*/ */
public void setAD_Org_ID (int AD_Org_ID); public void setAD_Org_ID (int AD_Org_ID);
/** Get Organization. /** Get Organization.
* Organizational entity within client * Organizational entity within tenant
*/ */
public int getAD_Org_ID(); public int getAD_Org_ID();
@ -137,14 +137,18 @@ public interface I_AD_PInstance_Para
*/ */
public boolean isActive(); public boolean isActive();
/** Column name ParameterName */ /** Column name IsNotClause */
public static final String COLUMNNAME_ParameterName = "ParameterName"; public static final String COLUMNNAME_IsNotClause = "IsNotClause";
/** Set Parameter Name */ /** Set Is not clause.
public void setParameterName (String ParameterName); * Indicates if a chosen multiple component value must be negate
*/
public void setIsNotClause (boolean IsNotClause);
/** Get Parameter Name */ /** Get Is not clause.
public String getParameterName(); * Indicates if a chosen multiple component value must be negate
*/
public boolean isNotClause();
/** Column name P_Date */ /** Column name P_Date */
public static final String COLUMNNAME_P_Date = "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(); 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 */ /** Column name SeqNo */
public static final String COLUMNNAME_SeqNo = "SeqNo"; public static final String COLUMNNAME_SeqNo = "SeqNo";

View File

@ -93,7 +93,8 @@ public class MQuery implements Serializable, Cloneable
+ "ip.P_Number,ip.P_Number_To," // 4..5 + "ip.P_Number,ip.P_Number_To," // 4..5
+ "ip.P_Date,ip.P_Date_To, ip.Info,ip.Info_To, " // 6..9 + "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.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 " + "FROM AD_PInstance_Para ip, AD_PInstance i, AD_Process_Para pp "
+ "WHERE i.AD_PInstance_ID=ip.AD_PInstance_ID" + "WHERE i.AD_PInstance_ID=ip.AD_PInstance_ID"
+ " AND pp.AD_Process_ID=i.AD_Process_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," 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, " + "ip.P_Date,ip.P_Date_To, ip.Info,ip.Info_To, "
+ "ppt.Name, pp.IsRange, pp.AD_Reference_ID, pp.Query, " + "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 " + "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" + "WHERE i.AD_PInstance_ID=ip.AD_PInstance_ID"
+ " AND pp.AD_Process_ID=i.AD_Process_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(); Reference_ID = udpp.getAD_Reference_ID();
String P_Query = rs.getString(13); 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 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 + ", 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 //custom query or column not exists - render as report parameters
if (!Util.isEmpty(P_Query) || (table != null && table.getColumn(ParameterName) == null)) 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; 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); 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) 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 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) else if (Reference_ID == DisplayType.ChosenMultipleSelectionTable || Reference_ID == DisplayType.ChosenMultipleSelectionSearch)
{ {
String columnName = TableName + "." + ParameterName; String columnName = TableName + "." + ParameterName;
if (columnName.endsWith("_ID")) 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 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 else
{ {

View File

@ -26,7 +26,7 @@ import org.compiere.util.KeyNamePair;
/** Generated Model for AD_PInstance_Para /** Generated Model for AD_PInstance_Para
* @author iDempiere (generated) * @author iDempiere (generated)
* @version Release 9 - $Id$ */ * @version Release 10 - $Id$ */
@org.adempiere.base.Model(table="AD_PInstance_Para") @org.adempiere.base.Model(table="AD_PInstance_Para")
public class X_AD_PInstance_Para extends PO implements I_AD_PInstance_Para, I_Persistent 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 */ /** Standard Constructor */
public X_AD_PInstance_Para (Properties ctx, int AD_PInstance_Para_ID, String trxName) 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) /** if (AD_PInstance_Para_ID == 0)
{ {
setAD_PInstance_ID (0); setAD_PInstance_ID (0);
setIsNotClause (false);
// N
setSeqNo (0); 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) /** if (AD_PInstance_Para_ID == 0)
{ {
setAD_PInstance_ID (0); setAD_PInstance_ID (0);
setIsNotClause (false);
// N
setSeqNo (0); 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); return (String)get_Value(COLUMNNAME_Info_To);
} }
/** Set Parameter Name. /** Set Is not clause.
@param ParameterName Parameter Name @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. /** Get Is not clause.
@return Parameter Name */ @return Indicates if a chosen multiple component value must be negate
public String getParameterName() */
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. /** Set Process Date.
@param P_Date Process Parameter @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); 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. /** Set Sequence.
@param SeqNo Method of ordering records; lowest number comes first @param SeqNo Method of ordering records; lowest number comes first
*/ */

View File

@ -52,12 +52,27 @@ public class ProcessInfoParameter implements Serializable
* @param info_To to info * @param info_To to info
*/ */
public ProcessInfoParameter (String parameterName, Object parameter, Object parameter_To, String info, String info_To) 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); setParameterName (parameterName);
setParameter (parameter); setParameter (parameter);
setParameter_To (parameter_To); setParameter_To (parameter_To);
setInfo (info); setInfo (info);
setInfo_To (info_To); setInfo_To (info_To);
setIsNotClause(isNotClause);
} // ProcessInfoParameter } // ProcessInfoParameter
private String m_ParameterName; private String m_ParameterName;
@ -65,6 +80,7 @@ public class ProcessInfoParameter implements Serializable
private Object m_Parameter_To; private Object m_Parameter_To;
private String m_Info = ""; private String m_Info = "";
private String m_Info_To = ""; private String m_Info_To = "";
private boolean m_IsNotClause;
/** /**
* String Representation * String Representation
@ -261,6 +277,14 @@ public class ProcessInfoParameter implements Serializable
{ {
return m_ParameterName; return m_ParameterName;
} }
/**
* Method isNotClause
* @return boolean
*/
public boolean isNotClause() {
return m_IsNotClause;
}
/** /**
* Method setInfo * Method setInfo
@ -312,6 +336,14 @@ public class ProcessInfoParameter implements Serializable
{ {
m_ParameterName = ParameterName; 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. * 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.

View File

@ -187,7 +187,8 @@ public class ProcessInfoUtil
String sql = "SELECT p.ParameterName," // 1 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_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 + " 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" + "FROM AD_PInstance_Para p"
+ " INNER JOIN AD_PInstance i ON (p.AD_PInstance_ID=i.AD_PInstance_ID) " + " INNER JOIN AD_PInstance i ON (p.AD_PInstance_ID=i.AD_PInstance_ID) "
+ "WHERE p.AD_PInstance_ID=? " + "WHERE p.AD_PInstance_ID=? "
@ -221,7 +222,8 @@ public class ProcessInfoUtil
String Info = rs.getString(8); String Info = rs.getString(8);
String Info_To = rs.getString(9); 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) if (pi.getAD_Client_ID() == null)
pi.setAD_Client_ID (rs.getInt(10)); pi.setAD_Client_ID (rs.getInt(10));

View File

@ -2602,15 +2602,32 @@ public final class DB
return ProxyFactory.newCPreparedStatement(resultSetType, resultSetConcurrency, sql, trxName); return ProxyFactory.newCPreparedStatement(resultSetType, resultSetConcurrency, sql, trxName);
} }
/** /**
* @param columnName * @param columnName
* @param csv comma separated value * @param csv comma separated value
* @return IN clause * @return IN clause
*/ */
public static String inClauseForCSV(String columnName, String csv) 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(); StringBuilder builder = new StringBuilder();
builder.append(columnName).append(" IN ("); builder.append(columnName);
if(isNotClause)
builder.append(" NOT ");
builder.append(" IN (");
String[] values = csv.split("[,]"); String[] values = csv.split("[,]");
for(int i = 0; i < values.length; i++) for(int i = 0; i < values.length; i++)
{ {
@ -2653,7 +2670,18 @@ public final class DB
*/ */
public static String intersectClauseForCSV(String columnName, String csv) 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);
} }
/** /**

View File

@ -503,6 +503,20 @@ public final class DisplayType
return false; 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 * Return Format for numeric DisplayType
* @param displayType Display Type (default Number) * @param displayType Display Type (default Number)

View File

@ -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_P_Date_To)
.append(",").append(X_AD_PInstance_Para.COLUMNNAME_Info) .append(",").append(X_AD_PInstance_Para.COLUMNNAME_Info)
.append(",").append(X_AD_PInstance_Para.COLUMNNAME_Info_To) .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(" FROM ").append(X_AD_PInstance_Para.Table_Name)
.append(" WHERE ").append(X_AD_PInstance_Para.COLUMNNAME_AD_PInstance_ID+"=?"); .append(" WHERE ").append(X_AD_PInstance_Para.COLUMNNAME_AD_PInstance_ID+"=?");
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
@ -1067,8 +1068,10 @@ public class ReportStarter implements ProcessCall, ClientProcess
// Add parameter info - teo_sarca FR [ 2581145 ] // Add parameter info - teo_sarca FR [ 2581145 ]
String info = rs.getString(8); String info = rs.getString(8);
String infoTo = rs.getString(9); String infoTo = rs.getString(9);
String isNotClause = rs.getString(10);
params.put(name+"_Info1", (info != null ? info : "")); params.put(name+"_Info1", (info != null ? info : ""));
params.put(name+"_Info2", (infoTo != null ? infoTo : "")); params.put(name+"_Info2", (infoTo != null ? infoTo : ""));
params.put(name+"_NOT", isNotClause);
} }
} }
catch (SQLException e) catch (SQLException e)

View File

@ -57,6 +57,6 @@ Copyright (C) 2007 Ashley G Ramdass (ADempiere WebUI).
<!-- this js module doesn't actually exists and it is here for default theme version --> <!-- this js module doesn't actually exists and it is here for default theme version -->
<!-- since loading of js module is on demand, it doesn't cause any error as long as you don't try to load it --> <!-- since loading of js module is on demand, it doesn't cause any error as long as you don't try to load it -->
<javascript-module name="idempiere.theme.default" version="202211281630" /> <javascript-module name="idempiere.theme.default" version="202211301708" />
</language> </language>

View File

@ -28,6 +28,7 @@ import java.util.logging.Level;
import org.adempiere.webui.Extensions; import org.adempiere.webui.Extensions;
import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.LayoutUtils;
import org.adempiere.webui.component.Button;
import org.adempiere.webui.component.Column; import org.adempiere.webui.component.Column;
import org.adempiere.webui.component.Columns; import org.adempiere.webui.component.Columns;
import org.adempiere.webui.component.EditorBox; 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.ContextMenuListener;
import org.adempiere.webui.event.ValueChangeEvent; import org.adempiere.webui.event.ValueChangeEvent;
import org.adempiere.webui.event.ValueChangeListener; import org.adempiere.webui.event.ValueChangeListener;
import org.adempiere.webui.factory.ButtonFactory;
import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.session.SessionManager;
import org.adempiere.webui.util.ZKUpdateUtil; import org.adempiere.webui.util.ZKUpdateUtil;
import org.adempiere.webui.window.DateRangeButton; import org.adempiere.webui.window.DateRangeButton;
@ -425,10 +427,10 @@ public class ProcessParameterPanel extends Panel implements
div.appendChild(label.getDecorator()); div.appendChild(label.getDecorator());
row.appendChild(div); row.appendChild(div);
// //
Div box = new Div();
box.setStyle("display: flex; align-items: center;");
ZKUpdateUtil.setWidth(box, "100%");
if (voF.isRange) { if (voF.isRange) {
Div box = new Div();
box.setStyle("display: flex; align-items: center;");
ZKUpdateUtil.setWidth(box, "100%");
box.appendChild(editor.getComponent()); box.appendChild(editor.getComponent());
ZKUpdateUtil.setWidth((HtmlBasedComponent) editor.getComponent(), "49%"); ZKUpdateUtil.setWidth((HtmlBasedComponent) editor.getComponent(), "49%");
// //
@ -470,11 +472,23 @@ public class ProcessParameterPanel extends Panel implements
box.appendChild(dateRangeButton); box.appendChild(dateRangeButton);
} }
} else { } else {
row.appendChild(editor.getComponent()); box.appendChild(editor.getComponent());
m_mFields2.add(null); m_mFields2.add(null);
m_wEditors2.add(null); m_wEditors2.add(null);
m_separators.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 } // createField
private void setEditorPlaceHolder(WEditor editor, String msg) { private void setEditorPlaceHolder(WEditor editor, String msg) {
@ -590,6 +604,10 @@ public class ProcessParameterPanel extends Panel implements
MPInstancePara para = params[i]; MPInstancePara para = params[i];
if ( mField.getColumnName().equals(para.getParameterName()) ) 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 ) if (para.getP_Date() != null || para.getP_Date_To() != null )
{ {
editor.setValue(para.getP_Date()); editor.setValue(para.getP_Date());
@ -624,6 +642,23 @@ public class ProcessParameterPanel extends Panel implements
valueChange(changeEvent); 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()); log.fine(para.toString());
break; break;
} }
@ -726,6 +761,14 @@ public class ProcessParameterPanel extends Panel implements
GridField mField = (GridField) m_mFields.get(i); GridField mField = (GridField) m_mFields.get(i);
para.setParameterName(mField.getColumnName()); 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 // Date
if (result instanceof Timestamp || result2 instanceof Timestamp) { if (result instanceof Timestamp || result2 instanceof Timestamp) {
if (result instanceof Timestamp) if (result instanceof Timestamp)
@ -918,7 +961,39 @@ public class ProcessParameterPanel extends Panel implements
dynamicDisplay(); dynamicDisplay();
} }
else if (event.getName().equals("onPostEditorValueChange")) { 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_separators.get(i).setVisible(true);
m_wEditors2.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 boolean rw = mField.isEditablePara(true); // r/w - check if field is Editable
editor.setReadWrite(rw); editor.setReadWrite(rw);
@ -1026,6 +1108,13 @@ public class ProcessParameterPanel extends Panel implements
m_separators.get(i).setVisible(false); m_separators.get(i).setVisible(false);
m_wEditors2.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.setMandatory(mField.isMandatory(true));
editor.updateStyle(); editor.updateStyle();

View File

@ -138,4 +138,29 @@
} }
.btn-cancel.z-button [class^="z-icon-"]:before { .btn-cancel.z-button [class^="z-icon-"]:before {
color: red; color: red;
} }
.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;
}

View File

@ -66,6 +66,9 @@
color: yellow; color: yellow;
font-family: FontAwesome; font-family: FontAwesome;
} }
.z-icon-ExcludeSelected:before {
content: "\f05e";
}
.z-icon-Expand:before { .z-icon-Expand:before {
content: "\f0d7"; content: "\f0d7";
} }
@ -117,6 +120,9 @@
.z-icon-Import:before { .z-icon-Import:before {
content: "\f0ee"; content: "\f0ee";
} }
.z-icon-IncludeSelected:before {
content: "\f05d";
}
.z-icon-Info:before { .z-icon-Info:before {
content: "\f0eb"; content: "\f0eb";
} }

View File

@ -962,17 +962,26 @@ public class DB_Oracle implements AdempiereDatabase
return builder.toString(); return builder.toString();
} }
@Override @Override
public String intersectClauseForCSV(String columnName, String csv) { 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(); StringBuilder builder = new StringBuilder();
builder.append("toTableOfVarchar2(") builder.append("toTableOfVarchar2(")
.append(columnName) .append(columnName)
.append(")"); .append(")");
builder.append(" MULTISET INTERSECT ") builder.append(" MULTISET INTERSECT ")
.append("toTableOfVarchar2(") .append("toTableOfVarchar2(")
.append(DB.TO_STRING(csv)) .append(DB.TO_STRING(csv)).append(") IS ");
.append(") IS NOT EMPTY");
if(!isNotClause)
builder.append("NOT ");
builder.append("EMPTY");
return builder.toString(); return builder.toString();
} }

View File

@ -1049,14 +1049,21 @@ public class DB_PostgreSQL implements AdempiereDatabase
@Override @Override
public String intersectClauseForCSV(String columnName, String csv) { 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(); StringBuilder builder = new StringBuilder();
builder.append("string_to_array(") if(isNotClause)
builder.append("NOT");
builder.append("(string_to_array(")
.append(columnName) .append(columnName)
.append(",',')"); .append(",',')");
builder.append(" && "); //intersect builder.append(" && "); //intersect
builder.append("string_to_array(") builder.append("string_to_array(")
.append(DB.TO_STRING(csv)) .append(DB.TO_STRING(csv))
.append(",',')"); .append(",','))");
return builder.toString(); return builder.toString();
} }