IDEMPIERE-325 Complete AD based info window ( AD_InfoWindow ) implementation. Fixed support for order by and group by.

This commit is contained in:
Heng Sin Low 2013-01-05 08:56:56 +08:00
parent 23ac59efae
commit 5fa0eb06de
6 changed files with 254 additions and 42 deletions

View File

@ -0,0 +1,43 @@
-- Jan 5, 2013 12:28:29 AM MYT
-- IDEMPIERE-325 AD_InfoWindow
INSERT INTO AD_Column (SeqNoSelection,IsSyncDatabase,IsEncrypted,Version,AD_Table_ID,AD_Column_ID,EntityType,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,AD_Reference_ID,IsKey,AD_Element_ID,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsUpdateable,ColumnName,Description,Help,Name,IsAllowCopy,Updated,CreatedBy,AD_Org_ID,IsActive,Created,UpdatedBy,AD_Client_ID,IsToolbarButton,IsAlwaysUpdateable) VALUES (0,'N','N',1,895,208362,'D','N','N','N',0,'N',2000,'N',14,'N',475,'N','Y','373b505f-1b5e-4ea1-9f0c-3d753724c772','Y','OrderByClause','Fully qualified ORDER BY clause','The ORDER BY Clause indicates the SQL ORDER BY clause to use for record selection','Sql ORDER BY','Y',TO_DATE('2013-01-05 00:28:27','YYYY-MM-DD HH24:MI:SS'),100,0,'Y',TO_DATE('2013-01-05 00:28:27','YYYY-MM-DD HH24:MI:SS'),100,0,'N','N')
;
-- Jan 5, 2013 12:29:22 AM MYT
-- IDEMPIERE-325 AD_InfoWindow
INSERT INTO AD_Field (ColumnSpan,NumLines,SortNo,IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,AD_Column_ID,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,Help,EntityType,Description,Name,IsDisplayed,IsFieldOnly,AD_Field_UU,UpdatedBy,AD_Org_ID,Created,AD_Client_ID,CreatedBy,Updated,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry) VALUES (5,1,0,'N',842,0,'N','N',208362,150,'Y',201634,'N','The ORDER BY Clause indicates the SQL ORDER BY clause to use for record selection','D','Fully qualified ORDER BY clause','Sql ORDER BY','Y','N','efcf0c8a-9b23-48fd-b131-8fa963c146d6',100,0,TO_DATE('2013-01-05 00:29:21','YYYY-MM-DD HH24:MI:SS'),0,100,TO_DATE('2013-01-05 00:29:21','YYYY-MM-DD HH24:MI:SS'),'Y','N',80,1,'N')
;
-- Jan 5, 2013 12:29:33 AM MYT
-- IDEMPIERE-325 AD_InfoWindow
ALTER TABLE AD_InfoWindow ADD OrderByClause NVARCHAR2(2000) DEFAULT NULL
;
-- Jan 5, 2013 12:30:28 AM MYT
-- IDEMPIERE-325 AD_InfoWindow
UPDATE AD_Field SET NumLines=3, SeqNo=110, IsDisplayed='Y', XPosition=1,Updated=TO_DATE('2013-01-05 00:30:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201634
;
-- Jan 5, 2013 12:30:28 AM MYT
-- IDEMPIERE-325 AD_InfoWindow
UPDATE AD_Field SET SeqNo=120,Updated=TO_DATE('2013-01-05 00:30:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=13579
;
-- Jan 5, 2013 12:30:28 AM MYT
-- IDEMPIERE-325 AD_InfoWindow
UPDATE AD_Field SET SeqNo=130,Updated=TO_DATE('2013-01-05 00:30:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=13580
;
-- Jan 5, 2013 12:30:28 AM MYT
-- IDEMPIERE-325 AD_InfoWindow
UPDATE AD_Field SET SeqNo=140,Updated=TO_DATE('2013-01-05 00:30:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201627
;
-- Jan 5, 2013 12:30:28 AM MYT
-- IDEMPIERE-325 AD_InfoWindow
UPDATE AD_Field SET SeqNo=150,Updated=TO_DATE('2013-01-05 00:30:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201628
;
SELECT register_migration_script('201301050051_IDEMPIERE-325.sql') FROM dual
;

View File

@ -0,0 +1,43 @@
-- Jan 5, 2013 12:28:29 AM MYT
-- IDEMPIERE-325 AD_InfoWindow
INSERT INTO AD_Column (SeqNoSelection,IsSyncDatabase,IsEncrypted,Version,AD_Table_ID,AD_Column_ID,EntityType,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,AD_Reference_ID,IsKey,AD_Element_ID,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsUpdateable,ColumnName,Description,Help,Name,IsAllowCopy,Updated,CreatedBy,AD_Org_ID,IsActive,Created,UpdatedBy,AD_Client_ID,IsToolbarButton,IsAlwaysUpdateable) VALUES (0,'N','N',1,895,208362,'D','N','N','N',0,'N',2000,'N',14,'N',475,'N','Y','373b505f-1b5e-4ea1-9f0c-3d753724c772','Y','OrderByClause','Fully qualified ORDER BY clause','The ORDER BY Clause indicates the SQL ORDER BY clause to use for record selection','Sql ORDER BY','Y',TO_TIMESTAMP('2013-01-05 00:28:27','YYYY-MM-DD HH24:MI:SS'),100,0,'Y',TO_TIMESTAMP('2013-01-05 00:28:27','YYYY-MM-DD HH24:MI:SS'),100,0,'N','N')
;
-- Jan 5, 2013 12:29:22 AM MYT
-- IDEMPIERE-325 AD_InfoWindow
INSERT INTO AD_Field (ColumnSpan,NumLines,SortNo,IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,AD_Column_ID,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,Help,EntityType,Description,Name,IsDisplayed,IsFieldOnly,AD_Field_UU,UpdatedBy,AD_Org_ID,Created,AD_Client_ID,CreatedBy,Updated,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry) VALUES (5,1,0,'N',842,0,'N','N',208362,150,'Y',201634,'N','The ORDER BY Clause indicates the SQL ORDER BY clause to use for record selection','D','Fully qualified ORDER BY clause','Sql ORDER BY','Y','N','efcf0c8a-9b23-48fd-b131-8fa963c146d6',100,0,TO_TIMESTAMP('2013-01-05 00:29:21','YYYY-MM-DD HH24:MI:SS'),0,100,TO_TIMESTAMP('2013-01-05 00:29:21','YYYY-MM-DD HH24:MI:SS'),'Y','N',80,1,'N')
;
-- Jan 5, 2013 12:29:33 AM MYT
-- IDEMPIERE-325 AD_InfoWindow
ALTER TABLE AD_InfoWindow ADD COLUMN OrderByClause VARCHAR(2000) DEFAULT NULL
;
-- Jan 5, 2013 12:30:28 AM MYT
-- IDEMPIERE-325 AD_InfoWindow
UPDATE AD_Field SET NumLines=3, SeqNo=110, IsDisplayed='Y', XPosition=1,Updated=TO_TIMESTAMP('2013-01-05 00:30:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201634
;
-- Jan 5, 2013 12:30:28 AM MYT
-- IDEMPIERE-325 AD_InfoWindow
UPDATE AD_Field SET SeqNo=120,Updated=TO_TIMESTAMP('2013-01-05 00:30:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=13579
;
-- Jan 5, 2013 12:30:28 AM MYT
-- IDEMPIERE-325 AD_InfoWindow
UPDATE AD_Field SET SeqNo=130,Updated=TO_TIMESTAMP('2013-01-05 00:30:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=13580
;
-- Jan 5, 2013 12:30:28 AM MYT
-- IDEMPIERE-325 AD_InfoWindow
UPDATE AD_Field SET SeqNo=140,Updated=TO_TIMESTAMP('2013-01-05 00:30:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201627
;
-- Jan 5, 2013 12:30:28 AM MYT
-- IDEMPIERE-325 AD_InfoWindow
UPDATE AD_Field SET SeqNo=150,Updated=TO_TIMESTAMP('2013-01-05 00:30:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201628
;
SELECT register_migration_script('201301050051_IDEMPIERE-325.sql') FROM dual
;

View File

@ -221,6 +221,19 @@ public interface I_AD_InfoWindow
*/
public String getName();
/** Column name OrderByClause */
public static final String COLUMNNAME_OrderByClause = "OrderByClause";
/** Set Sql ORDER BY.
* Fully qualified ORDER BY clause
*/
public void setOrderByClause (String OrderByClause);
/** Get Sql ORDER BY.
* Fully qualified ORDER BY clause
*/
public String getOrderByClause();
/** Column name OtherClause */
public static final String COLUMNNAME_OtherClause = "OtherClause";

View File

@ -30,7 +30,7 @@ public class X_AD_InfoWindow extends PO implements I_AD_InfoWindow, I_Persistent
/**
*
*/
private static final long serialVersionUID = 20130104L;
private static final long serialVersionUID = 20130105L;
/** Standard Constructor */
public X_AD_InfoWindow (Properties ctx, int AD_InfoWindow_ID, String trxName)
@ -288,6 +288,23 @@ public class X_AD_InfoWindow extends PO implements I_AD_InfoWindow, I_Persistent
return new KeyNamePair(get_ID(), getName());
}
/** Set Sql ORDER BY.
@param OrderByClause
Fully qualified ORDER BY clause
*/
public void setOrderByClause (String OrderByClause)
{
set_Value (COLUMNNAME_OrderByClause, OrderByClause);
}
/** Get Sql ORDER BY.
@return Fully qualified ORDER BY clause
*/
public String getOrderByClause ()
{
return (String)get_Value(COLUMNNAME_OrderByClause);
}
/** Set Other SQL Clause.
@param OtherClause
Other SQL Clause

View File

@ -33,10 +33,13 @@ import org.compiere.model.MInfoColumn;
import org.compiere.model.MInfoWindow;
import org.compiere.model.MLookupFactory;
import org.compiere.model.MLookupInfo;
import org.compiere.model.MRole;
import org.compiere.model.MTable;
import org.compiere.util.DB;
import org.compiere.util.DisplayType;
import org.compiere.util.Env;
import org.compiere.util.KeyNamePair;
import org.compiere.util.Msg;
import org.compiere.util.ValueNamePair;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Events;
@ -125,21 +128,30 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener {
private void processQueryValue() {
//try first 2 only
for(int i = 0; i < editors.size() && i < 2; i++) {
WEditor editor = editors.get(i);
editor.setValue(queryValue);
String[] values = queryValue.split("[_]");
if (values.length == 2) {
for(int i = 0; i < values.length && i < editors.size(); i++) {
WEditor editor = editors.get(i);
editor.setValue(values[i]);
}
testCount();
if (m_count > 0) {
break;
} else {
editor.setValue(null);
} else {
for(int i = 0; i < editors.size() && i < 2; i++) {
WEditor editor = editors.get(i);
editor.setValue(queryValue);
testCount();
if (m_count > 0) {
break;
} else {
editor.setValue(null);
}
}
}
if (m_count > 0) {
executeQuery();
renderItems();
} else if (editors.size() > 0) {
} else if (editors.size() > 0 && values.length != 2) {
editors.get(0).setValue(queryValue);
}
}
@ -246,7 +258,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener {
columnInfos = list.toArray(new ColumnInfo[0]);
prepareTable(columnInfos, infoWindow.getFromClause(), p_whereClause, infoWindow.getOtherClause());
prepareTable(columnInfos, infoWindow.getFromClause(), p_whereClause, infoWindow.getOrderByClause());
}
private ColumnInfo createLookupColumnInfo(TableInfo[] tableInfos,
@ -371,6 +383,15 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener {
if (infoWindow.isDistinct()) {
m_sqlMain = m_sqlMain.substring("SELECT ".length());
m_sqlMain = "SELECT DISTINCT " + m_sqlMain;
}
if (m_sqlOrder != null && m_sqlOrder.indexOf("@") >= 0) {
String sql = Env.parseContext(infoContext, p_WindowNo, m_sqlOrder, false, false);
if (sql == null || sql.length() == 9) {
log.severe("Failed to parsed sql. sql=" + m_sqlOrder);
} else {
m_sqlOrder = sql;
}
}
}
@ -541,6 +562,48 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener {
}
} // saveSelectionDetail
@Override
protected String buildDataSQL(int start, int end) {
String dataSql;
String dynWhere = getSQLWhere();
StringBuilder sql = new StringBuilder (m_sqlMain);
if (dynWhere.length() > 0)
sql.append(dynWhere); // includes first AND
if (sql.toString().trim().endsWith("WHERE")) {
int index = sql.lastIndexOf(" WHERE");
sql.delete(index, sql.length());
}
dataSql = Msg.parseTranslation(Env.getCtx(), sql.toString()); // Variables
dataSql = MRole.getDefault().addAccessSQL(dataSql, getTableName(),
MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO);
if (infoWindow.getOtherClause() != null && infoWindow.getOtherClause().trim().length() > 0) {
String otherClause = infoWindow.getOtherClause();
if (otherClause.indexOf("@") >= 0) {
String s = Env.parseContext(infoContext, p_WindowNo, otherClause, false, false);
if (s.length() == 0) {
log.severe("Failed to parse other clause. " + otherClause);
} else {
otherClause = s;
}
}
dataSql = dataSql + " " + otherClause;
}
if (m_sqlUserOrder != null && m_sqlUserOrder.trim().length() > 0)
dataSql = dataSql + m_sqlUserOrder;
else
dataSql = dataSql + m_sqlOrder;
if (end > start && isUseDatabasePaging() && DB.getDatabase().isPagingSupported())
{
dataSql = DB.getDatabase().addPagingSQL(dataSql, getCacheStart(), getCacheEnd());
}
return dataSql;
}
@Override
protected void executeQuery() {
prepareTable();

View File

@ -354,8 +354,8 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
/** Count SQL Statement */
private String m_sqlCount;
/** Order By Clause */
private String m_sqlOrder;
private String m_sqlUserOrder;
protected String m_sqlOrder;
protected String m_sqlUserOrder;
/**ValueChange listeners */
private ArrayList<ValueChangeListener> listeners = new ArrayList<ValueChangeListener>();
/** Loading success indicator */
@ -432,7 +432,7 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
protected void executeQuery()
{
line = new ArrayList<Object>();
cacheStart = -1;
setCacheStart(-1);
cacheEnd = -1;
testCount();
@ -581,13 +581,13 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
private List<Object> readLine(int start, int end) {
//cacheStart & cacheEnd - 1 based index, start & end - 0 based index
if (cacheStart >= 1 && cacheEnd > cacheStart)
if (getCacheStart() >= 1 && cacheEnd > getCacheStart())
{
if (m_useDatabasePaging)
{
if (start+1 >= cacheStart && end+1 <= cacheEnd)
if (start+1 >= getCacheStart() && end+1 <= cacheEnd)
{
return end == -1 ? line : line.subList(start-cacheStart+1, end-cacheStart+2);
return end == -1 ? line : line.subList(start-getCacheStart()+1, end-getCacheStart()+2);
}
}
else
@ -600,9 +600,9 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
}
}
cacheStart = start + 1 - (PAGE_SIZE * 4);
if (cacheStart <= 0)
cacheStart = 1;
setCacheStart(start + 1 - (PAGE_SIZE * 4));
if (getCacheStart() <= 0)
setCacheStart(1);
if (end == -1)
{
@ -619,30 +619,12 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
PreparedStatement m_pstmt = null;
ResultSet m_rs = null;
String dataSql = null;
long startTime = System.currentTimeMillis();
//
String dynWhere = getSQLWhere();
StringBuilder sql = new StringBuilder (m_sqlMain);
if (dynWhere.length() > 0)
sql.append(dynWhere); // includes first AND
if (sql.toString().trim().endsWith("WHERE")) {
int index = sql.lastIndexOf(" WHERE");
sql.delete(index, sql.length());
}
if (m_sqlUserOrder != null && m_sqlUserOrder.trim().length() > 0)
sql.append(m_sqlUserOrder);
else
sql.append(m_sqlOrder);
String dataSql = Msg.parseTranslation(Env.getCtx(), sql.toString()); // Variables
dataSql = MRole.getDefault().addAccessSQL(dataSql, getTableName(),
MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO);
if (end > start && m_useDatabasePaging && DB.getDatabase().isPagingSupported())
{
dataSql = DB.getDatabase().addPagingSQL(dataSql, cacheStart, cacheEnd);
}
dataSql = buildDataSQL(start, end);
if (log.isLoggable(Level.FINER))
log.finer(dataSql);
try
@ -658,14 +640,14 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
//skips the row that we dont need if we can't use native db paging
if (end > start && m_useDatabasePaging && !DB.getDatabase().isPagingSupported())
{
for (int i = 0; i < cacheStart - 1; i++)
for (int i = 0; i < getCacheStart() - 1; i++)
{
if (!m_rs.next())
break;
}
}
int rowPointer = cacheStart-1;
int rowPointer = getCacheStart()-1;
while (m_rs.next())
{
rowPointer++;
@ -695,6 +677,31 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
return line.subList(start, end+1);
}
protected String buildDataSQL(int start, int end) {
String dataSql;
String dynWhere = getSQLWhere();
StringBuilder sql = new StringBuilder (m_sqlMain);
if (dynWhere.length() > 0)
sql.append(dynWhere); // includes first AND
if (sql.toString().trim().endsWith("WHERE")) {
int index = sql.lastIndexOf(" WHERE");
sql.delete(index, sql.length());
}
if (m_sqlUserOrder != null && m_sqlUserOrder.trim().length() > 0)
sql.append(m_sqlUserOrder);
else
sql.append(m_sqlOrder);
dataSql = Msg.parseTranslation(Env.getCtx(), sql.toString()); // Variables
dataSql = MRole.getDefault().addAccessSQL(dataSql, getTableName(),
MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO);
if (end > start && m_useDatabasePaging && DB.getDatabase().isPagingSupported())
{
dataSql = DB.getDatabase().addPagingSQL(dataSql, getCacheStart(), cacheEnd);
}
return dataSql;
}
private void addDoubleClickListener() {
Iterator<EventListener<? extends Event>> i = contentPanel.getEventListeners(Events.ON_DOUBLE_CLICK).iterator();
while (i.hasNext()) {
@ -1375,4 +1382,30 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
public Integer getFirstRowKey() {
return contentPanel.getFirstRowKey();
}
/**
* @return the cacheStart
*/
protected int getCacheStart() {
return cacheStart;
}
/**
* @param cacheStart the cacheStart to set
*/
private void setCacheStart(int cacheStart) {
this.cacheStart = cacheStart;
}
/**
* @return the cacheEnd
*/
protected int getCacheEnd() {
return cacheEnd;
}
protected boolean isUseDatabasePaging() {
return m_useDatabasePaging;
}
} // Info