From 42fb2de77d24954df0c9e1ade7af2a9c40baab5f Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Tue, 9 Apr 2024 03:28:00 +0200 Subject: [PATCH] IDEMPIERE-6096 Implement regexp VFormat (#2301) --- .../oracle/202404081845_IDEMPIERE-6096.sql | 31 +++++++++++++++++++ .../202404081845_IDEMPIERE-6096.sql | 28 +++++++++++++++++ .../adempiere/webui/editor/WStringEditor.java | 22 ++++++++++--- 3 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 migration/iD11/oracle/202404081845_IDEMPIERE-6096.sql create mode 100644 migration/iD11/postgresql/202404081845_IDEMPIERE-6096.sql diff --git a/migration/iD11/oracle/202404081845_IDEMPIERE-6096.sql b/migration/iD11/oracle/202404081845_IDEMPIERE-6096.sql new file mode 100644 index 0000000000..0f115e3495 --- /dev/null +++ b/migration/iD11/oracle/202404081845_IDEMPIERE-6096.sql @@ -0,0 +1,31 @@ +-- IDEMPIERE-6096 Implement regexp VFormat +SELECT register_migration_script('202404081845_IDEMPIERE-6096.sql') FROM dual; + +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- Apr 8, 2024, 6:45:20 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','The entered value does not match the required regular expression: {0}',0,0,'Y',TO_TIMESTAMP('2024-04-08 18:45:20','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2024-04-08 18:45:20','YYYY-MM-DD HH24:MI:SS'),100,200886,'InvalidFormatRegExp','D','ba94f2c9-ac3e-4efd-a054-fa0b653e7322') +; + +-- Apr 8, 2024, 6:48:11 PM CEST +UPDATE AD_Element SET Description='Format of the value; Can contain fixed format elements, Variables: "_lLoOaAcCa09", or ~regex', Help='Validation elements: + +~regex - Validates a regular expression + + (Space) any character +_ Space (fixed character) +l any Letter a..Z NO space +L any Letter a..Z NO space converted to upper case +o any Letter a..Z or space +O any Letter a..Z or space converted to upper case +a any Letters & Digits NO space +A any Letters & Digits NO space converted to upper case +c any Letters & Digits or space +C any Letters & Digits or space converted to upper case +0 Digits 0..9 NO space +9 Digits 0..9 or space + +Example of format "(000)_000-0000"',Updated=TO_TIMESTAMP('2024-04-08 18:48:11','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=616 +; + diff --git a/migration/iD11/postgresql/202404081845_IDEMPIERE-6096.sql b/migration/iD11/postgresql/202404081845_IDEMPIERE-6096.sql new file mode 100644 index 0000000000..00111e350c --- /dev/null +++ b/migration/iD11/postgresql/202404081845_IDEMPIERE-6096.sql @@ -0,0 +1,28 @@ +-- IDEMPIERE-6096 Implement regexp VFormat +SELECT register_migration_script('202404081845_IDEMPIERE-6096.sql') FROM dual; + +-- Apr 8, 2024, 6:45:20 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','The entered value does not match the required regular expression: {0}',0,0,'Y',TO_TIMESTAMP('2024-04-08 18:45:20','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2024-04-08 18:45:20','YYYY-MM-DD HH24:MI:SS'),100,200886,'InvalidFormatRegExp','D','ba94f2c9-ac3e-4efd-a054-fa0b653e7322') +; + +-- Apr 8, 2024, 6:48:11 PM CEST +UPDATE AD_Element SET Description='Format of the value; Can contain fixed format elements, Variables: "_lLoOaAcCa09", or ~regex', Help='Validation elements: + +~regex - Validates a regular expression + + (Space) any character +_ Space (fixed character) +l any Letter a..Z NO space +L any Letter a..Z NO space converted to upper case +o any Letter a..Z or space +O any Letter a..Z or space converted to upper case +a any Letters & Digits NO space +A any Letters & Digits NO space converted to upper case +c any Letters & Digits or space +C any Letters & Digits or space converted to upper case +0 Digits 0..9 NO space +9 Digits 0..9 or space + +Example of format "(000)_000-0000"',Updated=TO_TIMESTAMP('2024-04-08 18:48:11','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=616 +; + diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WStringEditor.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WStringEditor.java index eadf2ddab2..c8f382cf4c 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WStringEditor.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WStringEditor.java @@ -35,8 +35,12 @@ import org.adempiere.webui.window.WTextEditorDialog; import org.compiere.model.GridField; import org.compiere.model.I_R_MailText; import org.compiere.util.DisplayType; +import org.compiere.util.Env; +import org.compiere.util.Msg; +import org.compiere.util.Util; import org.zkoss.zk.ui.AbstractComponent; import org.zkoss.zk.ui.Component; +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; @@ -54,6 +58,7 @@ public class WStringEditor extends WEditor implements ContextMenuListener private static final String[] LISTENER_EVENTS = {Events.ON_CHANGE, Events.ON_OK}; private String oldValue; + private String vFormat = null; private AbstractADWindowContent adwindowContent; @@ -93,8 +98,7 @@ public class WStringEditor extends WEditor implements ContextMenuListener { super(gridField.isAutocomplete() ? new Combobox() : new Textbox(), gridField, tableEditor, editorConfiguration); - if (gridField.getVFormat() != null && !gridField.getVFormat().isEmpty()) - getComponent().setWidgetListener("onBind", "jq(this).mask('" + gridField.getVFormat() + "');"); + vFormat = gridField.getVFormat(); init(gridField.getObscureType()); } @@ -114,8 +118,7 @@ public class WStringEditor extends WEditor implements ContextMenuListener { super(new Textbox(), columnName, null, null, mandatory, isReadOnly,isUpdateable); - if (wVFormat != null && !wVFormat.isEmpty()) - getComponent().setWidgetListener("onBind", "jq(this).mask('" + wVFormat + "');"); + vFormat = wVFormat; init(obscureType); } @@ -141,6 +144,9 @@ public class WStringEditor extends WEditor implements ContextMenuListener */ private void init(String obscureType) { + if (!Util.isEmpty(vFormat) && !vFormat.startsWith("~")) + getComponent().setWidgetListener("onBind", "jq(this).mask('" + vFormat + "');"); + setChangeEventWhenEditing (true); if (gridField != null) { @@ -211,6 +217,14 @@ public class WStringEditor extends WEditor implements ContextMenuListener if (!isStartEdit && oldValue == null && newValue == null) { return; } + + // Validate VFormat with regular expression + if (!Util.isEmpty(vFormat) && vFormat.startsWith("~")) { + String regex = gridField.getVFormat().substring(1); // remove the initial ~ + if (!newValue.matches(regex)) + throw new WrongValueException(component, Msg.getMsg(Env.getCtx(), "InvalidFormatRegExp", new Object[] {regex})); + } + ValueChangeEvent changeEvent = new ValueChangeEvent(this, this.getColumnName(), oldValue, newValue); changeEvent.setIsInitEdit(isStartEdit);