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) { if (recordId != null) {
mTab.setValue(recordId, null); mTab.setValue(recordId, null);
} }
GridField recordUU = mTab.getField("Record_UU");
if (recordUU != null) {
mTab.setValue(recordUU, null);
}
return null; return null;
} }
} }

View File

@ -849,8 +849,12 @@ public class Query
// //
if (whereBuffer.length() > 0) if (whereBuffer.length() > 0)
whereBuffer.append(" AND "); whereBuffer.append(" AND ");
whereBuffer.append(" EXISTS (SELECT 1 FROM T_Selection s WHERE s.AD_PInstance_ID=?" whereBuffer.append(" EXISTS (SELECT 1 FROM T_Selection s WHERE s.AD_PInstance_ID=? AND s.");
+" AND s.T_Selection_ID="+table.getTableName()+"."+keys[0]+")"); 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); 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_QUANTITY = 29;
public final static int REFERENCE_DATATYPE_RADIOGROUP_LIST= 200152; 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_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_ROWID = 26;
public final static int REFERENCE_DATATYPE_SCHEDULER_STATE = 200173; public final static int REFERENCE_DATATYPE_SCHEDULER_STATE = 200173;
public final static int REFERENCE_DATATYPE_SEARCH = 30; public final static int REFERENCE_DATATYPE_SEARCH = 30;

View File

@ -38,6 +38,7 @@ import java.util.logging.Level;
import javax.sql.RowSet; import javax.sql.RowSet;
import org.adempiere.exceptions.AdempiereException;
import org.adempiere.exceptions.DBException; import org.adempiere.exceptions.DBException;
import org.adempiere.util.ProcessUtil; import org.adempiere.util.ProcessUtil;
import org.compiere.Adempiere; 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 * saveKeys is map with key is rowID, value is list value of all viewID
* viewIDIndex is index of viewID need save. * viewIDIndex is index of viewID need save.
* @param AD_PInstance_ID * @param AD_PInstance_ID
* @param saveKeys * @param saveKeys - Collection of KeyNamePair
* @param trxName * @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(); String initialInsert = "INSERT INTO T_SELECTION(AD_PINSTANCE_ID, T_SELECTION_ID, T_SELECTION_UU, ViewID) ";
insert.append("INSERT INTO T_SELECTION(AD_PINSTANCE_ID, T_SELECTION_ID, ViewID) "); StringBuilder insert = new StringBuilder(initialInsert);
int counter = 0; 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++; counter++;
if (counter > 1) if (counter > 1)
insert.append(" UNION "); insert.append(" UNION ");
insert.append("SELECT "); insert.append("SELECT ");
insert.append(AD_PInstance_ID); insert.append(AD_PInstance_ID);
insert.append(", "); 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(", "); insert.append(", ");
String viewIDValue = saveKey.getName(); String viewIDValue = saveKey.getName();
@ -2443,8 +2471,8 @@ public final class DB
if (counter >= 1000) if (counter >= 1000)
{ {
DB.executeUpdateEx(insert.toString(), trxName); DB.executeUpdateEx(insert.toString(), trxName);
insert = new StringBuilder(); insert.delete(0, insert.length());
insert.append("INSERT INTO T_SELECTION(AD_PINSTANCE_ID, T_SELECTION_ID, ViewID) "); insert.append(initialInsert);
counter = 0; 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_QUANTITY;
import static org.compiere.model.SystemIDs.REFERENCE_DATATYPE_RADIOGROUP_LIST; 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_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_ROWID;
import static org.compiere.model.SystemIDs.REFERENCE_DATATYPE_SCHEDULER_STATE; import static org.compiere.model.SystemIDs.REFERENCE_DATATYPE_SCHEDULER_STATE;
import static org.compiere.model.SystemIDs.REFERENCE_DATATYPE_SEARCH; 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 RecordID = REFERENCE_DATATYPE_RECORD_ID;
public static final int RecordUU = REFERENCE_DATATYPE_RECORD_UU;
public static final int TimestampWithTimeZone = REFERENCE_DATATYPE_TIMESTAMP_WITH_TIMEZONE; public static final int TimestampWithTimeZone = REFERENCE_DATATYPE_TIMESTAMP_WITH_TIMEZONE;
@ -283,7 +285,7 @@ public final class DisplayType
public static boolean isUUID (int displayType) public static boolean isUUID (int displayType)
{ {
if (displayType == UUID || displayType == TableUU || displayType == TableDirUU if (displayType == UUID || displayType == TableUU || displayType == TableDirUU
|| displayType == SearchUU) || displayType == SearchUU || displayType == RecordUU)
return true; return true;
//not custom type, don't have to check factory //not custom type, don't have to check factory
@ -417,7 +419,7 @@ public final class DisplayType
|| displayType == ChosenMultipleSelectionTable || displayType == ChosenMultipleSelectionTable
|| displayType == ChosenMultipleSelectionSearch || displayType == ChosenMultipleSelectionSearch
|| displayType == TimeZoneId || displayType == TimeZoneId
|| displayType == UUID || displayType == UUID || displayType == RecordUU
|| displayType == TableDirUU || displayType == TableUU || displayType == SearchUU) || displayType == TableDirUU || displayType == TableUU || displayType == SearchUU)
return true; return true;
@ -1135,6 +1137,8 @@ public final class DisplayType
return "RadiogroupList"; return "RadiogroupList";
case RecordID: case RecordID:
return "RecordID"; return "RecordID";
case RecordUU:
return "RecordUUID";
case RowID: case RowID:
return "RowID"; return "RowID";
case SchedulerState: case SchedulerState:

View File

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

View File

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

View File

@ -113,10 +113,10 @@ public class InfoListSubModel implements ListSubModel<ValueNamePair> {
int rowCount = ip.getRowCount(); int rowCount = ip.getRowCount();
if (rowCount > 0) { if (rowCount > 0) {
List<String> added = new ArrayList<String>(); 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++) { for(int i = 0; i < rowCount; i++) {
Integer key = ip.getRowKeyAt(i); Object key = ip.getRowKeyAt(i);
if (key != null && key.intValue() > 0 && !keys.contains(key)) { if (key != null && (key instanceof Integer && ((Integer)key).intValue() > 0 || key instanceof String && key.toString().length() > 0) && !keys.contains(key)) {
keys.add(key); keys.add(key);
} }
if (nRows > 0 && keys.size() >= nRows) 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.ContextMenuListener;
import org.adempiere.webui.event.ValueChangeEvent; import org.adempiere.webui.event.ValueChangeEvent;
import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.theme.ThemeManager;
import org.adempiere.webui.window.Dialog;
import org.adempiere.webui.window.FindWindow; import org.adempiere.webui.window.FindWindow;
import org.adempiere.webui.window.WFieldRecordInfo; import org.adempiere.webui.window.WFieldRecordInfo;
import org.adempiere.webui.window.WRecordIDDialog; 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) : ""; String s = tableIDValue != null ? String.valueOf(tableIDValue) : "";
int tableID = s.length() > 0 ? Integer.parseInt(s) : 0; int tableID = s.length() > 0 ? Integer.parseInt(s) : 0;
s = recordIDValue != null ? String.valueOf(recordIDValue) : ""; MTable table = MTable.get(tableID);
int recordID = s.length() > 0 ? Integer.parseInt(s) : 0; if (table.isUUIDKeyTable()) {
if(tableID <= 0 || recordID < 0) String recordUU = recordIDValue != null ? recordIDValue.toString() : "";
return; if(tableID <= 0)
if (!MRole.getDefault().isTableAccess(tableID, false)) return;
throw new AdempiereException(Msg.getMsg(Env.getCtx(), "AccessTableNoView")); if (!MRole.getDefault().isTableAccess(tableID, false))
AEnv.zoom(tableID, recordID); 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())) if (GridField.PROPERTY.equals(evt.getPropertyName()))
{ {
int tableID = tableIDValue != null ? Integer.parseInt(String.valueOf(tableIDValue)) : 0; int tableID = tableIDValue != null ? Integer.parseInt(String.valueOf(tableIDValue)) : 0;
int recordID = Integer.parseInt(Objects.toString(evt.getNewValue(), "-1")); if (tableID > 0) {
if (tableID > 0 && recordID >= 0) MTable table = MTable.get(tableID);
{ if (table.isUUIDKeyTable()) {
MTable table = MTable.get(Env.getCtx(), tableID); String recordUU = Objects.toString(evt.getNewValue(), "");
table.getPO(recordID, null); // calls po.checkCrossTenant() method 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); setValue(evt.getNewValue(), false);
} }
@ -283,10 +301,17 @@ public class WRecordIDEditor extends WEditor implements ContextMenuListener, IZo
tableIDValue = tableIDGridField.getValue(); tableIDValue = tableIDGridField.getValue();
} }
if(value != null && tableIDValue != null) { if(value != null && tableIDValue != null) {
int recordID = Integer.parseInt(String.valueOf(value));
int tableID = Integer.parseInt(String.valueOf(tableIDValue)); int tableID = Integer.parseInt(String.valueOf(tableIDValue));
if(recordID >= 0 && tableID > 0) if (tableID > 0) {
recordTextBox.setValue(getIdentifier(tableID, recordID)); 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 != null && recordIDValue == null) || (value != null && recordIDValue == null)
|| !value.equals(recordIDValue) || (value != null && !value.equals(recordIDValue))
)) { )) {
// Record_ID // Record_ID
ValueChangeEvent changeEvent = new ValueChangeEvent(this, this.getColumnName(), recordIDValue, value); ValueChangeEvent changeEvent = new ValueChangeEvent(this, this.getColumnName(), recordIDValue, value);
@ -314,10 +339,14 @@ public class WRecordIDEditor extends WEditor implements ContextMenuListener, IZo
return ""; return "";
if((tableIDValue != null) && (recordIDValue != null)) { if((tableIDValue != null) && (recordIDValue != null)) {
int tableID; int tableID;
int recordID; Object recordID;
try { try {
tableID = Integer.parseInt(String.valueOf(tableIDValue)); 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) { } catch (NumberFormatException e) {
return recordIDValue.toString(); return recordIDValue.toString();
} }
@ -336,10 +365,14 @@ public class WRecordIDEditor extends WEditor implements ContextMenuListener, IZo
String key = gridTab.getWindowNo() + "|AD_Table_ID"; String key = gridTab.getWindowNo() + "|AD_Table_ID";
Object rowTableIdValue = gridRowCtx.get(key); Object rowTableIdValue = gridRowCtx.get(key);
int rowTableID; int rowTableID;
int rowRecordID; Object rowRecordID;
try { try {
rowTableID = Integer.parseInt(String.valueOf(rowTableIdValue)); 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) { } catch (NumberFormatException e) {
return value.toString(); return value.toString();
} }
@ -364,6 +397,15 @@ public class WRecordIDEditor extends WEditor implements ContextMenuListener, IZo
tableIDValue = Integer.parseInt(tableIdTxt); 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); new WRecordIDDialog(recordTextBox.getPage(), this, tableIDGridField);
} }
} }
@ -404,7 +446,7 @@ public class WRecordIDEditor extends WEditor implements ContextMenuListener, IZo
* @param recordID * @param recordID
* @return String * @return String
*/ */
public String getIdentifier(int tableID, int recordID) { public String getIdentifier(int tableID, Object recordID) {
MLookup lookup = getRecordsLookup(tableID); MLookup lookup = getRecordsLookup(tableID);
return lookup != null ? lookup.getDisplay(recordID) : ""; 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); if (log.isLoggable(Level.CONFIG)) log.config(getColumnName() + " - " + text);
int id = -1; Object id = null;
if (m_tableName == null) // sets table name & key column if (m_tableName == null) // sets table name & key column
setTableAndKeyColumn(); 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()); final InfoPanel ip = InfoManager.create(lookup, gridField, m_tableName, m_keyColumnName, getComponent().getText(), false, getWhereClause());
if (ip != null && ip.loadedOK() && ip.getRowCount() == 1) if (ip != null && ip.loadedOK() && ip.getRowCount() == 1)
{ {
Integer key = ip.getFirstRowKey(); if (ip.getFirstRowKey() instanceof Integer)
if (key != null && key.intValue() > 0)
{ {
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 // No (unique) result
if (id <= 0) if (id == null || (id instanceof Integer && ((Integer) id).intValue() <= 0))
{ {
//m_value = null; // force re-display //m_value = null; // force re-display
if (ip != null && ip.loadedOK()) if (ip != null && ip.loadedOK())
@ -492,7 +504,7 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
if (log.isLoggable(Level.FINE)) if (log.isLoggable(Level.FINE))
log.fine(getColumnName() + " - Unique ID=" + id); log.fine(getColumnName() + " - Unique ID=" + id);
actionCombo(Integer.valueOf(id)); // data binding actionCombo(id); // data binding
focusNext(); focusNext();
//safety check: if focus is going no where, focus back to self //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); editor = new WTimeZoneEditor(gridField, tableEditor);
} }
else if (displayType == DisplayType.RecordID) else if (displayType == DisplayType.RecordID || displayType == DisplayType.RecordUU)
{ {
editor = new WRecordIDEditor(gridField, tableEditor, editorConfiguration); 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.ColumnInfo;
import org.compiere.minigrid.EmbedWinInfo; import org.compiere.minigrid.EmbedWinInfo;
import org.compiere.minigrid.IDColumn; 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.AccessSqlParser.TableInfo;
import org.compiere.model.GridField; import org.compiere.model.GridField;
import org.compiere.model.GridFieldVO; 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 // F3P: Keep original values: when a row is unselected, restore original values
private boolean hasEditable = false; private boolean hasEditable = false;
private Map<Integer, List<Object>> cacheOriginalValues = new HashMap<>(); private Map<Object, List<Object>> cacheOriginalValues = new HashMap<>();
private Map<Integer, List<Object>> temporarySelectedData = new HashMap<>(); private Map<Object, List<Object>> temporarySelectedData = new HashMap<>();
private WInfoWindowListItemRenderer infoWindowListItemRenderer = null; private WInfoWindowListItemRenderer infoWindowListItemRenderer = null;
// F3P: export // F3P: export
@ -929,7 +931,10 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
: tableInfos[0].getTableName(); : tableInfos[0].getTableName();
String keySelectClause = keyTableAlias+"."+p_keyColumn; 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<>(); List<InfoColumnVO> gridDisplayedIC = new ArrayList<>();
gridDisplayedIC.add(null); // First column does not have any matching info column 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); gridDisplayedIC.add(infoColumn);
if (keyColumnOfView == infoColumn.getAD_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; isIDColumnKeyOfView = true;
indexKeyOfView = list.size() - 1; indexKeyOfView = list.size() - 1;
} }
@ -2708,6 +2713,11 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
IDColumn idc = (IDColumn)val; IDColumn idc = (IDColumn)val;
val = idc.getRecord_ID(); val = idc.getRecord_ID();
} }
else if(val instanceof UUIDColumn)
{
UUIDColumn idc = (UUIDColumn)val;
val = idc.getRecord_UU();
}
else if(val instanceof KeyNamePair) else if(val instanceof KeyNamePair)
{ {
KeyNamePair knp = (KeyNamePair)val; KeyNamePair knp = (KeyNamePair)val;
@ -2824,7 +2834,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
*/ */
protected void restoreOriginalValues(int rowIndex) 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 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) 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 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); 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()) if(idc.isSelected())
{ {
cacheOriginalValues(row); cacheOriginalValues(row);
@ -2916,7 +2926,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
for(int rowIndex:contentPanel.getSelectedIndices()) for(int rowIndex:contentPanel.getSelectedIndices())
{ {
Integer keyViewValue = getColumnValue(rowIndex); Object keyViewValue = getColumnValue(rowIndex);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<Object> row = (List<Object>)model.get(rowIndex); List<Object> row = (List<Object>)model.get(rowIndex);
@ -2924,7 +2934,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
temporarySelectedData.put(keyViewValue, clonedRow); 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()); ArrayList<Object> clonedRow = new ArrayList<>(entry.getValue());
temporarySelectedData.put(entry.getKey(), clonedRow); temporarySelectedData.put(entry.getKey(), clonedRow);
@ -2948,7 +2958,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
@Override @Override
public boolean onRestoreSelectedItemIndexInPage(Integer keyViewValue, int rowIndex, Object oRow) public boolean onRestoreSelectedItemIndexInPage(Object keyViewValue, int rowIndex, Object oRow)
{ {
if(hasEditable && temporarySelectedData != null) if(hasEditable && temporarySelectedData != null)
{ {
@ -2976,15 +2986,19 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
} }
// Restore isSelected status on IDColumn // Restore isSelected status on IDColumn
Object id = (IDColumn)row.get(0); Object id = row.get(0);
if(id instanceof IDColumn) if(id instanceof IDColumn)
{ {
IDColumn idc = (IDColumn)id; IDColumn idc = (IDColumn)id;
idc.setSelected(true); idc.setSelected(true);
} }
else if (id instanceof UUIDColumn)
{
UUIDColumn idc = (UUIDColumn)id;
idc.setSelected(true);
}
// Restore listners // Restore listeners
model.addTableModelListener(this); model.addTableModelListener(this);
} }

View File

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

View File

@ -396,7 +396,7 @@ public class InfoAssignmentPanel extends InfoPanel implements EventListener<Even
public void zoom() 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 MQuery zoomQuery = new MQuery(); // ColumnName might be changed in MTab.validateQuery
String column = getKeyColumn(); String column = getKeyColumn();

View File

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

View File

@ -18,6 +18,7 @@
package org.adempiere.webui.panel; package org.adempiere.webui.panel;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.io.Serializable;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -70,6 +71,7 @@ import org.adempiere.webui.util.ZKUpdateUtil;
import org.adempiere.webui.window.Dialog; import org.adempiere.webui.window.Dialog;
import org.compiere.minigrid.ColumnInfo; import org.compiere.minigrid.ColumnInfo;
import org.compiere.minigrid.IDColumn; import org.compiere.minigrid.IDColumn;
import org.compiere.minigrid.UUIDColumn;
import org.compiere.model.GridField; import org.compiere.model.GridField;
import org.compiere.model.InfoColumnVO; import org.compiere.model.InfoColumnVO;
import org.compiere.model.InfoRelatedVO; import org.compiere.model.InfoRelatedVO;
@ -90,6 +92,7 @@ import org.compiere.util.DisplayType;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.KeyNamePair; import org.compiere.util.KeyNamePair;
import org.compiere.util.Msg; import org.compiere.util.Msg;
import org.compiere.util.NamePair;
import org.compiere.util.Trx; import org.compiere.util.Trx;
import org.compiere.util.Util; import org.compiere.util.Util;
import org.compiere.util.ValueNamePair; import org.compiere.util.ValueNamePair;
@ -146,7 +149,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
// attribute key of info process // attribute key of info process
protected final static String ATT_INFO_PROCESS_KEY = "INFO_PROCESS"; protected final static String ATT_INFO_PROCESS_KEY = "INFO_PROCESS";
protected int pageSize; protected int pageSize;
public LinkedHashMap<KeyNamePair,LinkedHashMap<String, Object>> m_values = null; public LinkedHashMap<NamePair,LinkedHashMap<String, Object>> m_values = null;
protected InfoRelatedVO[] relatedInfoList; protected InfoRelatedVO[] relatedInfoList;
// for test disable load all record when num of record < 1000 // for test disable load all record when num of record < 1000
protected boolean isIgnoreCacheAll = true; protected boolean isIgnoreCacheAll = true;
@ -171,7 +174,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
/** /**
* store selected record info * store selected record info
* key of map is value of column play as keyView * 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, * zk6.x listview don't provide event when click to checkbox select all,
* so we can't manage selectedRecord time by time. * so we can't manage selectedRecord time by time.
* each time change page we will update this list with current * 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 * onclick. because don't direct use recordSelectedData, call
* {@link #getSelectedRowInfo()} * {@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) * 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 */ /** Cancel pressed - need to differentiate between OK - Cancel - Exit */
private boolean m_cancel = false; private boolean m_cancel = false;
/** Result IDs */ /** Result IDs */
private ArrayList<Integer> m_results = new ArrayList<Integer>(3); private ArrayList<Object> m_results = new ArrayList<Object>(3);
private ListModelTable model; private ListModelTable model;
/** Layout of Grid */ /** Layout of Grid */
@ -569,7 +572,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
/** /**
* save selected id and viewID * 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. * 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(); int selectedCount = recordSelectedData.size();
for (int rowIndex = 0; rowIndex < contentPanel.getModel().getRowCount(); rowIndex++){ for (int rowIndex = 0; rowIndex < contentPanel.getModel().getRowCount(); rowIndex++){
Integer keyCandidate = getColumnValue(rowIndex); Object keyCandidate = getColumnValue(rowIndex);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<Object> candidateRecord = (List<Object>)contentPanel.getModel().get(rowIndex); 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(); Class<?> c = p_layout[col].getColClass();
int colIndex = col + colOffset; int colIndex = col + colOffset;
if (c == IDColumn.class) if (c == IDColumn.class)
{
value = new IDColumn(rs.getInt(colIndex)); value = new IDColumn(rs.getInt(colIndex));
else if (c == UUIDColumn.class)
} value = new UUIDColumn(rs.getString(colIndex));
else if (c == Boolean.class) else if (c == Boolean.class)
value = Boolean.valueOf("Y".equals(rs.getString(colIndex))); value = Boolean.valueOf("Y".equals(rs.getString(colIndex)));
else if (c == Timestamp.class) else if (c == Timestamp.class)
@ -1513,7 +1515,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
} }
else // singleSelection else // singleSelection
{ {
Integer data = getSelectedRowKey(); Serializable data = getSelectedRowKey();
if (data != null) if (data != null)
m_results.add(data); m_results.add(data);
} }
@ -1529,9 +1531,9 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
* Get the key of currently selected row * Get the key of currently selected row
* @return selected key * @return selected key
*/ */
protected Integer getSelectedRowKey() protected <T extends Serializable> T getSelectedRowKey()
{ {
Integer key = contentPanel.getSelectedRowKey(); T key = contentPanel.getSelectedRowKey();
return key; return key;
} // getSelectedRowKey } // getSelectedRowKey
@ -1542,10 +1544,10 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
* @return IDs if selection present * @return IDs if selection present
* author ashley * author ashley
*/ */
protected ArrayList<Integer> getSelectedRowKeys() protected ArrayList<Object> getSelectedRowKeys()
{ {
ArrayList<Integer> selectedDataList = new ArrayList<Integer>(); ArrayList<Object> selectedDataList = new ArrayList<Object>();
Collection<Integer> lsKeyValueOfSelectedRow = getSelectedRowInfo().keySet(); Collection<Object> lsKeyValueOfSelectedRow = getSelectedRowInfo().keySet();
if (lsKeyValueOfSelectedRow.size() == 0) if (lsKeyValueOfSelectedRow.size() == 0)
{ {
return selectedDataList; return selectedDataList;
@ -1553,7 +1555,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
if (p_multipleSelection) if (p_multipleSelection)
{ {
for (Integer key : lsKeyValueOfSelectedRow){ for (Object key : lsKeyValueOfSelectedRow){
selectedDataList.add(key); selectedDataList.add(key);
} }
} }
@ -1566,7 +1568,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
* @deprecated use getSaveKeys * @deprecated use getSaveKeys
* @return selected keys (Integers) * @return selected keys (Integers)
*/ */
public Collection<Integer> getSelectedKeysCollection() public Collection<Object> getSelectedKeysCollection()
{ {
m_ok = true; m_ok = true;
saveSelection(); 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 * Save selected id, viewID of all process to map viewIDMap to save into T_Selection
* @param infoCulumnId * @param infoCulumnId
*/ */
public Collection<KeyNamePair> getSaveKeys (int infoCulumnId){ public Collection<NamePair> getSaveKeys (int infoCulumnId){
// clear result from prev time // clear result from prev time
m_viewIDMap.clear(); m_viewIDMap.clear();
if (p_multipleSelection) 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 // get key data column
Integer keyData = selectedInfo.getKey(); Object keyData = selectedInfo.getKey();
if (infoCulumnId > 0){ if (infoCulumnId > 0){
// have viewID, get it // have viewID, get it
@ -1598,11 +1600,16 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
// get row data from model // get row data from model
Object viewIDValue = selectedInfo.getValue().get(dataIndex); Object viewIDValue = selectedInfo.getValue().get(dataIndex);
if (keyData instanceof String)
m_viewIDMap.add (new KeyNamePair(keyData, viewIDValue == null?null:viewIDValue.toString())); 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{ }else{
// hasn't viewID, set viewID value is null // 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 (){ protected void updateListSelected (){
for (int rowIndex = 0; rowIndex < contentPanel.getModel().getRowCount(); rowIndex++){ for (int rowIndex = 0; rowIndex < contentPanel.getModel().getRowCount(); rowIndex++){
Integer keyCandidate = getColumnValue(rowIndex); Object keyCandidate = getColumnValue(rowIndex);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<Object> candidateRecord = (List<Object>)contentPanel.getModel().get(rowIndex); 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 if (recordSelectedData.containsKey(keyCandidate)){// unselected record
List<Object> recordSelected = recordSelectedData.get(keyCandidate); List<Object> recordSelected = recordSelectedData.get(keyCandidate);
IDColumn idcSel = null; IDColumn idcSel = null;
UUIDColumn uucSel = null;
if (recordSelected.get(0) instanceof IDColumn) { if (recordSelected.get(0) instanceof IDColumn) {
idcSel = (IDColumn) recordSelected.get(0); idcSel = (IDColumn) recordSelected.get(0);
} else if (recordSelected.get(0) instanceof UUIDColumn) {
uucSel = (UUIDColumn) recordSelected.get(0);
} }
IDColumn idcCan = null; IDColumn idcCan = null;
UUIDColumn uucCan = null;
if (candidateRecord.get(0) instanceof IDColumn) { if (candidateRecord.get(0) instanceof IDColumn) {
idcCan = (IDColumn) candidateRecord.get(0); 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())) { if ( (idcSel != null && idcCan != null && idcSel.getRecord_ID().equals(idcCan.getRecord_ID()))
recordSelected.set(0, candidateRecord.get(0)); // set same IDColumn for comparison || (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)) { if (recordSelected.equals(candidateRecord)) {
recordSelectedData.remove(keyCandidate); recordSelectedData.remove(keyCandidate);
@ -1712,7 +1726,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
Collection<Object> lsSelectionRecord = new ArrayList<Object>(); Collection<Object> lsSelectionRecord = new ArrayList<Object>();
for (int rowIndex = 0; rowIndex < contentPanel.getModel().getRowCount(); rowIndex++){ for (int rowIndex = 0; rowIndex < contentPanel.getModel().getRowCount(); rowIndex++){
Integer keyViewValue = getColumnValue(rowIndex); Object keyViewValue = getColumnValue(rowIndex);
if (recordSelectedData.containsKey(keyViewValue)){ 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 // 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 // because record can change by other user
@ -1733,7 +1747,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
* @param row row * @param row row
* @return false to skip restore selection * @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; return true;
} }
@ -1744,15 +1758,15 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
return new AdempiereException(errorMessage); return new AdempiereException(errorMessage);
} }
/** /**
* get keyView value at rowIndex and clumnIndex * get keyView value at rowIndex and columnIndex
* also check in case value is null will rise a exception * also check in case value is null will raise an exception
* @param rowIndex * @param rowIndex
* @return * @return
*/ */
protected Integer getColumnValue (int rowIndex){ protected Object getColumnValue (int rowIndex){
int keyIndex = getIndexKeyColumnOfView(); int keyIndex = getIndexKeyColumnOfView();
Integer keyValue = null; Object keyValue = null;
// get row data from model // get row data from model
Object keyColumValue = contentPanel.getModel().getDataAt(rowIndex, keyIndex); Object keyColumValue = contentPanel.getModel().getDataAt(rowIndex, keyIndex);
// throw exception when value is null // 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 // IDColumn is recreate after change page, because use value of IDColumn
if (keyColumValue != null && keyColumValue instanceof IDColumn){ if (keyColumValue != null) {
keyColumValue = ((IDColumn)keyColumValue).getRecord_ID(); 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; keyValue = (Integer)keyColumValue;
}else { } else if (keyColumValue instanceof String) {
String msg = "keyView column must be integer"; keyValue = (String)keyColumValue;
} else {
String msg = "keyView column must be integer or string";
AdempiereException ex = new AdempiereException (msg); AdempiereException ex = new AdempiereException (msg);
log.severe(msg); log.severe(msg);
throw ex; 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 * update list column key value of selected record and return this list
* @return {@link #recordSelectedData} after update * @return {@link #recordSelectedData} after update
*/ */
public Map<Integer, List<Object>> getSelectedRowInfo (){ public Map<Object, List<Object>> getSelectedRowInfo (){
updateListSelected(); updateListSelected();
return recordSelectedData; return recordSelectedData;
} }
@ -1819,7 +1839,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
{ {
if (!m_ok || m_results.size() == 0) if (!m_ok || m_results.size() == 0)
return null; return null;
return m_results.toArray(new Integer[0]); return m_results.toArray(new Object[0]);
} // getSelectedKeys; } // getSelectedKeys;
/** /**
@ -2372,7 +2392,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
title = m_process.getValue(); title = m_process.getValue();
// store in T_Selection table selected rows for Execute Process that retrieves from T_Selection in code. // 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); ADForm form = ADForm.openForm(adFormID, null, m_pi);
Mode mode = form.getWindowMode(); 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())){ if (DialogEvents.ON_BEFORE_RUN_PROCESS.equals(event.getName())){
updateListSelected(); updateListSelected();
// store in T_Selection table selected rows for Execute Process that retrieves from T_Selection in code. // 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); null);
saveResultSelection(getInfoColumnIDFromProcess(processModalDialog.getAD_Process_ID())); saveResultSelection(getInfoColumnIDFromProcess(processModalDialog.getAD_Process_ID()));
createT_Selection_InfoWindow(pInstanceID); createT_Selection_InfoWindow(pInstanceID);
@ -2466,25 +2486,31 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
return; return;
} }
m_values = new LinkedHashMap<KeyNamePair,LinkedHashMap<String,Object>>(); m_values = new LinkedHashMap<NamePair,LinkedHashMap<String,Object>>();
if (p_multipleSelection) { if (p_multipleSelection) {
Map <Integer, List<Object>> selectedRow = getSelectedRowInfo(); Map <Object, List<Object>> selectedRow = getSelectedRowInfo();
// for selected rows // for selected rows
for (Entry<Integer, List<Object>> selectedInfo : selectedRow.entrySet()) for (Entry<Object, List<Object>> selectedInfo : selectedRow.entrySet())
{ {
// get key and viewID // get key and viewID
Integer keyData = selectedInfo.getKey(); Object keyData = selectedInfo.getKey();
KeyNamePair kp = null; NamePair kp = null;
if (infoColumnId > 0){ if (infoColumnId > 0){
int dataIndex = columnDataIndex.get(infoColumnId) + p_layout.length; int dataIndex = columnDataIndex.get(infoColumnId) + p_layout.length;
Object viewIDValue = selectedInfo.getValue().get(dataIndex); 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{ }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 // get Data
@ -2507,9 +2533,15 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
*/ */
public void createT_Selection_InfoWindow(int AD_PInstance_ID) public void createT_Selection_InfoWindow(int AD_PInstance_ID)
{ {
MTable table = MTable.get(Env.getCtx(), getTableName());
StringBuilder insert = new StringBuilder(); 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(?,?,?,?,?,?) "); insert.append("INSERT INTO T_Selection_InfoWindow (AD_PINSTANCE_ID, ");
for (Entry<KeyNamePair,LinkedHashMap<String, Object>> records : m_values.entrySet()) { 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 //set Record ID
LinkedHashMap<String, Object> fields = records.getValue(); LinkedHashMap<String, Object> fields = records.getValue();
@ -2525,6 +2557,11 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
KeyNamePair knp = (KeyNamePair)key; KeyNamePair knp = (KeyNamePair)key;
parameters.add(knp.getKey()); parameters.add(knp.getKey());
} }
else if(key instanceof ValueNamePair)
{
ValueNamePair vnp = (ValueNamePair)key;
parameters.add(vnp.getValue());
}
else else
{ {
parameters.add(key); parameters.add(key);
@ -2541,6 +2578,13 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
parameters.add(id.getRecord_ID()); parameters.add(id.getRecord_ID());
parameters.add(null); 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) else if (data instanceof String)
{ {
parameters.add(data); parameters.add(data);
@ -2726,7 +2770,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
*/ */
public void zoom() public void zoom()
{ {
Integer recordId = contentPanel.getSelectedRowKey(); Object recordId = contentPanel.getSelectedRowKey();
// prevent NPE when double click is raise but no recore is selected // prevent NPE when double click is raise but no recore is selected
if (recordId == null) if (recordId == null)
return; return;
@ -2742,13 +2786,17 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
int AD_Table_ID = MTable.getTable_ID(p_tableName); int AD_Table_ID = MTable.getTable_ID(p_tableName);
if (AD_Table_ID <= 0) 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)); AD_Table_ID = MTable.getTable_ID(p_keyColumn.substring(0, p_keyColumn.length() - 3));
} }
} }
if (AD_Table_ID > 0) if (AD_Table_ID > 0) {
AEnv.zoom(AD_Table_ID, recordId); 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() { private void addAllCurrentContentPanelToSelected() {
for (int rowIndex = 0; rowIndex < contentPanel.getModel().getRowCount(); rowIndex++){ for (int rowIndex = 0; rowIndex < contentPanel.getModel().getRowCount(); rowIndex++){
Integer keyCandidate = getColumnValue(rowIndex); Object keyCandidate = getColumnValue(rowIndex);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<Object> candidateRecord = (List<Object>)contentPanel.getModel().get(rowIndex); List<Object> candidateRecord = (List<Object>)contentPanel.getModel().get(rowIndex);
if (!recordSelectedData.containsKey(keyCandidate)) { if (!recordSelectedData.containsKey(keyCandidate)) {
@ -2975,7 +3023,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
* *
* @return first row key/id * @return first row key/id
*/ */
public Integer getFirstRowKey() { public Object getFirstRowKey() {
return contentPanel.getFirstRowKey(); return contentPanel.getFirstRowKey();
} }
@ -2984,7 +3032,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
* @param row * @param row
* @return row key/id * @return row key/id
*/ */
public Integer getRowKeyAt(int row) { public Object getRowKeyAt(int row) {
return contentPanel.getRowKeyAt(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.adempiere.webui.factory.ButtonFactory;
import org.compiere.model.GridField; import org.compiere.model.GridField;
import org.compiere.model.MLookup; import org.compiere.model.MLookup;
import org.compiere.model.MTable;
import org.compiere.model.PO;
import org.compiere.util.DisplayType; import org.compiere.util.DisplayType;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.Msg; 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 */ /** Current tab's AD_Table_ID GrodField */
private GridField tableIDGridField; private GridField tableIDGridField;
/** Current Record_ID value from {@link #editor} */ /** Current Record_ID value from {@link #editor} */
private Integer recordIDValue; private Object recordIDValue;
/** Current AD_Table_ID value from {@link #editor} */ /** Current AD_Table_ID value from {@link #editor} */
private Integer tableIDValue; private Integer tableIDValue;
@ -93,17 +95,8 @@ public class WRecordIDDialog extends Window implements EventListener<Event>, Val
*/ */
public WRecordIDDialog(Page page, WRecordIDEditor editor, GridField tableIDGridField) { public WRecordIDDialog(Page page, WRecordIDEditor editor, GridField tableIDGridField) {
super(); super();
this.editor = editor; 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) { if (editor.getAD_Table_ID() instanceof Integer) {
tableIDValue = (Integer) editor.getAD_Table_ID(); 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()); 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); init(page);
} }
@ -152,8 +159,13 @@ public class WRecordIDDialog extends Window implements EventListener<Event>, Val
if (editor.getGridField().getGridTab() != null) { if (editor.getGridField().getGridTab() != null) {
parentTextBox = new Textbox(); parentTextBox = new Textbox();
parentTextBox.setReadonly(true); parentTextBox.setReadonly(true);
parentTextBox.setValue(editor.getIdentifier( MTable table = MTable.get(tableID);
editor.getGridField().getGridTab().getAD_Table_ID(), editor.getGridField().getGridTab().getRecord_ID())); 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) if (recordsEditor != null)
@ -219,14 +231,21 @@ public class WRecordIDDialog extends Window implements EventListener<Event>, Val
@Override @Override
public void valueChange(ValueChangeEvent evt) { public void valueChange(ValueChangeEvent evt) {
if (evt.getSource().equals(tableIDEditor)) { 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 // the Record_ID should be cleared when a different AD_Table_ID is selected
if (recordsEditor != null) { if (recordsEditor != null) {
recordsEditor.setValue(null); recordsEditor.setValue(null);
recordsEditorLabel.detach(); recordsEditorLabel.detach();
recordsEditor.getComponent().detach(); recordsEditor.getComponent().detach();
} }
int tableID = Integer.parseInt(Objects.toString(evt.getNewValue(), "-1"));
MLookup recordsLookup = editor.getRecordsLookup(tableID); MLookup recordsLookup = editor.getRecordsLookup(tableID);
if(recordsLookup != null) { if(recordsLookup != null) {
recordsEditor = new WSearchEditor("Record_ID", false, false, true, recordsLookup); recordsEditor = new WSearchEditor("Record_ID", false, false, true, recordsLookup);

View File

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

View File

@ -22,7 +22,7 @@ package org.compiere.minigrid;
* @author Jorg Janke * @author Jorg Janke
* @version $Id: IDColumn.java,v 1.2 2006/07/30 00:51:28 jjanke Exp $ * @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 * ID Column constructor

View File

@ -26,6 +26,7 @@
**********************************************************************/ **********************************************************************/
package org.compiere.minigrid; package org.compiere.minigrid;
import java.io.Serializable;
import java.sql.ResultSet; import java.sql.ResultSet;
import org.compiere.model.PO; import org.compiere.model.PO;
@ -125,7 +126,7 @@ public interface IMiniTable
* *
* @return row key * @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