IDEMPIERE-4904 Add custom query clause support to report parameter (#821)
This commit is contained in:
parent
5ede13acee
commit
184e8191e6
|
@ -0,0 +1,18 @@
|
|||
SET SQLBLANKLINES ON
|
||||
SET DEFINE OFF
|
||||
|
||||
-- Aug 9, 2021 12:54:11 PM GMT+08:00
|
||||
-- IDEMPIERE-4904 Add custom query clause support to report parameter
|
||||
INSERT INTO AD_Column (AD_Column_ID,SeqNoSelection,IsSyncDatabase,Version,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,IsKey,IsAutocomplete,IsAllowLogging,MandatoryLogic,AD_Column_UU,Updated,IsUpdateable,ColumnName,Description,Name,IsAllowCopy,IsActive,CreatedBy,UpdatedBy,IsAlwaysUpdateable,AD_Client_ID,AD_Org_ID,Created,EntityType,IsEncrypted,IsSecure,AD_Element_ID,AD_Reference_ID,AD_Table_ID,IsToolbarButton) VALUES (213185,0,'N',0,'N','N','N',0,'N',2000,'N','N','N','Y',NULL,'04f9c29a-7806-444f-a313-45204f9efa84',TO_DATE('2021-08-09 12:54:09','YYYY-MM-DD HH24:MI:SS'),'Y','Query','SQL','Query','N','Y',100,100,'N',0,0,TO_DATE('2021-08-09 12:54:09','YYYY-MM-DD HH24:MI:SS'),'D','N','N',53775,14,285,'N')
|
||||
;
|
||||
|
||||
-- Aug 9, 2021 12:54:23 PM GMT+08:00
|
||||
ALTER TABLE AD_Process_Para ADD Query VARCHAR2(2000 CHAR) DEFAULT NULL
|
||||
;
|
||||
|
||||
-- Aug 9, 2021 12:57:18 PM GMT+08:00
|
||||
INSERT INTO AD_Field (SortNo,AD_Field_ID,IsEncrypted,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,IsReadOnly,DisplayLogic,AD_Org_ID,Updated,Description,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,CreatedBy,UpdatedBy,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry,AD_Client_ID,Created,ColumnSpan,NumLines,IsAdvancedField,IsDefaultFocus,AD_Column_ID,EntityType,AD_Tab_ID) VALUES (0,205193,'N',0,'N','N',270,'Y','N','@IsReport@=Y',0,TO_DATE('2021-08-09 12:57:17','YYYY-MM-DD HH24:MI:SS'),'SQL','Query','ed208c1d-a58a-43d5-912f-af8294e5d276','Y','N',100,100,'Y','Y',270,1,'N',0,TO_DATE('2021-08-09 12:57:17','YYYY-MM-DD HH24:MI:SS'),5,3,'N','N',213185,'D',246)
|
||||
;
|
||||
|
||||
SELECT register_migration_script('202108091122_IDEMPIERE-4904.sql') FROM dual
|
||||
;
|
|
@ -0,0 +1,15 @@
|
|||
-- Aug 9, 2021 12:54:11 PM GMT+08:00
|
||||
-- IDEMPIERE-4904 Add custom query clause support to report parameter
|
||||
INSERT INTO AD_Column (AD_Column_ID,SeqNoSelection,IsSyncDatabase,Version,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,IsKey,IsAutocomplete,IsAllowLogging,MandatoryLogic,AD_Column_UU,Updated,IsUpdateable,ColumnName,Description,Name,IsAllowCopy,IsActive,CreatedBy,UpdatedBy,IsAlwaysUpdateable,AD_Client_ID,AD_Org_ID,Created,EntityType,IsEncrypted,IsSecure,AD_Element_ID,AD_Reference_ID,AD_Table_ID,IsToolbarButton) VALUES (213185,0,'N',0,'N','N','N',0,'N',2000,'N','N','N','Y',NULL,'04f9c29a-7806-444f-a313-45204f9efa84',TO_TIMESTAMP('2021-08-09 12:54:09','YYYY-MM-DD HH24:MI:SS'),'Y','Query','SQL','Query','N','Y',100,100,'N',0,0,TO_TIMESTAMP('2021-08-09 12:54:09','YYYY-MM-DD HH24:MI:SS'),'D','N','N',53775,14,285,'N')
|
||||
;
|
||||
|
||||
-- Aug 9, 2021 12:54:23 PM GMT+08:00
|
||||
ALTER TABLE AD_Process_Para ADD COLUMN Query VARCHAR(2000) DEFAULT NULL
|
||||
;
|
||||
|
||||
-- Aug 9, 2021 12:57:18 PM GMT+08:00
|
||||
INSERT INTO AD_Field (SortNo,AD_Field_ID,IsEncrypted,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,IsReadOnly,DisplayLogic,AD_Org_ID,Updated,Description,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,CreatedBy,UpdatedBy,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry,AD_Client_ID,Created,ColumnSpan,NumLines,IsAdvancedField,IsDefaultFocus,AD_Column_ID,EntityType,AD_Tab_ID) VALUES (0,205193,'N',0,'N','N',270,'Y','N','@IsReport@=Y',0,TO_TIMESTAMP('2021-08-09 12:57:17','YYYY-MM-DD HH24:MI:SS'),'SQL','Query','ed208c1d-a58a-43d5-912f-af8294e5d276','Y','N',100,100,'Y','Y',270,1,'N',0,TO_TIMESTAMP('2021-08-09 12:57:17','YYYY-MM-DD HH24:MI:SS'),5,3,'N','N',213185,'D',246)
|
||||
;
|
||||
|
||||
SELECT register_migration_script('202108091122_IDEMPIERE-4904.sql') FROM dual
|
||||
;
|
|
@ -414,6 +414,19 @@ public interface I_AD_Process_Para
|
|||
/** Get Placeholder2 */
|
||||
public String getPlaceholder2();
|
||||
|
||||
/** Column name Query */
|
||||
public static final String COLUMNNAME_Query = "Query";
|
||||
|
||||
/** Set Query.
|
||||
* SQL
|
||||
*/
|
||||
public void setQuery (String Query);
|
||||
|
||||
/** Get Query.
|
||||
* SQL
|
||||
*/
|
||||
public String getQuery();
|
||||
|
||||
/** Column name ReadOnlyLogic */
|
||||
public static final String COLUMNNAME_ReadOnlyLogic = "ReadOnlyLogic";
|
||||
|
||||
|
|
|
@ -21,7 +21,11 @@ import java.sql.PreparedStatement;
|
|||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
|
||||
|
@ -29,8 +33,10 @@ import org.compiere.util.CLogger;
|
|||
import org.compiere.util.DB;
|
||||
import org.compiere.util.DisplayType;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Evaluatee;
|
||||
import org.compiere.util.KeyNamePair;
|
||||
import org.compiere.util.Msg;
|
||||
import org.compiere.util.Util;
|
||||
import org.compiere.util.ValueNamePair;
|
||||
|
||||
/**
|
||||
|
@ -79,12 +85,14 @@ public class MQuery implements Serializable, Cloneable
|
|||
if (rows < 1)
|
||||
return reportQuery;
|
||||
|
||||
Map<String, String> parameterMap = new HashMap<>();
|
||||
List<String> queryList = new ArrayList<>();
|
||||
boolean trl = !Env.isBaseLanguage(ctx, "AD_Process_Para");
|
||||
if (!trl)
|
||||
SQL = "SELECT ip.ParameterName,ip.P_String,ip.P_String_To," // 1..3
|
||||
+ "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 " // 10..12
|
||||
+ "pp.Name, pp.IsRange, pp.AD_Reference_ID, pp.Query " // 10..13
|
||||
+ "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"
|
||||
|
@ -95,7 +103,7 @@ public class MQuery implements Serializable, Cloneable
|
|||
else
|
||||
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 "
|
||||
+ "ppt.Name, pp.IsRange, pp.AD_Reference_ID, pp.Query "
|
||||
+ "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"
|
||||
|
@ -147,13 +155,14 @@ public class MQuery implements Serializable, Cloneable
|
|||
boolean isRange = "Y".equals(rs.getString(11));
|
||||
//
|
||||
int Reference_ID = rs.getInt(12);
|
||||
String P_Query = rs.getString(13);
|
||||
//
|
||||
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);
|
||||
//
|
||||
//custom query or column not exists - render as report parameters
|
||||
if (table != null && table.getColumn(ParameterName) == null)
|
||||
if (!Util.isEmpty(P_Query) || (table != null && table.getColumn(ParameterName) == null))
|
||||
{
|
||||
query = reportQuery.getReportProcessQuery();
|
||||
}
|
||||
|
@ -161,6 +170,7 @@ public class MQuery implements Serializable, Cloneable
|
|||
//-------------------------------------------------------------
|
||||
if (P_String != null)
|
||||
{
|
||||
parameterMap.put(ParameterName, P_String);
|
||||
if (P_String_To == null)
|
||||
{
|
||||
if (Reference_ID == DisplayType.ChosenMultipleSelectionList)
|
||||
|
@ -191,14 +201,18 @@ public class MQuery implements Serializable, Cloneable
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
query.addRangeRestriction(ParameterName,
|
||||
P_String, P_String_To, Name, Info, Info_To);
|
||||
parameterMap.put("To_"+ParameterName, P_String_To);
|
||||
}
|
||||
}
|
||||
// Number
|
||||
else if (P_Number != null || P_Number_To != null)
|
||||
{
|
||||
if (P_Number_To == null)
|
||||
{
|
||||
parameterMap.put(ParameterName, P_Number.toString());
|
||||
if (isRange)
|
||||
query.addRestriction(ParameterName, MQuery.GREATER_EQUAL,
|
||||
P_Number, Name, Info);
|
||||
|
@ -208,12 +222,16 @@ public class MQuery implements Serializable, Cloneable
|
|||
}
|
||||
else // P_Number_To != null
|
||||
{
|
||||
if (P_Number == null)
|
||||
parameterMap.put("To_"+ParameterName, P_Number_To.toString());
|
||||
if (P_Number == null)
|
||||
query.addRestriction(ParameterName, MQuery.LESS_EQUAL,
|
||||
P_Number_To, Name, Info);
|
||||
else
|
||||
{
|
||||
query.addRangeRestriction(ParameterName,
|
||||
P_Number, P_Number_To, Name, Info, Info_To);
|
||||
parameterMap.put(ParameterName, P_Number.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
// Date
|
||||
|
@ -224,6 +242,7 @@ public class MQuery implements Serializable, Cloneable
|
|||
|
||||
if (P_Date_To == null)
|
||||
{
|
||||
parameterMap.put(ParameterName, DisplayType.getDateFormat().format(P_Date));
|
||||
if (isRange)
|
||||
query.addRestriction(paramName, MQuery.GREATER_EQUAL, P_Date, Name, Info);
|
||||
else
|
||||
|
@ -231,12 +250,21 @@ public class MQuery implements Serializable, Cloneable
|
|||
}
|
||||
else // P_Date_To != null
|
||||
{
|
||||
parameterMap.put("To_"+ParameterName, DisplayType.getDateFormat().format(P_Date_To));
|
||||
if (P_Date == null)
|
||||
query.addRestriction(paramName, MQuery.LESS_EQUAL, P_Date_To, Name, Info);
|
||||
else
|
||||
{
|
||||
query.addRangeRestriction(paramName, P_Date, P_Date_To, Name, Info, Info_To);
|
||||
parameterMap.put(ParameterName, DisplayType.getDateFormat().format(P_Date));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//keep custom query for later context parsing
|
||||
if (!Util.isEmpty(P_Query) && (parameterMap.containsKey(ParameterName) || parameterMap.containsKey("To_"+ParameterName)))
|
||||
queryList.add(P_Query);
|
||||
|
||||
//add to reportprocessquery if new restriction added to reportquery
|
||||
if (query == reportQuery && reportQuery.getReportProcessQuery() != null
|
||||
&& reportQuery.getRestrictionCount() > restrictionCount)
|
||||
|
@ -254,10 +282,76 @@ public class MQuery implements Serializable, Cloneable
|
|||
DB.close(rs, pstmt);
|
||||
rs = null; pstmt = null;
|
||||
}
|
||||
|
||||
//add custom query
|
||||
if (queryList.size() > 0)
|
||||
{
|
||||
QueryEvaluatee evaluatee= new QueryEvaluatee(parameterMap);
|
||||
for(String query : queryList)
|
||||
{
|
||||
if (query.indexOf("@") >= 0)
|
||||
{
|
||||
query = parseVariable(evaluatee, query, false);
|
||||
reportQuery.addRestriction(query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (s_log.isLoggable(Level.INFO)) s_log.info(reportQuery.toString());
|
||||
return reportQuery;
|
||||
} // get
|
||||
|
||||
private static String parseVariable(Evaluatee evaluatee, String expression, boolean ignoreUnparseable) {
|
||||
if (expression == null || expression.length() == 0)
|
||||
return "";
|
||||
|
||||
String token;
|
||||
String inStr = new String(expression);
|
||||
StringBuilder outStr = new StringBuilder();
|
||||
|
||||
int i = inStr.indexOf('@');
|
||||
while (i != -1)
|
||||
{
|
||||
outStr.append(inStr.substring(0, i)); // up to @
|
||||
inStr = inStr.substring(i+1, inStr.length()); // from first @
|
||||
|
||||
int j = inStr.indexOf('@'); // next @
|
||||
if (j < 0)
|
||||
{
|
||||
s_log.log(Level.SEVERE, "No second tag: " + inStr);
|
||||
return ""; // no second tag
|
||||
}
|
||||
|
||||
token = inStr.substring(0, j);
|
||||
|
||||
//format string
|
||||
String format = "";
|
||||
int f = token.indexOf('<');
|
||||
if (f > 0 && token.endsWith(">")) {
|
||||
format = token.substring(f+1, token.length()-1);
|
||||
token = token.substring(0, f);
|
||||
}
|
||||
|
||||
String v = evaluatee.get_ValueAsString(token);
|
||||
if (!Util.isEmpty(v)) {
|
||||
if (format != null && format.length() > 0) {
|
||||
MessageFormat mf = new MessageFormat(format);
|
||||
outStr.append(mf.format(v));
|
||||
} else {
|
||||
outStr.append(v.toString());
|
||||
}
|
||||
} else if (!ignoreUnparseable) {
|
||||
return "";
|
||||
}
|
||||
|
||||
inStr = inStr.substring(j+1, inStr.length()); // from second @
|
||||
i = inStr.indexOf('@');
|
||||
}
|
||||
outStr.append(inStr); // add the rest of the string
|
||||
|
||||
return outStr.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Zoom Column Name.
|
||||
* Converts Synonyms like SalesRep_ID to AD_User_ID
|
||||
|
@ -1350,3 +1444,68 @@ class Restriction implements Serializable
|
|||
} // getInfoDisplay
|
||||
|
||||
} // Restriction
|
||||
|
||||
class QueryEvaluatee implements Evaluatee {
|
||||
private Map<String, String> parameterMap;
|
||||
|
||||
public QueryEvaluatee(Map<String, String> parameterMap) {
|
||||
this.parameterMap = parameterMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Variable Value (Evaluatee)
|
||||
* @param variableName name
|
||||
* @return value
|
||||
*/
|
||||
public String get_ValueAsString (Properties ctx, String variableName)
|
||||
{
|
||||
//ref column
|
||||
String foreignColumn = "";
|
||||
int f = variableName.indexOf('.');
|
||||
if (f > 0) {
|
||||
foreignColumn = variableName.substring(f+1, variableName.length());
|
||||
variableName = variableName.substring(0, f);
|
||||
}
|
||||
|
||||
String value = null;
|
||||
if (variableName.startsWith("#") || variableName.startsWith("$")) {
|
||||
value = Env.getContext(ctx, variableName);
|
||||
} else {
|
||||
value = parameterMap.get(variableName);
|
||||
}
|
||||
if (!Util.isEmpty(value) && !Util.isEmpty(foreignColumn) && variableName.endsWith("_ID")) {
|
||||
String refValue = "";
|
||||
int id = 0;
|
||||
try {
|
||||
id = Integer.parseInt(value);
|
||||
} catch (Exception e){}
|
||||
if (id > 0) {
|
||||
if (variableName.startsWith("#") || variableName.startsWith("$")) {
|
||||
variableName = variableName.substring(1);
|
||||
} else if (variableName.indexOf("|") > 0) {
|
||||
variableName = variableName.substring(variableName.lastIndexOf("|")+1);
|
||||
}
|
||||
String foreignTable = null;
|
||||
if (foreignColumn.indexOf(".") > 0) {
|
||||
foreignTable = foreignColumn.substring(0, foreignColumn.indexOf("."));
|
||||
} else {
|
||||
foreignTable = variableName.substring(0, variableName.length()-3);
|
||||
}
|
||||
MTable t = MTable.get(Env.getCtx(), foreignTable);
|
||||
if (t != null) {
|
||||
refValue = DB.getSQLValueString(null,
|
||||
"SELECT " + foreignColumn + " FROM " + foreignTable + " WHERE "
|
||||
+ foreignTable + "_ID = ?", id);
|
||||
}
|
||||
}
|
||||
return refValue;
|
||||
}
|
||||
return value;
|
||||
} // get_ValueAsString
|
||||
|
||||
@Override
|
||||
public String get_ValueAsString(String variableName) {
|
||||
return get_ValueAsString(Env.getCtx(), variableName);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ public class X_AD_Process_Para extends PO implements I_AD_Process_Para, I_Persis
|
|||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 20210723L;
|
||||
private static final long serialVersionUID = 20210809L;
|
||||
|
||||
/** Standard Constructor */
|
||||
public X_AD_Process_Para (Properties ctx, int AD_Process_Para_ID, String trxName)
|
||||
|
@ -43,7 +43,7 @@ public class X_AD_Process_Para extends PO implements I_AD_Process_Para, I_Persis
|
|||
setAD_Reference_ID (0);
|
||||
setColumnName (null);
|
||||
setEntityType (null);
|
||||
// @SQL=select get_sysconfig('DEFAULT_ENTITYTYPE','U',0,0) from dual
|
||||
// @SQL=SELECT CASE WHEN '@P|AdempiereSys:N@'='Y' THEN 'D' ELSE get_sysconfig('DEFAULT_ENTITYTYPE','U',0,0) END FROM Dual
|
||||
setFieldLength (0);
|
||||
setIsAutocomplete (false);
|
||||
// N
|
||||
|
@ -618,6 +618,23 @@ public class X_AD_Process_Para extends PO implements I_AD_Process_Para, I_Persis
|
|||
return (String)get_Value(COLUMNNAME_Placeholder2);
|
||||
}
|
||||
|
||||
/** Set Query.
|
||||
@param Query
|
||||
SQL
|
||||
*/
|
||||
public void setQuery (String Query)
|
||||
{
|
||||
set_Value (COLUMNNAME_Query, Query);
|
||||
}
|
||||
|
||||
/** Get Query.
|
||||
@return SQL
|
||||
*/
|
||||
public String getQuery ()
|
||||
{
|
||||
return (String)get_Value(COLUMNNAME_Query);
|
||||
}
|
||||
|
||||
/** Set Read Only Logic.
|
||||
@param ReadOnlyLogic
|
||||
Logic to determine if field is read only (applies only when field is read-write)
|
||||
|
|
Loading…
Reference in New Issue