IDEMPIERE-5567 Support of UUID for Search (UU) data type (FHCA-4195) (#1771)

* IDEMPIERE-5567 Support of UUID for Search (UU) data type (FHCA-4195)

* - Search editor now assigns the value correctly when selecting from Info Window
- Info Window shows correctly the first UU key column
- Added Record UUID new data type to work with record ID editor but with UU column
- Added column/field Test.Record_UU for testing

* - Fix opening Record ID editor after saved

* - Implement changes suggested by Heng Sin's peer review

* - Remove other unnecessary changes

* - safer comparison
This commit is contained in:
Carlos Ruiz 2023-04-11 07:20:13 +02:00 committed by GitHub
parent 2e9b1222d3
commit b5cb64bc92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 689 additions and 181 deletions

View File

@ -0,0 +1,82 @@
-- IDEMPIERE-5567 Support of UUID on Search (FHCA-4195)
SELECT register_migration_script('202304060001_IDEMPIERE-5567.sql') FROM dual;
SET SQLBLANKLINES ON
SET DEFINE OFF
-- Apr 6, 2023, 12:01:14 AM 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 ('I','UUID based table is not compatible with Record_ID',0,0,'Y',TO_TIMESTAMP('2023-04-06 00:01:13','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-04-06 00:01:13','YYYY-MM-DD HH24:MI:SS'),100,200830,'UUTableNotCompatibleWithRecordID','D','5b220b22-2a21-493c-81f0-877dbc083874')
;
ALTER TABLE t_selection ADD t_selection_uu VARCHAR2(36 CHAR) DEFAULT '' NOT NULL;
ALTER TABLE T_SELECTION MODIFY T_SELECTION_ID DEFAULT 0;
ALTER TABLE t_selection DROP CONSTRAINT t_selection_key;
DROP INDEX t_selection_key;
ALTER TABLE t_selection ADD CONSTRAINT t_selection_pkey PRIMARY KEY (ad_pinstance_id, t_selection_id, t_selection_uu);
ALTER TABLE t_selection_infowindow ADD t_selection_uu VARCHAR2(36 CHAR) DEFAULT '' NOT NULL;
ALTER TABLE t_selection_infowindow MODIFY t_selection_id DEFAULT 0;
ALTER TABLE t_selection_infowindow DROP CONSTRAINT t_selection_infowindow_key;
DROP INDEX t_selection_infowindow_key;
ALTER TABLE t_selection_infowindow ADD CONSTRAINT t_selection_infowindow_key PRIMARY KEY (ad_pinstance_id, t_selection_id, t_selection_uu, columnname);
-- Apr 6, 2023, 1:39:46 AM CEST
UPDATE AD_Reference SET IsActive='Y',Updated=TO_TIMESTAMP('2023-04-06 01:39:46','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Reference_ID=200235
;
-- Apr 8, 2023, 12:42:49 PM CEST
INSERT INTO AD_Reference (AD_Reference_ID,Name,ValidationType,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,IsOrderByValue,AD_Reference_UU,ShowInactive) VALUES (200240,'Record UUID','D',0,0,'Y',TO_TIMESTAMP('2023-04-08 12:42:49','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-04-08 12:42:49','YYYY-MM-DD HH24:MI:SS'),100,'D','N','9bab064f-725d-4fc2-bdab-3ea690905549','N')
;
-- Apr 8, 2023, 1:00:34 PM CEST
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 (203804,0,0,'Y',TO_TIMESTAMP('2023-04-08 13:00:22','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-04-08 13:00:22','YYYY-MM-DD HH24:MI:SS'),100,'Record_UU','Record UUID',NULL,NULL,'Record UUID','D','0f02ad7f-7837-494f-b67f-092f3bba2fbc')
;
-- Apr 8, 2023, 1:00:51 PM CEST
INSERT INTO AD_Column (AD_Column_ID,Version,Name,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 (215833,0,'Record UUID',135,'Record_UU',36,'N','N','N','N','N',0,'N',200240,0,0,'Y',TO_TIMESTAMP('2023-04-08 13:00:51','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-04-08 13:00:51','YYYY-MM-DD HH24:MI:SS'),100,203804,'Y','N','D','N','N','N','Y','b608cf28-12a4-48ec-9e73-cecefa353432','Y',0,'N','N','N','N')
;
-- Apr 8, 2023, 1:01:07 PM CEST
ALTER TABLE Test ADD Record_UU VARCHAR2(36 CHAR) DEFAULT NULL
;
-- Apr 8, 2023, 1:01:18 PM CEST
INSERT INTO AD_Field (AD_Field_ID,Name,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 (207617,'Record UUID',152,215833,'Y',36,300,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-04-08 13:01:17','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-04-08 13:01:17','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','008d5c60-1fca-4f56-9494-96041e502a1c','Y',280,2)
;
-- Apr 8, 2023, 1:02:12 PM CEST
UPDATE AD_Field SET IsDisplayed='Y', SeqNo=240, XPosition=4,Updated=TO_TIMESTAMP('2023-04-08 13:02:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=207617
;
-- Apr 8, 2023, 1:02:12 PM CEST
UPDATE AD_Field SET SeqNo=250,Updated=TO_TIMESTAMP('2023-04-08 13:02:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=205590
;
-- Apr 8, 2023, 1:02:12 PM CEST
UPDATE AD_Field SET SeqNo=260,Updated=TO_TIMESTAMP('2023-04-08 13:02:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=8351
;
-- Apr 8, 2023, 1:02:12 PM CEST
UPDATE AD_Field SET SeqNo=270,Updated=TO_TIMESTAMP('2023-04-08 13:02:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=8352
;
-- Apr 8, 2023, 1:02:12 PM CEST
UPDATE AD_Field SET SeqNo=280,Updated=TO_TIMESTAMP('2023-04-08 13:02:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=3060
;
-- Apr 8, 2023, 1:02:12 PM CEST
UPDATE AD_Field SET SeqNo=290,Updated=TO_TIMESTAMP('2023-04-08 13:02:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=3061
;
-- Apr 8, 2023, 1:02:12 PM CEST
UPDATE AD_Field SET SeqNo=300,Updated=TO_TIMESTAMP('2023-04-08 13:02:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206818
;

View File

@ -0,0 +1,75 @@
-- IDEMPIERE-5567 Support of UUID on Search (FHCA-4195)
SELECT register_migration_script('202304060001_IDEMPIERE-5567.sql') FROM dual;
-- Apr 6, 2023, 12:01:14 AM 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 ('I','UUID based table is not compatible with Record_ID',0,0,'Y',TO_TIMESTAMP('2023-04-06 00:01:13','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-04-06 00:01:13','YYYY-MM-DD HH24:MI:SS'),100,200830,'UUTableNotCompatibleWithRecordID','D','5b220b22-2a21-493c-81f0-877dbc083874')
;
ALTER TABLE t_selection ADD COLUMN t_selection_uu VARCHAR(36) NOT NULL DEFAULT '';
ALTER TABLE t_selection ALTER COLUMN t_selection_id SET DEFAULT 0;
ALTER TABLE t_selection DROP CONSTRAINT t_selection_pkey;
ALTER TABLE t_selection ADD CONSTRAINT t_selection_pkey PRIMARY KEY (ad_pinstance_id, t_selection_id, t_selection_uu);
ALTER TABLE t_selection_infowindow ADD COLUMN t_selection_uu VARCHAR(36) NOT NULL DEFAULT '';
ALTER TABLE t_selection_infowindow ALTER COLUMN t_selection_id SET DEFAULT 0;
ALTER TABLE t_selection_infowindow DROP CONSTRAINT t_selection_infowindow_key;
ALTER TABLE t_selection_infowindow ADD CONSTRAINT t_selection_infowindow_key PRIMARY KEY (ad_pinstance_id, t_selection_id, t_selection_uu, columnname);
-- Apr 6, 2023, 1:39:46 AM CEST
UPDATE AD_Reference SET IsActive='Y',Updated=TO_TIMESTAMP('2023-04-06 01:39:46','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Reference_ID=200235
;
-- Apr 8, 2023, 12:42:49 PM CEST
INSERT INTO AD_Reference (AD_Reference_ID,Name,ValidationType,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,IsOrderByValue,AD_Reference_UU,ShowInactive) VALUES (200240,'Record UUID','D',0,0,'Y',TO_TIMESTAMP('2023-04-08 12:42:49','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-04-08 12:42:49','YYYY-MM-DD HH24:MI:SS'),100,'D','N','9bab064f-725d-4fc2-bdab-3ea690905549','N')
;
-- Apr 8, 2023, 1:00:34 PM CEST
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 (203804,0,0,'Y',TO_TIMESTAMP('2023-04-08 13:00:22','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-04-08 13:00:22','YYYY-MM-DD HH24:MI:SS'),100,'Record_UU','Record UUID',NULL,NULL,'Record UUID','D','0f02ad7f-7837-494f-b67f-092f3bba2fbc')
;
-- Apr 8, 2023, 1:00:51 PM CEST
INSERT INTO AD_Column (AD_Column_ID,Version,Name,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 (215833,0,'Record UUID',135,'Record_UU',36,'N','N','N','N','N',0,'N',200240,0,0,'Y',TO_TIMESTAMP('2023-04-08 13:00:51','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-04-08 13:00:51','YYYY-MM-DD HH24:MI:SS'),100,203804,'Y','N','D','N','N','N','Y','b608cf28-12a4-48ec-9e73-cecefa353432','Y',0,'N','N','N','N')
;
-- Apr 8, 2023, 1:01:07 PM CEST
ALTER TABLE Test ADD COLUMN Record_UU VARCHAR(36) DEFAULT NULL
;
-- Apr 8, 2023, 1:01:18 PM CEST
INSERT INTO AD_Field (AD_Field_ID,Name,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 (207617,'Record UUID',152,215833,'Y',36,300,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-04-08 13:01:17','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-04-08 13:01:17','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','008d5c60-1fca-4f56-9494-96041e502a1c','Y',280,2)
;
-- Apr 8, 2023, 1:02:12 PM CEST
UPDATE AD_Field SET IsDisplayed='Y', SeqNo=240, XPosition=4,Updated=TO_TIMESTAMP('2023-04-08 13:02:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=207617
;
-- Apr 8, 2023, 1:02:12 PM CEST
UPDATE AD_Field SET SeqNo=250,Updated=TO_TIMESTAMP('2023-04-08 13:02:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=205590
;
-- Apr 8, 2023, 1:02:12 PM CEST
UPDATE AD_Field SET SeqNo=260,Updated=TO_TIMESTAMP('2023-04-08 13:02:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=8351
;
-- Apr 8, 2023, 1:02:12 PM CEST
UPDATE AD_Field SET SeqNo=270,Updated=TO_TIMESTAMP('2023-04-08 13:02:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=8352
;
-- Apr 8, 2023, 1:02:12 PM CEST
UPDATE AD_Field SET SeqNo=280,Updated=TO_TIMESTAMP('2023-04-08 13:02:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=3060
;
-- Apr 8, 2023, 1:02:12 PM CEST
UPDATE AD_Field SET SeqNo=290,Updated=TO_TIMESTAMP('2023-04-08 13:02:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=3061
;
-- Apr 8, 2023, 1:02:12 PM CEST
UPDATE AD_Field SET SeqNo=300,Updated=TO_TIMESTAMP('2023-04-08 13:02:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206818
;

View File

@ -51,6 +51,10 @@ public class TableIDCallout implements IColumnCallout {
if (recordId != null) {
mTab.setValue(recordId, null);
}
GridField recordUU = mTab.getField("Record_UU");
if (recordUU != null) {
mTab.setValue(recordUU, null);
}
return null;
}
}

View File

@ -849,8 +849,12 @@ public class Query
//
if (whereBuffer.length() > 0)
whereBuffer.append(" AND ");
whereBuffer.append(" EXISTS (SELECT 1 FROM T_Selection s WHERE s.AD_PInstance_ID=?"
+" AND s.T_Selection_ID="+table.getTableName()+"."+keys[0]+")");
whereBuffer.append(" EXISTS (SELECT 1 FROM T_Selection s WHERE s.AD_PInstance_ID=? AND s.");
if (table.isUUIDKeyTable())
whereBuffer.append("T_Selection_UU=");
else
whereBuffer.append("T_Selection_ID=");
whereBuffer.append(table.getTableName()).append(".").append(keys[0]).append(")");
}
StringBuilder sqlBuffer = new StringBuilder(selectClause);

View File

@ -150,6 +150,7 @@ public class SystemIDs
public final static int REFERENCE_DATATYPE_QUANTITY = 29;
public final static int REFERENCE_DATATYPE_RADIOGROUP_LIST= 200152;
public final static int REFERENCE_DATATYPE_RECORD_ID = 200202;
public final static int REFERENCE_DATATYPE_RECORD_UU = 200240;
public final static int REFERENCE_DATATYPE_ROWID = 26;
public final static int REFERENCE_DATATYPE_SCHEDULER_STATE = 200173;
public final static int REFERENCE_DATATYPE_SEARCH = 30;

View File

@ -38,6 +38,7 @@ import java.util.logging.Level;
import javax.sql.RowSet;
import org.adempiere.exceptions.AdempiereException;
import org.adempiere.exceptions.DBException;
import org.adempiere.util.ProcessUtil;
import org.compiere.Adempiere;
@ -2408,24 +2409,51 @@ public final class DB
* 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 saveKeys
* @param saveKeys - Collection of KeyNamePair
* @param trxName
*/
public static void createT_SelectionNew (int AD_PInstance_ID, Collection<KeyNamePair> saveKeys, String trxName)
public static void createT_SelectionNew (int AD_PInstance_ID, Collection<KeyNamePair> saveKeys, String trxName) {
Collection<NamePair> saveKeysNP = new ArrayList<NamePair>();
for (NamePair saveKey : saveKeys)
saveKeysNP.add(saveKey);
createT_SelectionNewNP(AD_PInstance_ID, saveKeysNP, trxName);
}
/**
* 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 saveKeys can receive a Collection of KeyNamePair (IDs) or ValueNamePair (UUIDs)
* @param trxName
*/
public static void createT_SelectionNewNP (int AD_PInstance_ID, Collection<NamePair> saveKeys, String trxName)
{
StringBuilder insert = new StringBuilder();
insert.append("INSERT INTO T_SELECTION(AD_PINSTANCE_ID, T_SELECTION_ID, ViewID) ");
String initialInsert = "INSERT INTO T_SELECTION(AD_PINSTANCE_ID, T_SELECTION_ID, T_SELECTION_UU, ViewID) ";
StringBuilder insert = new StringBuilder(initialInsert);
int counter = 0;
for(KeyNamePair saveKey : saveKeys)
for(NamePair saveKey : saveKeys)
{
Integer selectedId = saveKey.getKey();
Object selectedId;
if (saveKey instanceof KeyNamePair)
selectedId = ((KeyNamePair)saveKey).getKey();
else if (saveKey instanceof ValueNamePair)
selectedId = ((ValueNamePair)saveKey).getValue();
else
throw new AdempiereException("NamePair type not allowed in DB.createT_SelectionNewNP, just KeyNamePair or ValueNamePair are allowed");
counter++;
if (counter > 1)
insert.append(" UNION ");
insert.append("SELECT ");
insert.append(AD_PInstance_ID);
insert.append(", ");
insert.append(selectedId);
if (selectedId instanceof Integer) {
insert.append((Integer)selectedId);
insert.append(", ''");
} else {
insert.append("0, ");
insert.append(DB.TO_STRING(selectedId.toString()));
}
insert.append(", ");
String viewIDValue = saveKey.getName();
@ -2443,8 +2471,8 @@ public final class DB
if (counter >= 1000)
{
DB.executeUpdateEx(insert.toString(), trxName);
insert = new StringBuilder();
insert.append("INSERT INTO T_SELECTION(AD_PINSTANCE_ID, T_SELECTION_ID, ViewID) ");
insert.delete(0, insert.length());
insert.append(initialInsert);
counter = 0;
}
}

View File

@ -47,6 +47,7 @@ import static org.compiere.model.SystemIDs.REFERENCE_DATATYPE_PRODUCTATTRIBUTE;
import static org.compiere.model.SystemIDs.REFERENCE_DATATYPE_QUANTITY;
import static org.compiere.model.SystemIDs.REFERENCE_DATATYPE_RADIOGROUP_LIST;
import static org.compiere.model.SystemIDs.REFERENCE_DATATYPE_RECORD_ID;
import static org.compiere.model.SystemIDs.REFERENCE_DATATYPE_RECORD_UU;
import static org.compiere.model.SystemIDs.REFERENCE_DATATYPE_ROWID;
import static org.compiere.model.SystemIDs.REFERENCE_DATATYPE_SCHEDULER_STATE;
import static org.compiere.model.SystemIDs.REFERENCE_DATATYPE_SEARCH;
@ -194,6 +195,7 @@ public final class DisplayType
public static final int RecordID = REFERENCE_DATATYPE_RECORD_ID;
public static final int RecordUU = REFERENCE_DATATYPE_RECORD_UU;
public static final int TimestampWithTimeZone = REFERENCE_DATATYPE_TIMESTAMP_WITH_TIMEZONE;
@ -283,7 +285,7 @@ public final class DisplayType
public static boolean isUUID (int displayType)
{
if (displayType == UUID || displayType == TableUU || displayType == TableDirUU
|| displayType == SearchUU)
|| displayType == SearchUU || displayType == RecordUU)
return true;
//not custom type, don't have to check factory
@ -417,7 +419,7 @@ public final class DisplayType
|| displayType == ChosenMultipleSelectionTable
|| displayType == ChosenMultipleSelectionSearch
|| displayType == TimeZoneId
|| displayType == UUID
|| displayType == UUID || displayType == RecordUU
|| displayType == TableDirUU || displayType == TableUU || displayType == SearchUU)
return true;
@ -1135,6 +1137,8 @@ public final class DisplayType
return "RadiogroupList";
case RecordID:
return "RecordID";
case RecordUU:
return "RecordUUID";
case RowID:
return "RowID";
case SchedulerState:

View File

@ -31,6 +31,7 @@ import org.adempiere.webui.info.InfoWindow;
import org.adempiere.webui.theme.ThemeManager;
import org.compiere.minigrid.ColumnInfo;
import org.compiere.minigrid.IDColumn;
import org.compiere.minigrid.UUIDColumn;
import org.compiere.model.GridField;
import org.compiere.model.InfoColumnVO;
import org.compiere.model.MStyle;
@ -110,6 +111,11 @@ public class WInfoWindowListItemRenderer extends WListItemRenderer
IDColumn idc = (IDColumn)value;
value = idc.getRecord_ID();
}
else if(value instanceof UUIDColumn)
{
UUIDColumn idc = (UUIDColumn)value;
value = idc.getRecord_UU();
}
else if(value instanceof KeyNamePair)
{
KeyNamePair knp = (KeyNamePair)value;

View File

@ -39,6 +39,8 @@ import org.adempiere.webui.event.TableValueChangeEvent;
import org.adempiere.webui.event.TableValueChangeListener;
import org.adempiere.webui.util.ZKUpdateUtil;
import org.compiere.minigrid.IDColumn;
import org.compiere.minigrid.SelectableIDColumn;
import org.compiere.minigrid.UUIDColumn;
import org.compiere.model.MImage;
import org.compiere.util.DisplayType;
import org.compiere.util.Env;
@ -348,10 +350,13 @@ public class WListItemRenderer implements ListitemRenderer<Object>, EventListene
}
}
}
// if ID column make it invisible
else if (value instanceof IDColumn)
// if ID or UUID column make it invisible
else if (value instanceof IDColumn || value instanceof UUIDColumn)
{
listcell.setValue(((IDColumn) value).getRecord_ID());
if (value instanceof IDColumn)
listcell.setValue(((IDColumn) value).getRecord_ID());
else
listcell.setValue(((UUIDColumn) value).getRecord_UU());
if (!table.isCheckmark()) {
table.setCheckmark(true);
table.removeEventListener(Events.ON_SELECT, this);
@ -468,7 +473,7 @@ public class WListItemRenderer implements ListitemRenderer<Object>, EventListene
String headerText = headerValue.toString();
if (m_headers.size() <= headerIndex || m_headers.get(headerIndex) == null)
{
if (classType != null && classType.isAssignableFrom(IDColumn.class))
if (classType != null && (classType.isAssignableFrom(IDColumn.class) || classType.isAssignableFrom(UUIDColumn.class)))
{
header = new ListHeader("");
ZKUpdateUtil.setWidth(header, "30px");
@ -500,7 +505,7 @@ public class WListItemRenderer implements ListitemRenderer<Object>, EventListene
if (width > 0 && width < 180)
width = 180;
}
else if (classType.equals(IDColumn.class))
else if (classType.equals(IDColumn.class) || classType.equals(UUIDColumn.class))
{
header.setSort("none");
if (width < 30)
@ -681,13 +686,13 @@ public class WListItemRenderer implements ListitemRenderer<Object>, EventListene
WListbox table = (WListbox) event.getTarget();
if (table.isCheckmark()) {
int cnt = table.getRowCount();
if (cnt == 0 || !(table.getValueAt(0, 0) instanceof IDColumn))
if (cnt == 0 || !(table.getValueAt(0, 0) instanceof IDColumn || table.getValueAt(0, 0) instanceof UUIDColumn))
return;
//update IDColumn
tableColumn = m_tableColumns.get(0);
for (int i = 0; i < cnt; i++) {
IDColumn idcolumn = (IDColumn) table.getValueAt(i, 0);
SelectableIDColumn idcolumn = (SelectableIDColumn) table.getValueAt(i, 0);
Listitem item = table.getItemAtIndex(i);
value = item.isSelected();

View File

@ -17,6 +17,7 @@
package org.adempiere.webui.component;
import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
@ -36,6 +37,8 @@ import org.adempiere.webui.util.ZKUpdateUtil;
import org.compiere.minigrid.ColumnInfo;
import org.compiere.minigrid.IDColumn;
import org.compiere.minigrid.IMiniTable;
import org.compiere.minigrid.SelectableIDColumn;
import org.compiere.minigrid.UUIDColumn;
import org.compiere.model.MRole;
import org.compiere.model.PO;
import org.compiere.util.CLogger;
@ -57,7 +60,7 @@ public class WListbox extends Listbox implements IMiniTable, TableValueChangeLis
/**
* generated serial id
*/
private static final long serialVersionUID = -5501893389366975849L;
private static final long serialVersionUID = 3758442599469915640L;
/** Logger. */
private static final CLogger logger = CLogger.getCLogger(WListbox.class);
@ -237,8 +240,8 @@ public class WListbox extends Listbox implements IMiniTable, TableValueChangeLis
// F3P: If allowed, use idcolumn as a switch for read/write (Some logic as boolean)
if(allowIDColumnForReadWrite
&& column != 0
&& val instanceof IDColumn
&& ((IDColumn)val).isSelected() == false)
&& val instanceof SelectableIDColumn
&& ((SelectableIDColumn)val).isSelected() == false)
{
return false;
}
@ -418,7 +421,7 @@ public class WListbox extends Listbox implements IMiniTable, TableValueChangeLis
{
setColorColumn(columnIndex);
}
if (layout[columnIndex].getColClass() == IDColumn.class)
if (layout[columnIndex].getColClass() == IDColumn.class || layout[columnIndex].getColClass() == UUIDColumn.class)
{
m_keyColumnIndex = columnIndex;
}
@ -626,6 +629,10 @@ public class WListbox extends Listbox implements IMiniTable, TableValueChangeLis
{
data = new IDColumn(rs.getInt(rsColIndex));
}
else if (columnClass == UUIDColumn.class)
{
data = new UUIDColumn(rs.getString(rsColIndex));
}
else if (columnClass == Boolean.class)
{
data = Boolean.valueOf(rs.getString(rsColIndex).equals("Y"));
@ -739,6 +746,10 @@ public class WListbox extends Listbox implements IMiniTable, TableValueChangeLis
{
data = new IDColumn(((Integer)data).intValue());
}
else if (columnClass == UUIDColumn.class)
{
data = new UUIDColumn(data.toString());
}
else if (columnClass == Double.class)
{
data = Double.valueOf(((BigDecimal)data).doubleValue());
@ -768,9 +779,9 @@ public class WListbox extends Listbox implements IMiniTable, TableValueChangeLis
* Get the key of currently selected row based on layout defined in
* {@link #prepareTable(ColumnInfo[], String, String, boolean, String)}.
*
* @return ID if key
* @return ID (int) or UUID (String) - if key
*/
public Integer getSelectedRowKey()
public <T extends Serializable> T getSelectedRowKey()
{
if (m_layout == null)
{
@ -787,22 +798,22 @@ public class WListbox extends Listbox implements IMiniTable, TableValueChangeLis
* IDEMPIERE-1334
* get key of record at index
* @param index
* @return
* @return ID (int) or UUID (String)
*/
public Integer getRowKeyAt (int index){
@SuppressWarnings("unchecked")
public <T extends Serializable> T getRowKeyAt (int index){
if (index < 0 || m_keyColumnIndex < 0)
return null;
Object data = getModel().getDataAt(index, m_keyColumnIndex);
if (data instanceof IDColumn)
{
data = ((IDColumn)data).getRecord_ID();
}
if (data instanceof Integer)
{
return (Integer)data;
}
else if (data instanceof UUIDColumn)
data = ((UUIDColumn)data).getRecord_UU();
if (data instanceof Integer || data instanceof String)
return (T) data;
return null;
}
@ -819,7 +830,7 @@ public class WListbox extends Listbox implements IMiniTable, TableValueChangeLis
ListModelTable model = getModel();
List<Object> lsSelectedItem = new ArrayList<Object> ();
for (int index = 0; index < model.getSize(); index++){
Integer key = getRowKeyAt(index);
Object key = getRowKeyAt(index);
if (key == null)
continue;
@ -833,7 +844,7 @@ public class WListbox extends Listbox implements IMiniTable, TableValueChangeLis
/**
* @return key for first row (row 0). null if table is empty.
*/
public Integer getFirstRowKey()
public <T extends Serializable> T getFirstRowKey()
{
if (m_layout == null)
{
@ -1066,21 +1077,20 @@ public class WListbox extends Listbox implements IMiniTable, TableValueChangeLis
int col = event.getColumn(); // column of table field which caused the event
int row = event.getRow(); // row of table field which caused the event
boolean newBoolean;
IDColumn idColumn;
// if the event was caused by an ID Column and the value is a boolean
// then set the IDColumn's select field
if (col >= 0 && row >=0)
{
if (this.getValueAt(row, col) instanceof IDColumn
if (this.getValueAt(row, col) instanceof SelectableIDColumn
&& event.getNewValue() instanceof Boolean)
{
newBoolean = ((Boolean)event.getNewValue()).booleanValue();
idColumn = (IDColumn)this.getValueAt(row, col);
SelectableIDColumn idColumn = (SelectableIDColumn)this.getValueAt(row, col);
idColumn.setSelected(newBoolean);
this.setValueAt(idColumn, row, col);
}
// othewise just set the value in the model to the new value
// otherwise just set the value in the model to the new value
else
{
this.setValueAt(event.getNewValue(), row, col);

View File

@ -113,10 +113,10 @@ public class InfoListSubModel implements ListSubModel<ValueNamePair> {
int rowCount = ip.getRowCount();
if (rowCount > 0) {
List<String> added = new ArrayList<String>();
List<Integer> keys = new ArrayList<Integer>();
List<Object> keys = new ArrayList<Object>();
for(int i = 0; i < rowCount; i++) {
Integer key = ip.getRowKeyAt(i);
if (key != null && key.intValue() > 0 && !keys.contains(key)) {
Object key = ip.getRowKeyAt(i);
if (key != null && (key instanceof Integer && ((Integer)key).intValue() > 0 || key instanceof String && key.toString().length() > 0) && !keys.contains(key)) {
keys.add(key);
}
if (nRows > 0 && keys.size() >= nRows)

View File

@ -38,6 +38,7 @@ import org.adempiere.webui.event.ContextMenuEvent;
import org.adempiere.webui.event.ContextMenuListener;
import org.adempiere.webui.event.ValueChangeEvent;
import org.adempiere.webui.theme.ThemeManager;
import org.adempiere.webui.window.Dialog;
import org.adempiere.webui.window.FindWindow;
import org.adempiere.webui.window.WFieldRecordInfo;
import org.adempiere.webui.window.WRecordIDDialog;
@ -201,13 +202,23 @@ public class WRecordIDEditor extends WEditor implements ContextMenuListener, IZo
{
String s = tableIDValue != null ? String.valueOf(tableIDValue) : "";
int tableID = s.length() > 0 ? Integer.parseInt(s) : 0;
s = recordIDValue != null ? String.valueOf(recordIDValue) : "";
int recordID = s.length() > 0 ? Integer.parseInt(s) : 0;
if(tableID <= 0 || recordID < 0)
return;
if (!MRole.getDefault().isTableAccess(tableID, false))
throw new AdempiereException(Msg.getMsg(Env.getCtx(), "AccessTableNoView"));
AEnv.zoom(tableID, recordID);
MTable table = MTable.get(tableID);
if (table.isUUIDKeyTable()) {
String recordUU = recordIDValue != null ? recordIDValue.toString() : "";
if(tableID <= 0)
return;
if (!MRole.getDefault().isTableAccess(tableID, false))
throw new AdempiereException(Msg.getMsg(Env.getCtx(), "AccessTableNoView"));
AEnv.zoomUU(tableID, recordUU);
} else {
s = recordIDValue != null ? String.valueOf(recordIDValue) : "";
int recordID = s.length() > 0 ? Integer.parseInt(s) : 0;
if(tableID <= 0 || recordID < 0)
return;
if (!MRole.getDefault().isTableAccess(tableID, false))
throw new AdempiereException(Msg.getMsg(Env.getCtx(), "AccessTableNoView"));
AEnv.zoom(tableID, recordID);
}
}
@ -251,11 +262,18 @@ public class WRecordIDEditor extends WEditor implements ContextMenuListener, IZo
if (GridField.PROPERTY.equals(evt.getPropertyName()))
{
int tableID = tableIDValue != null ? Integer.parseInt(String.valueOf(tableIDValue)) : 0;
int recordID = Integer.parseInt(Objects.toString(evt.getNewValue(), "-1"));
if (tableID > 0 && recordID >= 0)
{
MTable table = MTable.get(Env.getCtx(), tableID);
table.getPO(recordID, null); // calls po.checkCrossTenant() method
if (tableID > 0) {
MTable table = MTable.get(tableID);
if (table.isUUIDKeyTable()) {
String recordUU = Objects.toString(evt.getNewValue(), "");
if (tableID > 0 && recordUU.length() > 0)
table.getPOByUU(recordUU, null); // calls po.checkCrossTenant() method
} else {
int recordID = Integer.parseInt(Objects.toString(evt.getNewValue(), "-1"));
if (tableID > 0 && recordID >= 0)
table.getPO(recordID, null); // calls po.checkCrossTenant() method
}
}
setValue(evt.getNewValue(), false);
}
@ -283,10 +301,17 @@ public class WRecordIDEditor extends WEditor implements ContextMenuListener, IZo
tableIDValue = tableIDGridField.getValue();
}
if(value != null && tableIDValue != null) {
int recordID = Integer.parseInt(String.valueOf(value));
int tableID = Integer.parseInt(String.valueOf(tableIDValue));
if(recordID >= 0 && tableID > 0)
recordTextBox.setValue(getIdentifier(tableID, recordID));
if (tableID > 0) {
MTable table = MTable.get(tableID);
Object recordID;
if (table.isUUIDKeyTable())
recordID = value.toString();
else
recordID = Integer.parseInt(String.valueOf(value));
if(recordID != null && tableID > 0)
recordTextBox.setValue(getIdentifier(tableID, recordID));
}
}
}
@ -294,7 +319,7 @@ public class WRecordIDEditor extends WEditor implements ContextMenuListener, IZo
&&
( (value == null && recordIDValue != null)
|| (value != null && recordIDValue == null)
|| !value.equals(recordIDValue)
|| (value != null && !value.equals(recordIDValue))
)) {
// Record_ID
ValueChangeEvent changeEvent = new ValueChangeEvent(this, this.getColumnName(), recordIDValue, value);
@ -314,10 +339,14 @@ public class WRecordIDEditor extends WEditor implements ContextMenuListener, IZo
return "";
if((tableIDValue != null) && (recordIDValue != null)) {
int tableID;
int recordID;
Object recordID;
try {
tableID = Integer.parseInt(String.valueOf(tableIDValue));
recordID = Integer.parseInt(String.valueOf(recordIDValue));
MTable table = MTable.get(tableID);
if (table.isUUIDKeyTable())
recordID = recordIDValue.toString();
else
recordID = Integer.parseInt(String.valueOf(recordIDValue));
} catch (NumberFormatException e) {
return recordIDValue.toString();
}
@ -336,10 +365,14 @@ public class WRecordIDEditor extends WEditor implements ContextMenuListener, IZo
String key = gridTab.getWindowNo() + "|AD_Table_ID";
Object rowTableIdValue = gridRowCtx.get(key);
int rowTableID;
int rowRecordID;
Object rowRecordID;
try {
rowTableID = Integer.parseInt(String.valueOf(rowTableIdValue));
rowRecordID = Integer.parseInt(String.valueOf(value));
MTable table = MTable.get(rowTableID);
if (table.isUUIDKeyTable())
rowRecordID = value.toString();
else
rowRecordID = Integer.parseInt(String.valueOf(value));
} catch (NumberFormatException e) {
return value.toString();
}
@ -364,6 +397,15 @@ public class WRecordIDEditor extends WEditor implements ContextMenuListener, IZo
tableIDValue = Integer.parseInt(tableIdTxt);
}
}
if (tableIDValue != null && tableIDValue instanceof Integer) {
MTable table = MTable.get((Integer)tableIDValue);
if (table.isUUIDKeyTable()) {
if (! getColumnName().endsWith("_UU")) {
Dialog.error(tableIDGridField.getWindowNo(), "UUTableNotCompatibleWithRecordID");
return;
}
}
}
new WRecordIDDialog(recordTextBox.getPage(), this, tableIDGridField);
}
}
@ -404,7 +446,7 @@ public class WRecordIDEditor extends WEditor implements ContextMenuListener, IZo
* @param recordID
* @return String
*/
public String getIdentifier(int tableID, int recordID) {
public String getIdentifier(int tableID, Object recordID) {
MLookup lookup = getRecordsLookup(tableID);
return lookup != null ? lookup.getDisplay(recordID) : "";
}

View File

@ -459,7 +459,7 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
}
if (log.isLoggable(Level.CONFIG)) log.config(getColumnName() + " - " + text);
int id = -1;
Object id = null;
if (m_tableName == null) // sets table name & key column
setTableAndKeyColumn();
@ -467,15 +467,27 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
final InfoPanel ip = InfoManager.create(lookup, gridField, m_tableName, m_keyColumnName, getComponent().getText(), false, getWhereClause());
if (ip != null && ip.loadedOK() && ip.getRowCount() == 1)
{
Integer key = ip.getFirstRowKey();
if (key != null && key.intValue() > 0)
if (ip.getFirstRowKey() instanceof Integer)
{
id = key.intValue();
Integer key = (Integer) ip.getFirstRowKey();
if (key != null && key.intValue() > 0)
{
id = key.intValue();
}
}
else
{
Object key = ip.getFirstRowKey();
if (key != null && key.toString().length() > 0)
{
id = key.toString();
}
}
}
// No (unique) result
if (id <= 0)
if (id == null || (id instanceof Integer && ((Integer) id).intValue() <= 0))
{
//m_value = null; // force re-display
if (ip != null && ip.loadedOK())
@ -492,7 +504,7 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
if (log.isLoggable(Level.FINE))
log.fine(getColumnName() + " - Unique ID=" + id);
actionCombo(Integer.valueOf(id)); // data binding
actionCombo(id); // data binding
focusNext();
//safety check: if focus is going no where, focus back to self

View File

@ -232,7 +232,7 @@ public class DefaultEditorFactory implements IEditorFactory {
{
editor = new WTimeZoneEditor(gridField, tableEditor);
}
else if (displayType == DisplayType.RecordID)
else if (displayType == DisplayType.RecordID || displayType == DisplayType.RecordUU)
{
editor = new WRecordIDEditor(gridField, tableEditor, editorConfiguration);
}

View File

@ -90,6 +90,8 @@ import org.adempiere.webui.window.Dialog;
import org.compiere.minigrid.ColumnInfo;
import org.compiere.minigrid.EmbedWinInfo;
import org.compiere.minigrid.IDColumn;
import org.compiere.minigrid.SelectableIDColumn;
import org.compiere.minigrid.UUIDColumn;
import org.compiere.model.AccessSqlParser.TableInfo;
import org.compiere.model.GridField;
import org.compiere.model.GridFieldVO;
@ -197,8 +199,8 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
// F3P: Keep original values: when a row is unselected, restore original values
private boolean hasEditable = false;
private Map<Integer, List<Object>> cacheOriginalValues = new HashMap<>();
private Map<Integer, List<Object>> temporarySelectedData = new HashMap<>();
private Map<Object, List<Object>> cacheOriginalValues = new HashMap<>();
private Map<Object, List<Object>> temporarySelectedData = new HashMap<>();
private WInfoWindowListItemRenderer infoWindowListItemRenderer = null;
// F3P: export
@ -929,7 +931,10 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
: tableInfos[0].getTableName();
String keySelectClause = keyTableAlias+"."+p_keyColumn;
list.add(new ColumnInfo(" ", keySelectClause, IDColumn.class, true, false, null, p_keyColumn));
if (p_keyColumn.endsWith("_UU"))
list.add(new ColumnInfo(" ", keySelectClause, UUIDColumn.class, true, false, null, p_keyColumn));
else
list.add(new ColumnInfo(" ", keySelectClause, IDColumn.class, true, false, null, p_keyColumn));
List<InfoColumnVO> gridDisplayedIC = new ArrayList<>();
gridDisplayedIC.add(null); // First column does not have any matching info column
@ -980,7 +985,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
gridDisplayedIC.add(infoColumn);
if (keyColumnOfView == infoColumn.getAD_InfoColumn()){
if (columnInfo.getColClass().equals(IDColumn.class))
if (columnInfo.getColClass().equals(IDColumn.class) || columnInfo.getColClass().equals(UUIDColumn.class))
isIDColumnKeyOfView = true;
indexKeyOfView = list.size() - 1;
}
@ -2708,6 +2713,11 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
IDColumn idc = (IDColumn)val;
val = idc.getRecord_ID();
}
else if(val instanceof UUIDColumn)
{
UUIDColumn idc = (UUIDColumn)val;
val = idc.getRecord_UU();
}
else if(val instanceof KeyNamePair)
{
KeyNamePair knp = (KeyNamePair)val;
@ -2824,7 +2834,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
*/
protected void restoreOriginalValues(int rowIndex)
{
Integer viewIdKey = getColumnValue(rowIndex);
Object viewIdKey = getColumnValue(rowIndex);
if(cacheOriginalValues.containsKey(viewIdKey)) // Only cache if not cached to avoid caching subsequent modifications
{
@ -2845,7 +2855,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
*/
protected void cacheOriginalValues(int rowIndex)
{
Integer viewIdKey = getColumnValue(rowIndex);
Object viewIdKey = getColumnValue(rowIndex);
if(cacheOriginalValues.containsKey(viewIdKey) == false) // Only cache if not cached to avoid caching subsequent modifications
{
@ -2873,10 +2883,10 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
{
Object col0 = contentPanel.getValueAt(row, 0);
if(col0 instanceof IDColumn)
if(col0 instanceof SelectableIDColumn)
{
IDColumn idc = (IDColumn)col0;
SelectableIDColumn idc = (SelectableIDColumn)col0;
if(idc.isSelected())
{
cacheOriginalValues(row);
@ -2916,7 +2926,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
for(int rowIndex:contentPanel.getSelectedIndices())
{
Integer keyViewValue = getColumnValue(rowIndex);
Object keyViewValue = getColumnValue(rowIndex);
@SuppressWarnings("unchecked")
List<Object> row = (List<Object>)model.get(rowIndex);
@ -2924,7 +2934,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
temporarySelectedData.put(keyViewValue, clonedRow);
}
for(Entry<Integer, List<Object>> entry: recordSelectedData.entrySet())
for(Entry<Object, List<Object>> entry: recordSelectedData.entrySet())
{
ArrayList<Object> clonedRow = new ArrayList<>(entry.getValue());
temporarySelectedData.put(entry.getKey(), clonedRow);
@ -2948,7 +2958,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
@Override
public boolean onRestoreSelectedItemIndexInPage(Integer keyViewValue, int rowIndex, Object oRow)
public boolean onRestoreSelectedItemIndexInPage(Object keyViewValue, int rowIndex, Object oRow)
{
if(hasEditable && temporarySelectedData != null)
{
@ -2976,15 +2986,19 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
}
// Restore isSelected status on IDColumn
Object id = (IDColumn)row.get(0);
Object id = row.get(0);
if(id instanceof IDColumn)
{
IDColumn idc = (IDColumn)id;
idc.setSelected(true);
}
else if (id instanceof UUIDColumn)
{
UUIDColumn idc = (UUIDColumn)id;
idc.setSelected(true);
}
// Restore listners
// Restore listeners
model.addTableModelListener(this);
}

View File

@ -33,6 +33,7 @@ import org.adempiere.webui.editor.WEditor;
import org.compiere.minigrid.ColumnInfo;
import org.compiere.minigrid.EmbedWinInfo;
import org.compiere.minigrid.IDColumn;
import org.compiere.minigrid.UUIDColumn;
import org.compiere.model.MSysConfig;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
@ -120,6 +121,9 @@ public class RelatedInfoWindow implements EventListener<Event>, Sortable<Object>
if (parentId != null && parentId instanceof IDColumn){
IDColumn ID = (IDColumn) parentId;
linkPara = ID.getRecord_ID();
} else if (parentId != null && parentId instanceof UUIDColumn) {
UUIDColumn ID = (UUIDColumn) parentId;
linkPara = ID.getRecord_UU();
}else if (parentId != null){
linkPara = parentId.toString();
}
@ -342,6 +346,9 @@ public class RelatedInfoWindow implements EventListener<Event>, Sortable<Object>
if (parentId != null && parentId instanceof IDColumn){
IDColumn ID = (IDColumn) parentId;
linkPara = ID.getRecord_ID();
} else if (parentId != null && parentId instanceof UUIDColumn) {
UUIDColumn ID = (UUIDColumn) parentId;
linkPara = ID.getRecord_UU();
}else if (parentId != null){
linkPara = parentId.toString();
}
@ -423,9 +430,9 @@ public class RelatedInfoWindow implements EventListener<Event>, Sortable<Object>
Class<?> c = columnsLayout[col].getColClass();
int colIndex = col + colOffset;
if (c == IDColumn.class)
{
value = new IDColumn(rs.getInt(colIndex));
}
else if (c == UUIDColumn.class)
value = new UUIDColumn(rs.getString(colIndex));
else if (c == Boolean.class)
value = Boolean.valueOf("Y".equals(rs.getString(colIndex)));
else if (c == Timestamp.class)

View File

@ -396,7 +396,7 @@ public class InfoAssignmentPanel extends InfoPanel implements EventListener<Even
public void zoom()
{
if (getSelectedRowKey() != null && getSelectedRowKey() > 0)
if (getSelectedRowKey() != null && getSelectedRowKey() instanceof Integer && ((Integer)getSelectedRowKey()).intValue() > 0)
{
MQuery zoomQuery = new MQuery(); // ColumnName might be changed in MTab.validateQuery
String column = getKeyColumn();

View File

@ -37,12 +37,14 @@ import org.adempiere.webui.util.ZKUpdateUtil;
import org.adempiere.webui.window.Dialog;
import org.compiere.minigrid.ColumnInfo;
import org.compiere.minigrid.IDColumn;
import org.compiere.minigrid.UUIDColumn;
import org.compiere.model.GridField;
import org.compiere.model.I_C_ElementValue;
import org.compiere.model.MColumn;
import org.compiere.model.MLookupFactory;
import org.compiere.model.MReference;
import org.compiere.model.MTable;
import org.compiere.model.PO;
import org.compiere.util.DB;
import org.compiere.util.DisplayType;
import org.compiere.util.Env;
@ -390,9 +392,11 @@ public class InfoGeneralPanel extends InfoPanel implements EventListener<Event>
private boolean initInfoTable ()
{
// Get Query Columns
MTable table = MTable.get(Env.getCtx(), p_tableName);
String uucolName = PO.getUUIDColumnName(p_tableName);
String sql = "SELECT c.ColumnName, t.AD_Table_ID, t.TableName, c.ColumnSql "
// Get Query Columns
final String sqlqc = "SELECT c.ColumnName, t.AD_Table_ID, t.TableName, c.ColumnSql "
+ "FROM AD_Table t"
+ " INNER JOIN AD_Column c ON (t.AD_Table_ID=c.AD_Table_ID)"
+ "WHERE c.AD_Reference_ID IN (10,14)"
@ -410,7 +414,7 @@ public class InfoGeneralPanel extends InfoPanel implements EventListener<Event>
ResultSet rs = null;
try
{
pstmt = DB.prepareStatement(sql, null);
pstmt = DB.prepareStatement(sqlqc, null);
pstmt.setString(1, p_tableName);
rs = pstmt.executeQuery();
@ -437,7 +441,7 @@ public class InfoGeneralPanel extends InfoPanel implements EventListener<Event>
}
catch (SQLException e)
{
log.log(Level.SEVERE, sql, e);
log.log(Level.SEVERE, sqlqc, e);
return false;
}
finally
@ -466,23 +470,27 @@ public class InfoGeneralPanel extends InfoPanel implements EventListener<Event>
}
// Set Title
String title = Msg.translate(Env.getCtx(), tableName + "_ID"); // best bet
if (title.endsWith("_ID"))
title = Msg.translate(Env.getCtx(), tableName); // second best bet
String title = null;
if (table.isUUIDKeyTable())
title = Msg.translate(Env.getCtx(), uucolName);
else {
title = Msg.translate(Env.getCtx(), tableName + "_ID"); // best bet
if (title.endsWith("_ID"))
title = Msg.translate(Env.getCtx(), tableName); // second best bet
}
setTitle(getTitle() + " " + title);
// Get Display Columns
int AD_Window_ID = 0;
MTable table = MTable.get(AD_Table_ID);
if (table.getAD_Window_ID() > 0) {
AD_Window_ID = table.getAD_Window_ID();
} else {
AD_Window_ID = table.getWindowIDFromMenu();
}
ArrayList<ColumnInfo> list = new ArrayList<ColumnInfo>();
sql = "SELECT c.ColumnName, c.AD_Reference_ID, c.IsKey, f.IsDisplayed, c.AD_Reference_Value_ID, c.ColumnSql, c.AD_Column_ID "
StringBuilder sqlc = new StringBuilder().append(
"SELECT c.ColumnName, c.AD_Reference_ID, c.IsKey, f.IsDisplayed, c.AD_Reference_Value_ID, c.ColumnSql, c.AD_Column_ID "
+ "FROM AD_Column c"
+ " INNER JOIN AD_Table t ON (c.AD_Table_ID=t.AD_Table_ID)"
+ " INNER JOIN AD_Tab tab ON (t.AD_Table_ID=tab.AD_Table_ID)"
@ -493,11 +501,16 @@ public class InfoGeneralPanel extends InfoPanel implements EventListener<Event>
+ " AND (c.IsKey='Y' OR "
+ " (f.IsEncrypted='N' AND f.ObscureType IS NULL)) "
+ " AND c.IsActive = 'Y' "
+ "ORDER BY c.IsKey DESC, f.SeqNo";
+ "ORDER BY ");
if (table.isUUIDKeyTable())
sqlc.append("CASE WHEN c.columnname=").append(DB.TO_STRING(uucolName)).append("THEN 0 ELSE 1 END");
else
sqlc.append("c.IsKey DESC");
sqlc.append(", f.SeqNo");
try
{
pstmt = DB.prepareStatement(sql, null);
pstmt = DB.prepareStatement(sqlc.toString(), null);
pstmt.setInt(1, AD_Table_ID);
pstmt.setInt(2, AD_Window_ID);
rs = pstmt.executeQuery();
@ -523,6 +536,8 @@ public class InfoGeneralPanel extends InfoPanel implements EventListener<Event>
if (isKey)
colClass = IDColumn.class;
else if (uucolName.equals(columnName) && table.isUUIDKeyTable())
colClass = UUIDColumn.class;
else if (!isDisplayed)
;
else if (displayType == DisplayType.YesNo)
@ -577,7 +592,7 @@ public class InfoGeneralPanel extends InfoPanel implements EventListener<Event>
}
catch (SQLException e)
{
log.log(Level.SEVERE, sql, e);
log.log(Level.SEVERE, sqlc.toString(), e);
return false;
}
finally
@ -590,7 +605,7 @@ public class InfoGeneralPanel extends InfoPanel implements EventListener<Event>
if (list.size() == 0)
{
Dialog.error(p_WindowNo, "Error", "No Info Columns");
log.log(Level.SEVERE, "No Info for AD_Table_ID=" + AD_Table_ID + " - " + sql);
log.log(Level.SEVERE, "No Info for AD_Table_ID=" + AD_Table_ID + " - " + sqlc.toString());
return false;
}

View File

@ -18,6 +18,7 @@
package org.adempiere.webui.panel;
import java.awt.event.MouseEvent;
import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@ -70,6 +71,7 @@ import org.adempiere.webui.util.ZKUpdateUtil;
import org.adempiere.webui.window.Dialog;
import org.compiere.minigrid.ColumnInfo;
import org.compiere.minigrid.IDColumn;
import org.compiere.minigrid.UUIDColumn;
import org.compiere.model.GridField;
import org.compiere.model.InfoColumnVO;
import org.compiere.model.InfoRelatedVO;
@ -90,6 +92,7 @@ import org.compiere.util.DisplayType;
import org.compiere.util.Env;
import org.compiere.util.KeyNamePair;
import org.compiere.util.Msg;
import org.compiere.util.NamePair;
import org.compiere.util.Trx;
import org.compiere.util.Util;
import org.compiere.util.ValueNamePair;
@ -146,7 +149,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
// attribute key of info process
protected final static String ATT_INFO_PROCESS_KEY = "INFO_PROCESS";
protected int pageSize;
public LinkedHashMap<KeyNamePair,LinkedHashMap<String, Object>> m_values = null;
public LinkedHashMap<NamePair,LinkedHashMap<String, Object>> m_values = null;
protected InfoRelatedVO[] relatedInfoList;
// for test disable load all record when num of record < 1000
protected boolean isIgnoreCacheAll = true;
@ -171,7 +174,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
/**
* store selected record info
* key of map is value of column play as keyView
* in case has no key coloumn of view, use value of {@link #p_keyColumn}
* in case has no key column of view, use value of {@link #p_keyColumn}
* zk6.x listview don't provide event when click to checkbox select all,
* so we can't manage selectedRecord time by time.
* each time change page we will update this list with current
@ -180,7 +183,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
* onclick. because don't direct use recordSelectedData, call
* {@link #getSelectedRowInfo()}
*/
protected Map<Integer, List<Object>> recordSelectedData = new HashMap<Integer, List<Object>>();
protected Map<Object, List<Object>> recordSelectedData = new HashMap<Object, List<Object>>();
/**
* when requery but don't clear selected record (example after run process)
@ -477,7 +480,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
/** Cancel pressed - need to differentiate between OK - Cancel - Exit */
private boolean m_cancel = false;
/** Result IDs */
private ArrayList<Integer> m_results = new ArrayList<Integer>(3);
private ArrayList<Object> m_results = new ArrayList<Object>(3);
private ListModelTable model;
/** Layout of Grid */
@ -569,7 +572,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
/**
* save selected id and viewID
*/
protected Collection<KeyNamePair> m_viewIDMap = new ArrayList <KeyNamePair>();
protected Collection<NamePair> m_viewIDMap = new ArrayList <NamePair>();
/**
* store index of infoColumn have data append. each infoColumn just append only one time.
@ -638,7 +641,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
int selectedCount = recordSelectedData.size();
for (int rowIndex = 0; rowIndex < contentPanel.getModel().getRowCount(); rowIndex++){
Integer keyCandidate = getColumnValue(rowIndex);
Object keyCandidate = getColumnValue(rowIndex);
@SuppressWarnings("unchecked")
List<Object> candidateRecord = (List<Object>)contentPanel.getModel().get(rowIndex);
@ -730,10 +733,9 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
Class<?> c = p_layout[col].getColClass();
int colIndex = col + colOffset;
if (c == IDColumn.class)
{
value = new IDColumn(rs.getInt(colIndex));
}
else if (c == UUIDColumn.class)
value = new UUIDColumn(rs.getString(colIndex));
else if (c == Boolean.class)
value = Boolean.valueOf("Y".equals(rs.getString(colIndex)));
else if (c == Timestamp.class)
@ -1513,7 +1515,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
}
else // singleSelection
{
Integer data = getSelectedRowKey();
Serializable data = getSelectedRowKey();
if (data != null)
m_results.add(data);
}
@ -1529,9 +1531,9 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
* Get the key of currently selected row
* @return selected key
*/
protected Integer getSelectedRowKey()
protected <T extends Serializable> T getSelectedRowKey()
{
Integer key = contentPanel.getSelectedRowKey();
T key = contentPanel.getSelectedRowKey();
return key;
} // getSelectedRowKey
@ -1542,10 +1544,10 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
* @return IDs if selection present
* author ashley
*/
protected ArrayList<Integer> getSelectedRowKeys()
protected ArrayList<Object> getSelectedRowKeys()
{
ArrayList<Integer> selectedDataList = new ArrayList<Integer>();
Collection<Integer> lsKeyValueOfSelectedRow = getSelectedRowInfo().keySet();
ArrayList<Object> selectedDataList = new ArrayList<Object>();
Collection<Object> lsKeyValueOfSelectedRow = getSelectedRowInfo().keySet();
if (lsKeyValueOfSelectedRow.size() == 0)
{
return selectedDataList;
@ -1553,7 +1555,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
if (p_multipleSelection)
{
for (Integer key : lsKeyValueOfSelectedRow){
for (Object key : lsKeyValueOfSelectedRow){
selectedDataList.add(key);
}
}
@ -1566,7 +1568,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
* @deprecated use getSaveKeys
* @return selected keys (Integers)
*/
public Collection<Integer> getSelectedKeysCollection()
public Collection<Object> getSelectedKeysCollection()
{
m_ok = true;
saveSelection();
@ -1579,18 +1581,18 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
* Save selected id, viewID of all process to map viewIDMap to save into T_Selection
* @param infoCulumnId
*/
public Collection<KeyNamePair> getSaveKeys (int infoCulumnId){
public Collection<NamePair> getSaveKeys (int infoCulumnId){
// clear result from prev time
m_viewIDMap.clear();
if (p_multipleSelection)
{
Map <Integer, List<Object>> selectedRow = getSelectedRowInfo();
Map <Object, List<Object>> selectedRow = getSelectedRowInfo();
for (Entry<Integer, List<Object>> selectedInfo : selectedRow.entrySet())
for (Entry<Object, List<Object>> selectedInfo : selectedRow.entrySet())
{
// get key data column
Integer keyData = selectedInfo.getKey();
Object keyData = selectedInfo.getKey();
if (infoCulumnId > 0){
// have viewID, get it
@ -1598,11 +1600,16 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
// get row data from model
Object viewIDValue = selectedInfo.getValue().get(dataIndex);
m_viewIDMap.add (new KeyNamePair(keyData, viewIDValue == null?null:viewIDValue.toString()));
if (keyData instanceof String)
m_viewIDMap.add (new ValueNamePair((String) keyData, viewIDValue == null?null:viewIDValue.toString()));
else
m_viewIDMap.add (new KeyNamePair((Integer) keyData, viewIDValue == null?null:viewIDValue.toString()));
}else{
// hasn't viewID, set viewID value is null
m_viewIDMap.add (new KeyNamePair(keyData, null));
if (keyData instanceof String)
m_viewIDMap.add (new ValueNamePair((String) keyData, null));
else
m_viewIDMap.add (new KeyNamePair((Integer) keyData, null));
}
}
@ -1659,7 +1666,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
*/
protected void updateListSelected (){
for (int rowIndex = 0; rowIndex < contentPanel.getModel().getRowCount(); rowIndex++){
Integer keyCandidate = getColumnValue(rowIndex);
Object keyCandidate = getColumnValue(rowIndex);
@SuppressWarnings("unchecked")
List<Object> candidateRecord = (List<Object>)contentPanel.getModel().get(rowIndex);
@ -1670,15 +1677,22 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
if (recordSelectedData.containsKey(keyCandidate)){// unselected record
List<Object> recordSelected = recordSelectedData.get(keyCandidate);
IDColumn idcSel = null;
UUIDColumn uucSel = null;
if (recordSelected.get(0) instanceof IDColumn) {
idcSel = (IDColumn) recordSelected.get(0);
} else if (recordSelected.get(0) instanceof UUIDColumn) {
uucSel = (UUIDColumn) recordSelected.get(0);
}
IDColumn idcCan = null;
UUIDColumn uucCan = null;
if (candidateRecord.get(0) instanceof IDColumn) {
idcCan = (IDColumn) candidateRecord.get(0);
} else if (candidateRecord.get(0) instanceof UUIDColumn) {
uucCan = (UUIDColumn) candidateRecord.get(0);
}
if (idcSel != null && idcCan != null && idcSel.getRecord_ID().equals(idcCan.getRecord_ID())) {
recordSelected.set(0, candidateRecord.get(0)); // set same IDColumn for comparison
if ( (idcSel != null && idcCan != null && idcSel.getRecord_ID().equals(idcCan.getRecord_ID()))
|| (uucSel != null && uucCan != null && uucSel.getRecord_UU().equals(uucCan.getRecord_UU())) ) {
recordSelected.set(0, candidateRecord.get(0)); // set same ID/UUID Column for comparison
}
if (recordSelected.equals(candidateRecord)) {
recordSelectedData.remove(keyCandidate);
@ -1712,7 +1726,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
Collection<Object> lsSelectionRecord = new ArrayList<Object>();
for (int rowIndex = 0; rowIndex < contentPanel.getModel().getRowCount(); rowIndex++){
Integer keyViewValue = getColumnValue(rowIndex);
Object keyViewValue = getColumnValue(rowIndex);
if (recordSelectedData.containsKey(keyViewValue)){
// TODO: maybe add logic to check value of current record (focus only to viewKeys value) is same as value save in lsSelectedKeyValue
// because record can change by other user
@ -1733,7 +1747,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
* @param row row
* @return false to skip restore selection
*/
public boolean onRestoreSelectedItemIndexInPage(Integer keyViewValue, int rowIndex, Object row)
public boolean onRestoreSelectedItemIndexInPage(Object keyViewValue, int rowIndex, Object row)
{
return true;
}
@ -1744,15 +1758,15 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
return new AdempiereException(errorMessage);
}
/**
* get keyView value at rowIndex and clumnIndex
* also check in case value is null will rise a exception
* get keyView value at rowIndex and columnIndex
* also check in case value is null will raise an exception
* @param rowIndex
* @return
*/
protected Integer getColumnValue (int rowIndex){
protected Object getColumnValue (int rowIndex){
int keyIndex = getIndexKeyColumnOfView();
Integer keyValue = null;
Object keyValue = null;
// get row data from model
Object keyColumValue = contentPanel.getModel().getDataAt(rowIndex, keyIndex);
// throw exception when value is null
@ -1763,20 +1777,26 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
}
// IDColumn is recreate after change page, because use value of IDColumn
if (keyColumValue != null && keyColumValue instanceof IDColumn){
keyColumValue = ((IDColumn)keyColumValue).getRecord_ID();
if (keyColumValue != null) {
if (keyColumValue instanceof IDColumn) {
keyColumValue = ((IDColumn)keyColumValue).getRecord_ID();
} else if (keyColumValue instanceof UUIDColumn) {
keyColumValue = ((UUIDColumn)keyColumValue).getRecord_UU();
}
}
if (keyColumValue instanceof Integer){
if (keyColumValue instanceof Integer) {
keyValue = (Integer)keyColumValue;
}else {
String msg = "keyView column must be integer";
} else if (keyColumValue instanceof String) {
keyValue = (String)keyColumValue;
} else {
String msg = "keyView column must be integer or string";
AdempiereException ex = new AdempiereException (msg);
log.severe(msg);
throw ex;
}
return (Integer)keyValue;
return keyValue;
}
/**
@ -1805,7 +1825,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
* update list column key value of selected record and return this list
* @return {@link #recordSelectedData} after update
*/
public Map<Integer, List<Object>> getSelectedRowInfo (){
public Map<Object, List<Object>> getSelectedRowInfo (){
updateListSelected();
return recordSelectedData;
}
@ -1819,7 +1839,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
{
if (!m_ok || m_results.size() == 0)
return null;
return m_results.toArray(new Integer[0]);
return m_results.toArray(new Object[0]);
} // getSelectedKeys;
/**
@ -2372,7 +2392,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
title = m_process.getValue();
// store in T_Selection table selected rows for Execute Process that retrieves from T_Selection in code.
DB.createT_SelectionNew(pInstanceID, getSaveKeys(getInfoColumnIDFromProcess(processId)), null);
DB.createT_SelectionNewNP(pInstanceID, getSaveKeys(getInfoColumnIDFromProcess(processId)), null);
ADForm form = ADForm.openForm(adFormID, null, m_pi);
Mode mode = form.getWindowMode();
@ -2417,7 +2437,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
if (DialogEvents.ON_BEFORE_RUN_PROCESS.equals(event.getName())){
updateListSelected();
// store in T_Selection table selected rows for Execute Process that retrieves from T_Selection in code.
DB.createT_SelectionNew(pInstanceID, getSaveKeys(getInfoColumnIDFromProcess(processModalDialog.getAD_Process_ID())),
DB.createT_SelectionNewNP(pInstanceID, getSaveKeys(getInfoColumnIDFromProcess(processModalDialog.getAD_Process_ID())),
null);
saveResultSelection(getInfoColumnIDFromProcess(processModalDialog.getAD_Process_ID()));
createT_Selection_InfoWindow(pInstanceID);
@ -2466,25 +2486,31 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
return;
}
m_values = new LinkedHashMap<KeyNamePair,LinkedHashMap<String,Object>>();
m_values = new LinkedHashMap<NamePair,LinkedHashMap<String,Object>>();
if (p_multipleSelection) {
Map <Integer, List<Object>> selectedRow = getSelectedRowInfo();
Map <Object, List<Object>> selectedRow = getSelectedRowInfo();
// for selected rows
for (Entry<Integer, List<Object>> selectedInfo : selectedRow.entrySet())
for (Entry<Object, List<Object>> selectedInfo : selectedRow.entrySet())
{
// get key and viewID
Integer keyData = selectedInfo.getKey();
KeyNamePair kp = null;
Object keyData = selectedInfo.getKey();
NamePair kp = null;
if (infoColumnId > 0){
int dataIndex = columnDataIndex.get(infoColumnId) + p_layout.length;
Object viewIDValue = selectedInfo.getValue().get(dataIndex);
kp = new KeyNamePair(keyData, viewIDValue == null ? null : viewIDValue.toString());
if (keyData instanceof String)
kp = new ValueNamePair((String) keyData, viewIDValue == null ? null : viewIDValue.toString());
else
kp = new KeyNamePair((Integer) keyData, viewIDValue == null ? null : viewIDValue.toString());
}else{
kp = new KeyNamePair(keyData, null);
if (keyData instanceof String)
kp = new ValueNamePair((String) keyData, null);
else
kp = new KeyNamePair((Integer) keyData, null);
}
// get Data
@ -2507,9 +2533,15 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
*/
public void createT_Selection_InfoWindow(int AD_PInstance_ID)
{
MTable table = MTable.get(Env.getCtx(), getTableName());
StringBuilder insert = new StringBuilder();
insert.append("INSERT INTO T_Selection_InfoWindow (AD_PINSTANCE_ID, T_SELECTION_ID, COLUMNNAME , VALUE_STRING, VALUE_NUMBER , VALUE_DATE ) VALUES(?,?,?,?,?,?) ");
for (Entry<KeyNamePair,LinkedHashMap<String, Object>> records : m_values.entrySet()) {
insert.append("INSERT INTO T_Selection_InfoWindow (AD_PINSTANCE_ID, ");
if (table.isUUIDKeyTable())
insert.append("T_SELECTION_UU");
else
insert.append("T_SELECTION_ID");
insert.append(", COLUMNNAME , VALUE_STRING, VALUE_NUMBER , VALUE_DATE ) VALUES(?,?,?,?,?,?) ");
for (Entry<NamePair,LinkedHashMap<String, Object>> records : m_values.entrySet()) {
//set Record ID
LinkedHashMap<String, Object> fields = records.getValue();
@ -2525,6 +2557,11 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
KeyNamePair knp = (KeyNamePair)key;
parameters.add(knp.getKey());
}
else if(key instanceof ValueNamePair)
{
ValueNamePair vnp = (ValueNamePair)key;
parameters.add(vnp.getValue());
}
else
{
parameters.add(key);
@ -2541,6 +2578,13 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
parameters.add(id.getRecord_ID());
parameters.add(null);
}
else if (data instanceof UUIDColumn)
{
UUIDColumn id = (UUIDColumn) data;
parameters.add(null);
parameters.add(id.getRecord_UU());
parameters.add(null);
}
else if (data instanceof String)
{
parameters.add(data);
@ -2726,7 +2770,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
*/
public void zoom()
{
Integer recordId = contentPanel.getSelectedRowKey();
Object recordId = contentPanel.getSelectedRowKey();
// prevent NPE when double click is raise but no recore is selected
if (recordId == null)
return;
@ -2742,13 +2786,17 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
int AD_Table_ID = MTable.getTable_ID(p_tableName);
if (AD_Table_ID <= 0)
{
if (p_keyColumn.endsWith("_ID"))
if (p_keyColumn.endsWith("_ID") || p_keyColumn.endsWith("_UU"))
{
AD_Table_ID = MTable.getTable_ID(p_keyColumn.substring(0, p_keyColumn.length() - 3));
}
}
if (AD_Table_ID > 0)
AEnv.zoom(AD_Table_ID, recordId);
if (AD_Table_ID > 0) {
if (recordId instanceof String)
AEnv.zoomUU(AD_Table_ID, (String) recordId);
else
AEnv.zoom(AD_Table_ID, (Integer) recordId);
}
}
}
@ -2805,7 +2853,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
*/
private void addAllCurrentContentPanelToSelected() {
for (int rowIndex = 0; rowIndex < contentPanel.getModel().getRowCount(); rowIndex++){
Integer keyCandidate = getColumnValue(rowIndex);
Object keyCandidate = getColumnValue(rowIndex);
@SuppressWarnings("unchecked")
List<Object> candidateRecord = (List<Object>)contentPanel.getModel().get(rowIndex);
if (!recordSelectedData.containsKey(keyCandidate)) {
@ -2975,7 +3023,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
*
* @return first row key/id
*/
public Integer getFirstRowKey() {
public Object getFirstRowKey() {
return contentPanel.getFirstRowKey();
}
@ -2984,7 +3032,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
* @param row
* @return row key/id
*/
public Integer getRowKeyAt(int row) {
public Object getRowKeyAt(int row) {
return contentPanel.getRowKeyAt(row);
}

View File

@ -39,6 +39,8 @@ import org.adempiere.webui.event.ValueChangeListener;
import org.adempiere.webui.factory.ButtonFactory;
import org.compiere.model.GridField;
import org.compiere.model.MLookup;
import org.compiere.model.MTable;
import org.compiere.model.PO;
import org.compiere.util.DisplayType;
import org.compiere.util.Env;
import org.compiere.util.Msg;
@ -69,7 +71,7 @@ public class WRecordIDDialog extends Window implements EventListener<Event>, Val
/** Current tab's AD_Table_ID GrodField */
private GridField tableIDGridField;
/** Current Record_ID value from {@link #editor} */
private Integer recordIDValue;
private Object recordIDValue;
/** Current AD_Table_ID value from {@link #editor} */
private Integer tableIDValue;
@ -93,17 +95,8 @@ public class WRecordIDDialog extends Window implements EventListener<Event>, Val
*/
public WRecordIDDialog(Page page, WRecordIDEditor editor, GridField tableIDGridField) {
super();
this.editor = editor;
this.tableIDGridField = tableIDGridField;
if(editor.getValue() instanceof Integer) {
this.recordIDValue = (Integer)editor.getValue();
} else {
if (editor.getValue() == null)
this.recordIDValue = null;
else
this.recordIDValue = Integer.valueOf(editor.getValue().toString());
}
if (editor.getAD_Table_ID() instanceof Integer) {
tableIDValue = (Integer) editor.getAD_Table_ID();
@ -114,6 +107,20 @@ public class WRecordIDDialog extends Window implements EventListener<Event>, Val
tableIDValue = Integer.valueOf(editor.getAD_Table_ID().toString());
}
this.tableIDGridField = tableIDGridField;
if(editor.getValue() instanceof Integer) {
this.recordIDValue = (Integer)editor.getValue();
} else {
if (editor.getValue() == null)
this.recordIDValue = null;
else {
MTable table = MTable.get(tableIDValue);
if (editor.getValue() instanceof String && table != null && table.isUUIDKeyTable())
this.recordIDValue = editor.getValue().toString();
}
}
init(page);
}
@ -152,8 +159,13 @@ public class WRecordIDDialog extends Window implements EventListener<Event>, Val
if (editor.getGridField().getGridTab() != null) {
parentTextBox = new Textbox();
parentTextBox.setReadonly(true);
parentTextBox.setValue(editor.getIdentifier(
editor.getGridField().getGridTab().getAD_Table_ID(), editor.getGridField().getGridTab().getRecord_ID()));
MTable table = MTable.get(tableID);
Object recordId;
if (table.isUUIDKeyTable())
recordId = editor.getGridField().getGridTab().getValue(PO.getUUIDColumnName(table.getTableName()));
else
recordId = editor.getGridField().getGridTab().getRecord_ID();
parentTextBox.setValue(editor.getIdentifier(tableID, recordId));
}
if (recordsEditor != null)
@ -219,14 +231,21 @@ public class WRecordIDDialog extends Window implements EventListener<Event>, Val
@Override
public void valueChange(ValueChangeEvent evt) {
if (evt.getSource().equals(tableIDEditor)) {
int tableID = Integer.parseInt(Objects.toString(evt.getNewValue(), "-1"));
if (tableID > 0) {
MTable table = MTable.get(tableID);
if (table.isUUIDKeyTable()) {
if (! editor.getColumnName().endsWith("_UU"))
throw new WrongValueException(tableIDEditor.getComponent(), Msg.getMsg(Env.getCtx(), "UUTableNotCompatibleWithRecordID"));
}
}
// the Record_ID should be cleared when a different AD_Table_ID is selected
if (recordsEditor != null) {
recordsEditor.setValue(null);
recordsEditorLabel.detach();
recordsEditor.getComponent().detach();
}
int tableID = Integer.parseInt(Objects.toString(evt.getNewValue(), "-1"));
MLookup recordsLookup = editor.getRecordsLookup(tableID);
if(recordsLookup != null) {
recordsEditor = new WSearchEditor("Record_ID", false, false, true, recordsLookup);

View File

@ -343,8 +343,11 @@ public class WRecordInfo extends Window implements EventListener<Event>
} else {
uuid = po.get_UUID();
}
if (!Util.isEmpty(uuid))
m_info.append("\n ").append(uuidcol).append("=").append(uuid);
if (!Util.isEmpty(uuid)) {
StringBuilder uuinfo = new StringBuilder(uuidcol).append("=").append(uuid);
if (! m_info.toString().contains(uuinfo))
m_info.append("\n ").append(uuinfo);
}
if (po.get_KeyColumns().length == 1) {
String ticketURL;
if (Record_ID <= 0)

View File

@ -22,7 +22,7 @@ package org.compiere.minigrid;
* @author Jorg Janke
* @version $Id: IDColumn.java,v 1.2 2006/07/30 00:51:28 jjanke Exp $
*/
public class IDColumn
public class IDColumn implements SelectableIDColumn
{
/**
* ID Column constructor

View File

@ -26,6 +26,7 @@
**********************************************************************/
package org.compiere.minigrid;
import java.io.Serializable;
import java.sql.ResultSet;
import org.compiere.model.PO;
@ -125,7 +126,7 @@ public interface IMiniTable
*
* @return row key
*/
public Integer getSelectedRowKey();
public <T extends Serializable> T getSelectedRowKey();
/**
*

View File

@ -0,0 +1,34 @@
/***********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* 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., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - Carlos Ruiz - globalqss - bxservice *
**********************************************************************/
package org.compiere.minigrid;
public interface SelectableIDColumn {
public void setSelected(boolean selected);
public boolean isSelected();
}

View File

@ -0,0 +1,94 @@
/***********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* 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., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - Carlos Ruiz - globalqss - bxservice *
**********************************************************************/
package org.compiere.minigrid;
/**
* UUID Column for MiniGrid allows to select a column and maintains the record UUID
* @author Carlos Ruiz - globalqss - bxservice
*/
public class UUIDColumn implements SelectableIDColumn
{
/**
* UUID Column constructor
* @param record_UU
*/
public UUIDColumn(String record_UU)
{
super();
setRecord_UU(record_UU);
setSelected(false);
} // UUIDColumn
/** Is the row selected */
private boolean m_selected = false;
/** The Record_UU */
private String m_record_UU;
/**
* Set Selection
* @param selected
*/
public void setSelected(boolean selected)
{
m_selected = selected;
}
/**
* Is Selected
* @return true if selected
*/
public boolean isSelected()
{
return m_selected;
}
/**
* Set Record_UU
* @param record_UU
*/
public void setRecord_UU(String record_UU)
{
m_record_UU = record_UU;
}
/**
* Get Record UU
* @return UU
*/
public String getRecord_UU()
{
return m_record_UU;
}
/**
* To String
* @return String representation
*/
public String toString()
{
return "UUIDColumn - UU=" + m_record_UU + ", Selected=" + m_selected;
} // toString
} // UUIDColumn