diff --git a/migration/iD11/oracle/202306221620_IDEMPIERE-5062.sql b/migration/iD11/oracle/202306221620_IDEMPIERE-5062.sql new file mode 100644 index 0000000000..c222528aef --- /dev/null +++ b/migration/iD11/oracle/202306221620_IDEMPIERE-5062.sql @@ -0,0 +1,61 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- Jun 22, 2023, 4:20:22 PM WIB +UPDATE AD_Field SET DisplayLogic='@AD_Reference_ID@=11 | @AD_Reference_ID@=12 | @AD_Reference_ID@=15 | @AD_Reference_ID@=22 | @AD_Reference_ID@=29 | @AD_Reference_ID@=37 | @AD_Reference_ID@=10',Updated=TO_TIMESTAMP('2023-06-22 16:20:21','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=10 WHERE AD_Field_ID=2906 +; + +-- Jun 22, 2023, 4:20:38 PM WIB +UPDATE AD_Field SET DisplayLogic='@AD_Reference_ID@=11 | @AD_Reference_ID@=12 | @AD_Reference_ID@=15 | @AD_Reference_ID@=22 | @AD_Reference_ID@=29 | @AD_Reference_ID@=37 | @AD_Reference_ID@=10',Updated=TO_TIMESTAMP('2023-06-22 16:20:38','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=10 WHERE AD_Field_ID=2905 +; + +-- Jun 24, 2023, 3:39:38 PM WIB +UPDATE AD_Element SET Help='The Minimum Value indicates the lowest allowable value for a field. use format yyyy-mm-dd for Date',Updated=TO_TIMESTAMP('2023-06-24 15:39:38','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=10 WHERE AD_Element_ID=1060 +; + +-- Jun 24, 2023, 3:39:38 PM WIB +UPDATE AD_Column SET ColumnName='ValueMin', Name='Min. Value', Description='Minimum Value for a field', Help='The Minimum Value indicates the lowest allowable value for a field. use format yyyy-mm-dd for Date', Placeholder=NULL WHERE AD_Element_ID=1060 +; + +-- Jun 24, 2023, 3:39:38 PM WIB +UPDATE AD_Process_Para SET ColumnName='ValueMin', Name='Min. Value', Description='Minimum Value for a field', Help='The Minimum Value indicates the lowest allowable value for a field. use format yyyy-mm-dd for Date', AD_Element_ID=1060 WHERE UPPER(ColumnName)='VALUEMIN' AND IsCentrallyMaintained='Y' AND AD_Element_ID IS NULL +; + +-- Jun 24, 2023, 3:39:38 PM WIB +UPDATE AD_Process_Para SET ColumnName='ValueMin', Name='Min. Value', Description='Minimum Value for a field', Help='The Minimum Value indicates the lowest allowable value for a field. use format yyyy-mm-dd for Date', Placeholder=NULL WHERE AD_Element_ID=1060 AND IsCentrallyMaintained='Y' +; + +-- Jun 24, 2023, 3:39:38 PM WIB +UPDATE AD_InfoColumn SET ColumnName='ValueMin', Name='Min. Value', Description='Minimum Value for a field', Help='The Minimum Value indicates the lowest allowable value for a field. use format yyyy-mm-dd for Date', Placeholder=NULL WHERE AD_Element_ID=1060 AND IsCentrallyMaintained='Y' +; + +-- Jun 24, 2023, 3:39:38 PM WIB +UPDATE AD_Field SET Name='Min. Value', Description='Minimum Value for a field', Help='The Minimum Value indicates the lowest allowable value for a field. use format yyyy-mm-dd for Date', Placeholder=NULL WHERE AD_Column_ID IN (SELECT AD_Column_ID FROM AD_Column WHERE AD_Element_ID=1060) AND IsCentrallyMaintained='Y' +; + +-- Jun 24, 2023, 3:40:41 PM WIB +UPDATE AD_Element SET Help='The Maximum Value indicates the highest allowable value for a field. use format yyyy-mm-dd for Date',Updated=TO_TIMESTAMP('2023-06-24 15:40:41','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=10 WHERE AD_Element_ID=1059 +; + +-- Jun 24, 2023, 3:40:41 PM WIB +UPDATE AD_Column SET ColumnName='ValueMax', Name='Max. Value', Description='Maximum Value for a field', Help='The Maximum Value indicates the highest allowable value for a field. use format yyyy-mm-dd for Date', Placeholder=NULL WHERE AD_Element_ID=1059 +; + +-- Jun 24, 2023, 3:40:41 PM WIB +UPDATE AD_Process_Para SET ColumnName='ValueMax', Name='Max. Value', Description='Maximum Value for a field', Help='The Maximum Value indicates the highest allowable value for a field. use format yyyy-mm-dd for Date', AD_Element_ID=1059 WHERE UPPER(ColumnName)='VALUEMAX' AND IsCentrallyMaintained='Y' AND AD_Element_ID IS NULL +; + +-- Jun 24, 2023, 3:40:41 PM WIB +UPDATE AD_Process_Para SET ColumnName='ValueMax', Name='Max. Value', Description='Maximum Value for a field', Help='The Maximum Value indicates the highest allowable value for a field. use format yyyy-mm-dd for Date', Placeholder=NULL WHERE AD_Element_ID=1059 AND IsCentrallyMaintained='Y' +; + +-- Jun 24, 2023, 3:40:41 PM WIB +UPDATE AD_InfoColumn SET ColumnName='ValueMax', Name='Max. Value', Description='Maximum Value for a field', Help='The Maximum Value indicates the highest allowable value for a field. use format yyyy-mm-dd for Date', Placeholder=NULL WHERE AD_Element_ID=1059 AND IsCentrallyMaintained='Y' +; + +-- Jun 24, 2023, 3:40:41 PM WIB +UPDATE AD_Field SET Name='Max. Value', Description='Maximum Value for a field', Help='The Maximum Value indicates the highest allowable value for a field. use format yyyy-mm-dd for Date', Placeholder=NULL WHERE AD_Column_ID IN (SELECT AD_Column_ID FROM AD_Column WHERE AD_Element_ID=1059) AND IsCentrallyMaintained='Y' +; + +-- IDEMPIERE-5062 +SELECT register_migration_script('202306221620_IDEMPIERE-5062.sql') FROM dual; \ No newline at end of file diff --git a/migration/iD11/postgresql/202306221620_IDEMPIERE-5062.sql b/migration/iD11/postgresql/202306221620_IDEMPIERE-5062.sql new file mode 100644 index 0000000000..07b2edfff5 --- /dev/null +++ b/migration/iD11/postgresql/202306221620_IDEMPIERE-5062.sql @@ -0,0 +1,58 @@ +-- Jun 22, 2023, 4:20:22 PM WIB +UPDATE AD_Field SET DisplayLogic='@AD_Reference_ID@=11 | @AD_Reference_ID@=12 | @AD_Reference_ID@=15 | @AD_Reference_ID@=22 | @AD_Reference_ID@=29 | @AD_Reference_ID@=37 | @AD_Reference_ID@=10',Updated=TO_TIMESTAMP('2023-06-22 16:20:21','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=10 WHERE AD_Field_ID=2906 +; + +-- Jun 22, 2023, 4:20:38 PM WIB +UPDATE AD_Field SET DisplayLogic='@AD_Reference_ID@=11 | @AD_Reference_ID@=12 | @AD_Reference_ID@=15 | @AD_Reference_ID@=22 | @AD_Reference_ID@=29 | @AD_Reference_ID@=37 | @AD_Reference_ID@=10',Updated=TO_TIMESTAMP('2023-06-22 16:20:38','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=10 WHERE AD_Field_ID=2905 +; + +-- Jun 24, 2023, 3:39:38 PM WIB +UPDATE AD_Element SET Help='The Minimum Value indicates the lowest allowable value for a field. use format yyyy-mm-dd for Date',Updated=TO_TIMESTAMP('2023-06-24 15:39:38','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=10 WHERE AD_Element_ID=1060 +; + +-- Jun 24, 2023, 3:39:38 PM WIB +UPDATE AD_Column SET ColumnName='ValueMin', Name='Min. Value', Description='Minimum Value for a field', Help='The Minimum Value indicates the lowest allowable value for a field. use format yyyy-mm-dd for Date', Placeholder=NULL WHERE AD_Element_ID=1060 +; + +-- Jun 24, 2023, 3:39:38 PM WIB +UPDATE AD_Process_Para SET ColumnName='ValueMin', Name='Min. Value', Description='Minimum Value for a field', Help='The Minimum Value indicates the lowest allowable value for a field. use format yyyy-mm-dd for Date', AD_Element_ID=1060 WHERE UPPER(ColumnName)='VALUEMIN' AND IsCentrallyMaintained='Y' AND AD_Element_ID IS NULL +; + +-- Jun 24, 2023, 3:39:38 PM WIB +UPDATE AD_Process_Para SET ColumnName='ValueMin', Name='Min. Value', Description='Minimum Value for a field', Help='The Minimum Value indicates the lowest allowable value for a field. use format yyyy-mm-dd for Date', Placeholder=NULL WHERE AD_Element_ID=1060 AND IsCentrallyMaintained='Y' +; + +-- Jun 24, 2023, 3:39:38 PM WIB +UPDATE AD_InfoColumn SET ColumnName='ValueMin', Name='Min. Value', Description='Minimum Value for a field', Help='The Minimum Value indicates the lowest allowable value for a field. use format yyyy-mm-dd for Date', Placeholder=NULL WHERE AD_Element_ID=1060 AND IsCentrallyMaintained='Y' +; + +-- Jun 24, 2023, 3:39:38 PM WIB +UPDATE AD_Field SET Name='Min. Value', Description='Minimum Value for a field', Help='The Minimum Value indicates the lowest allowable value for a field. use format yyyy-mm-dd for Date', Placeholder=NULL WHERE AD_Column_ID IN (SELECT AD_Column_ID FROM AD_Column WHERE AD_Element_ID=1060) AND IsCentrallyMaintained='Y' +; + +-- Jun 24, 2023, 3:40:41 PM WIB +UPDATE AD_Element SET Help='The Maximum Value indicates the highest allowable value for a field. use format yyyy-mm-dd for Date',Updated=TO_TIMESTAMP('2023-06-24 15:40:41','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=10 WHERE AD_Element_ID=1059 +; + +-- Jun 24, 2023, 3:40:41 PM WIB +UPDATE AD_Column SET ColumnName='ValueMax', Name='Max. Value', Description='Maximum Value for a field', Help='The Maximum Value indicates the highest allowable value for a field. use format yyyy-mm-dd for Date', Placeholder=NULL WHERE AD_Element_ID=1059 +; + +-- Jun 24, 2023, 3:40:41 PM WIB +UPDATE AD_Process_Para SET ColumnName='ValueMax', Name='Max. Value', Description='Maximum Value for a field', Help='The Maximum Value indicates the highest allowable value for a field. use format yyyy-mm-dd for Date', AD_Element_ID=1059 WHERE UPPER(ColumnName)='VALUEMAX' AND IsCentrallyMaintained='Y' AND AD_Element_ID IS NULL +; + +-- Jun 24, 2023, 3:40:41 PM WIB +UPDATE AD_Process_Para SET ColumnName='ValueMax', Name='Max. Value', Description='Maximum Value for a field', Help='The Maximum Value indicates the highest allowable value for a field. use format yyyy-mm-dd for Date', Placeholder=NULL WHERE AD_Element_ID=1059 AND IsCentrallyMaintained='Y' +; + +-- Jun 24, 2023, 3:40:41 PM WIB +UPDATE AD_InfoColumn SET ColumnName='ValueMax', Name='Max. Value', Description='Maximum Value for a field', Help='The Maximum Value indicates the highest allowable value for a field. use format yyyy-mm-dd for Date', Placeholder=NULL WHERE AD_Element_ID=1059 AND IsCentrallyMaintained='Y' +; + +-- Jun 24, 2023, 3:40:41 PM WIB +UPDATE AD_Field SET Name='Max. Value', Description='Maximum Value for a field', Help='The Maximum Value indicates the highest allowable value for a field. use format yyyy-mm-dd for Date', Placeholder=NULL WHERE AD_Column_ID IN (SELECT AD_Column_ID FROM AD_Column WHERE AD_Element_ID=1059) AND IsCentrallyMaintained='Y' +; + +-- IDEMPIERE-5062 +SELECT register_migration_script('202306221620_IDEMPIERE-5062.sql') FROM dual; \ No newline at end of file diff --git a/org.adempiere.base/src/org/compiere/model/MProcessPara.java b/org.adempiere.base/src/org/compiere/model/MProcessPara.java index c9a54c2779..98c3c883b4 100644 --- a/org.adempiere.base/src/org/compiere/model/MProcessPara.java +++ b/org.adempiere.base/src/org/compiere/model/MProcessPara.java @@ -16,10 +16,14 @@ *****************************************************************************/ package org.compiere.model; +import java.math.BigDecimal; import java.sql.ResultSet; +import java.sql.Timestamp; +import java.text.SimpleDateFormat; import java.util.Properties; import java.util.logging.Level; +import org.adempiere.exceptions.AdempiereException; import org.adempiere.process.UUIDGenerator; import org.compiere.process.ProcessInfoParameter; import org.compiere.util.CLogger; @@ -43,7 +47,11 @@ public class MProcessPara extends X_AD_Process_Para implements ImmutablePOSuppor /** * */ - private static final long serialVersionUID = -1357447647930552555L; + private static final long serialVersionUID = -1116840975434565353L; + + /** + * + */ /** Static Logger */ private static CLogger s_log = CLogger.getCLogger (MProcessPara.class); @@ -374,6 +382,32 @@ public class MProcessPara extends X_AD_Process_Para implements ImmutablePOSuppor setIsShowNegateButton(true); } + if (getValueMin() != null) { + try { + if (getAD_Reference_ID() == DisplayType.Date) { // Date + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + new Timestamp(dateFormat.parse(getValueMin()).getTime()); + } else if (DisplayType.isNumeric(getAD_Reference_ID())) { + new BigDecimal(getValueMin()); + } + } catch (Exception e) { + throw new AdempiereException("Min Value : "+ e.getLocalizedMessage()); + } + } + + if (getValueMax() != null) { + try { + if (getAD_Reference_ID() == DisplayType.Date) { // Date + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + new Timestamp(dateFormat.parse(getValueMax()).getTime()); + } else if (DisplayType.isNumeric(getAD_Reference_ID())) { + new BigDecimal(getValueMax()); + } + } catch (Exception e) { + throw new AdempiereException("Max Value : "+ e.getLocalizedMessage()); + } + } + return true; } // beforeSave 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 9ecad4ccae..e6cc827601 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 @@ -78,6 +78,7 @@ import org.compiere.util.Msg; import org.compiere.util.Util; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.HtmlBasedComponent; +import org.zkoss.zk.ui.WrongValueException; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; @@ -102,7 +103,7 @@ public class ProcessParameterPanel extends Panel implements /** * generated serial id */ - private static final long serialVersionUID = -1398301240136128512L; + private static final long serialVersionUID = -8847249274740131848L; /** Event post from {@link #valueChange(ValueChangeEvent)} **/ private static final String ON_POST_EDITOR_VALUE_CHANGE_EVENT = "onPostEditorValueChange"; @@ -578,49 +579,30 @@ public class ProcessParameterPanel extends Panel implements if (log.isLoggable(Level.CONFIG)) log.config(""); //mandatory fields validation - StringBuilder sb = new StringBuilder(); int size = m_mFields.size(); for (int i = 0; i < size; i++) { GridField field = (GridField) m_mFields.get(i); - if (field.isMandatory(true)) // check context - { - WEditor wEditor = (WEditor) m_wEditors.get(i); - Object data = wEditor.getValue(); - if (data == null || data.toString().length() == 0) { - field.setInserting(true); // set editable (i.e. updateable) - // otherwise deadlock - field.setError(true); - if (sb.length() > 0) - sb.append(", "); - sb.append(field.getHeader()); - if (m_wEditors2.get(i) != null) // is a range - sb.append(" (").append(Msg.getMsg(Env.getCtx(), "ProcessParameterRangeFrom")).append(")"); - } else - field.setError(false); - // Check for Range - WEditor wEditor2 = (WEditor) m_wEditors2.get(i); - if (wEditor2 != null) { - Object data2 = wEditor2.getValue(); - GridField field2 = (GridField) m_mFields2.get(i); - if (data2 == null || data2.toString().length() == 0) { - field2.setInserting(true); // set editable (i.e. - // updateable) otherwise - // deadlock - field2.setError(true); - if (sb.length() > 0) - sb.append(", "); - sb.append(field2.getHeader()); - sb.append(" (").append(Msg.getMsg(Env.getCtx(), "ProcessParameterRangeTo")).append(")"); - } else - field2.setError(false); - } // range field - } // mandatory - } // field loop + GridField field2 = (GridField) m_mFields2.get(i); + WEditor wEditor = (WEditor) m_wEditors.get(i); + WEditor wEditor2 = (WEditor) m_wEditors2.get(i); + Object data = wEditor.getValue(); + String msg = validate(data, field.getValueMin(), field.getValueMax(), field.isMandatory(true), field.getDisplayType()); + if (msg != null) { + field.setInserting(true); // set editable (i.e. updateable) otherwise deadlock + field.setError(true); + throw new WrongValueException(wEditor.getComponent(), msg); + } + if (m_wEditors2.get(i) != null) { // is a range + data = wEditor2.getValue(); + msg = validate(data, field.getValueMin(), field.getValueMax(), field.isMandatory(true), field.getDisplayType()); + if (msg != null) { + field2.setInserting(true); // set editable (i.e. updateable) otherwise deadlock + field2.setError(true); + throw new WrongValueException(wEditor2.getComponent(), msg); + } + } - if (sb.length() != 0) { - Dialog.error(m_WindowNo, "FillMandatory", sb.toString()); - return false; - } + } // field loop /** call {@link IProcessParameterListener} validate(ProcessParameterPanel) **/ if (m_processInfo.getAD_Process_ID() > 0) { @@ -638,6 +620,68 @@ public class ProcessParameterPanel extends Panel implements return true; } // validateParameters + /** + * Validate mandatory and min/max value + * @param value + * @param valueMin + * @param valueMax + * @param isMandatory + * @param fieldType + * @return null if OK, any message if not OK + */ + public static String validate(Object value, String valueMin, String valueMax, boolean isMandatory, int fieldType) { + + if (isMandatory) { + if (value == null || value.toString().length() == 0) { + return Msg.getMsg(Env.getCtx(), "FillMandatory"); + } + } + + BigDecimal value_BD = null; + BigDecimal valueMin_BD = null; + BigDecimal valueMax_BD = null; + Timestamp value_TS = null; + Timestamp valueMin_TS = null; + Timestamp valueMax_TS = null; + + if (fieldType == DisplayType.Date) { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd"); + if (value != null) { + try { value_TS = new Timestamp(dateFormat.parse(value.toString()).getTime()); } catch (Exception ex){} + } + if (valueMin != null) { + try { valueMin_TS = new Timestamp(dateFormat.parse(valueMin).getTime()); } catch (Exception ex){} + } + if (valueMax != null) { + try { valueMax_TS = new Timestamp(dateFormat.parse(valueMax).getTime()); } catch (Exception ex){} + } + } else if (DisplayType.isNumeric(fieldType)) { + if (value != null) { + try { value_BD = new BigDecimal(value.toString()); } catch (Exception ex){} + } + if (valueMin != null) { + try { valueMin_BD = new BigDecimal(valueMin); } catch (Exception ex){} + } + if (valueMax != null) { + try { valueMax_BD = new BigDecimal(valueMax); } catch (Exception ex){} + } + } + + if ( (value_TS != null && valueMin_TS != null && value_TS.before(valueMin_TS)) + || (value_BD != null && valueMin_BD != null && valueMin_BD.compareTo(value_BD) > 0) + || (value != null && valueMin != null && valueMin.compareTo(value.toString()) > 0) + ) + return Msg.getMsg(Env.getCtx(), "LessThanMinValue", new Object[] {valueMin}); + + if ( (value_TS != null && valueMax_TS != null && value_TS.after(valueMax_TS)) + || (value_BD != null && valueMax_BD != null && valueMax_BD.compareTo(value_BD) < 0) + || (value != null && valueMax != null && valueMax.compareTo(value.toString()) < 0) + ) + return Msg.getMsg(Env.getCtx(), "MoreThanMaxValue", new Object[] {valueMax}); + + return null; + } + /** * load parameters from saved instance * @param instance