diff --git a/migration/i2.0z/oracle/201406061604_IDEMPIERE-1970.sql b/migration/i2.0z/oracle/201406061604_IDEMPIERE-1970.sql new file mode 100644 index 0000000000..214aba1f42 --- /dev/null +++ b/migration/i2.0z/oracle/201406061604_IDEMPIERE-1970.sql @@ -0,0 +1,36 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- Jun 6, 2014 7:41:43 PM ICT +-- I forgot to set the DICTIONARY_ID_COMMENTS System Configurator +INSERT INTO AD_Column (SeqNoSelection,IsSyncDatabase,Version,AD_Column_ID,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,IsKey,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsUpdateable,ColumnName,Description,Help,Name,IsAllowCopy,Updated,CreatedBy,AD_Org_ID,IsActive,Created,UpdatedBy,IsToolbarButton,IsAlwaysUpdateable,AD_Client_ID,EntityType,IsEncrypted,IsSecure,FKConstraintType,AD_Element_ID,AD_Reference_ID,AD_Table_ID,AD_Val_Rule_ID) VALUES (0,'N',0,211377,'N','N','N',0,'N',22,'N','N','N','Y','eff69801-5afa-4898-bc2b-c02e2ad4f94d','Y','AD_Column_ID','Column in the table','Link to the database column of the table','Column','Y',TO_DATE('2014-06-06 19:41:33','YYYY-MM-DD HH24:MI:SS'),100,0,'Y',TO_DATE('2014-06-06 19:41:33','YYYY-MM-DD HH24:MI:SS'),100,'N','N',0,'D','N','N','N',104,19,200129,100) +; + +-- Jun 6, 2014 7:43:12 PM ICT +UPDATE AD_Column SET Description='Name of unique column in a view. value of this column will save to t_selection table', Help='Column to resolve issue in https://idempiere.atlassian.net/browse/IDEMPIERE-1970', Name='ViewID Column', FKConstraintName='ADColumn_ADInfoProcess',Updated=TO_DATE('2014-06-06 19:43:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=211377 +; + +-- Jun 6, 2014 7:43:23 PM ICT +ALTER TABLE AD_InfoProcess ADD AD_Column_ID NUMBER(10) DEFAULT NULL +; + +-- Jun 6, 2014 7:43:23 PM ICT +ALTER TABLE AD_InfoProcess ADD CONSTRAINT ADColumn_ADInfoProcess FOREIGN KEY (AD_Column_ID) REFERENCES ad_column(ad_column_id) DEFERRABLE INITIALLY DEFERRED +; + +-- Jun 6, 2014 7:45:32 PM ICT +INSERT INTO AD_Field (SortNo,IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,Help,Description,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,UpdatedBy,AD_Org_ID,CreatedBy,Updated,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry,AD_Client_ID,ColumnSpan,NumLines,IsAdvancedField,IsDefaultFocus,AD_Column_ID,EntityType,Created) VALUES (0,'N',200142,0,'N','N',100,'N',203108,'N','Column to resolve issue in https://idempiere.atlassian.net/browse/IDEMPIERE-1970','Name of unique column in a view. value of this column will save to t_selection table','ViewID Column','5aacf0a1-baba-4bab-9b24-047b538a6f5d','Y','N',100,0,100,TO_DATE('2014-06-06 19:45:26','YYYY-MM-DD HH24:MI:SS'),'Y','Y',70,1,'N',0,1,1,'N','N',211377,'D',TO_DATE('2014-06-06 19:45:26','YYYY-MM-DD HH24:MI:SS')) +; + +-- Jun 6, 2014 7:46:32 PM ICT +UPDATE AD_Field SET SeqNo=80, IsDisplayed='Y', XPosition=4, ColumnSpan=2,Updated=TO_DATE('2014-06-06 19:46:32','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203108 +; + +-- Jun 6, 2014 7:46:32 PM ICT +UPDATE AD_Field SET SeqNo=100, IsDisplayed='Y', XPosition=2,Updated=TO_DATE('2014-06-06 19:46:32','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203038 +; +ALTER TABLE t_selection ADD ViewID VARCHAR2(30) DEFAULT NULL +; +SELECT register_migration_script('201406061604_IDEMPIERE-1970.sql') FROM dual +; + diff --git a/migration/i2.0z/postgresql/201406061604_IDEMPIERE-1970.sql b/migration/i2.0z/postgresql/201406061604_IDEMPIERE-1970.sql new file mode 100644 index 0000000000..611fbcc91d --- /dev/null +++ b/migration/i2.0z/postgresql/201406061604_IDEMPIERE-1970.sql @@ -0,0 +1,32 @@ +-- Jun 6, 2014 7:41:43 PM ICT +-- I forgot to set the DICTIONARY_ID_COMMENTS System Configurator +INSERT INTO AD_Column (SeqNoSelection,IsSyncDatabase,Version,AD_Column_ID,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,IsKey,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsUpdateable,ColumnName,Description,Help,Name,IsAllowCopy,Updated,CreatedBy,AD_Org_ID,IsActive,Created,UpdatedBy,IsToolbarButton,IsAlwaysUpdateable,AD_Client_ID,EntityType,IsEncrypted,IsSecure,FKConstraintType,AD_Element_ID,AD_Reference_ID,AD_Table_ID,AD_Val_Rule_ID) VALUES (0,'N',0,211377,'N','N','N',0,'N',22,'N','N','N','Y','eff69801-5afa-4898-bc2b-c02e2ad4f94d','Y','AD_Column_ID','Column in the table','Link to the database column of the table','Column','Y',TO_TIMESTAMP('2014-06-06 19:41:33','YYYY-MM-DD HH24:MI:SS'),100,0,'Y',TO_TIMESTAMP('2014-06-06 19:41:33','YYYY-MM-DD HH24:MI:SS'),100,'N','N',0,'D','N','N','N',104,19,200129,100) +; + +-- Jun 6, 2014 7:43:12 PM ICT +UPDATE AD_Column SET Description='Name of unique column in a view. value of this column will save to t_selection table', Help='Column to resolve issue in https://idempiere.atlassian.net/browse/IDEMPIERE-1970', Name='ViewID Column', FKConstraintName='ADColumn_ADInfoProcess',Updated=TO_TIMESTAMP('2014-06-06 19:43:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=211377 +; + +-- Jun 6, 2014 7:43:23 PM ICT +ALTER TABLE AD_InfoProcess ADD COLUMN AD_Column_ID NUMERIC(10) DEFAULT NULL +; + +-- Jun 6, 2014 7:43:23 PM ICT +ALTER TABLE AD_InfoProcess ADD CONSTRAINT ADColumn_ADInfoProcess FOREIGN KEY (AD_Column_ID) REFERENCES ad_column(ad_column_id) DEFERRABLE INITIALLY DEFERRED +; + +-- Jun 6, 2014 7:45:32 PM ICT +INSERT INTO AD_Field (SortNo,IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,Help,Description,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,UpdatedBy,AD_Org_ID,CreatedBy,Updated,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry,AD_Client_ID,ColumnSpan,NumLines,IsAdvancedField,IsDefaultFocus,AD_Column_ID,EntityType,Created) VALUES (0,'N',200142,0,'N','N',100,'N',203108,'N','Column to resolve issue in https://idempiere.atlassian.net/browse/IDEMPIERE-1970','Name of unique column in a view. value of this column will save to t_selection table','ViewID Column','5aacf0a1-baba-4bab-9b24-047b538a6f5d','Y','N',100,0,100,TO_TIMESTAMP('2014-06-06 19:45:26','YYYY-MM-DD HH24:MI:SS'),'Y','Y',70,1,'N',0,1,1,'N','N',211377,'D',TO_TIMESTAMP('2014-06-06 19:45:26','YYYY-MM-DD HH24:MI:SS')) +; + +-- Jun 6, 2014 7:46:32 PM ICT +UPDATE AD_Field SET SeqNo=80, IsDisplayed='Y', XPosition=4, ColumnSpan=2,Updated=TO_TIMESTAMP('2014-06-06 19:46:32','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203108 +; + +-- Jun 6, 2014 7:46:32 PM ICT +UPDATE AD_Field SET SeqNo=100, IsDisplayed='Y', XPosition=2,Updated=TO_TIMESTAMP('2014-06-06 19:46:32','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203038 +; +ALTER TABLE t_selection ADD COLUMN ViewID character varying(30) +; +SELECT register_migration_script('201406061604_IDEMPIERE-1970.sql') FROM dual +; diff --git a/org.adempiere.base/src/org/adempiere/model/MInfoProcess.java b/org.adempiere.base/src/org/adempiere/model/MInfoProcess.java index 1934a076e4..2a6c7e57a0 100644 --- a/org.adempiere.base/src/org/adempiere/model/MInfoProcess.java +++ b/org.adempiere.base/src/org/adempiere/model/MInfoProcess.java @@ -16,6 +16,7 @@ package org.adempiere.model; import java.sql.ResultSet; import java.util.Properties; import java.util.logging.Level; +import org.compiere.model.MColumn; import org.compiere.model.MProcess; import org.compiere.model.X_AD_InfoProcess; import org.compiere.util.Env; @@ -56,6 +57,8 @@ public class MInfoProcess extends X_AD_InfoProcess { } + protected String m_viewIDName; + /************************************************************************** * Is the Column Visible ? Evaluater base in display logic expression and context of this po * @return true, if visible @@ -86,4 +89,25 @@ public class MInfoProcess extends X_AD_InfoProcess { return retValue; } + /** + * name of column define is ViewID + * @return + */ + public String getViewIDName (){ + // no column define + if (getAD_Column_ID() == 0) + return null; + + // return cache value + if (m_viewIDName != null) + return m_viewIDName; + + MColumn viewIDColumn = (MColumn)getAD_Column(); + if (viewIDColumn != null){ + return viewIDColumn.getColumnName(); +} + + return null; + } + } diff --git a/org.adempiere.base/src/org/compiere/model/I_AD_InfoProcess.java b/org.adempiere.base/src/org/compiere/model/I_AD_InfoProcess.java index 9adeeda0ef..da0c5bfbba 100644 --- a/org.adempiere.base/src/org/compiere/model/I_AD_InfoProcess.java +++ b/org.adempiere.base/src/org/compiere/model/I_AD_InfoProcess.java @@ -49,6 +49,21 @@ public interface I_AD_InfoProcess */ public int getAD_Client_ID(); + /** Column name AD_Column_ID */ + public static final String COLUMNNAME_AD_Column_ID = "AD_Column_ID"; + + /** Set ViewID Column. + * Name of unique column in a view. value of this column will save to t_selection table + */ + public void setAD_Column_ID (int AD_Column_ID); + + /** Get ViewID Column. + * Name of unique column in a view. value of this column will save to t_selection table + */ + public int getAD_Column_ID(); + + public org.compiere.model.I_AD_Column getAD_Column() throws RuntimeException; + /** Column name AD_InfoProcess_ID */ public static final String COLUMNNAME_AD_InfoProcess_ID = "AD_InfoProcess_ID"; diff --git a/org.adempiere.base/src/org/compiere/model/X_AD_InfoProcess.java b/org.adempiere.base/src/org/compiere/model/X_AD_InfoProcess.java index a88e564dce..0003f046d5 100644 --- a/org.adempiere.base/src/org/compiere/model/X_AD_InfoProcess.java +++ b/org.adempiere.base/src/org/compiere/model/X_AD_InfoProcess.java @@ -30,7 +30,7 @@ public class X_AD_InfoProcess extends PO implements I_AD_InfoProcess, I_Persiste /** * */ - private static final long serialVersionUID = 20140531L; + private static final long serialVersionUID = 20140606L; /** Standard Constructor */ public X_AD_InfoProcess (Properties ctx, int AD_InfoProcess_ID, String trxName) @@ -76,6 +76,34 @@ public class X_AD_InfoProcess extends PO implements I_AD_InfoProcess, I_Persiste return sb.toString(); } + public org.compiere.model.I_AD_Column getAD_Column() throws RuntimeException + { + return (org.compiere.model.I_AD_Column)MTable.get(getCtx(), org.compiere.model.I_AD_Column.Table_Name) + .getPO(getAD_Column_ID(), get_TrxName()); } + + /** Set ViewID Column. + @param AD_Column_ID + Name of unique column in a view. value of this column will save to t_selection table + */ + public void setAD_Column_ID (int AD_Column_ID) + { + if (AD_Column_ID < 1) + set_Value (COLUMNNAME_AD_Column_ID, null); + else + set_Value (COLUMNNAME_AD_Column_ID, Integer.valueOf(AD_Column_ID)); + } + + /** Get ViewID Column. + @return Name of unique column in a view. value of this column will save to t_selection table + */ + public int getAD_Column_ID () + { + Integer ii = (Integer)get_Value(COLUMNNAME_AD_Column_ID); + if (ii == null) + return 0; + return ii.intValue(); + } + /** Set Info Process. @param AD_InfoProcess_ID Info Process */ public void setAD_InfoProcess_ID (int AD_InfoProcess_ID) diff --git a/org.adempiere.base/src/org/compiere/util/DB.java b/org.adempiere.base/src/org/compiere/util/DB.java index d8a2ac7d7a..5ea1e72ae8 100644 --- a/org.adempiere.base/src/org/compiere/util/DB.java +++ b/org.adempiere.base/src/org/compiere/util/DB.java @@ -34,6 +34,7 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.Properties; import java.util.logging.Level; @@ -2291,6 +2292,8 @@ public final class DB /** * Create persistent selection in T_Selection table + * remain this function for backward compatibility. + * refer: IDEMPIERE-1970 * @param AD_PInstance_ID * @param selection * @param trxName @@ -2325,6 +2328,56 @@ public final class DB } } + /** + * Create persistent selection in T_Selection table + * saveKeys is map with key is rowID, value is list value of all viewID + * viewIDIndex is index of viewID need save. + * @param AD_PInstance_ID + * @param selection + * @param trxName + */ + public static void createT_Selection(int AD_PInstance_ID, Map> saveKeys, int viewIDIndex, String trxName) + { + StringBuilder insert = new StringBuilder(); + insert.append("INSERT INTO T_SELECTION(AD_PINSTANCE_ID, T_SELECTION_ID, ViewID) "); + int counter = 0; + for(Integer selectedId : saveKeys.keySet()) + { + counter++; + if (counter > 1) + insert.append(" UNION "); + insert.append("SELECT "); + insert.append(AD_PInstance_ID); + insert.append(", "); + insert.append(selectedId); + insert.append(", "); + + List viewIDValues = saveKeys.get(selectedId); + // when no process have viewID or this process have no viewID or value of viewID is null + if (viewIDValues == null || viewIDIndex < 0 || viewIDValues.get(viewIDIndex) == null){ + insert.append("NULL"); + }else{ + insert.append("'"); + insert.append(viewIDValues.get(viewIDIndex)); + insert.append("'"); + } + + insert.append(" FROM DUAL "); + + if (counter >= 1000) + { + DB.executeUpdateEx(insert.toString(), trxName); + insert = new StringBuilder(); + insert.append("INSERT INTO T_SELECTION(AD_PINSTANCE_ID, T_SELECTION_ID, ViewID) "); + counter = 0; + } + } + if (counter > 0) + { + DB.executeUpdateEx(insert.toString(), trxName); + } + } + private static boolean m_isUUIDVerified = false; private static boolean m_isUUIDSupported = false; /*** diff --git a/org.adempiere.extend/src/test/functional/QueryTest.java b/org.adempiere.extend/src/test/functional/QueryTest.java index 61cb02ef8b..1be6f76fcf 100644 --- a/org.adempiere.extend/src/test/functional/QueryTest.java +++ b/org.adempiere.extend/src/test/functional/QueryTest.java @@ -14,9 +14,10 @@ package test.functional; import java.sql.Timestamp; -import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import org.adempiere.exceptions.DBException; import org.compiere.model.MTable; @@ -286,11 +287,11 @@ public class QueryTest extends AdempiereTestCase assertTrue(AD_PInstance_ID > 0); // Create selection list - List elements = new ArrayList(); - elements.add(102); // AD_Element_ID=102 => AD_Client_ID - elements.add(104); // AD_Element_ID=104 => AD_Column_ID + Map> elements = new HashMap> (); + elements.put(102, null); // AD_Element_ID=102 => AD_Client_ID + elements.put(104, null); // AD_Element_ID=104 => AD_Column_ID DB.executeUpdateEx("DELETE FROM T_Selection WHERE AD_PInstance_ID="+AD_PInstance_ID, getTrxName()); - DB.createT_Selection(AD_PInstance_ID, elements, getTrxName()); + DB.createT_Selection(AD_PInstance_ID, elements, 0, getTrxName()); String whereClause = "1=1"; // some dummy where clause int[] ids = new Query(getCtx(), X_AD_Element.Table_Name, whereClause, getTrxName()) @@ -299,9 +300,12 @@ public class QueryTest extends AdempiereTestCase .getIDs(); assertEquals("Resulting number of elements differ", elements.size(), ids.length); - for (int i = 0; i < elements.size(); i++) + Integer[] keys = new Integer[elements.keySet().size()]; + keys = elements.keySet().toArray(keys); + + for (int i = 0; i < keys .length; i++) { - int expected = elements.get(i); + int expected = keys[i]; assertEquals("Element "+i+" not equals", expected, ids[i]); } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/WListItemRenderer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/WListItemRenderer.java index 200a4244ad..52d34ba87b 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/WListItemRenderer.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/WListItemRenderer.java @@ -178,6 +178,9 @@ public class WListItemRenderer implements ListitemRenderer, EventListene listcell.setParent(item); listcell.addEventListener(Events.ON_DOUBLE_CLICK, cellListener); colIndex++; + // just render column in list m_tableColumns + if (m_tableColumns != null && m_tableColumns.size() == colIndex) + break; } return; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/WListbox.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/WListbox.java index e4e8ce0c88..ef04eaffbc 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/WListbox.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/WListbox.java @@ -1135,6 +1135,12 @@ public class WListbox extends Listbox implements IMiniTable, TableValueChangeLis //no op } + /** + * TODO:in theory column of model maybe not map with column of view + * in case set other data model this function always return number of column of model, + * maybe not equal with number of column of view + * so it should is m_layout.length + */ public int getColumnCount() { return getModel() != null ? getModel().getNoColumns() : 0; } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java index da3d70daec..2867b122b9 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java @@ -122,26 +122,6 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL private List gridFields; private int AD_InfoWindow_ID; private Checkbox checkAND; - /** - * All info process of this infoWindow - */ - protected MInfoProcess [] infoProcessList; - /** - * flag detect exists info process - */ - protected boolean haveProcess = false; - /** - * Info process have style is button - */ - protected List infoProcessBtList; - /** - * Info process have style is drop down list - */ - protected List infoProcessDropList; - /** - * Info process have style is menu - */ - protected List infoProcessMenuList; /** * Menu contail process menu item */ @@ -903,6 +883,8 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL } } + addViewIDToQuery(); + if (m_sqlMain.length() > 0 && infoWindow.isDistinct()) { m_sqlMain = m_sqlMain.substring("SELECT ".length()); m_sqlMain = "SELECT DISTINCT " + m_sqlMain; @@ -918,6 +900,58 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL } } + /** + * add all ViewID in each MInfoProcess to query + * if main query have subquery in SELECT, it will beak or incorrect + */ + protected void addViewIDToQuery () { + + if (m_sqlMain.length() > 0 && infoProcessList != null && infoProcessList.length > 0){ + int fromIndex = m_sqlMain.indexOf("FROM"); + // split Select and from clause + String selectClause = m_sqlMain.substring(0, fromIndex); + String fromClause = m_sqlMain.substring(fromIndex); + + // get alias of main table + String alias = getTableName(); + StringBuilder sqlBuilder = new StringBuilder(selectClause); + + // reset flag relate viewID to recount + numOfViewID = 0; + isHasViewID = false; + + // add View_ID column to select clause + for (MInfoProcess infoProcess : infoProcessList){ + String columnInQuery = infoProcess.getViewIDName(); + // this process hasn't viewID column, next other infoProcess + if (columnInQuery == null) + continue; + + // add alias of main table to column + columnInQuery = alias + "." + columnInQuery; + + // maintain varial relate to ViewID, it can init just one time when load infoWindow define + // but let it here for simple logic control + numOfViewID++; + isHasViewID = true; + + // if query is include this viewID column, not need add + if (sqlBuilder.toString().toLowerCase().contains(columnInQuery.toLowerCase())){ + continue; + } + + // add column to SELECT clause of main sql + sqlBuilder.append(", "); + sqlBuilder.append (columnInQuery); + sqlBuilder.append(" "); + } + + sqlBuilder.append(fromClause); + // update main sql + m_sqlMain = sqlBuilder.toString(); + } + } + protected void renderWindow() { setTitle(infoWindow.get_Translation("Name")); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java index 4b19d07b6d..5df2b94152 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java @@ -33,6 +33,7 @@ import java.util.Map; import java.util.Vector; import java.util.logging.Level; +import org.adempiere.model.MInfoProcess; import org.adempiere.webui.AdempiereWebUI; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.apps.BusyDialog; @@ -322,6 +323,39 @@ public abstract class InfoPanel extends Window implements EventListener, protected List prevQueryOperators = null; private static final String[] lISTENER_EVENTS = {}; + /** + * All info process of this infoWindow + */ + protected MInfoProcess [] infoProcessList; + /** + * flag detect exists info process + */ + protected boolean haveProcess = false; + /** + * Info process have style is button + */ + protected List infoProcessBtList; + /** + * Info process have style is drop down list + */ + protected List infoProcessDropList; + /** + * Info process have style is menu + */ + protected List infoProcessMenuList; + /** + * save selected id and viewID + */ + protected Map> m_viewIDMap = new HashMap>(); + /** + * flag indicate have infoOProcess define ViewID + */ + protected boolean isHasViewID = false; + /** + * number of infoProcess contain ViewID + */ + protected int numOfViewID = 0; + /** * IDEMPIERE-1334 * button and combobox when layout process button as dropdow list @@ -375,7 +409,6 @@ public abstract class InfoPanel extends Window implements EventListener, m_sqlOrder = " ORDER BY " + orderBy; } // prepareTable - /************************************************************************** * Execute Query */ @@ -472,6 +505,34 @@ public abstract class InfoPanel extends Window implements EventListener, data.add(value); } line.add(data); + + readViewID(rs, data); + } + + /** + * save all viewID to end of data line + * when override readData(ResultSet rs), consider call this method + * IDEMPIERE-1970 + */ + protected void readViewID(ResultSet rs, List data) throws SQLException { + if (infoProcessList == null || infoProcessList.length == 0){ + return; + } + + // with each process have viewID, read it form resultSet by name + for (MInfoProcess infoProcess : infoProcessList){ + if (infoProcess.getAD_Column_ID() == 0){ + continue; + } + + String viewIDSql = infoProcess.getViewIDName(); + String viewIDValue = rs.getString(viewIDSql); + if (rs.wasNull()){ + data.add(null); + }else{ + data.add(viewIDValue); + } + } } protected void renderItems() @@ -762,10 +823,11 @@ public abstract class InfoPanel extends Window implements EventListener, return; if (log.isLoggable(Level.CONFIG)) log.config( "OK=" + m_ok); + // clear prev selected result + m_results.clear(); if (!m_ok) // did not press OK { - m_results.clear(); contentPanel = null; this.detach(); return; @@ -851,6 +913,7 @@ public abstract class InfoPanel extends Window implements EventListener, /** * Get selected Keys as Collection + * @deprecated use getSaveKeys * @return selected keys (Integers) */ public Collection getSelectedKeysCollection() @@ -862,6 +925,66 @@ public abstract class InfoPanel extends Window implements EventListener, return m_results; } + /** + * Save selected id, viewID of all process to map viewIDMap to save into T_Selection + */ + public Map> getSaveKeys (){ + // clear result from prev time + m_viewIDMap.clear(); + + if (p_multipleSelection) + { + int[] rows = contentPanel.getSelectedIndices(); + + // this flag to just check key column in first record + boolean isCheckedKeyType = false; + + for (int row = 0; row < rows.length; row++) + { + // get key data column + Object keyData = contentPanel.getModel().getValueAt(rows[row], contentPanel.getKeyColumnIndex()); + + // check key data must is IDColumn + if (!isCheckedKeyType){ + if (keyData instanceof IDColumn){ + isCheckedKeyType = true; + }else{ + log.severe("For multiple selection, IDColumn should be key column for selection"); + break; + } + } + + IDColumn dataColumn = (IDColumn)keyData; + + if (isHasViewID){ + // have viewID, get it + List viewIDValueList = new ArrayList (); + String viewIDValue = null; + for (int viewIDIndex = 0; viewIDIndex < numOfViewID; viewIDIndex++){ + // get row data from model + @SuppressWarnings("unchecked") + List selectedRowData = (List)contentPanel.getModel().get(rows[row]); + // view data store at end of data line + viewIDValue = (String)selectedRowData.get (contentPanel.getLayout().length + viewIDIndex); + viewIDValueList.add(viewIDValue); + } + + m_viewIDMap.put(dataColumn.getRecord_ID(), viewIDValueList); + }else{ + // hasn't viewID, set viewID value collection is null + m_viewIDMap.put(dataColumn.getRecord_ID(), null); + } + + } + + return m_viewIDMap; + }else{ + // never has this case, because when have process, p_multipleSelection always is true + return null; + } + + } + /** * Get selected Keys * @return selected keys (Integers) @@ -1311,7 +1434,7 @@ public abstract class InfoPanel extends Window implements EventListener, ProcessModalDialog processModalDialog = (ProcessModalDialog)event.getTarget(); if (DialogEvents.ON_BEFORE_RUN_PROCESS.equals(event.getName())){ // store in T_Selection table selected rows for Execute Process that retrieves from T_Selection in code. - DB.createT_Selection(pInstanceID, getSelectedKeysCollection(), + DB.createT_Selection(pInstanceID, getSaveKeys(), getProcessIndex(processModalDialog.getAD_Process_ID()), null); }else if (ProcessModalDialog.ON_WINDOW_CLOSE.equals(event.getName())){ if (processModalDialog.isCancel()){ @@ -1337,6 +1460,24 @@ public abstract class InfoPanel extends Window implements EventListener, }); } + /** + * Get index of infoProcess have processId + * @param processId + * @return + */ + protected int getProcessIndex (int processId){ + int index = 0; + for (int i = 0; i < infoProcessList.length; i++){ + if (infoProcessList[i].getAD_Process_ID() == processId){ + return index; + } + // just increase index when process is have ViewID column + if (infoProcessList[i].getAD_Column_ID() > 0) + index++; + } + return -1; + } + private void showBusyDialog() { progressWindow = new BusyDialog();