IDEMPIERE-2152:Info Window - Join related tabs on other columns than primary key

combine and repatch for 2.1
This commit is contained in:
Carlos Ruiz 2015-01-14 09:20:08 -05:00
parent 18bbd814c1
commit 9ae8fdfeaf
12 changed files with 430 additions and 110 deletions

View File

@ -0,0 +1,48 @@
SET SQLBLANKLINES ON
SET DEFINE OFF
-- Sep 11, 2014 9:56:05 AM ICT
-- I forgot to set the DICTIONARY_ID_COMMENTS System Configurator
INSERT INTO AD_Element (ColumnName,AD_Element_ID,Help,Name,Description,PrintName,AD_Element_UU,AD_Org_ID,CreatedBy,UpdatedBy,IsActive,AD_Client_ID,EntityType,Created,Updated) VALUES ('ParentRelatedColumn_ID',202792,'default column RelatedColumn in Relate Info window will link with key column of main info window
column define in ParentRelatedColumn will replace key column','Parent Related Column','column in parent info window, link with column in this relate info','Parent Related Column','d35a2b4b-6022-4b52-bace-93f05958a77a',0,100,100,'Y',0,'D',TO_DATE('2014-09-11 09:55:54','YYYY-MM-DD HH24:MI:SS'),TO_DATE('2014-09-11 09:55:54','YYYY-MM-DD HH24:MI:SS'))
;
-- Sep 11, 2014 9:57:38 AM ICT
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,AD_Element_ID,AD_Reference_ID,AD_Reference_Value_ID,AD_Table_ID,AD_Val_Rule_ID) VALUES (0,'N',0,211765,'N','N','N',0,'N',10,'N','N','N','Y','e03bf0ab-df24-4a01-80b8-92e61d11188c','Y','ParentRelatedColumn_ID','column in parent info window, link with column in this relate info','default column RelatedColumn in Relate Info window will link with key column of main info window
column define in ParentRelatedColumn will replace key column','Parent Related Column','Y',TO_DATE('2014-09-11 09:57:33','YYYY-MM-DD HH24:MI:SS'),100,0,'Y',TO_DATE('2014-09-11 09:57:33','YYYY-MM-DD HH24:MI:SS'),100,'N','N',0,'D','N','N',202792,18,200072,200089,200065)
;
-- Sep 11, 2014 9:58:27 AM ICT
UPDATE AD_Column SET FKConstraintName='ParentRelatedColumn_ADInfoRela', FKConstraintType='N',Updated=TO_DATE('2014-09-11 09:58:27','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=211765
;
-- Sep 11, 2014 9:58:27 AM ICT
ALTER TABLE AD_InfoRelated ADD ParentRelatedColumn_ID NUMBER(10) DEFAULT NULL
;
-- Sep 11, 2014 9:58:28 AM ICT
ALTER TABLE AD_InfoRelated ADD CONSTRAINT ParentRelatedColumn_ADInfoRela FOREIGN KEY (ParentRelatedColumn_ID) REFERENCES ad_infocolumn(ad_infocolumn_id) DEFERRABLE INITIALLY DEFERRED
;
-- Sep 11, 2014 10:00:39 AM 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',200100,0,'N','N',110,'Y',203446,'N','default column RelatedColumn in Relate Info window will link with key column of main info window
column define in ParentRelatedColumn will replace key column','column in parent info window, link with column in this relate info','Parent Related Column','59dd442c-8596-4be5-b689-cd437ac62edf','Y','N',100,0,100,TO_DATE('2014-09-11 10:00:30','YYYY-MM-DD HH24:MI:SS'),'Y','Y',80,1,'N',0,1,1,'N','N',211765,'D',TO_DATE('2014-09-11 10:00:30','YYYY-MM-DD HH24:MI:SS'))
;
-- Sep 11, 2014 10:00:59 AM ICT
UPDATE AD_Field SET Name='Parent Link Column',Updated=TO_DATE('2014-09-11 10:00:59','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203446
;
-- Sep 11, 2014 10:01:23 AM ICT
UPDATE AD_Field SET SeqNo=100, IsDisplayed='Y', XPosition=1, ColumnSpan=2,Updated=TO_DATE('2014-09-11 10:01:23','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203446
;
-- Sep 11, 2014 10:01:23 AM ICT
UPDATE AD_Field SET SeqNo=110, IsDisplayed='Y', XPosition=4,Updated=TO_DATE('2014-09-11 10:01:23','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202268
;
-- Sep 11, 2014 10:01:23 AM ICT
UPDATE AD_Field SET SeqNo=0,Updated=TO_DATE('2014-09-11 10:01:23','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202269
;
SELECT register_migration_script('201411091604_IDEMPIERE-2152.sql') FROM dual
;

View File

@ -0,0 +1,45 @@
-- Sep 11, 2014 9:56:05 AM ICT
-- I forgot to set the DICTIONARY_ID_COMMENTS System Configurator
INSERT INTO AD_Element (ColumnName,AD_Element_ID,Help,Name,Description,PrintName,AD_Element_UU,AD_Org_ID,CreatedBy,UpdatedBy,IsActive,AD_Client_ID,EntityType,Created,Updated) VALUES ('ParentRelatedColumn_ID',202792,'default column RelatedColumn in Relate Info window will link with key column of main info window
column define in ParentRelatedColumn will replace key column','Parent Related Column','column in parent info window, link with column in this relate info','Parent Related Column','d35a2b4b-6022-4b52-bace-93f05958a77a',0,100,100,'Y',0,'D',TO_TIMESTAMP('2014-09-11 09:55:54','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2014-09-11 09:55:54','YYYY-MM-DD HH24:MI:SS'))
;
-- Sep 11, 2014 9:57:38 AM ICT
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,AD_Element_ID,AD_Reference_ID,AD_Reference_Value_ID,AD_Table_ID,AD_Val_Rule_ID) VALUES (0,'N',0,211765,'N','N','N',0,'N',10,'N','N','N','Y','e03bf0ab-df24-4a01-80b8-92e61d11188c','Y','ParentRelatedColumn_ID','column in parent info window, link with column in this relate info','default column RelatedColumn in Relate Info window will link with key column of main info window
column define in ParentRelatedColumn will replace key column','Parent Related Column','Y',TO_TIMESTAMP('2014-09-11 09:57:33','YYYY-MM-DD HH24:MI:SS'),100,0,'Y',TO_TIMESTAMP('2014-09-11 09:57:33','YYYY-MM-DD HH24:MI:SS'),100,'N','N',0,'D','N','N',202792,18,200072,200089,200065)
;
-- Sep 11, 2014 9:58:27 AM ICT
UPDATE AD_Column SET FKConstraintName='ParentRelatedColumn_ADInfoRela', FKConstraintType='N',Updated=TO_TIMESTAMP('2014-09-11 09:58:27','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=211765
;
-- Sep 11, 2014 9:58:27 AM ICT
ALTER TABLE AD_InfoRelated ADD COLUMN ParentRelatedColumn_ID NUMERIC(10) DEFAULT NULL
;
-- Sep 11, 2014 9:58:28 AM ICT
ALTER TABLE AD_InfoRelated ADD CONSTRAINT ParentRelatedColumn_ADInfoRela FOREIGN KEY (ParentRelatedColumn_ID) REFERENCES ad_infocolumn(ad_infocolumn_id) DEFERRABLE INITIALLY DEFERRED
;
-- Sep 11, 2014 10:00:39 AM 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',200100,0,'N','N',110,'Y',203446,'N','default column RelatedColumn in Relate Info window will link with key column of main info window
column define in ParentRelatedColumn will replace key column','column in parent info window, link with column in this relate info','Parent Related Column','59dd442c-8596-4be5-b689-cd437ac62edf','Y','N',100,0,100,TO_TIMESTAMP('2014-09-11 10:00:30','YYYY-MM-DD HH24:MI:SS'),'Y','Y',80,1,'N',0,1,1,'N','N',211765,'D',TO_TIMESTAMP('2014-09-11 10:00:30','YYYY-MM-DD HH24:MI:SS'))
;
-- Sep 11, 2014 10:00:59 AM ICT
UPDATE AD_Field SET Name='Parent Link Column',Updated=TO_TIMESTAMP('2014-09-11 10:00:59','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203446
;
-- Sep 11, 2014 10:01:23 AM ICT
UPDATE AD_Field SET SeqNo=100, IsDisplayed='Y', XPosition=1, ColumnSpan=2,Updated=TO_TIMESTAMP('2014-09-11 10:01:23','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203446
;
-- Sep 11, 2014 10:01:23 AM ICT
UPDATE AD_Field SET SeqNo=110, IsDisplayed='Y', XPosition=4,Updated=TO_TIMESTAMP('2014-09-11 10:01:23','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202268
;
-- Sep 11, 2014 10:01:23 AM ICT
UPDATE AD_Field SET SeqNo=0,Updated=TO_TIMESTAMP('2014-09-11 10:01:23','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202269
;
SELECT register_migration_script('201411091604_IDEMPIERE-2152.sql') FROM dual
;

View File

@ -0,0 +1,38 @@
/******************************************************************************
* Copyright (C) 2014 iDempiere *
* Product: iDempiere ERP & CRM Smart Business Solution *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. This program is distributed in the hope *
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
*****************************************************************************/
package org.adempiere.model;
import org.compiere.model.MInfoColumn;
/**
*
* @author hieplq
* implement to provide InfoColumn
* example MInfoProcess, MInfoRelate
*
*/
public interface IInfoColumn {
/**
* Id of MInfoColumn
* @return
*/
public int getInfoColumnID ();
/**
* Object MInfoColumn
* @return
*/
public MInfoColumn getAD_InfoColumn ();
}

View File

@ -17,6 +17,7 @@ import java.sql.ResultSet;
import java.util.Properties;
import java.util.logging.Level;
import org.compiere.model.MInfoColumn;
import org.compiere.model.MProcess;
import org.compiere.model.X_AD_InfoProcess;
import org.compiere.util.Env;
@ -29,11 +30,12 @@ import org.compiere.util.Evaluator;
* @author hieplq
*
*/
public class MInfoProcess extends X_AD_InfoProcess {
public class MInfoProcess extends X_AD_InfoProcess implements IInfoColumn {
/**
*
*/
private static final long serialVersionUID = 2478699719088685214L;
private static final long serialVersionUID = 6603281032935632048L;
/**
* {@inheritDoc}
@ -88,5 +90,21 @@ public class MInfoProcess extends X_AD_InfoProcess {
+ " (" + getDisplayLogic() + ") => " + retValue);
return retValue;
}
/**
* just forward call to {@link #getAD_InfoColumn_ID()}
*/
@Override
public int getInfoColumnID() {
return getAD_InfoColumn_ID();
}
/**
* Just forward call to {@link #getAD_InfoColumn ()}
*/
@Override
public MInfoColumn getAD_InfoColumn (){
return (MInfoColumn)super.getAD_InfoColumn();
}
}

View File

@ -17,16 +17,16 @@ import java.sql.ResultSet;
import java.util.Properties;
import java.util.logging.Level;
import org.compiere.model.I_AD_InfoRelated;
import org.compiere.model.MInfoColumn;
import org.compiere.model.Query;
import org.compiere.model.X_AD_InfoRelated;
public class MInfoRelated extends X_AD_InfoRelated implements I_AD_InfoRelated {
public class MInfoRelated extends X_AD_InfoRelated implements IInfoColumn {
/**
*
*/
private static final long serialVersionUID = 7899684001732574833L;
private static final long serialVersionUID = -4239930986439783006L;
public MInfoRelated(Properties ctx, int AD_InfoRelated_ID, String trxName) {
super(ctx, AD_InfoRelated_ID, trxName);
@ -54,4 +54,20 @@ public class MInfoRelated extends X_AD_InfoRelated implements I_AD_InfoRelated {
return "";
}
/**
* Just forward call to {@link #getParentRelatedColumn_ID()}
*/
@Override
public int getInfoColumnID() {
return getParentRelatedColumn_ID();
}
/**
* Just forward call to {@link #getParentRelatedColumn()}
*/
@Override
public MInfoColumn getAD_InfoColumn (){
return (MInfoColumn) getParentRelatedColumn();
}
}

View File

@ -163,6 +163,21 @@ public interface I_AD_InfoRelated
*/
public String getName();
/** Column name ParentRelatedColumn_ID */
public static final String COLUMNNAME_ParentRelatedColumn_ID = "ParentRelatedColumn_ID";
/** Set Parent Related Column.
* column in parent info window, link with column in this relate info
*/
public void setParentRelatedColumn_ID (int ParentRelatedColumn_ID);
/** Get Parent Related Column.
* column in parent info window, link with column in this relate info
*/
public int getParentRelatedColumn_ID();
public org.compiere.model.I_AD_InfoColumn getParentRelatedColumn() throws RuntimeException;
/** Column name RelatedColumn_ID */
public static final String COLUMNNAME_RelatedColumn_ID = "RelatedColumn_ID";

View File

@ -30,7 +30,7 @@ public class X_AD_InfoRelated extends PO implements I_AD_InfoRelated, I_Persiste
/**
*
*/
private static final long serialVersionUID = 20141030L;
private static final long serialVersionUID = 20141112L;
/** Standard Constructor */
public X_AD_InfoRelated (Properties ctx, int AD_InfoRelated_ID, String trxName)
@ -198,6 +198,34 @@ public class X_AD_InfoRelated extends PO implements I_AD_InfoRelated, I_Persiste
return new KeyNamePair(get_ID(), getName());
}
public org.compiere.model.I_AD_InfoColumn getParentRelatedColumn() throws RuntimeException
{
return (org.compiere.model.I_AD_InfoColumn)MTable.get(getCtx(), org.compiere.model.I_AD_InfoColumn.Table_Name)
.getPO(getParentRelatedColumn_ID(), get_TrxName()); }
/** Set Parent Related Column.
@param ParentRelatedColumn_ID
column in parent info window, link with column in this relate info
*/
public void setParentRelatedColumn_ID (int ParentRelatedColumn_ID)
{
if (ParentRelatedColumn_ID < 1)
set_Value (COLUMNNAME_ParentRelatedColumn_ID, null);
else
set_Value (COLUMNNAME_ParentRelatedColumn_ID, Integer.valueOf(ParentRelatedColumn_ID));
}
/** Get Parent Related Column.
@return column in parent info window, link with column in this relate info
*/
public int getParentRelatedColumn_ID ()
{
Integer ii = (Integer)get_Value(COLUMNNAME_ParentRelatedColumn_ID);
if (ii == null)
return 0;
return ii.intValue();
}
public org.compiere.model.I_AD_InfoColumn getRelatedColumn() throws RuntimeException
{
return (org.compiere.model.I_AD_InfoColumn)MTable.get(getCtx(), org.compiere.model.I_AD_InfoColumn.Table_Name)

View File

@ -34,7 +34,6 @@ 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;
@ -2336,13 +2335,14 @@ public final class DB
* @param selection
* @param trxName
*/
public static void createT_Selection(int AD_PInstance_ID, Map<Integer, List<String>> saveKeys, int viewIDIndex, String trxName)
public static void createT_SelectionNew (int AD_PInstance_ID, Collection<KeyNamePair> saveKeys, 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())
for(KeyNamePair saveKey : saveKeys)
{
Integer selectedId = saveKey.getKey();
counter++;
if (counter > 1)
insert.append(" UNION ");
@ -2352,13 +2352,13 @@ public final class DB
insert.append(selectedId);
insert.append(", ");
List<String> viewIDValues = saveKeys.get(selectedId);
String viewIDValue = saveKey.getName();
// 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){
if (viewIDValue == null){
insert.append("NULL");
}else{
insert.append("'");
insert.append(viewIDValues.get(viewIDIndex));
insert.append(viewIDValue);
insert.append("'");
}

View File

@ -14,6 +14,8 @@
package test.functional;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@ -26,6 +28,7 @@ import org.compiere.model.Query;
import org.compiere.model.X_AD_Element;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.KeyNamePair;
import test.AdempiereTestCase;
@ -287,11 +290,11 @@ public class QueryTest extends AdempiereTestCase
assertTrue(AD_PInstance_ID > 0);
// Create selection list
Map<Integer, List<String>> elements = new HashMap<Integer, List<String>> ();
elements.put(102, null); // AD_Element_ID=102 => AD_Client_ID
elements.put(104, null); // AD_Element_ID=104 => AD_Column_ID
List<KeyNamePair> elements = new ArrayList<KeyNamePair> ();
elements.add(new KeyNamePair(102, null)); // AD_Element_ID=102 => AD_Client_ID
elements.add(new KeyNamePair(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, 0, getTrxName());
DB.createT_SelectionNew (AD_PInstance_ID, elements, getTrxName());
String whereClause = "1=1"; // some dummy where clause
int[] ids = new Query(getCtx(), X_AD_Element.Table_Name, whereClause, getTrxName())
@ -300,12 +303,9 @@ public class QueryTest extends AdempiereTestCase
.getIDs();
assertEquals("Resulting number of elements differ", elements.size(), ids.length);
Integer[] keys = new Integer[elements.keySet().size()];
keys = elements.keySet().toArray(keys);
for (int i = 0; i < keys .length; i++)
for (int i = 0; i < elements.size(); i++)
{
int expected = keys[i];
int expected = elements.get(i).getKey();
assertEquals("Element "+i+" not equals", expected, ids[i]);
}
}

View File

@ -14,6 +14,7 @@ import java.util.Properties;
import java.util.TreeMap;
import java.util.logging.Level;
import org.adempiere.model.IInfoColumn;
import org.adempiere.model.MInfoProcess;
import org.adempiere.model.MInfoRelated;
import org.adempiere.webui.AdempiereWebUI;
@ -96,7 +97,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
/**
*
*/
private static final long serialVersionUID = -2192106603768665006L;
private static final long serialVersionUID = 2751982942639167289L;
protected Grid parameterGrid;
private Borderlayout layout;
@ -159,7 +160,11 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
int row = contentPanel.getSelectedRow();
if (row >= 0) {
for (EmbedWinInfo embed : embeddedWinList) {
refresh(contentPanel.getValueAt(row,0),embed);
int indexData = 0;
if (columnDataIndex.containsKey(embed.getParentLinkColumnID())){
indexData = p_layout.length + columnDataIndex.get(embed.getParentLinkColumnID());
}
refresh(contentPanel.getValueAt(row,indexData),embed);
}// refresh for all
}
}
@ -519,7 +524,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
return false;
// topinfoColumns = infoWindow.getInfoColumns();
MInfoRelated[] relatedInfoList = infoWindow.getInfoRelated(true);
relatedInfoList = infoWindow.getInfoRelated(true);
Tabpanels tabPanels = new Tabpanels();
Tabs tabs = new Tabs();
@ -573,8 +578,9 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
embeddedTbl.getModel().addTableModelListener(this);
embeddedTbl.setVflex("1");
//Xolali - add embeddedTbl to list, add m_sqlembedded to list
EmbedWinInfo ewinInfo = new EmbedWinInfo(embedInfo,embeddedTbl,m_sqlEmbedded,relatedInfo.getLinkColumnName(), relatedInfo.getLinkInfoColumn());
EmbedWinInfo ewinInfo = new EmbedWinInfo(embedInfo,embeddedTbl,m_sqlEmbedded,relatedInfo.getLinkColumnName(), relatedInfo.getLinkInfoColumn(), relatedInfo.getParentRelatedColumn_ID());
embeddedWinList.add(ewinInfo);
MInfoWindow riw = (MInfoWindow) relatedInfo.getRelatedInfo();
@ -894,6 +900,7 @@ 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;
@ -914,46 +921,58 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
* 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
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) {
// this process hasn't viewID column, next other infoProcess
if (infoProcess.getAD_InfoColumn_ID() <= 0)
continue;
MInfoColumn infocol = (MInfoColumn) infoProcess.getAD_InfoColumn();
// 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 (! infocol.isDisplayed()) {
// add column to SELECT clause of main sql
sqlBuilder.append(", ");
sqlBuilder.append (infocol.getSelectClause());
sqlBuilder.append(" AS ");
sqlBuilder.append (infocol.getColumnName());
sqlBuilder.append(" ");
}
}
sqlBuilder.append(fromClause);
// update main sql
m_sqlMain = sqlBuilder.toString();
m_sqlMain = addMoreColumnToQuery (m_sqlMain, infoProcessList);
}
/**
* because data of infoColumn have isDisplay = false not load,
* just display column is load to show in List.
* Some function receive data from hidden column as viewID in infoProcess
* or parentLink of infoRelateWindow.
*
* this function just add column name of hidden infoWindow to end of query
* @param sqlMain main sql to append column
* @param listInfoColumn list of PO contain infoColumnID, this infoColumnID will add to query
* @return sql after append column
*/
protected String addMoreColumnToQuery (String sqlMain, IInfoColumn [] listInfoColumn) {
if (sqlMain == null || sqlMain.length() == 0 || listInfoColumn == null || listInfoColumn.length == 0){
return sqlMain;
}
int fromIndex = sqlMain.indexOf("FROM");
// split Select and from clause
String selectClause = sqlMain.substring(0, fromIndex);
String fromClause = sqlMain.substring(fromIndex);
// get alias of main table
StringBuilder sqlBuilder = new StringBuilder(selectClause);
StringBuilder sqlColumn = new StringBuilder();
// add View_ID column to select clause
for (IInfoColumn infoProcess : listInfoColumn) {
// this process hasn't viewID column, next other infoProcess
if (infoProcess.getInfoColumnID() <= 0)
continue;
MInfoColumn infocol = (MInfoColumn) infoProcess.getAD_InfoColumn();
if (! infocol.isDisplayed()) {
sqlColumn.append(", ").append(infocol.getSelectClause()).append(" AS ").append(infocol.getColumnName()).append(" ");
// add column to SELECT clause of main sql, if query is include this viewID column, not need add
if (!sqlBuilder.toString().contains(sqlColumn)){
sqlBuilder.append(sqlColumn);
}
sqlColumn.delete(0, sqlColumn.length());
}
}
sqlBuilder.append(fromClause);
// update main sql
return sqlBuilder.toString();
}
protected void renderWindow()
@ -1646,13 +1665,32 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
sql.append(relatedInfo.getInfoSql()); // delete get sql method from MInfoWindow
if (log.isLoggable(Level.FINEST))
log.finest(sql.toString());
IDColumn ID = (IDColumn) obj;
Object linkPara = null;
if (obj != null && obj instanceof IDColumn){
IDColumn ID = (IDColumn) obj;
linkPara = ID.getRecord_ID();
}else if (obj != null){
linkPara = obj.toString();
}else {
//TODO:hard case
}
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
pstmt = DB.prepareStatement(relatedInfo.getInfoSql(), null);
pstmt.setObject(1, ID.getRecord_ID());
//TODO: implicit type conversion. will exception in some case must recheck
if (relatedInfo.getTypeDataOfLink().equals(String.class)){
pstmt.setString(1, (String)linkPara);
}else if (relatedInfo.getTypeDataOfLink().equals(int.class)){
pstmt.setInt(1, Integer.parseInt(linkPara.toString()));
}else{
pstmt.setObject(1, linkPara);
}
rs = pstmt.executeQuery();
loadEmbedded(rs, relatedInfo);
}

View File

@ -33,7 +33,9 @@ import java.util.Map;
import java.util.Vector;
import java.util.logging.Level;
import org.adempiere.model.IInfoColumn;
import org.adempiere.model.MInfoProcess;
import org.adempiere.model.MInfoRelated;
import org.adempiere.webui.AdempiereWebUI;
import org.adempiere.webui.LayoutUtils;
import org.adempiere.webui.apps.AEnv;
@ -111,11 +113,12 @@ import org.zkoss.zul.ext.Sortable;
*/
public abstract class InfoPanel extends Window implements EventListener<Event>, WTableModelListener, Sortable<Object>, IHelpContext
{
/**
*
*/
private static final long serialVersionUID = 6027970576265023451L;
private static final long serialVersionUID = 6617464791677971237L;
private final static int DEFAULT_PAGE_SIZE = 100;
protected List<Button> btProcessList = new ArrayList<Button>();
protected Map<String, WEditor> editorMap = new HashMap<String, WEditor>();
@ -123,7 +126,9 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
protected final static String ON_RUN_PROCESS = "onRunProcess";
// attribute key of info process
protected final static String ATT_INFO_PROCESS_KEY = "INFO_PROCESS";
protected int pageSize;
protected MInfoRelated[] relatedInfoList;
public static InfoPanel create (int WindowNo,
String tableName, String keyColumn, String value,
@ -353,15 +358,28 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
/**
* save selected id and viewID
*/
protected Map<Integer, List<String>> m_viewIDMap = new HashMap<Integer, List<String>>();
protected Collection<KeyNamePair> m_viewIDMap = new ArrayList <KeyNamePair>();
/**
* flag indicate have infoOProcess define ViewID
* store index of infoColumn have data append. each infoColumn just append only one time.
* index increase from 0.
*/
protected boolean isHasViewID = false;
protected Map <Integer, Integer> columnDataIndex = new HashMap <Integer, Integer> ();
/**
* number of infoProcess contain ViewID
* after load first record, set it to false.
* when need update index of column data append to end of list {@link #columnDataIndex}, set it to true
*/
protected int numOfViewID = 0;
protected boolean isMustUpdateColumnIndex = true;
/**
* When start update index of column data append to end of list {@link #columnDataIndex}, reset it to 0,
* each read data for new append column, increase it up 1
*/
protected int indexColumnCount = 0;
/**
* to prevent append duplicate data, when begin read each record reset this list,
* when read a column store id of infoColumn to list to check duplicate
*/
protected List <Integer> lsReadedColumn = new ArrayList <Integer> ();
/**
* IDEMPIERE-1334
@ -443,6 +461,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
private void readData(ResultSet rs) throws SQLException {
int colOffset = 1; // columns start with 1
List<Object> data = new ArrayList<Object>();
for (int col = 0; col < p_layout.length; col++)
{
Object value = null;
@ -511,34 +530,78 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
}
data.add(value);
}
line.add(data);
readViewID(rs, data);
appendDataForViewID(rs, data, lsReadedColumn);
appendDataForParentLink(rs, data, lsReadedColumn);
}
/**
* save all viewID to end of data line
* when override readData(ResultSet rs), consider call this method
* save data of all viewID column in infoProcessList to end of data line
* when override {@link #readData(ResultSet)} consider call this method
* IDEMPIERE-1970
* @param rs record set to read data
* @param data data line to append
* @param listReadedColumn list column is appended
* @throws SQLException
*/
protected void readViewID(ResultSet rs, List<Object> data) throws SQLException {
if (infoProcessList == null || infoProcessList.length == 0) {
protected void appendDataForViewID(ResultSet rs, List<Object> data, List<Integer> listReadedColumn) throws SQLException {
appendInfoColumnData(rs, data, infoProcessList, listReadedColumn);
}
/**
* save data of all viewID column in infoProcessList to end of data line
* when override {@link #readData(ResultSet)} consider call this method
* IDEMPIERE-2152
* @param rs
* @param data
* @param listReadedColumn
* @throws SQLException
*/
protected void appendDataForParentLink(ResultSet rs, List<Object> data, List<Integer> listReadedColumn) throws SQLException {
appendInfoColumnData(rs, data, relatedInfoList, listReadedColumn);
}
/**
* save data of all infoColumn in listModelHaveInfoColumn to end of data line
* @param rs record set to read data
* @param data data line to append
* @param listModelHasInfoColumn
* @param listReadedColumn list column is appended
* @throws SQLException
*/
protected void appendInfoColumnData(ResultSet rs, List<Object> data, IInfoColumn [] listModelHasInfoColumn, List<Integer> listReadedColumn) throws SQLException {
if (listModelHasInfoColumn == null || listModelHasInfoColumn.length == 0) {
return;
}
// with each process have viewID, read it form resultSet by name
for (MInfoProcess infoProcess : infoProcessList){
if (infoProcess.getAD_InfoColumn_ID() <= 0)
// get InfoColumn from each modelHaveInfoColumn, read it form resultSet by name and append to data line
for (IInfoColumn modelHasInfoColumn : listModelHasInfoColumn){
// have no InfoColumn or this column is readed, read next column
if (modelHasInfoColumn.getInfoColumnID() <= 0 || listReadedColumn.contains(modelHasInfoColumn.getInfoColumnID()))
continue;
MInfoColumn infocol = (MInfoColumn) infoProcess.getAD_InfoColumn();
String viewIDValue = rs.getString(infocol.getColumnName());
MInfoColumn infoColumnAppend = (MInfoColumn) modelHasInfoColumn.getAD_InfoColumn();
//TODO: improve read data to get data by data type of column.
String appendData = rs.getString(infoColumnAppend.getColumnName());
if (rs.wasNull()) {
data.add(null);
} else {
data.add(viewIDValue);
data.add(appendData);
}
// when need update append column index, just update it.
if (isMustUpdateColumnIndex && !columnDataIndex.containsKey(modelHasInfoColumn.getInfoColumnID())){
columnDataIndex.put(modelHasInfoColumn.getInfoColumnID(), indexColumnCount);
indexColumnCount++;
}
// mark this column is readed
listReadedColumn.add(modelHasInfoColumn.getInfoColumnID());
}
}
protected void renderItems()
@ -675,10 +738,17 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
}
int rowPointer = getCacheStart()-1;
while (m_rs.next())
{
rowPointer++;
// reset list column readed to start new round
lsReadedColumn.clear();
readData(m_rs);
// just set column index only one time.
isMustUpdateColumnIndex = false;
//check now of rows loaded, break if we hit the suppose end
if (m_useDatabasePaging && rowPointer >= cacheEnd)
{
@ -934,7 +1004,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
/**
* Save selected id, viewID of all process to map viewIDMap to save into T_Selection
*/
public Map<Integer, List<String>> getSaveKeys (){
public Collection<KeyNamePair> getSaveKeys (int infoCulumnId){
// clear result from prev time
m_viewIDMap.clear();
@ -962,23 +1032,17 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
IDColumn dataColumn = (IDColumn)keyData;
if (isHasViewID){
if (infoCulumnId > 0){
// have viewID, get it
List<String> viewIDValueList = new ArrayList <String> ();
String viewIDValue = null;
for (int viewIDIndex = 0; viewIDIndex < numOfViewID; viewIDIndex++){
// get row data from model
@SuppressWarnings("unchecked")
List<Object> selectedRowData = (List<Object>)contentPanel.getModel().get(rows[row]);
// view data store at end of data line
viewIDValue = (String)selectedRowData.get (contentPanel.getLayout().length + viewIDIndex);
viewIDValueList.add(viewIDValue);
}
int dataIndex = columnDataIndex.get(infoCulumnId) + p_layout.length;
m_viewIDMap.put(dataColumn.getRecord_ID(), viewIDValueList);
// get row data from model
Object viewIDValue = contentPanel.getModel().getDataAt(rows[row], dataIndex);
m_viewIDMap.add (new KeyNamePair(dataColumn.getRecord_ID(), viewIDValue == null?null:viewIDValue.toString()));
}else{
// hasn't viewID, set viewID value collection is null
m_viewIDMap.put(dataColumn.getRecord_ID(), null);
// hasn't viewID, set viewID value is null
m_viewIDMap.add (new KeyNamePair(dataColumn.getRecord_ID(), null));
}
}
@ -1476,7 +1540,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
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, getSaveKeys(), getProcessIndex(processModalDialog.getAD_Process_ID()),
DB.createT_SelectionNew(pInstanceID, getSaveKeys(getInfoColumnIDFromProcess(processModalDialog.getAD_Process_ID())),
null);
}else if (ProcessModalDialog.ON_WINDOW_CLOSE.equals(event.getName())){
if (processModalDialog.isCancel()){
@ -1517,19 +1581,15 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
}
/**
* Get index of infoProcess have processId
* Get InfoColumnID of infoProcess have processID is processId
* @param processId
* @return
* @return value InfoColumnID, -1 when has not any map
*/
protected int getProcessIndex (int processId){
int index = 0;
protected int getInfoColumnIDFromProcess (int processId){
for (int i = 0; i < infoProcessList.length; i++){
if (infoProcessList[i].getAD_Process_ID() == processId){
return index;
return infoProcessList[i].getAD_InfoColumn_ID();
}
// just increase index when process is have ViewID column
if (infoProcessList[i].getAD_InfoColumn_ID() > 0)
index++;
}
return -1;
}

View File

@ -23,8 +23,10 @@ public class EmbedWinInfo {
private String linkColumnSql;
private MInfoColumn linkInfoColumn;
private String linkColumnName;
private int parentLinkColumnID;
public EmbedWinInfo(MInfoWindow iw, IMiniTable mt, String isql, String linkName, MInfoColumn linkColumn) {
public EmbedWinInfo(MInfoWindow iw, IMiniTable mt, String isql, String linkName, MInfoColumn linkColumn, int parentLinkColumnID) {
this.parentLinkColumnID = parentLinkColumnID;
infowin=iw;
infoTbl=mt;
infoSql=isql;
@ -57,5 +59,17 @@ public class EmbedWinInfo {
public String getLinkColumnName() {
return linkColumnName;
}
public int getParentLinkColumnID() {
return parentLinkColumnID;
}
public Class<?> getTypeDataOfLink (){
if (linkInfoColumn.getColumnName().lastIndexOf("_ID") > 0){
return int.class;
}else{
return String.class;
}
}
}