From 5c4973b5282d91101231830ac5ec64dfb87f3fc0 Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Sat, 8 Apr 2017 22:08:32 +0800 Subject: [PATCH] IDEMPIERE-3321 Add Mandatory Logic to Report & Process Parameter. --- .../oracle/201703291605_IDEMPIERE-3321.sql | 33 +++++++++++++++++ .../201703291605_IDEMPIERE-3321.sql | 31 ++++++++++++++++ .../src/org/compiere/model/GridField.java | 36 ++++++++++++++++++- .../src/org/compiere/model/GridFieldVO.java | 2 +- .../org/compiere/model/I_AD_Process_Para.java | 9 +++++ .../org/compiere/model/X_AD_Process_Para.java | 16 ++++++++- .../webui/apps/ProcessParameterPanel.java | 6 ++-- .../org/adempiere/webui/editor/WEditor.java | 4 +-- 8 files changed, 129 insertions(+), 8 deletions(-) create mode 100755 migration/i4.1z/oracle/201703291605_IDEMPIERE-3321.sql create mode 100755 migration/i4.1z/postgresql/201703291605_IDEMPIERE-3321.sql diff --git a/migration/i4.1z/oracle/201703291605_IDEMPIERE-3321.sql b/migration/i4.1z/oracle/201703291605_IDEMPIERE-3321.sql new file mode 100755 index 0000000000..df9ae50ecb --- /dev/null +++ b/migration/i4.1z/oracle/201703291605_IDEMPIERE-3321.sql @@ -0,0 +1,33 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +ALTER TABLE AD_Process_Para +ADD mandatorylogic VARCHAR2(2000) DEFAULT NULL +; + +-- Mar 27, 2017 9:06:38 PM SGT +INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,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) VALUES (212967,0,'Mandatory Logic',285,'MandatoryLogic',2000,'N','N','N','N','N',0,'N',14,0,0,'Y',TO_DATE('2017-03-27 21:06:37','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-03-27 21:06:37','YYYY-MM-DD HH24:MI:SS'),100,50074,'Y','N','D','N','N','N','Y','e9fab689-db8f-4d61-8ef6-9f08c2c405a4','Y',0,'N','N') +; +-- Mar 27, 2017 9:24:30 PM SGT +INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,SortNo,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,NumLines,IsQuickEntry,IsDefaultFocus,IsAdvancedField) VALUES (204372,'Mandatory Logic',246,212967,'Y',0,270,0,'N','N','N','N',0,0,'Y',TO_DATE('2017-03-27 21:24:29','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-03-27 21:24:29','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','3f1360c0-d89e-4b28-aaef-2b6ae45678f5','Y',270,1,1,1,'N','N','N') +; + +-- Mar 27, 2017 9:26:58 PM SGT +UPDATE AD_Field SET AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, NumLines=2, IsToolbarButton=NULL,Updated=TO_DATE('2017-03-27 21:26:58','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204372 +; + +-- Mar 27, 2017 9:28:23 PM SGT +UPDATE AD_Field SET AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, ColumnSpan=5, IsToolbarButton=NULL,Updated=TO_DATE('2017-03-27 21:28:23','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204372 +; + +-- Mar 27, 2017 9:29:19 PM SGT +UPDATE AD_Field SET AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, NumLines=3, IsToolbarButton=NULL,Updated=TO_DATE('2017-03-27 21:29:19','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204372 +; + +-- Mar 27, 2017 9:35:44 PM SGT +UPDATE AD_Field SET Help='Logic expression or @SQL=SELECT something FROM ... (Both can contain context variables). For @SQL=, the field is mandatory if the SQL statement return a non-empty result set. ', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-03-27 21:35:44','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204372 +; + + +SELECT register_migration_script('201703291605_IDEMPIERE-3321.sql') FROM dual +; diff --git a/migration/i4.1z/postgresql/201703291605_IDEMPIERE-3321.sql b/migration/i4.1z/postgresql/201703291605_IDEMPIERE-3321.sql new file mode 100755 index 0000000000..67c7b71643 --- /dev/null +++ b/migration/i4.1z/postgresql/201703291605_IDEMPIERE-3321.sql @@ -0,0 +1,31 @@ +ALTER TABLE AD_Process_Para +ADD mandatorylogic character varying(2000) DEFAULT NULL::character varying +; + + +-- Mar 27, 2017 9:06:38 PM SGT +INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,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) VALUES (212967,0,'Mandatory Logic',285,'MandatoryLogic',2000,'N','N','N','N','N',0,'N',14,0,0,'Y',TO_TIMESTAMP('2017-03-27 21:06:37','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-03-27 21:06:37','YYYY-MM-DD HH24:MI:SS'),100,50074,'Y','N','D','N','N','N','Y','e9fab689-db8f-4d61-8ef6-9f08c2c405a4','Y',0,'N','N') +; + +-- Mar 27, 2017 9:24:30 PM SGT +INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,SortNo,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,NumLines,IsQuickEntry,IsDefaultFocus,IsAdvancedField) VALUES (204372,'Mandatory Logic',246,212967,'Y',0,270,0,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2017-03-27 21:24:29','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-03-27 21:24:29','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','3f1360c0-d89e-4b28-aaef-2b6ae45678f5','Y',270,1,1,1,'N','N','N') +; + +-- Mar 27, 2017 9:26:58 PM SGT +UPDATE AD_Field SET AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, NumLines=2, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-03-27 21:26:58','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204372 +; + +-- Mar 27, 2017 9:28:23 PM SGT +UPDATE AD_Field SET AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, ColumnSpan=5, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-03-27 21:28:23','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204372 +; + +-- Mar 27, 2017 9:29:19 PM SGT +UPDATE AD_Field SET AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, NumLines=3, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-03-27 21:29:19','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204372 +; + +-- Mar 27, 2017 9:35:44 PM SGT +UPDATE AD_Field SET Help='Logic expression or @SQL=SELECT something FROM ... (Both can contain context variables). For @SQL=, the field is mandatory if the SQL statement return a non-empty result set. ', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-03-27 21:35:44','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204372 +; + +SELECT register_migration_script('201703291605_IDEMPIERE-3321.sql') FROM dual +; diff --git a/org.adempiere.base/src/org/compiere/model/GridField.java b/org.adempiere.base/src/org/compiere/model/GridField.java index 8ef4e0bc87..7037e2a8b9 100644 --- a/org.adempiere.base/src/org/compiere/model/GridField.java +++ b/org.adempiere.base/src/org/compiere/model/GridField.java @@ -352,7 +352,15 @@ public class GridField // Do we have a mandatory rule if (checkContext && m_vo.MandatoryLogic.length() > 0) { - boolean retValue = Evaluator.evaluateLogic(this, m_vo.MandatoryLogic); + boolean retValue = false; + if (m_vo.MandatoryLogic != null && m_vo.MandatoryLogic.startsWith("@SQL=")) { + retValue = mandatorySqlStatement(); + + } else{ + retValue= Evaluator.evaluateLogic(this, m_vo.MandatoryLogic); + + } + if (log.isLoggable(Level.FINEST)) log.finest(m_vo.ColumnName + " Mandatory(" + m_vo.MandatoryLogic + ") => Mandatory-" + retValue); if (retValue) return true; @@ -378,6 +386,32 @@ public class GridField return isDisplayed (checkContext); } // isMandatory + private boolean mandatorySqlStatement() { + String sql = m_vo.MandatoryLogic.substring(5); // w/o tag + sql = Env.parseContext(m_vo.ctx, m_vo.WindowNo, sql, false, false); // replace + + // variables + if (sql.equals("")) { + log.log(Level.WARNING,"(" + m_vo.ColumnName + ") - Mandatory SQL variable parse failed: " + m_vo.MandatoryLogic); + } else { + PreparedStatement stmt = null; + ResultSet rs = null; + try { + stmt = DB.prepareStatement(sql, null); + rs = stmt.executeQuery(); + if (rs.next()) + return true; + } catch (SQLException e) { + log.log(Level.WARNING, "(" + m_vo.ColumnName + ") " + sql, e); + } finally { + DB.close(rs, stmt); + rs = null; + stmt = null; + } + } + return false; + } + /** * Is parameter Editable - checks if parameter is Read Only * @param checkContext if true checks Context diff --git a/org.adempiere.base/src/org/compiere/model/GridFieldVO.java b/org.adempiere.base/src/org/compiere/model/GridFieldVO.java index beb4e2c961..2372e6715b 100644 --- a/org.adempiere.base/src/org/compiere/model/GridFieldVO.java +++ b/org.adempiere.base/src/org/compiere/model/GridFieldVO.java @@ -371,7 +371,7 @@ public class GridFieldVO implements Serializable vo.ReadOnlyLogic = rs.getString("ReadOnlyLogic"); vo.DisplayLogic= rs.getString("DisplayLogic"); vo.IsEncryptedField=rs.getString("IsEncrypted").equals("Y"); - + vo.MandatoryLogic = rs.getString("MandatoryLogic"); } catch (SQLException e) { diff --git a/org.adempiere.base/src/org/compiere/model/I_AD_Process_Para.java b/org.adempiere.base/src/org/compiere/model/I_AD_Process_Para.java index ae8aa72e4f..34ef997723 100644 --- a/org.adempiere.base/src/org/compiere/model/I_AD_Process_Para.java +++ b/org.adempiere.base/src/org/compiere/model/I_AD_Process_Para.java @@ -346,6 +346,15 @@ public interface I_AD_Process_Para */ public boolean isRange(); + /** Column name MandatoryLogic */ + public static final String COLUMNNAME_MandatoryLogic = "MandatoryLogic"; + + /** Set Mandatory Logic */ + public void setMandatoryLogic (String MandatoryLogic); + + /** Get Mandatory Logic */ + public String getMandatoryLogic(); + /** Column name Name */ public static final String COLUMNNAME_Name = "Name"; diff --git a/org.adempiere.base/src/org/compiere/model/X_AD_Process_Para.java b/org.adempiere.base/src/org/compiere/model/X_AD_Process_Para.java index 3b7cec6bac..8832286c2e 100644 --- a/org.adempiere.base/src/org/compiere/model/X_AD_Process_Para.java +++ b/org.adempiere.base/src/org/compiere/model/X_AD_Process_Para.java @@ -30,7 +30,7 @@ public class X_AD_Process_Para extends PO implements I_AD_Process_Para, I_Persis /** * */ - private static final long serialVersionUID = 20161030L; + private static final long serialVersionUID = 20170408L; /** Standard Constructor */ public X_AD_Process_Para (Properties ctx, int AD_Process_Para_ID, String trxName) @@ -497,6 +497,20 @@ public class X_AD_Process_Para extends PO implements I_AD_Process_Para, I_Persis return false; } + /** Set Mandatory Logic. + @param MandatoryLogic Mandatory Logic */ + public void setMandatoryLogic (String MandatoryLogic) + { + set_Value (COLUMNNAME_MandatoryLogic, MandatoryLogic); + } + + /** Get Mandatory Logic. + @return Mandatory Logic */ + public String getMandatoryLogic () + { + return (String)get_Value(COLUMNNAME_MandatoryLogic); + } + /** Set Name. @param Name Alphanumeric identifier of the entity 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 878146d515..a12dfaa695 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 @@ -202,7 +202,7 @@ public class ProcessParameterPanel extends Panel implements + "p.FieldLength, p.IsMandatory, p.IsRange, p.ColumnName, " + "p.DefaultValue, p.DefaultValue2, p.VFormat, p.ValueMin, p.ValueMax, " + "p.SeqNo, p.AD_Reference_Value_ID, vr.Code AS ValidationCode, " - + "p.ReadOnlyLogic, p.DisplayLogic, p.IsEncrypted, NULL AS FormatPattern " + + "p.ReadOnlyLogic, p.DisplayLogic, p.IsEncrypted, NULL AS FormatPattern, p.MandatoryLogic " + "FROM AD_Process_Para p" + " LEFT OUTER JOIN AD_Val_Rule vr ON (p.AD_Val_Rule_ID=vr.AD_Val_Rule_ID) " + "WHERE p.AD_Process_ID=?" // 1 @@ -213,7 +213,7 @@ public class ProcessParameterPanel extends Panel implements + "p.FieldLength, p.IsMandatory, p.IsRange, p.ColumnName, " + "p.DefaultValue, p.DefaultValue2, p.VFormat, p.ValueMin, p.ValueMax, " + "p.SeqNo, p.AD_Reference_Value_ID, vr.Code AS ValidationCode, " - + "p.ReadOnlyLogic, p.DisplayLogic, p.IsEncrypted, NULL AS FormatPattern " + + "p.ReadOnlyLogic, p.DisplayLogic, p.IsEncrypted, NULL AS FormatPattern,p.MandatoryLogic " + "FROM AD_Process_Para p" + " INNER JOIN AD_Process_Para_Trl t ON (p.AD_Process_Para_ID=t.AD_Process_Para_ID)" + " LEFT OUTER JOIN AD_Val_Rule vr ON (p.AD_Val_Rule_ID=vr.AD_Val_Rule_ID) " @@ -797,7 +797,7 @@ public class ProcessParameterPanel extends Panel implements } } editor.setMandatory(mField.isMandatory(true)); - editor.updateLabelStyle(); + editor.updateStyle(); } if (getParent() != null) { getParent().invalidate(); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WEditor.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WEditor.java index c5b55aeec1..42b5877001 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WEditor.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WEditor.java @@ -172,9 +172,9 @@ public abstract class WEditor implements EventListener, PropertyChangeLis comp.setClientAttribute(AdempiereWebUI.WIDGET_INSTANCE_NAME, gridField.getGridTab().getTableName()+"0"+gridField.getColumnName()); this.gridTab = gridField.getGridTab(); } else { - comp.setWidgetAttribute(AdempiereWebUI.WIDGET_INSTANCE_NAME, gridField.getColumnName()); + comp.setClientAttribute(AdempiereWebUI.WIDGET_INSTANCE_NAME, gridField.getColumnName()); } - this.setMandatory(gridField.isMandatory(false)); + this.setMandatory(gridField.isMandatory(true)); this.readOnly = gridField.isReadOnly(); this.description = gridField.getDescription(); this.updateable = gridField.isUpdateable();