IDEMPIERE-5062 validation when run process and input min max value on process parameter (#1908)

* - added validation for min and max value when run process
- added validation when insert min and max value format

* - remove unused class
- change reference id to displayType
- translate error massage

* refactoring code by carlosRuiz-globalqss
This commit is contained in:
Zuhri Utama 2023-07-03 22:14:16 +07:00 committed by GitHub
parent b7b0b16476
commit 9f55c76573
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 238 additions and 41 deletions

View File

@ -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;

View File

@ -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;

View File

@ -16,10 +16,14 @@
*****************************************************************************/ *****************************************************************************/
package org.compiere.model; package org.compiere.model;
import java.math.BigDecimal;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Properties; import java.util.Properties;
import java.util.logging.Level; import java.util.logging.Level;
import org.adempiere.exceptions.AdempiereException;
import org.adempiere.process.UUIDGenerator; import org.adempiere.process.UUIDGenerator;
import org.compiere.process.ProcessInfoParameter; import org.compiere.process.ProcessInfoParameter;
import org.compiere.util.CLogger; 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 */ /** Static Logger */
private static CLogger s_log = CLogger.getCLogger (MProcessPara.class); 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); 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; return true;
} // beforeSave } // beforeSave

View File

@ -78,6 +78,7 @@ import org.compiere.util.Msg;
import org.compiere.util.Util; import org.compiere.util.Util;
import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.HtmlBasedComponent; 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.Event;
import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.Events;
@ -102,7 +103,7 @@ public class ProcessParameterPanel extends Panel implements
/** /**
* generated serial id * generated serial id
*/ */
private static final long serialVersionUID = -1398301240136128512L; private static final long serialVersionUID = -8847249274740131848L;
/** Event post from {@link #valueChange(ValueChangeEvent)} **/ /** Event post from {@link #valueChange(ValueChangeEvent)} **/
private static final String ON_POST_EDITOR_VALUE_CHANGE_EVENT = "onPostEditorValueChange"; 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(""); if (log.isLoggable(Level.CONFIG)) log.config("");
//mandatory fields validation //mandatory fields validation
StringBuilder sb = new StringBuilder();
int size = m_mFields.size(); int size = m_mFields.size();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
GridField field = (GridField) m_mFields.get(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); GridField field2 = (GridField) m_mFields2.get(i);
if (data2 == null || data2.toString().length() == 0) { WEditor wEditor = (WEditor) m_wEditors.get(i);
field2.setInserting(true); // set editable (i.e. WEditor wEditor2 = (WEditor) m_wEditors2.get(i);
// updateable) otherwise Object data = wEditor.getValue();
// deadlock String msg = validate(data, field.getValueMin(), field.getValueMax(), field.isMandatory(true), field.getDisplayType());
field2.setError(true); if (msg != null) {
if (sb.length() > 0) field.setInserting(true); // set editable (i.e. updateable) otherwise deadlock
sb.append(", "); field.setError(true);
sb.append(field2.getHeader()); throw new WrongValueException(wEditor.getComponent(), msg);
sb.append(" (").append(Msg.getMsg(Env.getCtx(), "ProcessParameterRangeTo")).append(")");
} else
field2.setError(false);
} // range field
} // mandatory
} // field loop
if (sb.length() != 0) {
Dialog.error(m_WindowNo, "FillMandatory", sb.toString());
return false;
} }
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);
}
}
} // field loop
/** call {@link IProcessParameterListener} validate(ProcessParameterPanel) **/ /** call {@link IProcessParameterListener} validate(ProcessParameterPanel) **/
if (m_processInfo.getAD_Process_ID() > 0) { if (m_processInfo.getAD_Process_ID() > 0) {
@ -638,6 +620,68 @@ public class ProcessParameterPanel extends Panel implements
return true; return true;
} // validateParameters } // 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 * load parameters from saved instance
* @param instance * @param instance