IDEMPIERE-5567 Support of UUID as Key (FHCA-4195) + IDEMPIERE-6143 (#2367)

- fix export and import for UUID based tables
- fix ExportAction creating temporary files with the wrong extension
- fix export and import of multi-selection fields IDEMPIERE-6143
This commit is contained in:
Carlos Ruiz 2024-05-18 04:22:03 +02:00
parent a3fb6f5b9c
commit 2aa7215e2c
3 changed files with 55 additions and 49 deletions

View File

@ -106,6 +106,8 @@ public class GridTabCSVExporter implements IGridTabExporter
specialHDispayType = DisplayType.Location; specialHDispayType = DisplayType.Location;
continue; continue;
} else if (! (field.isDisplayed() || field.isDisplayedGrid())) { } else if (! (field.isDisplayed() || field.isDisplayedGrid())) {
continue;
} else if (DisplayType.Binary == field.getDisplayType()) {
continue; continue;
} }
String headName = resolveColumnName(table, column); String headName = resolveColumnName(table, column);
@ -438,15 +440,16 @@ public class GridTabCSVExporter implements IGridTabExporter
String ref = (String) idO; String ref = (String) idO;
value = MRefList.getListName(Env.getCtx(), column.getAD_Reference_Value_ID(), ref); value = MRefList.getListName(Env.getCtx(), column.getAD_Reference_Value_ID(), ref);
} else { } else {
int id = (Integer) idO; MTable forTab = MTable.get(Env.getCtx(), foreignTable);
String foreignKeyCol = forTab.getKeyColumns()[0];
int start = headName.indexOf("[")+1; int start = headName.indexOf("[")+1;
int end = headName.length()-1; int end = headName.length()-1;
String foreignColumn = headName.substring(start, end); String foreignColumn = headName.substring(start, end);
StringBuilder select = new StringBuilder("SELECT ") StringBuilder select = new StringBuilder("SELECT ")
.append(foreignColumn).append(" FROM ") .append(foreignColumn).append(" FROM ")
.append(foreignTable).append(" WHERE ") .append(foreignTable).append(" WHERE ")
.append(foreignTable).append("_ID=?"); .append(foreignKeyCol).append("=?");
value = DB.getSQLValueStringEx(null, select.toString(), id); value = DB.getSQLValueStringEx(null, select.toString(), idO);
} }
} }
} else { } else {
@ -478,7 +481,7 @@ public class GridTabCSVExporter implements IGridTabExporter
*/ */
private String resolveColumnName(MTable table, MColumn column) { private String resolveColumnName(MTable table, MColumn column) {
StringBuilder name = new StringBuilder(column.getColumnName()); StringBuilder name = new StringBuilder(column.getColumnName());
if (DisplayType.isLookup(column.getAD_Reference_ID())) { if (DisplayType.isLookup(column.getAD_Reference_ID()) && !DisplayType.isMultiID(column.getAD_Reference_ID())) {
// resolve to identifier - search for value first, if not search for name - if not use the ID // resolve to identifier - search for value first, if not search for name - if not use the ID
String foreignTable = column.getReferenceTableName(); String foreignTable = column.getReferenceTableName();
if ("AD_EntityType".equals(foreignTable) && I_AD_EntityType.COLUMNNAME_AD_EntityType_ID.equals(column.getColumnName())){ if ("AD_EntityType".equals(foreignTable) && I_AD_EntityType.COLUMNNAME_AD_EntityType_ID.equals(column.getColumnName())){
@ -579,7 +582,8 @@ public class GridTabCSVExporter implements IGridTabExporter
|| gridField.isEncryptedColumn() || gridField.isEncryptedColumn()
|| !(gridField.isDisplayed() || gridField.isDisplayedGrid()) || !(gridField.isDisplayed() || gridField.isDisplayedGrid())
|| gridField.isReadOnly() || gridField.isReadOnly()
|| (DisplayType.Button == MColumn.get(Env.getCtx(),gridField.getAD_Column_ID()).getAD_Reference_ID()) || DisplayType.Button == gridField.getDisplayType()
|| DisplayType.Binary == gridField.getDisplayType()
) )
continue; continue;
@ -598,7 +602,8 @@ public class GridTabCSVExporter implements IGridTabExporter
{ {
if ("AD_Client_ID".equals(field.getColumnName())) if ("AD_Client_ID".equals(field.getColumnName()))
continue; continue;
if (DisplayType.Button == MColumn.get(Env.getCtx(),field.getAD_Column_ID()).getAD_Reference_ID()) if ( DisplayType.Button == field.getDisplayType()
|| DisplayType.Binary == field.getDisplayType())
continue; continue;
if ( field.isVirtualColumn() if ( field.isVirtualColumn()
|| field.isEncrypted() || field.isEncrypted()

View File

@ -1022,17 +1022,16 @@ public class GridTabCSVImporter implements IGridTabImporter
if (isForeing && value != null && !"(null)".equals(value)){ if (isForeing && value != null && !"(null)".equals(value)){
String foreignTable = column.getReferenceTableName(); String foreignTable = column.getReferenceTableName();
String idS = null; Object idS = null;
int id = -1;
if("AD_Ref_List".equals(foreignTable)) if("AD_Ref_List".equals(foreignTable))
idS= resolveForeignList(column,foreignColumn,value,null); idS = resolveForeignList(column,foreignColumn,value,null);
else else
id = resolveForeign(foreignTable,foreignColumn,value,field,null); idS = resolveForeign(foreignTable,foreignColumn,value,field,null);
if(idS == null && id < 0){ if(idS == null){
//it could be that record still doesn't exist if import mode is inserting or merging //it could be that record still doesn't exist if import mode is inserting or merging
if(isUpdateMode()) if(isUpdateMode())
return new StringBuilder(Msg.getMsg(Env.getCtx(),id==-2?"ForeignMultipleResolved":"ForeignNotResolved",new Object[]{header.get(i),value})); return new StringBuilder(Msg.getMsg(Env.getCtx(),(idS instanceof Integer && (int)idS==-2)?"ForeignMultipleResolved":"ForeignNotResolved",new Object[]{header.get(i),value}));
} }
} else { } else {
// TODO: we could validate length of string or min/max // TODO: we could validate length of string or min/max
@ -1095,9 +1094,9 @@ public class GridTabCSVImporter implements IGridTabImporter
if(isForeing && !"(null)".equals(value)){ if(isForeing && !"(null)".equals(value)){
String foreignTable = columnName.substring(0,columnName.length()-3); String foreignTable = columnName.substring(0,columnName.length()-3);
int id = resolveForeign(foreignTable,foreignColumn,value,field,null); Object id = resolveForeign(foreignTable,foreignColumn,value,field,null);
if (id < 0) if (id == null || (id instanceof Integer && (int)id < 0))
return new StringBuilder(Msg.getMsg(Env.getCtx(), id==-2?"ForeignMultipleResolved":"ForeignNotResolved" ,new Object[]{header.get(j),value})); return new StringBuilder(Msg.getMsg(Env.getCtx(),(id instanceof Integer && (int)id==-2)?"ForeignMultipleResolved":"ForeignNotResolved" ,new Object[]{header.get(j),value}));
} }
isEmptyRow=false; isEmptyRow=false;
} }
@ -1205,19 +1204,18 @@ public class GridTabCSVImporter implements IGridTabImporter
}else if (masterRecord==null && isDetail){ }else if (masterRecord==null && isDetail){
MColumn column = MColumn.get(Env.getCtx(),field.getAD_Column_ID()); MColumn column = MColumn.get(Env.getCtx(),field.getAD_Column_ID());
String foreignTable = column.getReferenceTableName(); String foreignTable = column.getReferenceTableName();
String idS = null; Object idS = null;
int id = -1;
if ("AD_Ref_List".equals(foreignTable)) if ("AD_Ref_List".equals(foreignTable))
idS= resolveForeignList(column, foreignColumn, value,trx); idS = resolveForeignList(column, foreignColumn, value,trx);
else else
id = resolveForeign(foreignTable,foreignColumn,value, field, trx); idS = resolveForeign(foreignTable,foreignColumn,value, field, trx);
if(idS == null && id < 0) if (idS == null || (idS instanceof Integer && (int)idS < 0))
return Msg.getMsg(Env.getCtx(),id==-2?"ForeignMultipleResolved":"ForeignNotResolved",new Object[]{header.get(i),value}); return Msg.getMsg(Env.getCtx(),(idS instanceof Integer && (int)idS==-2)?"ForeignMultipleResolved":"ForeignNotResolved",new Object[]{header.get(i),value});
if(id >= 0) if (idS instanceof Integer && (int)idS >= 0)
logMsg = gridTab.setValue(field,id); logMsg = gridTab.setValue(field,idS);
else if (idS != null) else if (idS != null)
logMsg = gridTab.setValue(field,idS); logMsg = gridTab.setValue(field,idS);
@ -1251,14 +1249,14 @@ public class GridTabCSVImporter implements IGridTabImporter
isThereRow =true; isThereRow =true;
} else { } else {
int id = resolveForeign(foreignTable, foreignColumn, value,field,trx); Object id = resolveForeign(foreignTable, foreignColumn, value,field,trx);
if(id < 0) if (id == null || (id instanceof Integer && (int)id < 0))
return Msg.getMsg(Env.getCtx(),id==-2?"ForeignMultipleResolved":"ForeignNotResolved",new Object[]{header.get(i),value}); return Msg.getMsg(Env.getCtx(),(id instanceof Integer && (int)id==-2)?"ForeignMultipleResolved":"ForeignNotResolved",new Object[]{header.get(i),value});
setValue = id; setValue = id;
if (field.isParentValue()) { if (field.isParentValue()) {
int actualId = (Integer) field.getValue(); Object actualId = field.getValue();
if (actualId != id) { if (actualId != null && ! actualId.equals(id)) {
logMsg = Msg.getMsg(Env.getCtx(), "ParentCannotChange",new Object[]{header.get(i)}); logMsg = Msg.getMsg(Env.getCtx(), "ParentCannotChange",new Object[]{header.get(i)});
break; break;
} }
@ -1380,9 +1378,9 @@ public class GridTabCSVImporter implements IGridTabImporter
setValue = idS; setValue = idS;
} else { } else {
int id = resolveForeign(foreignTable, foreignColumn, setValue, field, trx); Object id = resolveForeign(foreignTable, foreignColumn, setValue, field, trx);
if (id < 0) if (id == null || (id instanceof Integer && (int)id < 0))
return Msg.getMsg(Env.getCtx(),id==-2?"ForeignMultipleResolved":"ForeignNotResolved",new Object[]{columnName,setValue}); return Msg.getMsg(Env.getCtx(),(id instanceof Integer && (int)id==-2)?"ForeignMultipleResolved":"ForeignNotResolved",new Object[]{columnName,setValue});
setValue = id; setValue = id;
} }
@ -1478,7 +1476,7 @@ public class GridTabCSVImporter implements IGridTabImporter
String idS = resolveForeignList(column, foreignColumn, tmpValue,trx); String idS = resolveForeignList(column, foreignColumn, tmpValue,trx);
setValue = idS; setValue = idS;
}else { }else {
int id = resolveForeign(foreignTable, foreignColumn, tmpValue,field,trx); Object id = resolveForeign(foreignTable, foreignColumn, tmpValue,field,trx);
setValue = id; setValue = id;
} }
}else{ }else{
@ -1519,8 +1517,7 @@ public class GridTabCSVImporter implements IGridTabImporter
String idS = resolveForeignList(column,foreignColumn,value,trx); String idS = resolveForeignList(column,foreignColumn,value,trx);
value = idS; value = idS;
}else { }else {
int id = resolveForeign(foreignTable,foreignColumn,value,field,trx); value = resolveForeign(foreignTable,foreignColumn,value,field,trx);
value = id;
} }
} }
}else{ //mandatory key not found }else{ //mandatory key not found
@ -1587,7 +1584,7 @@ public class GridTabCSVImporter implements IGridTabImporter
* @param trx * @param trx
* @return -3 for not found, -2 for more than 1 match and > 0 for foreign id * @return -3 for not found, -2 for more than 1 match and > 0 for foreign id
*/ */
private int resolveForeign(String foreignTable, String foreignColumn, Object value, GridField field, Trx trx) { private Object resolveForeign(String foreignTable, String foreignColumn, Object value, GridField field, Trx trx) {
boolean systemAccess = false; boolean systemAccess = false;
if (!"AD_Client".equals(foreignTable)) { if (!"AD_Client".equals(foreignTable)) {
MTable ft = MTable.get(Env.getCtx(), foreignTable); MTable ft = MTable.get(Env.getCtx(), foreignTable);
@ -1632,10 +1629,14 @@ public class GridTabCSVImporter implements IGridTabImporter
} }
} }
StringBuilder selectCount = new StringBuilder("SELECT COUNT(*)").append(postSelect); StringBuilder selectCount = new StringBuilder("SELECT COUNT(*)").append(postSelect);
StringBuilder selectId = new StringBuilder("SELECT ").append(foreignTable).append("_ID").append(postSelect); MTable forTab = MTable.get(Env.getCtx(), foreignTable);
StringBuilder selectId = new StringBuilder("SELECT ").append(forTab.getKeyColumns()[0]).append(postSelect);
int count = DB.getSQLValueEx(trxName, selectCount.toString(), value, thisClientId); int count = DB.getSQLValueEx(trxName, selectCount.toString(), value, thisClientId);
if (count == 1) { // single value found, OK if (count == 1) { // single value found, OK
return DB.getSQLValueEx(trxName, selectId.toString(), value, thisClientId); if (forTab.isUUIDKeyTable())
return DB.getSQLValueStringEx(trxName, selectId.toString(), value, thisClientId);
else
return DB.getSQLValueEx(trxName, selectId.toString(), value, thisClientId);
} else if (count > 1) { // multiple values found, error ForeignMultipleResolved } else if (count > 1) { // multiple values found, error ForeignMultipleResolved
return -2; return -2;
} else if (count == 0) { // no values found, error ForeignNotResolved } else if (count == 0) { // no values found, error ForeignNotResolved
@ -1643,7 +1644,10 @@ public class GridTabCSVImporter implements IGridTabImporter
// not found in client, try with System // not found in client, try with System
count = DB.getSQLValueEx(trxName, selectCount.toString(), value, 0 /* System */); count = DB.getSQLValueEx(trxName, selectCount.toString(), value, 0 /* System */);
if (count == 1) { // single value found, OK if (count == 1) { // single value found, OK
return DB.getSQLValueEx(trxName, selectId.toString(), value, 0 /* System */); if (forTab.isUUIDKeyTable())
return DB.getSQLValueStringEx(trxName, selectId.toString(), value, 0 /* System */);
else
return DB.getSQLValueEx(trxName, selectId.toString(), value, 0 /* System */);
} else if (count > 1) { // multiple values found, error ForeignMultipleResolved } else if (count > 1) { // multiple values found, error ForeignMultipleResolved
return -2; return -2;
} }

View File

@ -15,12 +15,12 @@ package org.adempiere.webui.panel.action;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.TreeMap;
import org.adempiere.base.IGridTabExporter; import org.adempiere.base.IGridTabExporter;
import org.adempiere.base.equinox.EquinoxExtensionLocator; import org.adempiere.base.equinox.EquinoxExtensionLocator;
@ -99,8 +99,8 @@ public class ExportAction implements EventListener<Event>
*/ */
public void export() public void export()
{ {
exporterMap = new HashMap<String, IGridTabExporter>(); exporterMap = new TreeMap<String, IGridTabExporter>();
extensionMap = new HashMap<String, String>(); extensionMap = new TreeMap<String, String>();
List<IGridTabExporter> exporterList = EquinoxExtensionLocator.instance().list(IGridTabExporter.class).getExtensions(); List<IGridTabExporter> exporterList = EquinoxExtensionLocator.instance().list(IGridTabExporter.class).getExtensions();
MRole role = MRole.getDefault(); MRole role = MRole.getDefault();
for(IGridTabExporter exporter : exporterList) for(IGridTabExporter exporter : exporterList)
@ -130,11 +130,8 @@ public class ExportAction implements EventListener<Event>
cboType.setMold("select"); cboType.setMold("select");
cboType.getItems().clear(); cboType.getItems().clear();
List<String> keys = new ArrayList<>(extensionMap.keySet()); for (Entry<String, String> extension : extensionMap.entrySet()) {
Collections.sort(keys); cboType.appendItem(extension.getKey(), extension.getValue());
for(String key : keys)
{
cboType.appendItem(key, key);
} }
cboType.setSelectedIndex(0); cboType.setSelectedIndex(0);
@ -352,12 +349,12 @@ public class ExportAction implements EventListener<Event>
*/ */
protected IGridTabExporter getExporter() { protected IGridTabExporter getExporter() {
ListItem li = cboType.getSelectedItem(); ListItem li = cboType.getSelectedItem();
if(li == null || li.getValue() == null) if(li == null || li.getLabel() == null)
{ {
return null; return null;
} }
String ext = li.getValue().toString(); String ext = li.getLabel().toString();
IGridTabExporter exporter = exporterMap.get(ext); IGridTabExporter exporter = exporterMap.get(ext);
return exporter; return exporter;
} }