From e332df42180d14cc0ac60f2875e18ac54837f18a Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Tue, 22 Jul 2008 10:16:06 +0000 Subject: [PATCH] - Added ZK dashboard - Added Workflow Activities custom form - Implemented Check Requests and Product Info --- .../src/org/adempiere/webui/Desktop.java | 11 +- .../src/org/adempiere/webui/WRequest.java | 226 ++++++ .../src/org/adempiere/webui/apps/AEnv.java | 93 +-- .../webui/component/CWindowToolbar.java | 2 + .../adempiere/webui/component/Combobox.java | 9 + .../webui/panel/AbstractADWindowPanel.java | 67 +- .../src/org/compiere/apps/wf/WFActivity.java | 705 ++++++++++++++++++ 7 files changed, 1017 insertions(+), 96 deletions(-) create mode 100644 zkwebui/WEB-INF/src/org/adempiere/webui/WRequest.java create mode 100644 zkwebui/WEB-INF/src/org/compiere/apps/wf/WFActivity.java diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/Desktop.java b/zkwebui/WEB-INF/src/org/adempiere/webui/Desktop.java index 1c61df9b0b..b3fdc42276 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/Desktop.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/Desktop.java @@ -175,7 +175,7 @@ public class Desktop extends AbstractUIPart implements MenuListener, Serializabl btnNotice.setLabel("Notice : 0"); btnNotice.setTooltiptext("Notice"); btnNotice.setImage("/images/GetMail16.gif"); - int AD_Menu_ID = DB.getSQLValue(null, "SELECT MAX(AD_Menu_ID) FROM AD_Menu WHERE Name = 'Notice'"); + int AD_Menu_ID = DB.getSQLValue(null, "SELECT AD_Menu_ID FROM AD_Menu WHERE Name = 'Notice' AND IsSummary = 'N'"); btnNotice.setName(String.valueOf(AD_Menu_ID)); btnNotice.addEventListener(Events.ON_CLICK, this); @@ -184,7 +184,7 @@ public class Desktop extends AbstractUIPart implements MenuListener, Serializabl btnRequest.setLabel("Request : 0"); btnRequest.setTooltiptext("Request"); btnRequest.setImage("/images/Request16.gif"); - AD_Menu_ID = DB.getSQLValue(null, "SELECT MAX(AD_Menu_ID) FROM AD_Menu WHERE Name = 'Request'"); + AD_Menu_ID = DB.getSQLValue(null, "SELECT AD_Menu_ID FROM AD_Menu WHERE Name = 'Request' AND IsSummary = 'N'"); btnRequest.setName(String.valueOf(AD_Menu_ID)); btnRequest.addEventListener(Events.ON_CLICK, this); @@ -193,7 +193,7 @@ public class Desktop extends AbstractUIPart implements MenuListener, Serializabl btnWorkflow.setLabel("Workflow Activities : 0"); btnWorkflow.setTooltiptext("Workflow Activities"); btnWorkflow.setImage("/images/Assignment16.gif"); - AD_Menu_ID = DB.getSQLValue(null, "SELECT MAX(AD_Menu_ID) FROM AD_Menu WHERE Name = 'Workflow Activities'"); + AD_Menu_ID = DB.getSQLValue(null, "SELECT AD_Menu_ID FROM AD_Menu WHERE Name = 'Workflow Activities' AND IsSummary = 'N'"); btnWorkflow.setName(String.valueOf(AD_Menu_ID)); btnWorkflow.addEventListener(Events.ON_CLICK, this); @@ -531,10 +531,7 @@ public class Desktop extends AbstractUIPart implements MenuListener, Serializabl { Button btn = (Button) comp; -// int AD_Window_ID = Integer.valueOf(btn.getName()); -// if (AD_Window_ID > 0) AEnv.zoom(AD_Window_ID, new MQuery()); - - int menuId = 0; + int menuId = 0; try { menuId = Integer.valueOf(btn.getName()); diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/WRequest.java b/zkwebui/WEB-INF/src/org/adempiere/webui/WRequest.java new file mode 100644 index 0000000000..0c8e06c990 --- /dev/null +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/WRequest.java @@ -0,0 +1,226 @@ +package org.adempiere.webui; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.logging.Level; + +import org.adempiere.webui.apps.AEnv; +import org.compiere.model.MAsset; +import org.compiere.model.MBPartner; +import org.compiere.model.MCampaign; +import org.compiere.model.MInOut; +import org.compiere.model.MInvoice; +import org.compiere.model.MOrder; +import org.compiere.model.MPayment; +import org.compiere.model.MProduct; +import org.compiere.model.MProject; +import org.compiere.model.MQuery; +import org.compiere.model.MRMA; +import org.compiere.model.MRequest; +import org.compiere.model.MUser; +import org.compiere.util.CLogger; +import org.compiere.util.DB; +import org.compiere.util.Env; +import org.compiere.util.Msg; +import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zk.ui.event.Events; +import org.zkoss.zul.Menuitem; +import org.zkoss.zul.Menupopup; + +/** + * Request Button Action. + * Popup Menu + * + * @author Jorg Janke + * @version $Id: ARequest.java,v 1.2 2006/07/30 00:51:27 jjanke Exp $ + * + * @author Teo Sarca, SC ARHIPAC SERVICE SRL + *
  • BF [ 1904928 ] Request: Related Request field not filled + */ +public class WRequest implements EventListener +{ + /** + * Constructor + * @param invoker invoker button + * @param AD_Table_ID table + * @param Record_ID record + * @param C_BPartner_ID optional bp + */ + public WRequest (Component invoker, int AD_Table_ID, int Record_ID, int C_BPartner_ID) + { + log.config("AD_Table_ID=" + AD_Table_ID + ", Record_ID=" + Record_ID); + m_AD_Table_ID = AD_Table_ID; + m_Record_ID = Record_ID; + m_C_BPartner_ID = C_BPartner_ID; + getRequests(invoker); + + } // AReport + + /** The Table */ + private int m_AD_Table_ID; + /** The Record */ + private int m_Record_ID; + /** BPartner */ + private int m_C_BPartner_ID; + + /** The Popup */ + private Menupopup m_popup = new Menupopup(); + private Menuitem m_new = null; + private Menuitem m_active = null; + private Menuitem m_all = null; + /** Where Clause */ + StringBuffer m_where = null; + + /** Logger */ + private static CLogger log = CLogger.getCLogger (WRequest.class); + + /** + * Display Request Options - New/Existing. + * @param invoker button + */ + private void getRequests (Component invoker) + { + m_new = new Menuitem(Msg.getMsg(Env.getCtx(), "RequestNew")); + m_new.setImage("/images/New16.gif"); + m_new.addEventListener(Events.ON_CLICK, this); + m_popup.appendChild(m_new); + // + int activeCount = 0; + int inactiveCount = 0; + m_where = new StringBuffer(); + m_where.append("(AD_Table_ID=").append(m_AD_Table_ID) + .append(" AND Record_ID=").append(m_Record_ID) + .append(")"); + // + if (m_AD_Table_ID == MUser.Table_ID) + m_where.append(" OR AD_User_ID=").append(m_Record_ID) + .append(" OR SalesRep_ID=").append(m_Record_ID); + else if (m_AD_Table_ID == MBPartner.Table_ID) + m_where.append(" OR C_BPartner_ID=").append(m_Record_ID); + else if (m_AD_Table_ID == MOrder.Table_ID) + m_where.append(" OR C_Order_ID=").append(m_Record_ID); + else if (m_AD_Table_ID == MInvoice.Table_ID) + m_where.append(" OR C_Invoice_ID=").append(m_Record_ID); + else if (m_AD_Table_ID == MPayment.Table_ID) + m_where.append(" OR C_Payment_ID=").append(m_Record_ID); + else if (m_AD_Table_ID == MProduct.Table_ID) + m_where.append(" OR M_Product_ID=").append(m_Record_ID); + else if (m_AD_Table_ID == MProject.Table_ID) + m_where.append(" OR C_Project_ID=").append(m_Record_ID); + else if (m_AD_Table_ID == MCampaign.Table_ID) + m_where.append(" OR C_Campaign_ID=").append(m_Record_ID); + else if (m_AD_Table_ID == MAsset.Table_ID) + m_where.append(" OR A_Asset_ID=").append(m_Record_ID); + // + String sql = "SELECT Processed, COUNT(*) " + + "FROM R_Request WHERE " + m_where + + " GROUP BY Processed " + + "ORDER BY Processed DESC"; + PreparedStatement pstmt = null; + ResultSet rs = null; + try + { + pstmt = DB.prepareStatement (sql, null); + rs = pstmt.executeQuery (); + while (rs.next ()) + { + if ("Y".equals(rs.getString(1))) + inactiveCount = rs.getInt(2); + else + activeCount += rs.getInt(2); + } + } + catch (Exception e) + { + log.log(Level.SEVERE, sql, e); + } + finally + { + DB.close(rs, pstmt); + rs = null; + pstmt = null; + } + // + if (activeCount > 0) + { + m_active = new Menuitem(Msg.getMsg(Env.getCtx(), "RequestActive") + + " (" + activeCount + ")"); + m_active.addEventListener(Events.ON_CLICK, this); + m_popup.appendChild(m_active); + } + if (inactiveCount > 0) + { + m_all = new Menuitem(Msg.getMsg(Env.getCtx(), "RequestAll") + + " (" + (activeCount + inactiveCount) + ")"); + m_all.addEventListener(Events.ON_CLICK, this); + m_popup.appendChild(m_all); + } + + m_popup.setPage(invoker.getPage()); + m_popup.open(invoker); + } // getZoomTargets + + public void onEvent(Event e) throws Exception + { + if (e.getTarget() instanceof Menuitem) + { + MQuery query = null; + if (e.getTarget() == m_active) + { + query = new MQuery(""); + String where = "(" + m_where + ") AND Processed='N'"; + query.addRestriction(where); + } + else if (e.getTarget() == m_all) + { + query = new MQuery(""); + query.addRestriction(m_where.toString()); + } + + int AD_Window_ID = 232; // 232=all - 201=my + if (e.getTarget() == m_new) + { + Env.setContext(Env.getCtx(), "AD_Table_ID", new Integer(m_AD_Table_ID)); + Env.setContext(Env.getCtx(), "Record_ID", new Integer(m_Record_ID)); + // + if (m_C_BPartner_ID != 0) + Env.setContext(Env.getCtx(), "C_BPartner_ID", new Integer(m_C_BPartner_ID)); + // + if (m_AD_Table_ID == MBPartner.Table_ID) + Env.setContext(Env.getCtx(), "C_BPartner_ID", new Integer(m_Record_ID)); + else if (m_AD_Table_ID == MUser.Table_ID) + Env.setContext(Env.getCtx(), "AD_User_ID", new Integer(m_Record_ID)); + // + else if (m_AD_Table_ID == MProject.Table_ID) + Env.setContext(Env.getCtx(), "C_Project_ID", new Integer(m_Record_ID)); + else if (m_AD_Table_ID == MAsset.Table_ID) + Env.setContext(Env.getCtx(), "A_Asset_ID", new Integer(m_Record_ID)); + // + else if (m_AD_Table_ID == MOrder.Table_ID) + Env.setContext(Env.getCtx(), "C_Order_ID", new Integer(m_Record_ID)); + else if (m_AD_Table_ID == MInvoice.Table_ID) + Env.setContext(Env.getCtx(), "C_Invoice_ID", new Integer(m_Record_ID)); + // + else if (m_AD_Table_ID == MProduct.Table_ID) + Env.setContext(Env.getCtx(), "M_Product_ID", new Integer(m_Record_ID)); + else if (m_AD_Table_ID == MPayment.Table_ID) + Env.setContext(Env.getCtx(), "C_Payment_ID", new Integer(m_Record_ID)); + // + else if (m_AD_Table_ID == MInOut.Table_ID) + Env.setContext(Env.getCtx(), "M_InOut_ID", new Integer(m_Record_ID)); + else if (m_AD_Table_ID == MRMA.Table_ID) + Env.setContext(Env.getCtx(), "M_RMA_ID", new Integer(m_Record_ID)); + // + else if (m_AD_Table_ID == MCampaign.Table_ID) + Env.setContext(Env.getCtx(), "C_Campaign_ID", new Integer(m_Record_ID)); + // + else if (m_AD_Table_ID == MRequest.Table_ID) + Env.setContext(Env.getCtx(), MRequest.COLUMNNAME_R_RequestRelated_ID, new Integer(m_Record_ID)); + } + + AEnv.zoom(AD_Window_ID, query); + } + } +} diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/apps/AEnv.java b/zkwebui/WEB-INF/src/org/adempiere/webui/apps/AEnv.java index 1ba1d46526..70d7848764 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/apps/AEnv.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/apps/AEnv.java @@ -17,23 +17,35 @@ package org.adempiere.webui.apps; -import java.io.*; +import java.io.InvalidClassException; +import java.io.NotSerializableException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; -import java.rmi.*; -import java.sql.*; -import java.util.*; -import java.util.logging.*; +import java.rmi.RemoteException; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Enumeration; +import java.util.logging.Level; +import org.adempiere.webui.component.Window; import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.window.FDialog; import org.compiere.Adempiere; -import org.compiere.db.*; -import org.compiere.interfaces.*; -import org.compiere.model.*; -import org.compiere.util.*; -import org.adempiere.webui.component.Window; +import org.compiere.apps.ALogin; +import org.compiere.db.CConnection; +import org.compiere.interfaces.Server; +import org.compiere.model.GridWindowVO; +import org.compiere.model.Lookup; +import org.compiere.model.MQuery; +import org.compiere.model.MRole; +import org.compiere.util.CCache; +import org.compiere.util.CLogMgt; +import org.compiere.util.CLogger; +import org.compiere.util.DB; +import org.compiere.util.Env; +import org.compiere.util.Ini; /** * Windows Application Environment and utilities @@ -239,7 +251,7 @@ public final class AEnv * @param text text with '&' * @return Mnemonic or 0 */ - public static char getMnemonic (String text) + public static char getMnemonic (String text) { int pos = text.indexOf('&'); @@ -257,9 +269,7 @@ public final class AEnv */ public static void zoom (int AD_Table_ID, int Record_ID) { - /* - - String TableName = null; + String TableName = null; int AD_Window_ID = 0; int PO_Window_ID = 0; String sql = "SELECT TableName, AD_Window_ID, PO_Window_ID FROM AD_Table WHERE AD_Table_ID=?"; @@ -295,21 +305,8 @@ public final class AEnv AD_Window_ID = PO_Window_ID; } - log.config(TableName + " - Record_ID=" + Record_ID + " (IsSOTrx=" + isSOTrx + ")"); - AWindow frame = new AWindow(); - if (!frame.initWindow(AD_Window_ID, MQuery.getEqualQuery(TableName + "_ID", Record_ID))) - return; - addToWindowManager(frame); - if (Ini.isPropertyBool(Ini.P_OPEN_WINDOW_MAXIMIZED)) - { - AEnv.showMaximized(frame); - } - else - { - AEnv.showCenterScreen(frame); - } - frame = null; - */ + log.config(TableName + " - Record_ID=" + Record_ID + " (IsSOTrx=" + isSOTrx + ")"); + zoom(AD_Window_ID, MQuery.getEqualQuery(TableName + "_ID", Record_ID)); } // zoom /** @@ -393,31 +390,19 @@ public final class AEnv */ public static void startWorkflowProcess (int AD_Table_ID, int Record_ID) { - /* + if (s_workflow_Window_ID == 0) + { + int AD_Window_ID = DB.getSQLValue(null, "SELECT AD_Window_ID FROM AD_Window WHERE Name = 'Workflow Process'"); + s_workflow_Window_ID = AD_Window_ID; + } + if (s_workflow_Window_ID == 0) return; - // - MQuery query = null; - if (AD_Table_ID != 0 && Record_ID != 0) - { - query = new MQuery("AD_WF_Process"); - query.addRestriction("AD_Table_ID", MQuery.EQUAL, AD_Table_ID); - query.addRestriction("Record_ID", MQuery.EQUAL, Record_ID); - } - // - AWindow frame = new AWindow(); - if (!frame.initWindow(s_workflow_Window_ID, query)) - return; - addToWindowManager(frame); - if (Ini.isPropertyBool(Ini.P_OPEN_WINDOW_MAXIMIZED) ) { - frame.pack(); - frame.setExtendedState(Frame.MAXIMIZED_BOTH); - frame.setVisible(true); - frame.toFront(); - } else - AEnv.showCenterScreen(frame); - frame = null; - */ + + MQuery query = new MQuery(); + query.addRestriction("AD_Table_ID", MQuery.EQUAL, AD_Table_ID); + query.addRestriction("Record_ID", MQuery.EQUAL, Record_ID); + AEnv.zoom(s_workflow_Window_ID, query); } // startWorkflowProcess @@ -480,7 +465,7 @@ public final class AEnv */ public static String getServerVersion () { - return CConnection.get().getServerVersion(); + return CConnection.get().getServerVersion(); } // getServerVersion /** Window Cache */ @@ -592,7 +577,7 @@ public final class AEnv * @param force force posting * @return null if success, otherwise error */ - public static String postImmediate (int WindowNo, int AD_Client_ID, + public static String postImmediate (int WindowNo, int AD_Client_ID, int AD_Table_ID, int Record_ID, boolean force) { diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/component/CWindowToolbar.java b/zkwebui/WEB-INF/src/org/adempiere/webui/component/CWindowToolbar.java index 21df1bc41d..88ab54e8e5 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/component/CWindowToolbar.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/component/CWindowToolbar.java @@ -266,6 +266,8 @@ public class CWindowToolbar extends FToolbar implements EventListener btnZoomAcross.setDisabled(false); btnActiveWorkflows.setDisabled(false); // Elaine 2008/07/17 + btnRequests.setDisabled(false); // Elaine 2008/07/22 + btnProductInfo.setDisabled(false); // Elaine 2008/07/22 configureKeyMap(); diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/component/Combobox.java b/zkwebui/WEB-INF/src/org/adempiere/webui/component/Combobox.java index a7effc6bfc..ad84595e98 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/component/Combobox.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/component/Combobox.java @@ -40,4 +40,13 @@ public class Combobox extends org.zkoss.zul.Combobox item.setParent(this); return item; } + + // Elaine 2008/07/22 + public ComboItem getSelectedItem() + { + Comboitem item = super.getSelectedItem(); + if(item == null) return null; + return new ComboItem(item.getLabel(), (String) item.getValue()); + } + // } \ No newline at end of file diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/panel/AbstractADWindowPanel.java b/zkwebui/WEB-INF/src/org/adempiere/webui/panel/AbstractADWindowPanel.java index 27af35f992..46dafaa034 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/panel/AbstractADWindowPanel.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/panel/AbstractADWindowPanel.java @@ -20,6 +20,7 @@ package org.adempiere.webui.panel; import java.util.Properties; import java.util.logging.Level; +import org.adempiere.webui.WRequest; import org.adempiere.webui.WZoomAcross; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.apps.ProcessModalDialog; @@ -27,16 +28,13 @@ import org.adempiere.webui.apps.WReport; import org.adempiere.webui.apps.form.WCreateFrom; import org.adempiere.webui.apps.form.WPayment; import org.adempiere.webui.component.CWindowToolbar; -import org.adempiere.webui.component.IADTabList; import org.adempiere.webui.component.IADTab; +import org.adempiere.webui.component.IADTabList; import org.adempiere.webui.editor.WButtonEditor; import org.adempiere.webui.event.ActionEvent; import org.adempiere.webui.event.ActionListener; import org.adempiere.webui.event.ToolbarListener; import org.adempiere.webui.exception.ApplicationException; -import org.adempiere.webui.panel.StatusBarPanel; -import org.adempiere.webui.panel.WDocActionPanel; -import org.adempiere.webui.panel.WOnlyCurrentDays; import org.adempiere.webui.part.AbstractUIPart; import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.window.FDialog; @@ -1004,39 +1002,38 @@ public abstract class AbstractADWindowPanel extends AbstractUIPart implements To public void onActiveWorkflows() { if (toolbar.getEvent() != null) { - int record_ID = curTab.getRecord_ID(); - if (record_ID <= 0) + if (curTab.getRecord_ID() <= 0) return; - - // Query - MQuery query = new MQuery(); - // Current row - String link = curTab.getKeyColumnName(); - - // Link for detail records - if (link.length() == 0) - link = curTab.getLinkColumnName(); - if (link.length() != 0) - { - if (link.endsWith("_ID")) - { - int AD_Table_ID = DB.getSQLValue(null, "SELECT AD_Table_ID FROM AD_Table WHERE TableName = ?", link.substring(0, link.length() - 3)); - int Record_ID = new Integer(Env.getContextAsInt(ctx, curWindowNo, link)); - - query.addRestriction("AD_Table_ID", MQuery.EQUAL, AD_Table_ID); - query.addRestriction("Record_ID", MQuery.EQUAL, Record_ID); - } - else - { - query.addRestriction(link, MQuery.EQUAL, Env.getContext(ctx, curWindowNo, link)); - } - } - - int AD_Window_ID = DB.getSQLValue(null, "SELECT AD_Window_ID FROM AD_Window WHERE Name = 'Workflow Process'"); - if (AD_Window_ID > 0) AEnv.zoom(AD_Window_ID, query); + else + AEnv.startWorkflowProcess(curTab.getAD_Table_ID(), curTab.getRecord_ID()); } } // + + // Elaine 2008/07/22 + public void onRequests() + { + if (toolbar.getEvent() != null) + { + if (curTab.getRecord_ID() <= 0) + return; + + int C_BPartner_ID = 0; + Object bpartner = curTab.getValue("C_BPartner_ID"); + if(bpartner != null) + C_BPartner_ID = Integer.valueOf(bpartner.toString()); + + new WRequest(toolbar.getEvent().getTarget(), curTab.getAD_Table_ID(), curTab.getRecord_ID(), C_BPartner_ID); + } + } + // + + // Elaine 2008/07/22 + public void onProductInfo() + { + InfoPanel.showProduct(0); + } + // /************************************************************************** * Start Button Process @@ -1050,12 +1047,12 @@ public abstract class AbstractADWindowPanel extends AbstractUIPart implements To boolean batch = false; String col = wButton.getColumnName(); - // Zoom - + // Zoom if (col.equals("Record_ID")) { int AD_Table_ID = Env.getContextAsInt (ctx, curWindowNo, "AD_Table_ID"); int Record_ID = Env.getContextAsInt (ctx, curWindowNo, "Record_ID"); + AEnv.zoom(AD_Table_ID, Record_ID); return; } // Zoom diff --git a/zkwebui/WEB-INF/src/org/compiere/apps/wf/WFActivity.java b/zkwebui/WEB-INF/src/org/compiere/apps/wf/WFActivity.java new file mode 100644 index 0000000000..7eeec399dd --- /dev/null +++ b/zkwebui/WEB-INF/src/org/compiere/apps/wf/WFActivity.java @@ -0,0 +1,705 @@ +package org.compiere.apps.wf; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.ArrayList; +import java.util.logging.Level; + +import org.adempiere.webui.apps.AEnv; +import org.adempiere.webui.component.Button; +import org.adempiere.webui.component.ComboItem; +import org.adempiere.webui.component.Combobox; +import org.adempiere.webui.component.Grid; +import org.adempiere.webui.component.Label; +import org.adempiere.webui.component.Row; +import org.adempiere.webui.component.Rows; +import org.adempiere.webui.component.Textbox; +import org.adempiere.webui.component.WStatusBar; +import org.adempiere.webui.component.Window; +import org.adempiere.webui.editor.WSearchEditor; +import org.adempiere.webui.panel.ADForm; +import org.adempiere.webui.window.FDialog; +import org.compiere.model.MColumn; +import org.compiere.model.MLookup; +import org.compiere.model.MLookupFactory; +import org.compiere.model.MQuery; +import org.compiere.model.MRefList; +import org.compiere.util.CLogger; +import org.compiere.util.DB; +import org.compiere.util.DisplayType; +import org.compiere.util.Env; +import org.compiere.util.Msg; +import org.compiere.util.Trx; +import org.compiere.util.ValueNamePair; +import org.compiere.wf.MWFActivity; +import org.compiere.wf.MWFNode; +import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zk.ui.event.Events; +import org.zkoss.zkex.zul.Borderlayout; +import org.zkoss.zkex.zul.Center; +import org.zkoss.zkex.zul.South; +import org.zkoss.zul.Div; +import org.zkoss.zul.Hbox; + +public class WFActivity extends ADForm implements EventListener +{ + private static final long serialVersionUID = 1L; + + /** Window No */ + private int m_WindowNo = 0; + /** FormFrame */ +// private FormFrame m_frame = null; + /** Menu */ +// private AMenu m_menu = null; + /** Open Activities */ + private MWFActivity[] m_activities = null; + /** Current Activity */ + private MWFActivity m_activity = null; + /** Current Activity */ + private int m_index = 0; + /** Set Column */ + private MColumn m_column = null; + /** Logger */ + private static CLogger log = CLogger.getCLogger(WFActivity.class); + + // +// private Panel centerPanel = new Panel(); +// private GridBagLayout centerLayout = new GridBagLayout(); + private Label lNode = new Label(Msg.translate(Env.getCtx(), "AD_WF_Node_ID")); + private Textbox fNode = new Textbox(); + private Label lDesctiption = new Label(Msg.translate(Env.getCtx(), "Description")); + private Textbox fDescription = new Textbox(); + private Label lHelp = new Label(Msg.translate(Env.getCtx(), "Help")); + private Textbox fHelp = new Textbox(); + private Label lHistory = new Label(Msg.translate(Env.getCtx(), "History")); + private Textbox fHistory = new Textbox(); + private Label lAnswer = new Label(Msg.getMsg(Env.getCtx(), "Answer")); +// private Panel answers = new Panel(new FlowLayout(FlowLayout.LEADING)); + private Textbox fAnswerText = new Textbox(); + private Combobox fAnswerList = new Combobox(); + private Button fAnswerButton = new Button(); + private Button bPrevious = new Button();//AEnv.getButton("Previous"); + private Button bNext = new Button();//AEnv.getButton("Next"); + private Button bZoom = new Button();//AEnv.getButton("Zoom"); + private Label lTextMsg = new Label(Msg.getMsg(Env.getCtx(), "Messages")); + private Textbox fTextMsg = new Textbox(); + private Button bOK = new Button();//ConfirmPanel.createOKButton(true); + private WSearchEditor fForward = null; // dynInit + private Label lForward = new Label(Msg.getMsg(Env.getCtx(), "Forward")); + private Label lOptional = new Label("(" + Msg.translate(Env.getCtx(), "Optional") + ")"); + private WStatusBar statusBar = new WStatusBar(); + + public WFActivity() + { + super(); + } + + public void init(int adFormId, String name) + { + super.init(adFormId, name); + + loadActivities(); + + bPrevious.setImage("/images/Previous16.gif"); + bNext.setImage("/images/Next16.gif"); + bZoom.setImage("/images/Zoom16.gif"); + bOK.setImage("/images/Ok24.gif"); + + MLookup lookup = MLookupFactory.get(Env.getCtx(), super.m_windowNo, + 0, 10443, DisplayType.Search); + fForward = new WSearchEditor(lookup, Msg.translate( + Env.getCtx(), "AD_User_ID"), "", true, false, true); + + init(); + display(); + } + + private void init() + { + Grid grid = new Grid(); + grid.setWidth("99%"); + grid.setHeight("100%"); + grid.setStyle("margin:0; padding:0; position: absolute"); + grid.setSclass("grid-no-striped"); + grid.setOddRowSclass("even"); + + Rows rows = new Rows(); + grid.appendChild(rows); + + Row row = new Row(); + rows.appendChild(row); + Div div = new Div(); + div.setAlign("right"); + div.appendChild(lNode); + row.appendChild(div); + row.appendChild(fNode); + fNode.setWidth("100%"); + row.appendChild(bPrevious); + bPrevious.addEventListener(Events.ON_CLICK, this); + + row = new Row(); + rows.appendChild(row); + row.setValign("top"); + div = new Div(); + div.setAlign("right"); + div.appendChild(lDesctiption); + row.appendChild(div); + row.appendChild(fDescription); + fDescription.setMultiline(true); + fDescription.setWidth("100%"); + row.appendChild(bNext); + bNext.addEventListener(Events.ON_CLICK, this); + + row = new Row(); + rows.appendChild(row); + div = new Div(); + div.setAlign("right"); + div.appendChild(lHelp); + row.appendChild(div); + row.appendChild(fHelp); + fHelp.setMultiline(true); + fHelp.setWidth("100%"); + row.appendChild(new Label()); + + row = new Row(); + rows.appendChild(row); + div = new Div(); + div.setAlign("right"); + div.appendChild(lHistory); + row.appendChild(div); + row.appendChild(fHistory); + fHistory.setRows(10); + fHistory.setMultiline(true); + fHistory.setWidth("100%"); + row.appendChild(new Label()); + + row = new Row(); + rows.appendChild(row); + div = new Div(); + div.setAlign("right"); + div.appendChild(lAnswer); + row.appendChild(div); + Hbox hbox = new Hbox(); + hbox.appendChild(fAnswerText); + hbox.appendChild(fAnswerList); + hbox.appendChild(fAnswerButton); + fAnswerButton.addEventListener(Events.ON_CLICK, this); + row.appendChild(hbox); + row.appendChild(bZoom); + bZoom.addEventListener(Events.ON_CLICK, this); + + row = new Row(); + rows.appendChild(row); + div = new Div(); + div.setAlign("right"); + div.appendChild(lTextMsg); + row.appendChild(div); + row.appendChild(fTextMsg); + fTextMsg.setMultiline(true); + fTextMsg.setWidth("100%"); + row.appendChild(new Label()); + + row = new Row(); + rows.appendChild(row); + div = new Div(); + div.setAlign("right"); + div.appendChild(lForward); + row.appendChild(div); + hbox = new Hbox(); + hbox.appendChild(fForward.getComponent()); + hbox.appendChild(lOptional); + row.appendChild(hbox); + row.appendChild(bOK); + bOK.addEventListener(Events.ON_CLICK, this); + + Borderlayout layout = new Borderlayout(); + layout.setWidth("100%"); + layout.setHeight("100%"); + layout.setStyle("background-color: transparent; position: absolute;"); + + Center center = new Center(); + center.appendChild(grid); + layout.appendChild(center); + center.setStyle("background-color: transparent"); + + South south = new South(); + south.appendChild(statusBar); + statusBar.setWidth("100%"); + layout.appendChild(south); + south.setStyle("background-color: transparent"); + + this.appendChild(layout); + } + + public void onEvent(Event event) throws Exception + { +// this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + + Component comp = event.getTarget(); + String eventName = event.getName(); + + if(eventName.equals(Events.ON_CLICK)) + { + if(comp == bNext || comp == bPrevious) + { + if (comp == bNext) + m_index++; + else + m_index--; + display(); + } + else if (comp == bZoom) + cmd_zoom(); + else if (comp == bOK) + cmd_OK(); + else if (comp == fAnswerButton) + cmd_button(); + } + +// this.setCursor(Cursor.getDefaultCursor()); + } + + /** + * Get active activities count + * @return int + */ + public int getActivitiesCount() + { + int count = 0; + + String sql = "SELECT count(*) FROM AD_WF_Activity a " + + "WHERE a.Processed='N' AND a.WFState='OS' AND (" + // Owner of Activity + + " a.AD_User_ID=?" // #1 + // Invoker (if no invoker = all) + + " OR EXISTS (SELECT * FROM AD_WF_Responsible r WHERE a.AD_WF_Responsible_ID=r.AD_WF_Responsible_ID" + + " AND COALESCE(r.AD_User_ID,0)=0 AND COALESCE(r.AD_Role_ID,0)=0 AND (a.AD_User_ID=? OR a.AD_User_ID IS NULL))" // #2 + // Responsible User + + " OR EXISTS (SELECT * FROM AD_WF_Responsible r WHERE a.AD_WF_Responsible_ID=r.AD_WF_Responsible_ID" + + " AND r.AD_User_ID=?)" // #3 + // Responsible Role + + " OR EXISTS (SELECT * FROM AD_WF_Responsible r INNER JOIN AD_User_Roles ur ON (r.AD_Role_ID=ur.AD_Role_ID)" + + " WHERE a.AD_WF_Responsible_ID=r.AD_WF_Responsible_ID AND ur.AD_User_ID=?))"; // #4 + // + //+ ") ORDER BY a.Priority DESC, Created"; + int AD_User_ID = Env.getAD_User_ID(Env.getCtx()); + PreparedStatement pstmt = null; + ResultSet rs = null; + try + { + pstmt = DB.prepareStatement (sql, null); + pstmt.setInt (1, AD_User_ID); + pstmt.setInt (2, AD_User_ID); + pstmt.setInt (3, AD_User_ID); + pstmt.setInt (4, AD_User_ID); + rs = pstmt.executeQuery (); + if (rs.next ()) { + count = rs.getInt(1); + } + } + catch (Exception e) + { + log.log(Level.SEVERE, sql, e); + } + finally + { + DB.close(rs, pstmt); + rs = null; pstmt = null; + } + + return count; + + } + + /** + * Load Activities + * @return int + */ + public int loadActivities() + { + long start = System.currentTimeMillis(); + ArrayList list = new ArrayList(); + String sql = "SELECT * FROM AD_WF_Activity a " + + "WHERE a.Processed='N' AND a.WFState='OS' AND (" + // Owner of Activity + + " a.AD_User_ID=?" // #1 + // Invoker (if no invoker = all) + + " OR EXISTS (SELECT * FROM AD_WF_Responsible r WHERE a.AD_WF_Responsible_ID=r.AD_WF_Responsible_ID" + + " AND COALESCE(r.AD_User_ID,0)=0 AND COALESCE(r.AD_Role_ID,0)=0 AND (a.AD_User_ID=? OR a.AD_User_ID IS NULL))" // #2 + // Responsible User + + " OR EXISTS (SELECT * FROM AD_WF_Responsible r WHERE a.AD_WF_Responsible_ID=r.AD_WF_Responsible_ID" + + " AND r.AD_User_ID=?)" // #3 + // Responsible Role + + " OR EXISTS (SELECT * FROM AD_WF_Responsible r INNER JOIN AD_User_Roles ur ON (r.AD_Role_ID=ur.AD_Role_ID)" + + " WHERE a.AD_WF_Responsible_ID=r.AD_WF_Responsible_ID AND ur.AD_User_ID=?)" // #4 + // + + ") ORDER BY a.Priority DESC, Created"; + int AD_User_ID = Env.getAD_User_ID(Env.getCtx()); + PreparedStatement pstmt = null; + ResultSet rs = null; + try + { + pstmt = DB.prepareStatement (sql, null); + pstmt.setInt (1, AD_User_ID); + pstmt.setInt (2, AD_User_ID); + pstmt.setInt (3, AD_User_ID); + pstmt.setInt (4, AD_User_ID); + rs = pstmt.executeQuery (); + while (rs.next ()) + { + list.add (new MWFActivity(Env.getCtx(), rs, null)); + if (list.size() > 200) // HARDCODED + { + log.warning("More then 200 Activities - ignored"); + break; + } + } + } + catch (Exception e) + { + log.log(Level.SEVERE, sql, e); + } + finally + { + DB.close(rs, pstmt); + rs = null; pstmt = null; + } + m_activities = new MWFActivity[list.size ()]; + list.toArray (m_activities); + // + log.fine("#" + m_activities.length + + "(" + (System.currentTimeMillis()-start) + "ms)"); + m_index = 0; + return m_activities.length; + } // loadActivities + + /** + * Display. + * Fill Editors + */ + public void display () + { + log.fine("Index=" + m_index); + // + fTextMsg.setValue (""); + fAnswerText.setVisible(false); + fAnswerList.setVisible(false); + fAnswerButton.setImage("/images/mWindow.gif"); + fAnswerButton.setVisible(false); + fTextMsg.setReadonly(m_activities.length == 0); +// fTextMsg.setReadWrite(m_activities.length != 0); + bZoom.setEnabled(m_activities.length != 0); + bOK.setEnabled(m_activities.length != 0); + fForward.setValue(null); + fForward.setReadWrite(m_activities.length != 0); +// fForward.setEnabled(m_activities.length != 0); + statusBar.setStatusDB(String.valueOf(m_index) + "/" + m_activities.length); + m_activity = null; + if (m_activities.length > 0) + { + if (m_index+1 > m_activities.length) + { + log.log(Level.SEVERE, "Index (" + m_index + + ") greater then activity length=" + m_activities.length); + m_index = 0; + } + else + m_activity = m_activities[m_index]; + } + // Nothing to show + if (m_activity == null) + { + fNode.setText (""); + fDescription.setValue (""); + fHelp.setValue (""); + fHistory.setValue (""); + statusBar.setStatusDB("0/0"); + statusBar.setStatusLine(Msg.getMsg(Env.getCtx(), "WFNoActivities")); + bNext.setEnabled(false); + bPrevious.setEnabled(false); +// if (m_menu != null) +// m_menu.updateActivities(0); + return; + } + // Display Activity + fNode.setText (m_activity.getNodeName()); + fDescription.setValue (m_activity.getNodeDescription()); + fHelp.setValue (m_activity.getNodeHelp()); + // + fHistory.setValue (m_activity.getHistoryHTML()); + + // User Actions + MWFNode node = m_activity.getNode(); + if (MWFNode.ACTION_UserChoice.equals(node.getAction())) + { + if (m_column == null) + m_column = node.getColumn(); + if (m_column != null && m_column.get_ID() != 0) + { + int dt = m_column.getAD_Reference_ID(); + if (dt == DisplayType.YesNo) + { + ValueNamePair[] values = MRefList.getList(Env.getCtx(), 319, false); // _YesNo + for(int i = 0; i < values.length; i++) + { + ComboItem item = new ComboItem(values[i].getName(), values[i].getValue()); + fAnswerList.appendChild(item); + } +// fAnswerList.setModel(new DefaultComboBoxModel(values)); + fAnswerList.setVisible(true); + } + else if (dt == DisplayType.List) + { + ValueNamePair[] values = MRefList.getList(Env.getCtx(), m_column.getAD_Reference_Value_ID(), false); + for(int i = 0; i < values.length; i++) + { + ComboItem item = new ComboItem(values[i].getName(), values[i].getValue()); + fAnswerList.appendChild(item); + } +// fAnswerList.setModel(new DefaultComboBoxModel(values)); + fAnswerList.setVisible(true); + } + else // other display types come here + { + fAnswerText.setText (""); + fAnswerText.setVisible(true); + } + } + } + // -- + else if (MWFNode.ACTION_UserWindow.equals(node.getAction()) + || MWFNode.ACTION_UserForm.equals(node.getAction())) + { + fAnswerButton.setLabel(node.getName()); + fAnswerButton.setTooltiptext(node.getDescription()); + fAnswerButton.setVisible(true); + } + /* + else if (MWFNode.ACTION_UserWorkbench.equals(node.getAction())) + log.log(Level.SEVERE, "Workflow Action not implemented yet");*/ + else + log.log(Level.SEVERE, "Unknown Node Action: " + node.getAction()); + // + // globalqss - comment following lines to solve the + // Bug [ 1711626 ] Workflow tab just allow to navigate first two activities +// if (m_menu != null) +// { +// m_menu.updateActivities(m_activities.length); +// } + // End + if (m_index+1 >= m_activities.length) + { + m_index = m_activities.length - 1; + bNext.setEnabled(false); + } + else + bNext.setEnabled(true); + // Start + if (m_index <= 0) + { + m_index = 0; + bPrevious.setEnabled(false); + } + else + bPrevious.setEnabled(true); + statusBar.setStatusDB((m_index+1) + "/" + m_activities.length); + statusBar.setStatusLine(Msg.getMsg(Env.getCtx(), "WFActivities")); + } // display + + + /** + * Action Listener + * @param e event + * @see java.awt.event.ActionListener#actionPerformed(ActionEvent) + */ +/* public void actionPerformed (ActionEvent e) + { + this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + // + if (e.getSource() == bNext || e.getSource() == bPrevious) + { + if (e.getSource() == bNext) + m_index++; + else + m_index--; + display(); + } + else if (e.getSource() == bZoom) + cmd_zoom(); + else if (e.getSource() == bOK) + cmd_OK(); + else if (e.getSource() == fAnswerButton) + cmd_button(); + // + this.setCursor(Cursor.getDefaultCursor()); + } // actionPerformed +*/ + + /** + * Zoom + */ + private void cmd_zoom() + { + log.config("Activity=" + m_activity); + if (m_activity == null) + return; + AEnv.zoom(m_activity.getAD_Table_ID(), m_activity.getRecord_ID()); + } // cmd_zoom + + /** + * Answer Button + */ + private void cmd_button() + { + log.config("Activity=" + m_activity); + if (m_activity == null) + return; + // + MWFNode node = m_activity.getNode(); + if (MWFNode.ACTION_UserWindow.equals(node.getAction())) + { + int AD_Window_ID = node.getAD_Window_ID(); // Explicit Window + String ColumnName = m_activity.getPO().get_TableName() + "_ID"; + int Record_ID = m_activity.getRecord_ID(); + MQuery query = MQuery.getEqualQuery(ColumnName, Record_ID); + boolean IsSOTrx = m_activity.isSOTrx(); + // + log.info("Zoom to AD_Window_ID=" + AD_Window_ID + + " - " + query + " (IsSOTrx=" + IsSOTrx + ")"); + + AEnv.zoom(AD_Window_ID, query); +// AWindow frame = new AWindow(); +// if (!frame.initWindow(AD_Window_ID, query)) +// return; +// AEnv.addToWindowManager(frame); +// AEnv.showCenterScreen(frame); +// frame = null; + } + else if (MWFNode.ACTION_UserForm.equals(node.getAction())) + { + int AD_Form_ID = node.getAD_Form_ID(); + + Window form = ADForm.openForm(AD_Form_ID); + AEnv.showWindow(form); +// FormFrame ff = new FormFrame(); +// ff.openForm(AD_Form_ID); +// ff.pack(); +// AEnv.addToWindowManager(ff); +// AEnv.showCenterScreen(ff); + } + /* + else if (MWFNode.ACTION_UserWorkbench.equals(node.getAction())) + { + + }*/ + else + log.log(Level.SEVERE, "No User Action:" + node.getAction()); + } // cmd_button + + + /** + * Save + */ + private void cmd_OK() + { + log.config("Activity=" + m_activity); + if (m_activity == null) + return; + int AD_User_ID = Env.getAD_User_ID(Env.getCtx()); + String textMsg = fTextMsg.getValue(); + // + MWFNode node = m_activity.getNode(); + + Object forward = null;//fForward.getValue(); + + // ensure activity is ran within a transaction - [ 1953628 ] + Trx trx = Trx.get(Trx.createTrxName("FWFA"), true); + m_activity.set_TrxName(trx.getTrxName()); + + if (forward != null) + { + log.config("Forward to " + forward); + int fw = ((Integer)forward).intValue(); + if (fw == AD_User_ID || fw == 0) + { + log.log(Level.SEVERE, "Forward User=" + fw); + trx.rollback(); + trx.close(); + return; + } + if (!m_activity.forwardTo(fw, textMsg)) + { + FDialog.error(m_WindowNo, this, "CannotForward"); + trx.rollback(); + trx.close(); + return; + } + } + // User Choice - Answer + else if (MWFNode.ACTION_UserChoice.equals(node.getAction())) + { + if (m_column == null) + m_column = node.getColumn(); + // Do we have an answer? + int dt = m_column.getAD_Reference_ID(); + String value = fAnswerText.getText(); + if (dt == DisplayType.YesNo || dt == DisplayType.List) + { +// ValueNamePair pp = (ValueNamePair)fAnswerList.getSelectedItem(); +// value = pp.getValue(); + ComboItem item = fAnswerList.getSelectedItem(); + value = (String) item.getValue(); + } + if (value == null || value.length() == 0) + { + FDialog.error(m_WindowNo, this, "FillMandatory", Msg.getMsg(Env.getCtx(), "Answer")); + trx.rollback(); + trx.close(); + return; + } + // + log.config("Answer=" + value + " - " + textMsg); + try + { + m_activity.setUserChoice(AD_User_ID, value, dt, textMsg); + } + catch (Exception e) + { + log.log(Level.SEVERE, node.getName(), e); + FDialog.error(m_WindowNo, this, "Error", e.toString()); + trx.rollback(); + trx.close(); + return; + } + } + // User Action + else + { + log.config("Action=" + node.getAction() + " - " + textMsg); + try + { + // ensure activity is ran within a transaction + m_activity.set_TrxName(Trx.createTrxName("FWFA")); + m_activity.setUserConfirmation(AD_User_ID, textMsg); + } + catch (Exception e) + { + log.log(Level.SEVERE, node.getName(), e); + FDialog.error(m_WindowNo, this, "Error", e.toString()); + trx.rollback(); + trx.close(); + return; + } + + } + + trx.commit(); + trx.close(); + + // Next + loadActivities(); + display(); + } // cmd_OK +}