hg merge release-7.1 (merge release7.1 into default)

This commit is contained in:
Carlos Ruiz 2019-12-04 23:11:53 +01:00
commit f75174998c
14 changed files with 124 additions and 27 deletions

View File

@ -0,0 +1,15 @@
SET SQLBLANKLINES ON
SET DEFINE OFF
-- IDEMPIERE-4087 Copy the link to this issue virtual search columns
-- Dec 4, 2019, 8:01:25 PM CET
UPDATE AD_Field SET Help='You can define virtual columns (not stored in the database). If defined, the Column name is the synonym of the SQL expression defined here. The SQL expression must be valid.<br>
Example: "Updated-Created" would list the age of the entry in days.<br>
It is not recommended to add complex queries in virtual columns as the impact on the database performance can be too expensive.<br>
However, you can use the prefix @SQLFIND= for virtual columns that can be used for queries and reports, they have less impact on the database, but as a field they don''t show values.<br>
Additionally, the prefix @SQL= allows to define a virtual UI column, this is calculated on the fly and can use context variables in the query, virtual UI columns are shown in grid just on the current row, they are not searchable, and not shown in reports.', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2019-12-04 20:46:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=11264
;
SELECT register_migration_script('201912042002_IDEMPIERE-4087.sql') FROM dual
;

View File

@ -0,0 +1,12 @@
-- IDEMPIERE-4087 Copy the link to this issue virtual search columns
-- Dec 4, 2019, 8:01:25 PM CET
UPDATE AD_Field SET Help='You can define virtual columns (not stored in the database). If defined, the Column name is the synonym of the SQL expression defined here. The SQL expression must be valid.<br>
Example: "Updated-Created" would list the age of the entry in days.<br>
It is not recommended to add complex queries in virtual columns as the impact on the database performance can be too expensive.<br>
However, you can use the prefix @SQLFIND= for virtual columns that can be used for queries and reports, they have less impact on the database, but as a field they don''t show values.<br>
Additionally, the prefix @SQL= allows to define a virtual UI column, this is calculated on the fly and can use context variables in the query, virtual UI columns are shown in grid just on the current row, they are not searchable, and not shown in reports.', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2019-12-04 20:46:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=11264
;
SELECT register_migration_script('201912042002_IDEMPIERE-4087.sql') FROM dual
;

View File

@ -83,7 +83,7 @@ public class GridField
/**
*
*/
private static final long serialVersionUID = -5923967271000455417L;
private static final long serialVersionUID = 496387784464611123L;
/**
* Field Constructor.
@ -1323,7 +1323,7 @@ public class GridField
if (m_vo.ColumnSQL != null && m_vo.ColumnSQL.length() > 0)
{
String query;
if (m_vo.ColumnSQL.startsWith("@SQL="))
if (m_vo.ColumnSQL.startsWith("@SQL=") || m_vo.ColumnSQL.startsWith("@SQLFIND="))
query = "NULL";
else
query = m_vo.ColumnSQL;
@ -1334,6 +1334,26 @@ public class GridField
}
return m_vo.ColumnName;
} // getColumnSQL
/**
* Get Column Name or SQL for search queries
* @return column name
*/
public String getSearchColumnSQL()
{
if (m_vo.ColumnSQL != null && m_vo.ColumnSQL.length() > 0)
{
String query;
if (m_vo.ColumnSQL.startsWith("@SQL="))
query = "NULL";
else if (m_vo.ColumnSQL.startsWith("@SQLFIND="))
query = m_vo.ColumnSQL.substring(9);
else
query = m_vo.ColumnSQL;
return query;
}
return m_vo.ColumnName;
} // getSearchColumnSQL
/**
* Is Virtual Column
@ -1362,6 +1382,15 @@ public class GridField
return (m_vo.ColumnSQL != null && m_vo.ColumnSQL.length() > 0 && m_vo.ColumnSQL.startsWith("@SQL="));
} // isVirtualUIColumn
/**
* Is Virtual search Column
* @return column is virtual search
*/
public boolean isVirtualSearchColumn()
{
return (m_vo.ColumnSQL != null && m_vo.ColumnSQL.length() > 0 && m_vo.ColumnSQL.startsWith("@SQLFIND="));
} // isVirtualDBColumn
/**
* Get Header
* @return header

View File

@ -202,7 +202,7 @@ public class GridFieldVO implements Serializable
vo.ValidationCode = rs.getString(i);
else if (columnName.equalsIgnoreCase("ColumnSQL")) {
vo.ColumnSQL = rs.getString(i);
if (vo.ColumnSQL != null && !vo.ColumnSQL.startsWith("@SQL=") && vo.ColumnSQL.contains("@")) {
if (vo.ColumnSQL != null && !vo.ColumnSQL.startsWith("@SQL=") && !vo.ColumnSQL.startsWith("@SQLFIND=") && vo.ColumnSQL.contains("@")) {
// NOTE: cannot use window context because this is set globally on the query, not per record
vo.ColumnSQL = Env.parseContext(ctx, -1, vo.ColumnSQL, false, true);
}

View File

@ -67,7 +67,7 @@ public class LookupDisplayColumn implements Serializable
IsTranslated = isTranslated;
DisplayType = ad_Reference_ID;
AD_Reference_ID = ad_Reference_Value_ID;
if (columnSQL != null && columnSQL.length() > 0 && columnSQL.startsWith("@SQL="))
if (columnSQL != null && columnSQL.length() > 0 && (columnSQL.startsWith("@SQL=") || columnSQL.startsWith("@SQLFIND=")))
ColumnSQL = "NULL";
else
ColumnSQL = columnSQL;

View File

@ -52,7 +52,7 @@ public class MColumn extends X_AD_Column
/**
*
*/
private static final long serialVersionUID = 7215660422231054443L;
private static final long serialVersionUID = -6905852892037761285L;
public static MColumn get (Properties ctx, int AD_Column_ID)
{
@ -228,6 +228,16 @@ public class MColumn extends X_AD_Column
String s = getColumnSQL();
return s != null && s.length() > 0 && s.startsWith("@SQL=");
} // isVirtualUIColumn
/**
* Is Virtual Search Column
* @return true if virtual search column
*/
public boolean isVirtualSearchColumn()
{
String s = getColumnSQL();
return s != null && s.length() > 0 && s.startsWith("@SQLFIND=");
} // isVirtualSearchColumn
/**
* Is the Column Encrypted?
@ -362,7 +372,7 @@ public class MColumn extends X_AD_Column
setIsMandatory(false);
if (isUpdateable())
setIsUpdateable(false);
if (isVirtualUIColumn() && isIdentifier())
if ((isVirtualUIColumn() || isVirtualSearchColumn()) && isIdentifier())
setIsIdentifier(false);
}
// Updateable
@ -1240,10 +1250,18 @@ public class MColumn extends X_AD_Column
}
public String getColumnSQL(boolean nullForUI) {
return getColumnSQL(nullForUI, true);
}
public String getColumnSQL(boolean nullForUI, boolean nullForSearch) {
String query = getColumnSQL();
if (query != null && query.length() > 0) {
if (query.startsWith("@SQL=") && nullForUI)
query = "NULL";
else if (query.startsWith("@SQLFIND=") && nullForSearch)
query = "NULL";
else if (query.startsWith("@SQLFIND=") && !nullForSearch)
query = query.substring(9);
}
return query;
}

View File

@ -149,6 +149,13 @@ public class MField extends X_AD_Field
setAD_Val_Rule_ID(0);
setIsToolbarButton(null);
}
if (isDisplayed()) {
MColumn column = (MColumn) getAD_Column();
if (column.isVirtualSearchColumn()) {
setIsDisplayed(false);
setIsDisplayedGrid(false);
}
}
return true;
} // beforeSave

View File

@ -435,7 +435,7 @@ public class MLookupFactory
ZoomWindowPO = rs.getInt(9);
//AD_Table_ID = rs.getInt(10);
displayColumnSQL = rs.getString(11);
if (displayColumnSQL != null && displayColumnSQL.length() > 0 && displayColumnSQL.startsWith("@SQL="))
if (displayColumnSQL != null && displayColumnSQL.length() > 0 && (displayColumnSQL.startsWith("@SQL=") || displayColumnSQL.startsWith("@SQLFIND=")))
displayColumnSQL = "NULL";
if (displayColumnSQL != null && displayColumnSQL.contains("@") && displayColumnSQL.startsWith("@SQL="))
displayColumnSQL = Env.parseContext(Env.getCtx(), -1, displayColumnSQL, false, true);
@ -668,7 +668,7 @@ public class MLookupFactory
embedSQL.append(TableNameAlias).append(".Value||'-'||");
MColumn columnDisplay = new MColumn(Env.getCtx(), columnDisplay_ID, null);
if (columnDisplay.isVirtualUIColumn())
if (columnDisplay.isVirtualUIColumn() || columnDisplay.isVirtualSearchColumn())
{
s_log.warning("Virtual UI Column must not be used as display");
return null;

View File

@ -1183,7 +1183,7 @@ class Restriction implements Serializable
MTable table = MTable.get(Env.getCtx(), tableName);
if (table != null) {
for (MColumn col : table.getColumns(false)) {
String colSQL = col.getColumnSQL(true);
String colSQL = col.getColumnSQL(true, false);
if (colSQL != null && colSQL.contains("@"))
colSQL = Env.parseContext(Env.getCtx(), -1, colSQL, false, true);
if (colSQL != null && ColumnName.equals(colSQL.trim())) {

View File

@ -48,7 +48,7 @@ public class POInfo implements Serializable
/**
*
*/
private static final long serialVersionUID = 3496403499343293597L;
private static final long serialVersionUID = -6346988499971159874L;
/** Used by Remote FinReport */
/**
@ -199,7 +199,7 @@ public class POInfo implements Serializable
//
m_AccessLevel = rs.getString(18);
String ColumnSQL = rs.getString(19);
if (ColumnSQL != null && ColumnSQL.length() > 0 && ColumnSQL.startsWith("@SQL="))
if (ColumnSQL != null && ColumnSQL.length() > 0 && (ColumnSQL.startsWith("@SQL=") || ColumnSQL.startsWith("@SQLFIND=")))
ColumnSQL = "NULL";
if (ColumnSQL != null && ColumnSQL.contains("@"))
ColumnSQL = Env.parseContext(Env.getCtx(), -1, ColumnSQL, false, true);
@ -378,7 +378,7 @@ public class POInfo implements Serializable
if (index < 0 || index >= m_columns.length)
return null;
if (m_columns[index].ColumnSQL != null && m_columns[index].ColumnSQL.length() > 0) {
if (m_columns[index].ColumnSQL.startsWith("@SQL="))
if (m_columns[index].ColumnSQL.startsWith("@SQL=") || m_columns[index].ColumnSQL.startsWith("@SQLFIND="))
return "NULL AS " + m_columns[index].ColumnName;
return m_columns[index].ColumnSQL + " AS " + m_columns[index].ColumnName;
}
@ -425,6 +425,20 @@ public class POInfo implements Serializable
&& m_columns[index].ColumnSQL.length() > 0
&& m_columns[index].ColumnSQL.startsWith("@SQL=");
} // isVirtualUIColumn
/**
* Is Column Virtual Search?
* @param index index
* @return true if column is virtual search
*/
public boolean isVirtualSearchColumn (int index)
{
if (index < 0 || index >= m_columns.length)
return true;
return m_columns[index].ColumnSQL != null
&& m_columns[index].ColumnSQL.length() > 0
&& m_columns[index].ColumnSQL.startsWith("@SQLFIND=");
} // isVirtualSearchColumn
/**
* Get Column Label

View File

@ -310,6 +310,8 @@ public class DataEngine
int AD_Column_ID = rs.getInt(1);
String ColumnName = rs.getString(2);
String ColumnSQL = rs.getString(24);
if (ColumnSQL != null && ColumnSQL.length() > 0 && ColumnSQL.startsWith("@SQLFIND="))
ColumnSQL = ColumnSQL.substring(9);
if (ColumnSQL != null && ColumnSQL.length() > 0 && ColumnSQL.startsWith("@SQL="))
ColumnSQL = "NULL";
if (ColumnSQL != null && ColumnSQL.contains("@"))

View File

@ -72,7 +72,7 @@ public class FactReconciliation extends SvrProcess
pstmt.setTimestamp(3, p_DateAcct_From);
pstmt.setTimestamp(4, p_DateAcct_To);
int count = pstmt.executeUpdate();
String result = Msg.getMsg(getCtx(),"@Created@") + ": " + count + ", ";
String result = Msg.getMsg(getCtx(),"Created") + ": " + count + ", ";
if (log.isLoggable(Level.FINE))log.log(Level.FINE, result);
@ -88,7 +88,7 @@ public class FactReconciliation extends SvrProcess
pstmt = DB.prepareStatement(sql, get_TrxName());
pstmt.setInt(1, getAD_PInstance_ID());
count = pstmt.executeUpdate();
result = Msg.getMsg(getCtx(), "@Deleted@") + ": " + count;
result = Msg.getMsg(getCtx(), "Deleted") + ": " + count;
if (log.isLoggable(Level.FINE))log.log(Level.FINE, result);

View File

@ -286,7 +286,7 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
}
}
private void actionRefresh(Object value)
protected void actionRefresh(Object value)
{
// boolean mandatory = isMandatory();
// AEnv.actionRefresh(lookup, value, mandatory);
@ -345,7 +345,7 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
//
}
private void actionText(String text)
protected void actionText(String text)
{
// Nothing entered
if (text == null || text.length() == 0 || text.equals("%"))
@ -411,7 +411,7 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
} // actionText
private void resetButtonState() {
protected void resetButtonState() {
getComponent().getButton().setEnabled(true);
if (ThemeManager.isUseFontIconForImage())
getComponent().getButton().setIconSclass(imageUrl);
@ -421,7 +421,7 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
}
private void actionCombo (Object value)
protected void actionCombo (Object value)
{
if (log.isLoggable(Level.FINE))
log.fine("Value=" + value);
@ -465,7 +465,7 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
* Action - Special Quick Entry Screen
* @param newRecord true if new record should be created
*/
private void actionQuickEntry (boolean newRecord)
protected void actionQuickEntry (boolean newRecord)
{
if(!getComponent().isEnabled())
return;
@ -538,7 +538,7 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
}
} // actionQuickEntry
private void actionButton(String queryValue)
protected void actionButton(String queryValue)
{
if (lookup == null)
return; // leave button disabled

View File

@ -768,7 +768,7 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
if (mField.isSelectionColumn()) {
gridFieldList.add(mField); // isSelectionColumn
} else {
if (isDisplayed && mField.getDisplayType() != DisplayType.Button && !mField.getColumnName().equals("AD_Client_ID"))
if ((isDisplayed || mField.isVirtualSearchColumn()) && mField.getDisplayType() != DisplayType.Button && !mField.getColumnName().equals("AD_Client_ID"))
moreFieldList.add(mField);
}
} // for all target tab fields
@ -1633,7 +1633,7 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
if (field == null || field.isVirtualUIColumn())
continue;
boolean isProductCategoryField = isProductCategoryField(field.getColumnName());
String ColumnSQL = field.getColumnSQL(false);
String ColumnSQL = field.getSearchColumnSQL();
// Left brackets
Listbox listLeftBracket = (Listbox)row.getFellow("listLeftBracket"+row.getId());
String lBrackets = listLeftBracket.getSelectedItem().getValue().toString();
@ -1866,7 +1866,7 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
GridField field = getTargetMField(ColumnName);
if (field.isVirtualUIColumn())
continue;
StringBuilder ColumnSQL = new StringBuilder(field.getColumnSQL(false));
StringBuilder ColumnSQL = new StringBuilder(field.getSearchColumnSQL());
m_query.addRangeRestriction(ColumnSQL.toString(), value, valueTo,
ColumnName, wed.getDisplay(), wedTo.getDisplay(), true, 0);
appendCode(code, ColumnName, MQuery.BETWEEN, value.toString(), valueTo.toString(), "AND", "", "");
@ -1881,7 +1881,7 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
GridField field = getTargetMField(ColumnName);
boolean isProductCategoryField = isProductCategoryField(field.getColumnName());
StringBuilder ColumnSQL = new StringBuilder(field.getColumnSQL(false));
StringBuilder ColumnSQL = new StringBuilder(field.getSearchColumnSQL());
// add encryption here if the field is encrypted.
if (field.isEncrypted()) {
@ -1947,7 +1947,7 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
}
GridField field = getTargetMField(ColumnName);
StringBuilder ColumnSQL = new StringBuilder(field.getColumnSQL(false));
StringBuilder ColumnSQL = new StringBuilder(field.getSearchColumnSQL());
//
m_query.addRestriction(ColumnSQL.toString(), MQuery.LESS_EQUAL, valueTo, ColumnName, wed.getDisplay());
appendCode(code, ColumnName, MQuery.LESS_EQUAL, valueTo.toString(), "", "AND", "", "");
@ -2379,7 +2379,7 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
private String getSubCategoryWhereClause(GridField field, int productCategoryId) {
//if a node with this id is found later in the search we have a loop in the tree
int subTreeRootParentId = 0;
StringBuilder retString = new StringBuilder(field.getColumnSQL(false)).append(" IN (");
StringBuilder retString = new StringBuilder(field.getSearchColumnSQL()).append(" IN (");
String sql = "SELECT M_Product_Category_ID, M_Product_Category_Parent_ID FROM M_Product_Category WHERE AD_Client_ID=? AND IsActive='Y'";
final Vector<SimpleTreeNode> categories = new Vector<SimpleTreeNode>(100);
PreparedStatement pstmt = null;
@ -2709,4 +2709,4 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
} // setDtatusDB
/** END DEVCOFFEE **/
} // FindPanel
} // FindPanel