hg merge release-7.1 (merge release7.1 into default)
This commit is contained in:
commit
f75174998c
|
@ -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
|
||||
;
|
||||
|
|
@ -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
|
||||
;
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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())) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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("@"))
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue