diff --git a/migration/i8.2z/oracle/202103081000_IDEMPIERE-4724.sql b/migration/i8.2z/oracle/202103081000_IDEMPIERE-4724.sql new file mode 100644 index 0000000000..afe12c4d80 --- /dev/null +++ b/migration/i8.2z/oracle/202103081000_IDEMPIERE-4724.sql @@ -0,0 +1,52 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- Add column to allow concatenation on import +-- Mar 7, 2021, 9:03:37 PM UTC +INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,Description,Help,PrintName,EntityType,AD_Element_UU) VALUES (203480,0,0,'Y',TO_DATE('2021-03-07 21:03:31','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-03-07 21:03:31','YYYY-MM-DD HH24:MI:SS'),100,'ImportPrefix','Import prefix','This prefix will be added in front of import string if they are not empty','Use it e.g. when concatening input fields into one import field to add a blank','Import prefix','D','a7213dfc-f1fc-49f5-b15a-9e66a49b74dc') +; + +-- Mar 7, 2021, 9:05:04 PM UTC +INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,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,FKConstraintType,IsHtml) VALUES (214417,0,'Import prefix','This prefix will be added in front of import string if they are not empty','Use it e.g. when concatening input fields into one import field to add a blank',382,'ImportPrefix',20,'N','N','N','N','N',0,'N',10,0,0,'Y',TO_DATE('2021-03-07 21:04:58','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-03-07 21:04:58','YYYY-MM-DD HH24:MI:SS'),100,203480,'Y','N','D','N','N','N','Y','cf947051-dad5-4143-8988-275cb457689c','Y',0,'N','N','N','N') +; + +-- Mar 7, 2021, 9:07:31 PM UTC +ALTER TABLE AD_ImpFormat_Row ADD ImportPrefix VARCHAR2(20 CHAR) DEFAULT NULL +; + +-- Mar 7, 2021, 9:08:09 PM UTC +INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (206602,'Import prefix','This prefix will be added in front of import string if they are not empty','Use it e.g. when concatening input fields into one import field to add a blank',316,214417,'Y',20,170,'N','N','N','N',0,0,'Y',TO_DATE('2021-03-07 21:08:03','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-03-07 21:08:03','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','62227bb3-45fc-447f-a6f1-e9d724a40880','Y',180,2) +; + +-- Mar 7, 2021, 9:08:39 PM UTC +UPDATE AD_Field SET SeqNo=120,IsDisplayed='Y', Updated=getDate(), UpdatedBy=100 WHERE AD_Field_ID=206602 +; + +-- Mar 7, 2021, 9:08:39 PM UTC +UPDATE AD_Field SET SeqNo=130,IsDisplayed='Y', Updated=getDate(), UpdatedBy=100 WHERE AD_Field_ID=3734 +; + +-- Mar 7, 2021, 9:08:39 PM UTC +UPDATE AD_Field SET SeqNo=140,IsDisplayed='Y', Updated=getDate(), UpdatedBy=100 WHERE AD_Field_ID=3735 +; + +-- Mar 7, 2021, 9:08:39 PM UTC +UPDATE AD_Field SET SeqNo=150,IsDisplayed='Y', Updated=getDate(), UpdatedBy=100 WHERE AD_Field_ID=3740 +; + +-- Mar 7, 2021, 9:08:40 PM UTC +UPDATE AD_Field SET SeqNo=160,IsDisplayed='Y', Updated=getDate(), UpdatedBy=100 WHERE AD_Field_ID=3741 +; + +-- Mar 7, 2021, 9:08:40 PM UTC +UPDATE AD_Field SET SeqNo=170,IsDisplayed='Y', Updated=getDate(), UpdatedBy=100 WHERE AD_Field_ID=5324 +; + +-- Mar 7, 2021, 9:09:10 PM UTC +UPDATE AD_Field SET DisplayLogic='@DataType@=S', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2021-03-07 21:09:10','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206602 +; + +SELECT register_migration_script('202103081000_IDEMPIERE-4724.sql') FROM dual +; + + diff --git a/migration/i8.2z/postgresql/202103081000_IDEMPIERE-4724.sql b/migration/i8.2z/postgresql/202103081000_IDEMPIERE-4724.sql new file mode 100644 index 0000000000..df2f129584 --- /dev/null +++ b/migration/i8.2z/postgresql/202103081000_IDEMPIERE-4724.sql @@ -0,0 +1,49 @@ +-- Add column to allow concatenation on import +-- Mar 7, 2021, 9:03:37 PM UTC +INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,Description,Help,PrintName,EntityType,AD_Element_UU) VALUES (203480,0,0,'Y',TO_TIMESTAMP('2021-03-07 21:03:31','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-03-07 21:03:31','YYYY-MM-DD HH24:MI:SS'),100,'ImportPrefix','Import prefix','This prefix will be added in front of import string if they are not empty','Use it e.g. when concatening input fields into one import field to add a blank','Import prefix','D','a7213dfc-f1fc-49f5-b15a-9e66a49b74dc') +; + +-- Mar 7, 2021, 9:05:04 PM UTC +INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,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,FKConstraintType,IsHtml) VALUES (214417,0,'Import prefix','This prefix will be added in front of import string if they are not empty','Use it e.g. when concatening input fields into one import field to add a blank',382,'ImportPrefix',20,'N','N','N','N','N',0,'N',10,0,0,'Y',TO_TIMESTAMP('2021-03-07 21:04:58','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-03-07 21:04:58','YYYY-MM-DD HH24:MI:SS'),100,203480,'Y','N','D','N','N','N','Y','cf947051-dad5-4143-8988-275cb457689c','Y',0,'N','N','N','N') +; + +-- Mar 7, 2021, 9:07:31 PM UTC +ALTER TABLE AD_ImpFormat_Row ADD COLUMN ImportPrefix VARCHAR(20) DEFAULT NULL +; + +-- Mar 7, 2021, 9:08:09 PM UTC +INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (206602,'Import prefix','This prefix will be added in front of import string if they are not empty','Use it e.g. when concatening input fields into one import field to add a blank',316,214417,'Y',20,170,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2021-03-07 21:08:03','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-03-07 21:08:03','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','62227bb3-45fc-447f-a6f1-e9d724a40880','Y',180,2) +; + +-- Mar 7, 2021, 9:08:39 PM UTC +UPDATE AD_Field SET SeqNo=120,IsDisplayed='Y', Updated=statement_timestamp(), UpdatedBy=100 WHERE AD_Field_ID=206602 +; + +-- Mar 7, 2021, 9:08:39 PM UTC +UPDATE AD_Field SET SeqNo=130,IsDisplayed='Y', Updated=statement_timestamp(), UpdatedBy=100 WHERE AD_Field_ID=3734 +; + +-- Mar 7, 2021, 9:08:39 PM UTC +UPDATE AD_Field SET SeqNo=140,IsDisplayed='Y', Updated=statement_timestamp(), UpdatedBy=100 WHERE AD_Field_ID=3735 +; + +-- Mar 7, 2021, 9:08:39 PM UTC +UPDATE AD_Field SET SeqNo=150,IsDisplayed='Y', Updated=statement_timestamp(), UpdatedBy=100 WHERE AD_Field_ID=3740 +; + +-- Mar 7, 2021, 9:08:40 PM UTC +UPDATE AD_Field SET SeqNo=160,IsDisplayed='Y', Updated=statement_timestamp(), UpdatedBy=100 WHERE AD_Field_ID=3741 +; + +-- Mar 7, 2021, 9:08:40 PM UTC +UPDATE AD_Field SET SeqNo=170,IsDisplayed='Y', Updated=statement_timestamp(), UpdatedBy=100 WHERE AD_Field_ID=5324 +; + +-- Mar 7, 2021, 9:09:10 PM UTC +UPDATE AD_Field SET DisplayLogic='@DataType@=S', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2021-03-07 21:09:10','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206602 +; + +SELECT register_migration_script('202103081000_IDEMPIERE-4724.sql') FROM dual +; + + diff --git a/org.adempiere.base/src/org/compiere/impexp/ImpFormat.java b/org.adempiere.base/src/org/compiere/impexp/ImpFormat.java index 77dcab56e4..8031f72386 100644 --- a/org.adempiere.base/src/org/compiere/impexp/ImpFormat.java +++ b/org.adempiere.base/src/org/compiere/impexp/ImpFormat.java @@ -307,7 +307,8 @@ public final class ImpFormat private static void loadRows (ImpFormat format, int ID) { String sql = "SELECT f.SeqNo,c.ColumnName,f.StartNo,f.EndNo,f.DataType,c.FieldLength," // 1..6 - + "f.DataFormat,f.DecimalPoint,f.DivideBy100,f.ConstantValue,f.Callout,f.Name " // 7..12 + + "f.DataFormat,f.DecimalPoint,f.DivideBy100,f.ConstantValue,f.Callout," // 7..11 + + "f.Name, f.importprefix " // 12..13 + "FROM AD_ImpFormat_Row f,AD_Column c " + "WHERE f.AD_ImpFormat_ID=? AND f.AD_Column_ID=c.AD_Column_ID AND f.IsActive='Y'" + "ORDER BY f.SeqNo"; @@ -325,7 +326,7 @@ public final class ImpFormat // row.setFormatInfo(rs.getString(7), rs.getString(8), rs.getString(9).equals("Y"), - rs.getString(10), rs.getString(11)); + rs.getString(10), rs.getString(11), rs.getString(13)); // format.addRow (row); } @@ -365,12 +366,33 @@ public final class ImpFormat // Label-Start if (withLabel) { - entry.append(row.getColumnName()); - entry.append("="); - if (row.isString()) - entry.append("'"); - else if (row.isDate()) - entry.append("TO_DATE('"); + //start concat mechanic + boolean concat = false; + + //only act if we combine String or Constant + if (row.isString() || row.isConstant()) + //if the list contains an entry for the same column, remove the old one and concatenate the two + for (int j = 0; j < list.size(); j++) { + if (list.get(j).startsWith(row.getColumnName() + "=")) { + concat = true; + entry.append(list.get(j)); + + if (entry.charAt(entry.length()-1) == '\'') + entry.deleteCharAt(entry.length()-1); //remove "'" for strings + + list.remove(j); + break; + } + } //end concat mechanic + + if (!concat) { + entry.append(row.getColumnName()); + entry.append("="); + if (row.isString()) + entry.append("'"); + else if (row.isDate()) + entry.append("TO_DATE('"); + } } // Get Data diff --git a/org.adempiere.base/src/org/compiere/impexp/ImpFormatRow.java b/org.adempiere.base/src/org/compiere/impexp/ImpFormatRow.java index 130332c651..cde7b23dd8 100644 --- a/org.adempiere.base/src/org/compiere/impexp/ImpFormatRow.java +++ b/org.adempiere.base/src/org/compiere/impexp/ImpFormatRow.java @@ -93,8 +93,9 @@ public final class ImpFormatRow private String m_constantValue = ""; private boolean m_constantIsString = true; // - private Callout m_callout = null; - private String m_method = null; + private Callout[] m_callout = null; + private String[] m_method = null; + private String importprefix = ""; // private SimpleDateFormat m_dformat = null; private int m_maxLength = 0; @@ -266,9 +267,10 @@ public final class ImpFormatRow * @param divideBy100 divide number by 100 * @param constantValue constant value * @param callout Java callout + * @param importprefix Prefix to be added if value is not null or empty */ public void setFormatInfo (String dataFormat, String decimalPoint, boolean divideBy100, - String constantValue, String callout) + String constantValue, String callout, String importprefix) { if (dataFormat == null) m_dataFormat = ""; @@ -304,25 +306,36 @@ public final class ImpFormatRow // callout if (callout != null) { - int methodStart = callout.lastIndexOf('.'); - try - { - if (methodStart != -1) // no class + String[] callouts = callout.split(";"); + m_callout = new Callout[callouts.length]; + m_method = new String[callouts.length]; + for (int i = 0; i < callouts.length; i++) { + int methodStart = callouts[i].trim().lastIndexOf('.'); + try { - Class cClass = Class.forName(callout.substring(0,methodStart)); - m_callout = (Callout)cClass.getDeclaredConstructor().newInstance(); - m_method = callout.substring(methodStart+1); + if (methodStart != -1) // no class + { + Class cClass = Class.forName(callouts[i].trim().substring(0,methodStart)); + m_callout[i] = (Callout)cClass.getDeclaredConstructor().newInstance(); + m_method[i] = callouts[i].trim().substring(methodStart+1); + } + } + catch (Exception e) + { + throw new AdempiereException(e); + } + if (m_callout.length == 0 || m_method == null || m_method.length == 0) + { + log.log(Level.SEVERE, "MTab.setFormatInfo - Invalid Callout " + callout); + m_callout = null; } } - catch (Exception e) - { - log.log(Level.SEVERE, "MTab.setFormatInfo - " + e.toString()); - } - if (m_callout == null || m_method == null || m_method.length() == 0) - { - log.log(Level.SEVERE, "MTab.setFormatInfo - Invalid Callout " + callout); - m_callout = null; - } + } + //import prefix + if (importprefix != null) { + this.importprefix = importprefix; + } else { + this.importprefix = ""; } } // setFormatInfo @@ -398,11 +411,12 @@ public final class ImpFormatRow else retValue = parseString (info); // - if (m_callout != null) + if (m_callout != null && m_callout.length > 0) { try { - retValue = m_callout.convert (m_method, retValue); + for (int i = 0; i < m_callout.length; i++) + retValue = m_callout[i].convert (m_method[i], retValue); } catch (Exception e) { @@ -411,8 +425,8 @@ public final class ImpFormatRow } // if (retValue == null) - retValue = ""; - return retValue.trim(); + retValue = ""; + return (retValue.trim().length() > 0 ? importprefix : "") + retValue.trim(); } // parse diff --git a/org.adempiere.base/src/org/compiere/model/CalloutEngine.java b/org.adempiere.base/src/org/compiere/model/CalloutEngine.java index 72f19fa382..41086338d9 100644 --- a/org.adempiere.base/src/org/compiere/model/CalloutEngine.java +++ b/org.adempiere.base/src/org/compiere/model/CalloutEngine.java @@ -53,6 +53,8 @@ public class CalloutEngine implements Callout protected CLogger log = CLogger.getCLogger(getClass()); private GridTab m_mTab; private GridField m_mField; + protected String[] additionalArgs; + public static final String ARG_SEPARATOR = ","; /** * Start Callout. @@ -133,12 +135,22 @@ public class CalloutEngine implements Callout * Conversion Rules. * Convert a String * - * @param methodName method name + * @param methodName method name and additional arguments (in brackets, separated by commas) * @param value the value * @return converted String or Null if no method found */ - public String convert (String methodName, String value) + public String convert (String methodAndArgs, String value) { + String methodName; + //find '(' and ')' + if(methodAndArgs.contains("(") && methodAndArgs.substring(methodAndArgs.indexOf("(")).contains(")")) { + methodName = methodAndArgs.substring(0, methodAndArgs.indexOf('(')); + additionalArgs = methodAndArgs.substring(methodAndArgs.indexOf("(")+1, methodAndArgs.indexOf(")")) + .split(ARG_SEPARATOR); //Everything between the brackets, separated by commas, is considered additional arguments + } else { + methodName = methodAndArgs; + } + if (methodName == null || methodName.length() == 0) throw new IllegalArgumentException ("No Method Name"); // diff --git a/org.adempiere.base/src/org/compiere/model/I_AD_ImpFormat_Row.java b/org.adempiere.base/src/org/compiere/model/I_AD_ImpFormat_Row.java index 2f8ff4a05e..1296d26866 100644 --- a/org.adempiere.base/src/org/compiere/model/I_AD_ImpFormat_Row.java +++ b/org.adempiere.base/src/org/compiere/model/I_AD_ImpFormat_Row.java @@ -209,6 +209,19 @@ public interface I_AD_ImpFormat_Row /** Get End No */ public int getEndNo(); + /** Column name ImportPrefix */ + public static final String COLUMNNAME_ImportPrefix = "ImportPrefix"; + + /** Set Import prefix. + * This prefix will be added in front of import string if they are not empty + */ + public void setImportPrefix (String ImportPrefix); + + /** Get Import prefix. + * This prefix will be added in front of import string if they are not empty + */ + public String getImportPrefix(); + /** Column name IsActive */ public static final String COLUMNNAME_IsActive = "IsActive"; diff --git a/org.adempiere.base/src/org/compiere/model/X_AD_ImpFormat_Row.java b/org.adempiere.base/src/org/compiere/model/X_AD_ImpFormat_Row.java index 0eabd8a739..1111d750cd 100644 --- a/org.adempiere.base/src/org/compiere/model/X_AD_ImpFormat_Row.java +++ b/org.adempiere.base/src/org/compiere/model/X_AD_ImpFormat_Row.java @@ -30,7 +30,7 @@ public class X_AD_ImpFormat_Row extends PO implements I_AD_ImpFormat_Row, I_Pers /** * */ - private static final long serialVersionUID = 20201220L; + private static final long serialVersionUID = 20210323L; /** Standard Constructor */ public X_AD_ImpFormat_Row (Properties ctx, int AD_ImpFormat_Row_ID, String trxName) @@ -303,6 +303,23 @@ public class X_AD_ImpFormat_Row extends PO implements I_AD_ImpFormat_Row, I_Pers return ii.intValue(); } + /** Set Import prefix. + @param ImportPrefix + This prefix will be added in front of import string if they are not empty + */ + public void setImportPrefix (String ImportPrefix) + { + set_Value (COLUMNNAME_ImportPrefix, ImportPrefix); + } + + /** Get Import prefix. + @return This prefix will be added in front of import string if they are not empty + */ + public String getImportPrefix () + { + return (String)get_Value(COLUMNNAME_ImportPrefix); + } + /** Set Name. @param Name Alphanumeric identifier of the entity