From ad8de98fe5eee8c859e15b43e1365060115e1e2a Mon Sep 17 00:00:00 2001 From: Nicolas Micoud <58596990+nmicoud@users.noreply.github.com> Date: Tue, 11 May 2021 13:10:25 +0200 Subject: [PATCH] IDEMPIERE-4781 : Dashboard / Report : use @SQL= syntax (#677) * IDEMPIERE-4781 : Dashboard / Report : use @SQL= syntax * IDEMPIERE-4781 : Dashboard / Report - be able to use Range parameters * IDEMPIERE-4781 : Dashboard Content as Advanced * Update DashboardController.java Implement partial solution for IDEMPIERE-4779 Fix issue with Timestamp not working for IDEMPIERE-4781 it was throwing: 12:58:07.928-----------> DashboardController.render: Failed to create dashboard content [358] java.lang.NumberFormatException: Error at index 6 in: "474671+02" at java.base/java.lang.NumberFormatException.forCharSequence(NumberFormatException.java:81) at java.base/java.lang.Integer.parseInt(Integer.java:735) at java.sql/java.sql.Timestamp.valueOf(Timestamp.java:239) at org.adempiere.webui.desktop.DashboardController.fillParameter(DashboardController.java:974) Co-authored-by: Carlos Ruiz --- .../oracle/202105101345_IDEMPIERE-4781.sql | 17 ++ .../202105101345_IDEMPIERE-4781.sql | 14 ++ .../webui/desktop/DashboardController.java | 167 +++++++++++++----- 3 files changed, 151 insertions(+), 47 deletions(-) create mode 100644 migration/i8.2z/oracle/202105101345_IDEMPIERE-4781.sql create mode 100644 migration/i8.2z/postgresql/202105101345_IDEMPIERE-4781.sql diff --git a/migration/i8.2z/oracle/202105101345_IDEMPIERE-4781.sql b/migration/i8.2z/oracle/202105101345_IDEMPIERE-4781.sql new file mode 100644 index 0000000000..670e088f96 --- /dev/null +++ b/migration/i8.2z/oracle/202105101345_IDEMPIERE-4781.sql @@ -0,0 +1,17 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- May 10, 2021, 1:50:01 PM CEST +UPDATE AD_Tab SET IsAdvancedTab='Y',Updated=TO_DATE('2021-05-10 13:50:01','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=0 WHERE AD_Tab_ID=50010 +; + +-- May 10, 2021, 1:50:09 PM CEST +UPDATE AD_Tab SET IsAdvancedTab='Y',Updated=TO_DATE('2021-05-10 13:50:09','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=0 WHERE AD_Tab_ID=200112 +; + +-- May 10, 2021, 1:50:17 PM CEST +UPDATE AD_Tab SET IsAdvancedTab='Y',Updated=TO_DATE('2021-05-10 13:50:17','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=0 WHERE AD_Tab_ID=53372 +; + +SELECT register_migration_script('202105101345_IDEMPIERE-4781.sql') FROM dual +; diff --git a/migration/i8.2z/postgresql/202105101345_IDEMPIERE-4781.sql b/migration/i8.2z/postgresql/202105101345_IDEMPIERE-4781.sql new file mode 100644 index 0000000000..fe4a415960 --- /dev/null +++ b/migration/i8.2z/postgresql/202105101345_IDEMPIERE-4781.sql @@ -0,0 +1,14 @@ +-- May 10, 2021, 1:50:01 PM CEST +UPDATE AD_Tab SET IsAdvancedTab='Y',Updated=TO_TIMESTAMP('2021-05-10 13:50:01','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=0 WHERE AD_Tab_ID=50010 +; + +-- May 10, 2021, 1:50:09 PM CEST +UPDATE AD_Tab SET IsAdvancedTab='Y',Updated=TO_TIMESTAMP('2021-05-10 13:50:09','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=0 WHERE AD_Tab_ID=200112 +; + +-- May 10, 2021, 1:50:17 PM CEST +UPDATE AD_Tab SET IsAdvancedTab='Y',Updated=TO_TIMESTAMP('2021-05-10 13:50:17','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=0 WHERE AD_Tab_ID=53372 +; + +SELECT register_migration_script('202105101345_IDEMPIERE-4781.sql') FROM dual +; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DashboardController.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DashboardController.java index 621ddf2c8a..d55ff6d850 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DashboardController.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DashboardController.java @@ -18,7 +18,12 @@ import java.io.File; import java.io.InputStreamReader; import java.math.BigDecimal; import java.net.URL; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; import java.sql.Timestamp; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -60,6 +65,7 @@ import org.compiere.util.DB; import org.compiere.util.DisplayType; import org.compiere.util.Env; import org.compiere.util.Msg; +import org.compiere.util.Util; import org.zkoss.util.media.AMedia; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Desktop; @@ -881,59 +887,126 @@ public class DashboardController implements EventListener { String[] params = parameters.split("[,]"); for (String s : params) { - String[] elements = s.split("[=]"); - String key = elements[0]; - String value = elements[1]; + int pos = s.indexOf("="); + String key = s.substring(0, pos); + String value = s.substring(pos + 1); paramMap.put(key, value); } MPInstancePara[] iParams = pInstance.getParameters(); for (MPInstancePara iPara : iParams) { - String variable = paramMap.get(iPara.getParameterName()); - // Value - Constant/Variable - Object value = variable; - if (variable == null - || (variable != null && variable.length() == 0)) - value = null; - else if (variable.indexOf('@') != -1) // we have a variable - { - value = Env.parseContext(Env.getCtx(), 0, variable, false, false); - } // @variable@ - - // No Value - if (value == null) - { + String variable = paramMap.get(iPara.getParameterName()); + + if (Util.isEmpty(variable)) continue; - } - - // Convert to Type - if (DisplayType.isNumeric(iPara.getDisplayType()) - || DisplayType.isID(iPara.getDisplayType())) - { - BigDecimal bd = null; - if (value instanceof BigDecimal) - bd = (BigDecimal)value; - else if (value instanceof Integer) - bd = new BigDecimal (((Integer)value).intValue()); - else - bd = new BigDecimal (value.toString()); - iPara.setP_Number(bd); - } - else if (DisplayType.isDate(iPara.getDisplayType())) - { - Timestamp ts = null; - if (value instanceof Timestamp) - ts = (Timestamp)value; - else - ts = Timestamp.valueOf(value.toString()); - iPara.setP_Date(ts); - } - else - { - iPara.setP_String(value.toString()); - } - iPara.saveEx(); - + + boolean isTo = false; + + for (String paramValue : variable.split(";")) { + + // Value - Constant/Variable + Object value = paramValue; + if (paramValue == null + || (paramValue != null && paramValue.length() == 0)) + value = null; + else if (paramValue.startsWith("@SQL=")) { + String sql = paramValue.substring(5); + sql = Env.parseContext(Env.getCtx(), 0, sql, false, false); // replace variables + if (!Util.isEmpty(sql)) { + PreparedStatement stmt = null; + ResultSet rs = null; + try { + stmt = DB.prepareStatement(sql, null); + rs = stmt.executeQuery(); + if (rs.next()) { + if ( DisplayType.isNumeric(iPara.getDisplayType()) + || DisplayType.isID(iPara.getDisplayType())) + value = rs.getBigDecimal(1); + else if (DisplayType.isDate(iPara.getDisplayType())) + value = rs.getTimestamp(1); + else + value = rs.getString(1); + } else { + if (logger.isLoggable(Level.INFO)) + logger.log(Level.INFO, "(" + iPara.getParameterName() + ") - no Result: " + sql); + } + } + catch (SQLException e) { + logger.log(Level.WARNING, "(" + iPara.getParameterName() + ") " + sql, e); + } + finally{ + DB.close(rs, stmt); + rs = null; + stmt = null; + } + } + } // SQL Statement + else if (paramValue.indexOf('@') != -1) // we have a variable + { + value = Env.parseContext(Env.getCtx(), 0, paramValue, false, false); + } // @variable@ + + // No Value + if (value == null) + { + continue; + } + + // Convert to Type + if (DisplayType.isNumeric(iPara.getDisplayType()) + || DisplayType.isID(iPara.getDisplayType())) + { + BigDecimal bd = null; + if (value instanceof BigDecimal) + bd = (BigDecimal)value; + else if (value instanceof Integer) + bd = new BigDecimal (((Integer)value).intValue()); + else + bd = new BigDecimal (value.toString()); + DecimalFormat decimalFormat = DisplayType.getNumberFormat(iPara.getDisplayType()); + String info = decimalFormat.format(iPara.getP_Number()); + if (isTo) { + iPara.setP_Number_To(bd); + iPara.setInfo_To(info); + } + else { + iPara.setP_Number(bd); + iPara.setInfo(info); + } + } + else if (DisplayType.isDate(iPara.getDisplayType())) + { + Timestamp ts = null; + if (value instanceof Timestamp) + ts = (Timestamp)value; + else + ts = Timestamp.valueOf(value.toString()); + SimpleDateFormat dateFormat = DisplayType.getDateFormat(iPara.getDisplayType()); + String info = dateFormat.format(ts); + if (isTo) { + iPara.setP_Date_To(ts); + iPara.setInfo_To(info); + } + else { + iPara.setP_Date(ts); + iPara.setInfo(info); + } + } + else + { + if (isTo) { + iPara.setP_String_To(value.toString()); + iPara.setInfo_To(value.toString()); + } + else { + iPara.setP_String(value.toString()); + iPara.setInfo(value.toString()); + } + } + iPara.saveEx(); + + isTo = true; + } } } }