[ adempiere-Patches-2761420 ] Advanced Search

- Refactor to work for both swing and zk client
This commit is contained in:
Heng Sin Low 2009-04-24 07:41:10 +00:00
parent 75eaa4c2c9
commit 648979a759
7 changed files with 510 additions and 366 deletions

View File

@ -0,0 +1,292 @@
/**********************************************************************
* This file is part of Adempiere ERP Bazaar *
* http://www.adempiere.org *
* *
* Copyright (C) Jan Roessler - Schaeffer *
* 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: *
* - Jan Roessler *
* - Heng Sin Low *
* *
* Sponsors: *
* - Schaeffer *
**********************************************************************/
package org.adempiere.util;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Vector;
import org.compiere.model.MColumn;
import org.compiere.model.MQuery;
import org.compiere.model.MRole;
import org.compiere.model.MSearchDefinition;
import org.compiere.model.MTable;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.Env;
/**
* Executes search and opens windows for defined transaction codes
*
* @author Jan Roessler, jr@schaeffer-ag.de
*
*/
public abstract class AbstractDocumentSearch {
/** the logger */
static CLogger log = CLogger.getCLogger(AbstractDocumentSearch.class);
protected boolean windowOpened = false;
/**
* @param searchString
*/
public boolean openDocumentsByDocumentNo(String searchString) {
windowOpened = false;
log.fine("Search started with String: " + searchString);
// Check if / how many transaction-codes are used
if (searchString != null && !"".equals(searchString)) {
String[] codes = searchString.trim().replaceAll(" ", " ").split(" ");
List<String> codeList = new ArrayList<String>();
boolean codeSearch = true;
searchString = "";
// Analyze String to separate transactionCodes from searchString
for (int i = 0; i < codes.length; i++) {
try {
String s = codes[i];
if (MSearchDefinition.isValidTransactionCode(s) && codeSearch) {
codeList.add(s);
} else {
// Build the searchString with eventually appearing
// whitespaces
codeSearch = false;
searchString += s;
if (i != (codes.length - 1)) {
searchString += " ";
}
}
} catch (SQLException e) {
log.severe(e.toString());
e.printStackTrace();
}
}
// Start the search for every single code
if (codeList.size() > 0) {
for (int i = 0; i < codeList.size(); i++) {
log.fine("Search with Transaction: '" + codeList.get(i) + "' for: '"
+ searchString + "'");
getID(codeList.get(i), searchString);
}
} else {
log.fine("Search without Transaction: " + searchString);
getID(null, searchString);
}
} else {
log.fine("Search String is invalid");
}
return windowOpened;
}
/**
* search for id's that fit the searchString
*
* @param transactionCode
* @param searchString
*/
private void getID(String transactionCode, String searchString) {
ResultSet rsSO = null;
ResultSet rsPO = null;
PreparedStatement pstmtSO = null;
PreparedStatement pstmtPO = null;
String sqlSO = null;
String sqlPO = null;
final Properties ctx = Env.getCtx();
final MRole role = MRole.get(ctx, Env.getAD_Role_ID(ctx), Env.getAD_User_ID(ctx), true);
try {
for (MSearchDefinition msd : MSearchDefinition.getForCode(transactionCode)) {
MTable table = new MTable(Env.getCtx(), msd.getAD_Table_ID(), null);
// SearchDefinition with a given table and column
if (msd.getSearchType().equals(MSearchDefinition.SEARCHTYPE_TABLE)) {
MColumn column = new MColumn(Env.getCtx(), msd.getAD_Column_ID(), null);
sqlSO = "SELECT " + table.getTableName() + "_ID FROM " + table.getTableName() + " ";
// search for an Integer
if (msd.getDataType().equals(MSearchDefinition.DATATYPE_INTEGER)) {
sqlSO += "WHERE " + column.getColumnName() + "=?";
// search for a String
} else {
sqlSO += "WHERE UPPER(" + column.getColumnName()+ ") LIKE UPPER(?)";
}
if (msd.getPO_Window_ID() != 0) {
sqlPO = sqlSO + " AND IsSOTrx='N'";
sqlSO += " AND IsSOTrx='Y'";
}
pstmtSO = DB.prepareStatement(sqlSO, null);
pstmtPO = DB.prepareStatement(sqlPO, null);
// search for a Integer
if (msd.getDataType().equals(MSearchDefinition.DATATYPE_INTEGER)) {
pstmtSO.setInt(1, Integer.valueOf(searchString.replaceAll("\\D", "")));
if (msd.getPO_Window_ID() != 0) {
pstmtPO.setInt(1, Integer.valueOf(searchString.replaceAll("\\D", "")));
}
// search for a String
} else if (msd.getDataType().equals(MSearchDefinition.DATATYPE_STRING)) {
pstmtSO.setString(1, searchString);
if (msd.getPO_Window_ID() != 0) {
pstmtPO.setString(1, searchString);
}
}
// SearchDefinition with a special query
} else if (msd.getSearchType().equals(MSearchDefinition.SEARCHTYPE_QUERY)) {
sqlSO = msd.getQuery();
pstmtSO = DB.prepareStatement(sqlSO, null);
// count '?' in statement
int count = 1;
for (char c : sqlSO.toCharArray()) {
if (c == '?') {
count++;
}
}
for (int i = 1; i < count; i++) {
if (msd.getDataType().equals(MSearchDefinition.DATATYPE_INTEGER)) {
pstmtSO.setInt(i, Integer.valueOf(searchString.replaceAll("\\D", "")));
} else if (msd.getDataType().equals(MSearchDefinition.DATATYPE_STRING)) {
pstmtSO.setString(i, searchString);
}
}
}
if (pstmtSO != null) {
log.fine("SQL Sales: " + sqlSO);
rsSO = pstmtSO.executeQuery();
Vector<Integer> idSO = new Vector<Integer>();
while (rsSO.next()) {
idSO.add(new Integer(rsSO.getInt(1)));
}
if (role.getWindowAccess(msd.getAD_Window_ID()) != null) {
log.fine("Open Window: " + msd.getAD_Window_ID() + " / Table: "
+ table.getTableName() + " / Number of Results: " + idSO.size());
if (idSO.size() == 0 && (searchString == null || searchString.trim().length() == 0)) {
// No search string - open the window with new record
idSO.add(new Integer(0));
}
openWindow(idSO, table.getTableName(), msd.getAD_Window_ID());
} else {
log.warning("Role is not allowed to view this window");
}
}
if (pstmtPO != null) {
log.fine("SQL Purchase: " + sqlPO);
rsPO = pstmtPO.executeQuery();
Vector<Integer> idPO = new Vector<Integer>();
while (rsPO.next()) {
idPO.add(new Integer(rsPO.getInt(1)));
}
if (role.getWindowAccess(msd.getPO_Window_ID()) != null) {
log.fine("Open Window: " + msd.getPO_Window_ID() + " / Table: "
+ table.getTableName() + " / Number of Results: " + idPO.size());
openWindow(idPO, table.getTableName(), msd.getPO_Window_ID());
} else {
log.warning("Role is not allowed to view this window");
}
}
DB.close(rsSO, pstmtSO);
DB.close(rsPO, pstmtPO);
pstmtSO = null;
pstmtPO = null;
rsSO = null;
rsPO = null;
}
} catch (Exception e) {
log.severe(e.toString());
e.printStackTrace();
} finally {
DB.close(rsSO, pstmtSO);
DB.close(rsPO, pstmtPO);
rsSO = null;
rsPO = null;
pstmtSO = null;
pstmtPO = null;
}
}
/**
* opens window with the given documents
*
* @param ids
* - document id's
* @param tableName
* @param windowId
*/
private void openWindow(Vector<Integer> ids, String tableName, int windowId) {
if (ids == null || ids.size() == 0) {
return;
}
String whereString = " " + tableName + "_ID";
// create query string
if (ids.size() == 1) {
if (ids.get(0).intValue() == 0) {
whereString = null;
} else {
whereString += "=" + ids.get(0).intValue();
}
} else {
whereString += " IN (";
for (int i = 0; i < ids.size(); i++) {
whereString += ids.get(i).intValue();
if (i < ids.size() - 1) {
whereString += ",";
} else {
whereString += ") ";
}
}
}
log.fine(whereString);
final MQuery query = new MQuery(tableName);
query.addRestriction(whereString);
final boolean ok = openWindow(windowId, query);
if (!ok) {
log.severe("Unable to open window: " + whereString);
}
if (!windowOpened && ok)
windowOpened = true;
}
/**
* @param windowId
* @param query
* @return true if windowId open successfully
*/
protected abstract boolean openWindow(int windowId, MQuery query);
}

View File

@ -22,6 +22,7 @@
* * * *
* Contributors: * * Contributors: *
* - Jan Roessler * * - Jan Roessler *
* - Heng Sin Low *
* * * *
* Sponsors: * * Sponsors: *
* - Schaeffer * * - Schaeffer *
@ -29,24 +30,11 @@
package de.schaeffer.compiere.tools; package de.schaeffer.compiere.tools;
import java.sql.PreparedStatement; import org.adempiere.util.AbstractDocumentSearch;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Vector;
import org.compiere.apps.AEnv; import org.compiere.apps.AEnv;
import org.compiere.apps.AWindow; import org.compiere.apps.AWindow;
import org.compiere.model.MColumn;
import org.compiere.model.MQuery; import org.compiere.model.MQuery;
import org.compiere.model.MRole;
import org.compiere.model.MSearchDefinition;
import org.compiere.model.MTable;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.Env;
/** /**
* Executes search and opens windows for defined transaction codes * Executes search and opens windows for defined transaction codes
@ -54,238 +42,18 @@ import org.compiere.util.Env;
* @author Jan Roessler, jr@schaeffer-ag.de * @author Jan Roessler, jr@schaeffer-ag.de
* *
*/ */
public class DocumentSearch { public class DocumentSearch extends AbstractDocumentSearch {
/** the logger */ /** the logger */
static CLogger log = CLogger.getCLogger(DocumentSearch.class); static CLogger log = CLogger.getCLogger(DocumentSearch.class);
private static boolean windowOpened = false; @Override
protected boolean openWindow(int windowId, MQuery query) {
/**
* @param searchString
*/
public static boolean openDocumentsByDocumentNo(String searchString) {
windowOpened = false;
log.fine("Search started with String: " + searchString);
// Check if / how many transaction-codes are used
if (searchString != null && !"".equals(searchString)) {
String[] codes = searchString.trim().replaceAll(" ", " ").split(" ");
List<String> codeList = new ArrayList<String>();
boolean codeSearch = true;
searchString = "";
// Analyze String to separate transactionCodes from searchString
for (int i = 0; i < codes.length; i++) {
try {
String s = codes[i];
if (MSearchDefinition.isValidTransactionCode(s) && codeSearch) {
codeList.add(s);
} else {
// Build the searchString with eventually appearing
// whitespaces
codeSearch = false;
searchString += s;
if (i != (codes.length - 1)) {
searchString += " ";
}
}
} catch (SQLException e) {
log.severe(e.toString());
e.printStackTrace();
}
}
// Start the search for every single code
if (codeList.size() > 0) {
for (int i = 0; i < codeList.size(); i++) {
log.fine("Search with Transaction: '" + codeList.get(i) + "' for: '"
+ searchString + "'");
getID(codeList.get(i), searchString);
}
} else {
log.fine("Search without Transaction: " + searchString);
getID(null, searchString);
}
} else {
log.fine("Search String is invalid");
}
return windowOpened;
}
/**
* search for id's that fit the searchString
*
* @param transactionCode
* @param searchString
*/
private static void getID(String transactionCode, String searchString) {
ResultSet rsSO = null;
ResultSet rsPO = null;
PreparedStatement pstmtSO = null;
PreparedStatement pstmtPO = null;
String sqlSO = null;
String sqlPO = null;
final Properties ctx = Env.getCtx();
final MRole role = MRole.get(ctx, Env.getAD_Role_ID(ctx), Env.getAD_User_ID(ctx), true);
try {
for (MSearchDefinition msd : MSearchDefinition.getForCode(transactionCode)) {
MTable table = new MTable(Env.getCtx(), msd.getAD_Table_ID(), null);
// SearchDefinition with a given table and column
if (msd.getSearchType().equals(MSearchDefinition.SEARCHTYPE_TABLE)) {
MColumn column = new MColumn(Env.getCtx(), msd.getAD_Column_ID(), null);
sqlSO = "SELECT " + table.getTableName() + "_ID FROM " + table.getTableName() + " ";
// search for an Integer
if (msd.getDataType().equals(MSearchDefinition.DATATYPE_INTEGER)) {
sqlSO += "WHERE " + column.getColumnName() + "=?";
// search for a String
} else {
sqlSO += "WHERE UPPER(" + column.getColumnName()+ ") LIKE UPPER(?)";
}
if (msd.getPO_Window_ID() != 0) {
sqlPO = sqlSO + " AND IsSOTrx='N'";
sqlSO += " AND IsSOTrx='Y'";
}
pstmtSO = DB.prepareStatement(sqlSO, null);
pstmtPO = DB.prepareStatement(sqlPO, null);
// search for a Integer
if (msd.getDataType().equals(MSearchDefinition.DATATYPE_INTEGER)) {
pstmtSO.setInt(1, Integer.valueOf(searchString.replaceAll("\\D", "")));
if (msd.getPO_Window_ID() != 0) {
pstmtPO.setInt(1, Integer.valueOf(searchString.replaceAll("\\D", "")));
}
// search for a String
} else if (msd.getDataType().equals(MSearchDefinition.DATATYPE_STRING)) {
pstmtSO.setString(1, searchString);
if (msd.getPO_Window_ID() != 0) {
pstmtPO.setString(1, searchString);
}
}
// SearchDefinition with a special query
} else if (msd.getSearchType().equals(MSearchDefinition.SEARCHTYPE_QUERY)) {
sqlSO = msd.getQuery();
pstmtSO = DB.prepareStatement(sqlSO, null);
// count '?' in statement
int count = 1;
for (char c : sqlSO.toCharArray()) {
if (c == '?') {
count++;
}
}
for (int i = 1; i < count; i++) {
if (msd.getDataType().equals(MSearchDefinition.DATATYPE_INTEGER)) {
pstmtSO.setInt(i, Integer.valueOf(searchString.replaceAll("\\D", "")));
} else if (msd.getDataType().equals(MSearchDefinition.DATATYPE_STRING)) {
pstmtSO.setString(i, searchString);
}
}
}
if (pstmtSO != null) {
log.fine("SQL Sales: " + sqlSO);
rsSO = pstmtSO.executeQuery();
Vector<Integer> idSO = new Vector<Integer>();
while (rsSO.next()) {
idSO.add(new Integer(rsSO.getInt(1)));
}
if (role.getWindowAccess(msd.getAD_Window_ID()) != null) {
log.fine("Open Window: " + msd.getAD_Window_ID() + " / Table: "
+ table.getTableName() + " / Number of Results: " + idSO.size());
if (idSO.size() == 0 && (searchString == null || searchString.trim().length() == 0)) {
// No search string - open the window with new record
idSO.add(new Integer(0));
}
openWindow(idSO, table.getTableName(), msd.getAD_Window_ID());
} else {
log.warning("Role is not allowed to view this window");
}
}
if (pstmtPO != null) {
log.fine("SQL Purchase: " + sqlPO);
rsPO = pstmtPO.executeQuery();
Vector<Integer> idPO = new Vector<Integer>();
while (rsPO.next()) {
idPO.add(new Integer(rsPO.getInt(1)));
}
if (role.getWindowAccess(msd.getPO_Window_ID()) != null) {
log.fine("Open Window: " + msd.getPO_Window_ID() + " / Table: "
+ table.getTableName() + " / Number of Results: " + idPO.size());
openWindow(idPO, table.getTableName(), msd.getPO_Window_ID());
} else {
log.warning("Role is not allowed to view this window");
}
}
DB.close(rsSO, pstmtSO);
DB.close(rsPO, pstmtPO);
pstmtSO = null;
pstmtPO = null;
rsSO = null;
rsPO = null;
}
} catch (Exception e) {
log.severe(e.toString());
e.printStackTrace();
} finally {
DB.close(rsSO, pstmtSO);
DB.close(rsPO, pstmtPO);
rsSO = null;
rsPO = null;
pstmtSO = null;
pstmtPO = null;
}
}
/**
* opens window with the given documents
*
* @param ids
* - document id's
* @param tableName
* @param windowId
*/
private static void openWindow(Vector<Integer> ids, String tableName, int windowId) {
if (ids == null || ids.size() == 0) {
return;
}
String whereString = " " + tableName + "_ID";
// create query string
if (ids.size() == 1) {
if (ids.get(0).intValue() == 0) {
whereString = null;
} else {
whereString += "=" + ids.get(0).intValue();
}
} else {
whereString += " IN (";
for (int i = 0; i < ids.size(); i++) {
whereString += ids.get(i).intValue();
if (i < ids.size() - 1) {
whereString += ",";
} else {
whereString += ") ";
}
}
}
log.fine(whereString);
final AWindow frame = new AWindow(); final AWindow frame = new AWindow();
AEnv.addToWindowManager(frame); AEnv.addToWindowManager(frame);
final MQuery query = new MQuery(tableName);
query.addRestriction(whereString);
final boolean ok = frame.initWindow(windowId, query); final boolean ok = frame.initWindow(windowId, query);
if (!ok) {
log.severe("Unable to open window: " + whereString);
}
frame.pack(); frame.pack();
AEnv.showCenterScreen(frame); AEnv.showCenterScreen(frame);
if (!windowOpened && ok) return ok;
windowOpened = true;
} }
} }

View File

@ -665,7 +665,8 @@ public final class VTreePanel extends CPanel
&& treeSearch.getText().length() > 0 && treeSearch.getText().length() > 0
&& treeSearch.getText().substring(0, 1).equals(PREFIX_DOCUMENT_SEARCH)) { && treeSearch.getText().substring(0, 1).equals(PREFIX_DOCUMENT_SEARCH)) {
setBusy(true); setBusy(true);
if (DocumentSearch.openDocumentsByDocumentNo(treeSearch.getText().substring(1))) DocumentSearch search = new DocumentSearch();
if (search.openDocumentsByDocumentNo(treeSearch.getText().substring(1)))
treeSearch.setText(null); treeSearch.setText(null);
setBusy(false); setBusy(false);
return; return;

View File

@ -109,6 +109,13 @@ public interface IDesktop extends UIPart {
*/ */
public void showZoomWindow(int window_ID, MQuery query); public void showZoomWindow(int window_ID, MQuery query);
/**
*
* @param window_ID
* @param query
*/
public void showWindow(int window_ID, MQuery query);
/** /**
* *
* @param windowNo * @param windowNo

View File

@ -196,6 +196,19 @@ public abstract class TabbedDesktop extends AbstractDesktop {
windowContainer.insertAfter(windowContainer.getSelectedTab(), tabPanel, wnd.getTitle(), true, true); windowContainer.insertAfter(windowContainer.getSelectedTab(), tabPanel, wnd.getTitle(), true, true);
} }
/**
* @param AD_Window_ID
* @param query
*/
public void showWindow(int AD_Window_ID, MQuery query)
{
ADWindow wnd = new ADWindow(Env.getCtx(), AD_Window_ID, query);
DesktopTabpanel tabPanel = new DesktopTabpanel();
wnd.createPart(tabPanel);
windowContainer.addWindow(tabPanel, wnd.getTitle(), true);
}
/** /**
* *
* @param window * @param window

View File

@ -22,6 +22,7 @@ import java.util.TreeMap;
import org.adempiere.webui.component.AutoComplete; import org.adempiere.webui.component.AutoComplete;
import org.adempiere.webui.component.Label; import org.adempiere.webui.component.Label;
import org.adempiere.webui.component.Panel; import org.adempiere.webui.component.Panel;
import org.adempiere.webui.util.DocumentSearch;
import org.adempiere.webui.util.TreeItemAction; import org.adempiere.webui.util.TreeItemAction;
import org.adempiere.webui.util.TreeNodeAction; import org.adempiere.webui.util.TreeNodeAction;
import org.adempiere.webui.util.TreeUtils; import org.adempiere.webui.util.TreeUtils;
@ -59,6 +60,8 @@ public class TreeSearchPanel extends Panel implements EventListener, TreeDataLis
private String eventToFire; private String eventToFire;
private static final String PREFIX_DOCUMENT_SEARCH = "/";
/** /**
* @param tree * @param tree
*/ */
@ -173,6 +176,16 @@ public class TreeSearchPanel extends Panel implements EventListener, TreeDataLis
if (cmbSearch.equals(event.getTarget()) && (event.getName().equals(Events.ON_CHANGE))) if (cmbSearch.equals(event.getTarget()) && (event.getName().equals(Events.ON_CHANGE)))
{ {
String value = cmbSearch.getValue(); String value = cmbSearch.getValue();
if (value != null && value.trim().length() > 0
&& value.substring(0, 1).equals(PREFIX_DOCUMENT_SEARCH))
{
DocumentSearch search = new DocumentSearch();
if (search.openDocumentsByDocumentNo(value.substring(1)))
cmbSearch.setText(null);
return;
}
Object node = treeNodeItemMap.get(value); Object node = treeNodeItemMap.get(value);
Treeitem treeItem = null; Treeitem treeItem = null;
if (node == null) { if (node == null) {

View File

@ -0,0 +1,50 @@
/**********************************************************************
* This file is part of Adempiere ERP Bazaar *
* http://www.adempiere.org *
* *
* Copyright (C) Heng Sin Low *
* Copyright (C) Idalica Corporation *
* *
* 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: *
* - Jan Roessler *
* - Heng Sin Low
* *
* Sponsors: *
* - Schaeffer *
* - Idalica Corporation *
**********************************************************************/
package org.adempiere.webui.util;
import org.adempiere.util.AbstractDocumentSearch;
import org.adempiere.webui.session.SessionManager;
import org.compiere.model.MQuery;
/**
*
* @author hengsin
*
*/
public class DocumentSearch extends AbstractDocumentSearch {
@Override
protected boolean openWindow(int windowId, MQuery query) {
SessionManager.getAppDesktop().showWindow(windowId, query);
return true;
}
}