From b1bf9bc4e9cc365e6cf07bfee9a1daae21e39eca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Tak=C3=A1cs?= <93127072+PeterTakacs300@users.noreply.github.com> Date: Wed, 5 Apr 2023 13:00:00 +0200 Subject: [PATCH] IDEMPIERE-5650 - Cannot Define Multiple Values for Dashboard Content Process Parameters (#1757) * IDEMPIERE-5650 - Cannot Define Multiple Values for Dashboard Content Process Parameters * IDEMPIERE-5650 - remove hardcoded condition * IDEMPIERE-5650 - fix for reference list multiselection - support for non-ID multiselection types (values were not rendered e.g. with DocType="IP,CO") * IDEMPIERE-5650 - fix for reference list multiselection * IDEMPIERE-5650 - bug fixes - error use case: reference list with numeric values e.g. "10", "20",... (fix: check DisplayType instead of data type) - error use case 2: defining more than one multi-selection caused parsing error (fixed parsing logic in MDashboardContent) * IDEMPIERE-5650 - optimise parsing method * IDEMPIERE-5650 - pr1757_PR0 patch --- .../oracle/202304042029_IDEMPIERE-5650.sql | 13 +++++++ .../202304042029_IDEMPIERE-5650.sql | 10 ++++++ .../org/compiere/model/MDashboardContent.java | 36 ++++++++++++++++--- .../webui/desktop/DashboardController.java | 27 +++++++++++--- 4 files changed, 78 insertions(+), 8 deletions(-) create mode 100644 migration/iD10/oracle/202304042029_IDEMPIERE-5650.sql create mode 100644 migration/iD10/postgresql/202304042029_IDEMPIERE-5650.sql diff --git a/migration/iD10/oracle/202304042029_IDEMPIERE-5650.sql b/migration/iD10/oracle/202304042029_IDEMPIERE-5650.sql new file mode 100644 index 0000000000..cf302d178c --- /dev/null +++ b/migration/iD10/oracle/202304042029_IDEMPIERE-5650.sql @@ -0,0 +1,13 @@ +-- +SELECT register_migration_script('202304042029_IDEMPIERE-5650.sql') FROM dual; + +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- Apr 4, 2023, 8:29:09 PM CEST +UPDATE AD_Field SET DisplayLogic='@AD_Process_ID@!0&@IsEmbedReportContent@=''Y''', DefaultValue=NULL,Updated=TO_TIMESTAMP('2023-04-04 20:29:09','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=200263 +; + +-- Apr 4, 2023, 8:45:33 PM CEST +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Please review the definition of Process Parameters',0,0,'Y',TO_TIMESTAMP('2023-04-04 20:45:31','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-04-04 20:45:31','YYYY-MM-DD HH24:MI:SS'),100,200829,'WrongProcessParameters','D','3cda0c21-5059-4f49-8971-6ffcf969efee') +; diff --git a/migration/iD10/postgresql/202304042029_IDEMPIERE-5650.sql b/migration/iD10/postgresql/202304042029_IDEMPIERE-5650.sql new file mode 100644 index 0000000000..9838e3fba2 --- /dev/null +++ b/migration/iD10/postgresql/202304042029_IDEMPIERE-5650.sql @@ -0,0 +1,10 @@ +-- +SELECT register_migration_script('202304042029_IDEMPIERE-5650.sql') FROM dual; + +-- Apr 4, 2023, 8:29:09 PM CEST +UPDATE AD_Field SET DisplayLogic='@AD_Process_ID@!0&@IsEmbedReportContent@=''Y''', DefaultValue=NULL,Updated=TO_TIMESTAMP('2023-04-04 20:29:09','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=200263 +; + +-- Apr 4, 2023, 8:45:33 PM CEST +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Please review the definition of Process Parameters',0,0,'Y',TO_TIMESTAMP('2023-04-04 20:45:31','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-04-04 20:45:31','YYYY-MM-DD HH24:MI:SS'),100,200829,'WrongProcessParameters','D','3cda0c21-5059-4f49-8971-6ffcf969efee') +; diff --git a/org.adempiere.base/src/org/compiere/model/MDashboardContent.java b/org.adempiere.base/src/org/compiere/model/MDashboardContent.java index bcf188df5d..d6c6b19b9c 100644 --- a/org.adempiere.base/src/org/compiere/model/MDashboardContent.java +++ b/org.adempiere.base/src/org/compiere/model/MDashboardContent.java @@ -9,6 +9,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.adempiere.exceptions.AdempiereException; import org.compiere.util.Env; @@ -185,13 +187,38 @@ public class MDashboardContent extends X_PA_DashboardContent */ public static Map parseProcessParameters(String parameters) { Map paramMap = new HashMap(); - if (parameters != null && parameters.trim().length() > 0) { - String[] params = parameters.split("[,]"); + if (Util.isEmpty(parameters, true)) + return paramMap; + Map multiSelections = new HashMap(); + final String placeHolder = "_MULTISELECTVALUE_"; + String multiSelection; + String parsedParameters = parameters; + int idx = 0; + Pattern p = Pattern.compile("\"(.*?)\""); // regex to extract multiselection values between double quotes: "(.*?)" + Matcher m = p.matcher(parameters); + + // extract the multiselection values before splitting by [,] + while (m.find()) { + String multiSelectionKey = placeHolder+idx; + multiSelection = parameters.substring(m.start(), m.end()); + multiSelections.put(multiSelectionKey, multiSelection.replace("\"", "")); + parsedParameters = parsedParameters.replaceFirst(multiSelection, multiSelectionKey); + idx++; + } + + // split values by [,] + if (! Util.isEmpty(parsedParameters, true)) { + String[] params = parsedParameters.split("[,]"); for (String s : params) { int pos = s.indexOf("="); + if (pos < 0) + throw new AdempiereException(Msg.getMsg(Env.getCtx(), "WrongProcessParameters")); String key = s.substring(0, pos); String value = s.substring(pos + 1); + if(value.startsWith(placeHolder)) { + value = multiSelections.get(value); // insert the multiselection values back to the HashMap + } paramMap.put(key, value); } } @@ -226,10 +253,11 @@ public class MDashboardContent extends X_PA_DashboardContent */ protected boolean beforeSave (boolean newRecord) { // all mandatory process parameters need to be set - if(getAD_Process_ID() > 0) { + if (getAD_Process_ID() > 0 && isEmbedReportContent()) { String emptyPara = getEmptyMandatoryProcessPara(); if(!Util.isEmpty(emptyPara)) { - throw new AdempiereException(Msg.getMsg(getCtx(), "FillMandatoryParametersDashboard", new Object[] {emptyPara})); + log.saveError("Error", Msg.getMsg(getCtx(), "FillMandatoryParametersDashboard", new Object[] {emptyPara})); + return false; } } return true; 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 232f925df4..9c2b7aa5c9 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 @@ -29,6 +29,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Properties; import java.util.logging.Level; @@ -49,8 +50,8 @@ import org.adempiere.webui.component.ToolBarButton; import org.adempiere.webui.dashboard.DashboardPanel; import org.adempiere.webui.dashboard.DashboardRunnable; import org.adempiere.webui.event.DrillEvent; -import org.adempiere.webui.event.ZoomEvent; import org.adempiere.webui.event.DrillEvent.DrillData; +import org.adempiere.webui.event.ZoomEvent; import org.adempiere.webui.report.HTMLExtension; import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.theme.ThemeManager; @@ -1705,6 +1706,10 @@ public class DashboardController implements EventListener { iPara.setP_String_To(value.toString()); iPara.setInfo_To(value.toString()); } + else if(DisplayType.isChosenMultipleSelection(iPara.getDisplayType())) { + iPara.setP_String(value.toString()); + iPara.setInfo(getMultiSelectionDisplay(pInstance, iPara, value.toString())); + } else { iPara.setP_String(value.toString()); iPara.setInfo(value.toString()); @@ -1726,7 +1731,18 @@ public class DashboardController implements EventListener { return true; } - private String getDisplay(MPInstance i, MPInstancePara ip, int id) { + private String getMultiSelectionDisplay(MPInstance i, MPInstancePara ip, String values) { + String returnValue = ""; + String[] splittedValues = values.split("[,]"); + for(String value : splittedValues) { + if(!Util.isEmpty(returnValue)) + returnValue += ", "; + returnValue += getDisplay(i, ip, DisplayType.ChosenMultipleSelectionList == ip.getDisplayType() ? value : Integer.parseInt(value)); + } + return returnValue; + } + + private String getDisplay(MPInstance i, MPInstancePara ip, Object value) { try { MProcessPara pp = MProcess.get(i.getAD_Process_ID()).getParameter(ip.getParameterName()); @@ -1741,7 +1757,10 @@ public class DashboardController implements EventListener { try { pstmt = DB.prepareStatement(mli.QueryDirect, null); - pstmt.setInt(1, id); + if(value instanceof Integer) + pstmt.setInt(1, (Integer)value); + else + pstmt.setString(1, Objects.toString(value, "")); rs = pstmt.executeQuery(); if (rs.next()) { @@ -1770,7 +1789,7 @@ public class DashboardController implements EventListener { logger.log(Level.WARNING, "Failed to retrieve data to display for embedded report " + MProcess.get(i.getAD_Process_ID()).getName() + " : " + ip.getParameterName(), e); } - return Integer.toString(id); + return Objects.toString(value, ""); } /**