();
+ //
+ private Grid centerPanel = null;
+
+ /**
+ * Dispose
+ */
+ public void dispose()
+ {
+ m_wEditors.clear();
+ m_wEditors2.clear();
+ m_mFields.clear();
+ m_mFields2.clear();
+
+ } // dispose
+
+ /**
+ * Read Fields to display
+ * @return true if loaded OK
+ */
+ public boolean init()
+ {
+ log.config("");
+
+ //
+ String sql = null;
+ if (Env.isBaseLanguage(Env.getCtx(), "AD_Process_Para"))
+ sql = "SELECT p.Name, p.Description, p.Help, "
+ + "p.AD_Reference_ID, p.AD_Process_Para_ID, "
+ + "p.FieldLength, p.IsMandatory, p.IsRange, p.ColumnName, "
+ + "p.DefaultValue, p.DefaultValue2, p.VFormat, p.ValueMin, p.ValueMax, "
+ + "p.SeqNo, p.AD_Reference_Value_ID, vr.Code AS ValidationCode "
+ + "FROM AD_Process_Para p"
+ + " LEFT OUTER JOIN AD_Val_Rule vr ON (p.AD_Val_Rule_ID=vr.AD_Val_Rule_ID) "
+ + "WHERE p.AD_Process_ID=?" // 1
+ + " AND p.IsActive='Y' "
+ + "ORDER BY SeqNo";
+ else
+ sql = "SELECT t.Name, t.Description, t.Help, "
+ + "p.AD_Reference_ID, p.AD_Process_Para_ID, "
+ + "p.FieldLength, p.IsMandatory, p.IsRange, p.ColumnName, "
+ + "p.DefaultValue, p.DefaultValue2, p.VFormat, p.ValueMin, p.ValueMax, "
+ + "p.SeqNo, p.AD_Reference_Value_ID, vr.Code AS ValidationCode "
+ + "FROM AD_Process_Para p"
+ + " INNER JOIN AD_Process_Para_Trl t ON (p.AD_Process_Para_ID=t.AD_Process_Para_ID)"
+ + " LEFT OUTER JOIN AD_Val_Rule vr ON (p.AD_Val_Rule_ID=vr.AD_Val_Rule_ID) "
+ + "WHERE p.AD_Process_ID=?" // 1
+ + " AND t.AD_Language='" + Env.getAD_Language(Env.getCtx()) + "'"
+ + " AND p.IsActive='Y' "
+ + "ORDER BY SeqNo";
+
+ // Create Fields
+ boolean hasFields = false;
+ Rows rows = new Rows();
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql, null);
+ pstmt.setInt(1, m_processInfo.getAD_Process_ID());
+ ResultSet rs = pstmt.executeQuery();
+ while (rs.next())
+ {
+ hasFields = true;
+ createField (rs, rows);
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch(SQLException e)
+ {
+ log.log(Level.SEVERE, sql, e);
+ }
+
+ // both vectors the same?
+ if (m_mFields.size() != m_mFields2.size()
+ || m_mFields.size() != m_wEditors.size()
+ || m_mFields2.size() != m_wEditors2.size())
+ log.log(Level.SEVERE, "View & Model vector size is different");
+
+ // clean up
+ if (hasFields)
+ {
+ centerPanel.appendChild(rows);
+ }
+ else
+ dispose();
+ return hasFields;
+ } // initDialog
+
+
+ /**
+ * Create Field.
+ * - creates Fields and adds it to m_mFields list
+ * - creates Editor and adds it to m_vEditors list
+ * Handeles Ranges by adding additional mField/vEditor.
+ *
+ * mFields are used for default value and mandatory checking;
+ * vEditors are used to retrieve the value (no data binding)
+ *
+ * @param rs result set
+ */
+ private void createField (ResultSet rs, Rows rows)
+ {
+ // Create Field
+ GridFieldVO voF = GridFieldVO.createParameter(Env.getCtx(), m_WindowNo, rs);
+ GridField mField = new GridField (voF);
+ m_mFields.add(mField); // add to Fields
+
+ Row row = new Row();
+
+ // The Editor
+ WEditor wEditor = WebEditorFactory.getEditor(mField, false);
+ wEditor.addValueChangeListner(this);
+ // MField => VEditor - New Field value to be updated to editor
+ mField.addPropertyChangeListener(wEditor);
+ // Set Default
+ Object defaultObject = mField.getDefault();
+ mField.setValue (defaultObject, true);
+ //
+ m_wEditors.add (wEditor); // add to Editors
+
+ row.appendChild(wEditor.getLabel());
+ //
+ if (voF.isRange)
+ {
+ Hbox box = new Hbox();
+ box.appendChild(wEditor.getComponent());
+ //
+ GridFieldVO voF2 = GridFieldVO.createParameter(voF);
+ GridField mField2 = new GridField (voF2);
+ m_mFields2.add (mField2);
+ // The Editor
+ WEditor wEditor2 = WebEditorFactory.getEditor(mField2, false);
+ // New Field value to be updated to editor
+ mField2.addPropertyChangeListener(wEditor2);
+ // Set Default
+ Object defaultObject2 = mField2.getDefault();
+ mField2.setValue (defaultObject2, true);
+ //
+ m_wEditors2.add (wEditor2);
+ box.appendChild(new Label(" - "));
+ box.appendChild(wEditor2.getComponent());
+ row.appendChild(box);
+ }
+ else
+ {
+ row.appendChild(wEditor.getComponent());
+ m_mFields2.add (null);
+ m_wEditors2.add (null);
+ }
+ rows.appendChild(row);
+ } // createField
+
+
+
+ /**
+ * Save Parameter values
+ * @return true if parameters saved
+ */
+ public boolean saveParameters()
+ {
+ log.config("");
+
+ /**
+ * Mandatory fields
+ * see - MTable.getMandatory
+ */
+ StringBuffer sb = new StringBuffer();
+ int size = m_mFields.size();
+ for (int i = 0; i < size; i++)
+ {
+ GridField field = (GridField)m_mFields.get(i);
+ if (field.isMandatory(true)) // check context
+ {
+ WEditor wEditor = (WEditor)m_wEditors.get(i);
+ Object data = wEditor.getValue();
+ if (data == null || data.toString().length() == 0)
+ {
+ field.setInserting (true); // set editable (i.e. updateable) otherwise deadlock
+ field.setError(true);
+ if (sb.length() > 0)
+ sb.append(", ");
+ sb.append(field.getHeader());
+ }
+ else
+ field.setError(false);
+ // Check for Range
+ WEditor wEditor2 = (WEditor)m_wEditors2.get(i);
+ if (wEditor2 != null)
+ {
+ Object data2 = wEditor.getValue();
+ GridField field2 = (GridField)m_mFields2.get(i);
+ if (data2 == null || data2.toString().length() == 0)
+ {
+ field.setInserting (true); // set editable (i.e. updateable) otherwise deadlock
+ field2.setError(true);
+ if (sb.length() > 0)
+ sb.append(", ");
+ sb.append(field.getHeader());
+ }
+ else
+ field2.setError(false);
+ } // range field
+ } // mandatory
+ } // field loop
+
+
+ if (sb.length() != 0)
+ {
+ //ADialog.error(m_WindowNo, this, "FillMandatory", sb.toString());
+ return false;
+ }
+
+ /**********************************************************************
+ * Save Now
+ */
+ for (int i = 0; i < m_mFields.size(); i++)
+ {
+ // Get Values
+ WEditor editor = (WEditor)m_wEditors.get(i);
+ WEditor editor2 = (WEditor)m_wEditors2.get(i);
+ Object result = editor.getValue();
+ Object result2 = null;
+ if (editor2 != null)
+ result2 = editor2.getValue();
+
+ // Don't save NULL values
+ if (result == null && result2 == null)
+ continue;
+
+ // Create Parameter
+ MPInstancePara para = new MPInstancePara (Env.getCtx(), m_processInfo.getAD_PInstance_ID(), i);
+ GridField mField = (GridField)m_mFields.get(i);
+ para.setParameterName(mField.getColumnName());
+
+ // Date
+ if (result instanceof Timestamp || result2 instanceof Timestamp)
+ {
+ para.setP_Date((Timestamp)result);
+ if (editor2 != null && result2 != null)
+ para.setP_Date_To((Timestamp)result2);
+ }
+ // Integer
+ else if (result instanceof Integer || result2 instanceof Integer)
+ {
+ if (result != null)
+ {
+ Integer ii = (Integer)result;
+ para.setP_Number(ii.intValue());
+ }
+ if (editor2 != null && result2 != null)
+ {
+ Integer ii = (Integer)result2;
+ para.setP_Number_To(ii.intValue());
+ }
+ }
+ // BigDecimal
+ else if (result instanceof BigDecimal || result2 instanceof BigDecimal)
+ {
+ para.setP_Number ((BigDecimal)result);
+ if (editor2 != null && result2 != null)
+ para.setP_Number_To ((BigDecimal)result2);
+ }
+ // Boolean
+ else if (result instanceof Boolean)
+ {
+ Boolean bb = (Boolean)result;
+ String value = bb.booleanValue() ? "Y" : "N";
+ para.setP_String (value);
+ // to does not make sense
+ }
+ // String
+ else
+ {
+ if (result != null)
+ para.setP_String (result.toString());
+ if (editor2 != null && result2 != null)
+ para.setP_String_To (result2.toString());
+ }
+
+ // Info
+ para.setInfo (editor.getDisplay());
+ if (editor2 != null)
+ para.setInfo_To (editor2.getDisplay());
+ //
+ para.save();
+ log.fine(para.toString());
+ } // for every parameter
+
+ return true;
+ } // saveParameters
+
+ /**
+ * Editor Listener
+ * @param evt ValueChangeEvent
+
+ */
+
+ public void valueChange(ValueChangeEvent evt)
+ {
+ String value = evt.getNewValue() == null ? "" : evt.getNewValue().toString();
+
+ if (evt.getSource() instanceof WEditor)
+ {
+ WEditor comp = (WEditor)(evt.getSource());
+ comp.setValue(value);
+
+ }
+ Env.setContext(Env.getCtx(), m_WindowNo, evt.getPropertyName(), value);
+
+ }
+ /**
+ * Restore window context.
+ * @author teo_sarca [ 1699826 ]
+ * @see org.compiere.model.GridField#restoreValue()
+ */
+ protected void restoreContext() {
+ for (GridField f : m_mFields) {
+ if (f != null)
+ f.restoreValue();
+ }
+ for (GridField f : m_mFields2) {
+ if (f != null)
+ f.restoreValue();
+ }
+ }
+ } // ProcessParameterPanel
+
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/WReport.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/WReport.java
new file mode 100644
index 0000000000..c3fb613edc
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/WReport.java
@@ -0,0 +1,251 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 2007 Adempiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ *
+ * Copyright (C) 2007 Low Heng Sin hengsin@avantz.com
+ * _____________________________________________
+ *****************************************************************************/
+package org.adempiere.webui.apps;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.logging.Level;
+
+import javax.sql.RowSet;
+
+import org.adempiere.webui.component.Listbox;
+import org.adempiere.webui.component.Window;
+import org.adempiere.webui.window.FDialog;
+import org.compiere.apps.ProcessCtl;
+import org.compiere.model.MQuery;
+import org.compiere.model.MRole;
+import org.compiere.model.MTable;
+import org.compiere.model.PrintInfo;
+import org.compiere.print.AReport;
+import org.compiere.print.MPrintFormat;
+import org.compiere.print.ReportCtl;
+import org.compiere.print.ReportEngine;
+import org.compiere.process.ProcessInfo;
+import org.compiere.util.ASyncProcess;
+import org.compiere.util.CLogger;
+import org.compiere.util.Env;
+import org.compiere.util.KeyNamePair;
+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.ListModelList;
+
+/**
+ * Base on org.compiere.print.AReport
+ * @author Low Heng Sin
+ *
+ */
+public class WReport implements EventListener {
+
+ /**
+ * Constructor
+ *
+ * @param AD_Table_ID table
+ * @param invoker component to display popup (optional)
+ * @param query query
+ */
+ public WReport (int AD_Table_ID, MQuery query)
+ {
+ new WReport(AD_Table_ID, query, null, 0);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param AD_Table_ID table
+ * @param invoker component to display popup (optional)
+ * @param query query
+ * @param parent The invoking parent window
+ * @param WindowNo The invoking parent window number
+ */
+ public WReport (int AD_Table_ID, MQuery query, ASyncProcess parent,
+ int WindowNo)
+ {
+ log.config("AD_Table_ID=" + AD_Table_ID + " " + query);
+ if (!MRole.getDefault().isCanReport(AD_Table_ID))
+ {
+ FDialog.error(0, "AccessCannotReport", query.getTableName());
+ return;
+ }
+
+ m_query = query;
+ this.parent = parent;
+ this.WindowNo = WindowNo;
+
+ // See What is there
+ getPrintFormats (AD_Table_ID);
+ } // AReport
+
+ /** The Query */
+ private MQuery m_query;
+ /** The Popup */
+ private Listbox m_listbox;
+ private Window m_popup;
+ /** The Option List */
+ private ArrayList m_list = new ArrayList();
+ /** Logger */
+ private static CLogger log = CLogger.getCLogger(AReport.class);
+ /** The parent window for locking/unlocking during process execution */
+ ASyncProcess parent;
+ /** The parent window number */
+ int WindowNo;
+
+ /**
+ * Get the Print Formats for the table.
+ * Fill the list and the popup menu
+ * @param AD_Table_ID table
+ * @param invoker component to display popup (optional)
+ */
+ private void getPrintFormats (int AD_Table_ID)
+ {
+ int AD_Client_ID = Env.getAD_Client_ID(Env.getCtx());
+ RowSet rowSet = MPrintFormat.getAccessiblePrintFormats(AD_Table_ID, -1, null);
+ KeyNamePair pp = null;
+ try
+ {
+ while (rowSet.next())
+ {
+ pp = new KeyNamePair (rowSet.getInt(1), rowSet.getString(2));
+ if (rowSet.getInt(3) == AD_Client_ID)
+ {
+ m_list.add(pp);
+ }
+ }
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, e.getLocalizedMessage(), e);
+ }
+
+ // No Format exists - create it
+ if (m_list.size() == 0)
+ {
+ if (pp == null)
+ createNewFormat (AD_Table_ID); // calls launch
+ else
+ copyFormat(pp.getKey(), AD_Client_ID);
+ }
+ // One Format exists or no invoker - show it
+ else if (m_list.size() == 1)
+ launchReport ((KeyNamePair)m_list.get(0));
+ // Multiple Formats exist - show selection
+ else
+ showPopup(); // below button
+ } // getPrintFormats
+
+ private void showPopup() {
+ m_listbox = new Listbox();
+ m_listbox.setModel(ListModelList.instance(m_list));
+ m_listbox.addEventListener(Events.ON_SELECT, this);
+ m_listbox.setHeight("300px");
+ m_popup = new Window();
+ m_popup.setTitle("Select Report");
+ m_popup.appendChild(m_listbox);
+ m_popup.setAttribute("mode", "popup");
+ m_popup.setWidth("200px");
+ m_popup.setPosition("center");
+ AEnv.showWindow(m_popup);
+ }
+
+ /**
+ * Create and Launch new Format for table
+ * @param AD_Table_ID table
+ */
+ private void createNewFormat (int AD_Table_ID)
+ {
+ MPrintFormat pf = MPrintFormat.createFromTable(Env.getCtx(), AD_Table_ID);
+ launchReport (pf);
+ } // createNewFormat
+
+ /**
+ * Copy existing Format
+ * @param AD_PrintFormat_ID print format
+ * @param To_Client_ID to client
+ */
+ private void copyFormat (int AD_PrintFormat_ID, int To_Client_ID)
+ {
+ MPrintFormat pf = MPrintFormat.copyToClient(Env.getCtx(), AD_PrintFormat_ID, To_Client_ID);
+ launchReport (pf);
+ } // copyFormatFromClient
+
+ /**
+ * Launch Report
+ * @param pp Key=AD_PrintFormat_ID
+ */
+ private void launchReport (KeyNamePair pp)
+ {
+ MPrintFormat pf = MPrintFormat.get(Env.getCtx(), pp.getKey(), false);
+ launchReport (pf);
+ } // launchReport
+
+ /**
+ * Launch Report
+ * @param pf print format
+ */
+ private void launchReport (MPrintFormat pf)
+ {
+ int Record_ID = 0;
+ if (m_query.getRestrictionCount()==1 && m_query.getCode(0) instanceof Integer)
+ Record_ID = ((Integer)m_query.getCode(0)).intValue();
+ PrintInfo info = new PrintInfo(
+ pf.getName(),
+ pf.getAD_Table_ID(),
+ Record_ID);
+ info.setDescription(m_query.getInfo());
+
+ if(pf != null && pf.getJasperProcess_ID() > 0)
+ {
+ // It's a report using the JasperReports engine
+ ProcessInfo pi = new ProcessInfo ("", pf.getJasperProcess_ID());
+
+ // Execute Process
+ ProcessCtl worker = ProcessCtl.process(parent, WindowNo, pi, null);
+ }
+ else
+ {
+ // It's a default report using the standard printing engine
+ ReportEngine re = new ReportEngine (Env.getCtx(), pf, m_query, info);
+ ReportCtl.preview(re);
+ }
+ } // launchReport
+
+ /**************************************************************************
+ * Get AD_Table_ID for Table Name
+ * @param tableName table name
+ * @return AD_Table_ID or 0
+ */
+ public static int getAD_Table_ID (String tableName)
+ {
+ return MTable.getTable_ID(tableName);
+ } // getAD_Table_ID
+
+ public boolean isAsap() {
+ return true;
+ }
+
+ public void onEvent(Event event) {
+ if (event.getTarget() == m_listbox) {
+ int i = m_listbox.getSelectedIndex();
+ if (i >= 0 ) {
+ KeyNamePair pp = (KeyNamePair)m_list.get(i);
+ m_popup.setVisible(false);
+ m_popup.detach();
+ launchReport (pp);
+ }
+ }
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WAllocation.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WAllocation.java
new file mode 100755
index 0000000000..81ce82961d
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WAllocation.java
@@ -0,0 +1,2157 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
+ * or via info@compiere.org or http://www.compiere.org/license.html *
+ *****************************************************************************/
+
+/**
+ * 2007, Modified by Posterita Ltd.
+ */
+
+package org.adempiere.webui.apps.form;
+
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.Vector;
+import java.util.logging.Level;
+
+import org.adempiere.webui.component.Button;
+import org.adempiere.webui.component.Checkbox;
+import org.adempiere.webui.component.Grid;
+import org.adempiere.webui.component.ListModelTable;
+import org.adempiere.webui.component.Panel;
+import org.adempiere.webui.component.Row;
+import org.adempiere.webui.component.Rows;
+import org.adempiere.webui.component.Textbox;
+import org.adempiere.webui.component.WListbox;
+import org.adempiere.webui.component.WStatusBar;
+import org.adempiere.webui.editor.WDateEditor;
+import org.adempiere.webui.editor.WEditor;
+import org.adempiere.webui.editor.WSearchEditor;
+import org.adempiere.webui.editor.WTableDirEditor;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.event.ValueChangeListener;
+import org.adempiere.webui.event.WTableModelEvent;
+import org.adempiere.webui.event.WTableModelListener;
+import org.adempiere.webui.panel.ADForm;
+import org.adempiere.webui.window.FDialog;
+import org.compiere.model.MAllocationHdr;
+import org.compiere.model.MAllocationLine;
+import org.compiere.model.MInvoice;
+import org.compiere.model.MLookup;
+import org.compiere.model.MLookupFactory;
+import org.compiere.model.MPayment;
+import org.compiere.process.DocAction;
+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.TimeUtil;
+import org.compiere.util.Trx;
+import org.compiere.util.Util;
+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.Hbox;
+import org.zkoss.zul.Label;
+import org.zkoss.zul.Separator;
+import org.zkoss.zul.Space;
+import org.zkoss.zul.Vbox;
+import org.zkoss.zul.event.ListDataEvent;
+
+
+/**
+ * Allocation panel. Panel for selecting sets of invoices and payments to
+ * process. The panel contains a set of paramater components that select and
+ * filter the invoices and payments, a panel for displaying and selecting
+ * invoices, a panel for selecting and displaying payments, and a panel for
+ * allocating payments.
+ *
+ *
+ * @author Andrew Kimball
+ *
+ */
+public class WAllocation extends ADForm implements EventListener,
+ ValueChangeListener, WTableModelListener
+{
+ /*
+ * TODO A lot of the code here replicates code in the rich client version of
+ * VAllocation. Creating a common superclass would remove a lot of this
+ * duplication.
+ */
+
+ /** Unique identifier. */
+ private static final long serialVersionUID = 1L;
+
+ /** */
+ private Panel m_pnlMain = new Panel();
+
+ /** Parameter panel. */
+ private Panel m_pnlParameter = new Panel();
+ /** Parameter grid. */
+ private Grid m_grdParameter = new Grid();
+ /** Business Partner label. */
+ private Label m_lblBusinessPartner = new Label();
+ /** Business Partner search editor. */
+ private WEditor m_wedBusinessPartnerSearch = null;
+ /** Currency label. */
+ private Label m_lblCurrency = new Label();
+ /** Currency pick editor. */
+ private WEditor m_wedCurrencyPick = null;
+ /** Date label. */
+ private Label m_lblDate = new Label();
+ /** Date Field editor. */
+ private WDateEditor m_wdeDateField = new WDateEditor();
+ /** Multi Currency checkbox. */
+ private Checkbox m_chbMultiCurrency = new Checkbox();
+
+ /** Payment panel. */
+ private Panel m_pnlPayment = new Panel();
+ /** Payment Panel label. */
+ private Label m_lblPayment = new Label();
+ /** Payment Info label. */
+ private Label m_lblPaymentInfo = new Label();
+ /** Payment Info table. */
+ private WListbox m_lsbPayments = new WListbox();
+
+ /** Invoice panel. */
+ private Panel m_pnlInvoice = new Panel();
+ /** Invoice Panel label. */
+ private Label m_lblInvoice = new Label();
+ /** Invoice Info label. */
+ private Label m_lblInvoiceInfo = new Label();
+ /** Invoice Info table. */
+ private WListbox m_lsbInvoices = new WListbox();
+
+ /** Panel to group Invoice and Payment panels. */
+ private Panel m_pnlInfo = new Panel();
+
+ /** Allocation panel. */
+ private Panel m_pnlAllocate = new Panel();
+ /** Difference label. */
+ private Label m_lblDifference = new Label();
+ /** Difference field. */
+ private Textbox m_txbDifferenceField = new Textbox();
+ /** Allocation button. */
+ private Button m_btnAllocate = new Button();
+ /** Allocation Currency label. */
+ private Label m_lblAllocCurrency = new Label();
+ /** Automatic write-off checkbox. */
+ private Checkbox m_chbAutoWriteOff = new Checkbox();
+
+ /** Status Bar. */
+ private WStatusBar m_statusBar = new WStatusBar();
+
+ /** true if a calculation is currentl being performed. */
+ private boolean m_isCalculating = false;
+
+ /** index of selected currency. */
+ private int m_currencyId = 0;
+
+ /** index of selected business partner. */
+ private int m_businessPartnerId = 0;
+
+ /** number of affected invoices. */
+ private int m_noSelectedInvoices = 0;
+
+ /** number of affected payments. */
+ private int m_noSelectedPayments = 0;
+
+ /** the index of the last row containing an invoice. */
+ private int m_rowLastInvoice = 0;
+
+ private ArrayList m_bPartnerCheck = new ArrayList();
+
+ /** index of the selected column. */
+ static final private int ms_selectedColIndex = 0;
+
+ /** index of the date column. */
+ static final private int ms_dateColIndex = 1;
+
+ /** index of the value column. */
+ static final private int ms_valueColIndex = 2;
+
+ // Index changed if multi-currency (either 5 or 7)
+ /** index of the payment column. */
+ private int m_paymentColIndex = 7;
+
+ /** index of the open column. */
+ private int m_openColIndex = 6;
+
+ /** index of the discount column. */
+ private int m_discountColIndex = 7;
+
+ /** index of the write-off column. */
+ private int m_writeOffColIndex = 8;
+
+ /** index of the applied column. */
+ private int m_appliedColIndex = 9;
+
+ /** value of total payments */
+ private BigDecimal m_totalPayment = new BigDecimal(0.0);
+
+ /** value of total invoice */
+ private BigDecimal m_totalInvoiced = new BigDecimal(0.0);
+
+ /** value of total credit */
+ private BigDecimal m_totalCredit = new BigDecimal(0.0);
+
+ /** enumeration of the possible types of allocation */
+ private enum EIndicator
+ {
+ /** No allocation. */
+ NONE,
+ /** Total payment = Total invoiced. */
+ TOTAL_PAY,
+ /**
+ * Subpayment
+ *
+ * issotrx=y
+ */
+ SUBPAYMENT_SO,
+ /**
+ * Total payment > Total invoiced.
+ *
+ * issotrx=y
+ */
+ GREATER_PAYMENT_SO,
+ /** Subpayment with credit note. */
+ CREDIT_MEMO,
+ /**
+ * Total payment > Total invoiced
+ *
+ * issotrx=n
+ */
+ GREATER_PAYMENT_PO,
+ /**
+ * Total payment < Total invoiced
+ *
+ * issotrx=n
+ */
+ GREATER_INVOICED_PO,
+ /** Credit emo > Invoiced. */
+ GREATER_CREDIT
+ }
+
+ /** Indicator for the type of allocation being made. */
+ private EIndicator m_eIndicator = EIndicator.NONE;
+
+ /** column index for Invoice. */
+ private int m_invoiceIndex = 0;
+
+ /** column index for credit. */
+ private int m_creditIndex = 0;
+
+ /**
+ * Default constructor.
+ */
+ public WAllocation()
+ {
+ super();
+ }
+
+ /**
+ * Create a panel containing details of payments.
+ *
+ * @see #createInfoPanel()
+ * @see #createInvoicePanel()
+ */
+ private void createPaymentPanel()
+ {
+ Hbox hbox = new Hbox();
+
+ // Put the table label at the top of this panel
+ hbox.setWidth("98%");
+ m_lblPayment.setValue(Msg.translate(Env.getCtx(), "C_Payment_ID"));
+ hbox.setStyle("text-align:left");
+ hbox.appendChild(m_lblPayment);
+ m_pnlPayment.appendChild(hbox);
+
+ // Add the payment details table
+ m_lsbPayments.setWidth(null);
+ m_lsbPayments.setRows(10);
+ m_pnlPayment.appendChild(m_lsbPayments);
+
+ // Put the selected payment information just below the table and
+ // right-align it
+ hbox = new Hbox();
+ hbox.setWidth("98%");
+ m_lblPaymentInfo.setValue(".");
+ hbox.setStyle("text-align:right");
+ hbox.appendChild(m_lblPaymentInfo);
+ m_pnlPayment.appendChild(hbox);
+
+ return;
+ }
+
+ /**
+ * Create a panel containing details of invoices
+ *
+ * @see #createInfoPanel()
+ * @see #createPaymentPanel()
+ */
+ private void createInvoicePanel()
+ {
+ Hbox hbox = new Hbox();
+
+ // Put the table label at the top of this panel
+ hbox.setWidth("98%");
+ m_lblInvoice.setValue(Msg.translate(Env.getCtx(), "C_Invoice_ID"));
+ hbox.setStyle("text-align:left");
+ hbox.appendChild(m_lblInvoice);
+ m_pnlInvoice.appendChild(hbox);
+
+ // Add the invoice details table
+ m_lsbInvoices.setWidth(null);
+ m_lsbInvoices.setRows(10);
+ m_pnlInvoice.appendChild(m_lsbInvoices);
+
+ // Put the selected invoice information just below the table and
+ // right-align it
+ hbox = new Hbox();
+ hbox.setWidth("98%");
+ m_lblInvoiceInfo.setValue(".");
+ hbox.setStyle("text-align:right");
+ hbox.appendChild(m_lblInvoiceInfo);
+ m_pnlInvoice.appendChild(hbox);
+
+ return;
+ }
+
+ /**
+ * Create a panel containing details of payments and invoices.
+ *
+ * @see #createInvoicePanel()
+ * @see #createPaymentPanel()
+ */
+ private void createInfoPanel()
+ {
+ Vbox vbox = new Vbox();
+ Separator separator = new Separator();
+
+ vbox.setWidth("98%");
+ vbox.setHeight("200px");
+ vbox.setHeights("45%,5%,45%");
+
+ // Put the payment panel in the top half of the box
+ createPaymentPanel();
+ vbox.appendChild(m_pnlPayment);
+
+ // adda separator between the two panels
+ // this should be a splitter, but splitters don't work with Listboxes
+ separator.setBar(true);
+ vbox.appendChild(separator);
+
+ // Put the invoice panel in the bottom half of the box
+ createInvoicePanel();
+ vbox.appendChild(m_pnlInvoice);
+
+ // add the box to the panel
+ m_pnlInfo.appendChild(vbox);
+
+ return;
+ }
+
+ /**
+ * Create a panel containing components to enable allocations of payments to
+ * invoices.
+ */
+ private void createAllocationPanel()
+ {
+ Hbox box = new Hbox();
+
+ // align the components
+ box.setValign("center");
+
+ // First add the difference label
+ m_lblDifference.setValue(Msg.getMsg(Env.getCtx(), "Difference"));
+ box.appendChild(m_lblDifference);
+
+ // Then put a label showing the currency
+ m_lblAllocCurrency.setValue(".");
+ box.appendChild(m_lblAllocCurrency);
+
+ // Then add the label showing the difference between the selected
+ // payment and invoice
+ // amounts
+ m_txbDifferenceField.setReadonly(true);
+ m_txbDifferenceField.setText("0");
+ m_txbDifferenceField.setCols(8);
+ m_txbDifferenceField.setStyle("text-align:right");
+ box.appendChild(m_txbDifferenceField);
+
+ // Then add the auto write-off checkbox
+ m_chbAutoWriteOff.setChecked(false);
+ m_chbAutoWriteOff.setLabel(Msg.getMsg(Env.getCtx(), "AutoWriteOff", true));
+ m_chbAutoWriteOff.setTooltiptext(Msg.getMsg(Env.getCtx(), "AutoWriteOff",
+ false));
+ box.appendChild(m_chbAutoWriteOff);
+
+ // Finally add the allocate button
+ m_btnAllocate.setLabel(Msg.getMsg(Env.getCtx(), "Process"));
+ box.appendChild(m_btnAllocate);
+ m_btnAllocate.addEventListener(Events.ON_CLICK, this);
+
+ // Add the complete box to the panel
+ m_pnlAllocate.appendChild(box);
+
+ return;
+ }
+
+ /**
+ * Create the panel containing the business partner, currency and date
+ * parameters.
+ *
+ * These parameters are used for filtering and displaying
+ * invoices and payments.
+ */
+ private void createParameterPanel()
+ {
+ Rows rows = new Rows();
+ Row rowTop = new Row();
+ Row rowBottom = new Row();
+
+ // set the labels
+ m_lblDate.setValue(Msg.getMsg(Env.getCtx(), "Date"));
+ m_lblCurrency.setValue(Msg.translate(Env.getCtx(), "C_Currency_ID"));
+ m_lblBusinessPartner.setValue(Msg.translate(Env.getCtx(), "C_BPartner_ID"));
+ m_chbMultiCurrency.setLabel(Msg.getMsg(Env.getCtx(), "MultiCurrency"));
+ m_chbMultiCurrency.addEventListener(Events.ON_CHECK, this);
+
+ rowTop.setAlign("left");
+ rowTop.setStyle("text-align:right");
+ rowBottom.setAlign("left");
+ rowBottom.setStyle("text-align:right");
+
+ // add the business partner search box to the top row
+ rowTop.appendChild(m_lblBusinessPartner);
+ rowTop.appendChild(m_wedBusinessPartnerSearch.getComponent());
+
+ // add the date box to the top row
+ rowTop.appendChild(m_lblDate);
+ rowTop.appendChild(m_wdeDateField.getComponent());
+
+ rows.appendChild(rowTop);
+
+ // add the currency search box to the bottom row
+ rowBottom.appendChild(m_lblCurrency);
+ rowBottom.appendChild(m_wedCurrencyPick.getComponent());
+
+ // add the mult-currency check-box to the bottom row
+ rowBottom.appendChild(new Space());
+ rowBottom.appendChild(m_chbMultiCurrency);
+
+ // put it all together
+ rows.appendChild(rowBottom);
+
+ m_grdParameter.setWidth("600px");
+ m_grdParameter.appendChild(rows);
+
+ m_pnlParameter.appendChild(m_grdParameter);
+
+ return;
+ }
+
+ /**
+ * Initialise the panel.
+ *
+ * @param adFormId
+ * The Adempiere identifier for the form
+ * @param name
+ * The name of the form
+ */
+ public void init(int adFormId, String name)
+ {
+ super.init(adFormId, name);
+
+ m_currencyId = Env.getContextAsInt(Env.getCtx(), "$C_Currency_ID"); // default
+ logger.info("Currency=" + m_currencyId);
+
+ dynamicInitialise();
+
+ createParameterPanel();
+ m_pnlMain.appendChild(m_pnlParameter);
+
+ createInfoPanel();
+ m_pnlMain.appendChild(m_pnlInfo);
+
+ createAllocationPanel();
+ m_pnlMain.appendChild(m_pnlAllocate);
+
+ m_pnlMain.setAlign("center");
+
+ this.appendChild(m_pnlMain);
+
+ this.appendChild(m_statusBar);
+
+ this.setWidth("850px");
+
+ calculate();
+
+ return;
+ }
+
+ /**
+ * Create the components of the panel which have dynamic content.
+ *
+ */
+ private void dynamicInitialise()
+ {
+ // these magic numbers are copied from VAllocation
+ final int adCurrencyId = 3505; // C_Invoice.C_Currency_ID
+ final int adBPartnerId = 3499; // C_Invoice.C_BPartner_ID
+
+ // status bar
+ m_statusBar.setStatusLine(Msg.getMsg(Env.getCtx(), "AllocateStatus"));
+ m_statusBar.setStatusDB("");
+
+ // date field
+ m_wdeDateField.setValue(Env.getContextAsDate(Env.getCtx(), "#Date"));
+ m_wdeDateField.addValueChangeListner(this);
+
+ // business partner search edit box
+ MLookup lookupBP = MLookupFactory.get(Env.getCtx(), super.m_windowNo,
+ 0, adBPartnerId, DisplayType.Search);
+ m_wedBusinessPartnerSearch = new WSearchEditor(lookupBP, Msg.translate(
+ Env.getCtx(), "C_BPartner_ID"), "", true, false, true);
+ m_wedBusinessPartnerSearch.addValueChangeListner(this);
+
+ // currency pick search box
+ MLookup lookupCur = MLookupFactory.get(Env.getCtx(), super.m_windowNo,
+ 0, adCurrencyId, DisplayType.TableDir);
+ m_wedCurrencyPick = new WTableDirEditor(lookupCur, Msg.translate(Env
+ .getCtx(), "C_Currency_ID"), "", true, false, true);
+ m_wedCurrencyPick.addValueChangeListner(this);
+ m_wedCurrencyPick.setValue(new Integer(m_currencyId));
+
+ return;
+ }
+
+ /**
+ * Retrieve unallocated payments from the database and store them in the
+ * payments table.
+ */
+ private void loadUnallocatedPayments()
+ {
+ /*
+ * Load unallocated Payments 1-TrxDate, 2-DocumentNo, (3-Currency,
+ * 4-PayAmt,) 5-ConvAmt, 6-ConvOpen, 7-Allocated
+ */
+ Vector data = null;
+ // Header Info
+ Vector columnNames = getPaymentColumnNames();
+
+ data = getPaymentData();
+
+ // Set Model
+ ListModelTable model = new ListModelTable(data);
+ model.addTableModelListener(this);
+ m_lsbPayments.setData(model, columnNames);
+ //
+ setPaymentColumnClasses();
+
+ // removed terniary operator for clarity
+ if (m_chbMultiCurrency.isChecked())
+ {
+ m_paymentColIndex = 7;
+ }
+ else
+ {
+ m_paymentColIndex = 5;
+ }
+
+ // Table UI
+ // paymentTable.autoSize();
+
+ return;
+ }
+
+ /**
+ * Get the payment data.
+ *
+ * @return A vector containing the payment data
+ */
+ private Vector getPaymentData()
+ {
+ Vector data = new Vector();
+ ResultSet rs = null;
+ PreparedStatement pstmt = null;
+
+ try
+ {
+ pstmt = preparePaymentStatement();
+ rs = pstmt.executeQuery();
+
+ while (rs.next())
+ {
+ Vector line = new Vector();
+ line.add(new Boolean(false)); // 0-Selection
+ line.add(rs.getTimestamp(1)); // 1-TrxDate
+ KeyNamePair pp = new KeyNamePair(rs.getInt(3), rs.getString(2));
+ line.add(pp); // 2-DocumentNo
+ if (m_chbMultiCurrency.isChecked())
+ {
+ line.add(rs.getString(4)); // 3-Currency
+ line.add(rs.getBigDecimal(5)); // 4-PayAmt
+ }
+ line.add(rs.getBigDecimal(6)); // 3/5-ConvAmt
+ BigDecimal available = rs.getBigDecimal(7);
+ if (available == null || available.signum() == 0) // nothing
+ // available
+ {
+ continue;
+ }
+ line.add(available); // 4/6-ConvOpen/Available
+ line.add(Env.ZERO); // 5/7-Payment
+ //
+ data.add(line);
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException exception)
+ {
+ // TODO what to report here if don't have access to SQL statement
+ logger.log(Level.SEVERE, getPaymentSql(), exception);
+ }
+
+ return data;
+ }
+
+ /**
+ * Prepare the SQL statement for obtaining the unallocated payments.
+ *
+ * @return the precompiled SQL statement
+ * @throws SQLException
+ */
+ private PreparedStatement preparePaymentStatement() throws SQLException
+ {
+ String sql = getPaymentSql();
+ PreparedStatement pstmt = DB.prepareStatement(sql.toString(), null);
+ pstmt.setInt(1, m_currencyId);
+ pstmt.setInt(2, m_currencyId);
+ pstmt.setInt(3, m_businessPartnerId);
+
+ if (!m_chbMultiCurrency.isChecked())
+ {
+ pstmt.setInt(4, m_currencyId);
+ }
+ return pstmt;
+ }
+
+ /**
+ * Create the SQL statement for obtaining unallocated payments.
+ *
+ * @return the SQL statement for obtaining unallocated payments
+ */
+ private String getPaymentSql()
+ {
+ // Create SELECT statement
+ StringBuffer sql = new StringBuffer("SELECT p.DateTrx, "
+ + "p.DocumentNo, "
+ + "p.C_Payment_ID," // 1..3
+ + "c.ISO_Code, "
+ + "p.PayAmt," // 4..5
+ + "currencyConvert(p.PayAmt," + "p.C_Currency_ID,"
+ + "?,"
+ + "p.DateTrx,"
+ + "p.C_ConversionType_ID,"
+ + "p.AD_Client_ID,"
+ + "p.AD_Org_ID),"// 6 #1
+ + "currencyConvert(paymentAvailable(C_Payment_ID),"
+ + "p.C_Currency_ID," + "?," + "p.DateTrx,"
+ + "p.C_ConversionType_ID," + "p.AD_Client_ID,"
+ + "p.AD_Org_ID)," // 7 #2
+ + "p.MultiplierAP ");
+
+ // Append FROM clause
+ sql
+ .append("FROM C_Payment_v p" // Corrected for AP/AR
+ + " INNER JOIN C_Currency c ON (p.C_Currency_ID=c.C_Currency_ID) ");
+
+ // Append WHERE clause
+ sql.append("WHERE p.IsAllocated='N' AND p.Processed='Y'"
+ + " AND p.C_Charge_ID IS NULL" // Prepayments OK
+ + " AND p.C_BPartner_ID=?"); // #3
+
+ if (!m_chbMultiCurrency.isChecked())
+ {
+ sql.append(" AND p.C_Currency_ID=?"); // #4
+ }
+ sql.append(" ORDER BY p.DateTrx,p.DocumentNo");
+
+ logger.fine("PaySQL=" + sql.toString());
+
+ return sql.toString();
+ }
+
+ /**
+ * Set the classes and read-only property for all payment table columns.
+ */
+ private void setPaymentColumnClasses()
+ {
+ int columnIndex = 0;
+ m_lsbPayments.setColumnClass(columnIndex++, Boolean.class, false); // 0-Selection
+ m_lsbPayments.setColumnClass(columnIndex++, Timestamp.class, true); // 1-TrxDate
+ m_lsbPayments.setColumnClass(columnIndex++, String.class, true); // 2-Value
+ if (m_chbMultiCurrency.isChecked())
+ {
+ m_lsbPayments.setColumnClass(columnIndex++, String.class, true); // 3-Currency
+ m_lsbPayments.setColumnClass(columnIndex++, BigDecimal.class, true); // 4-PayAmt
+ }
+ m_lsbPayments.setColumnClass(columnIndex++, BigDecimal.class, true); // 5-ConvAmt
+ m_lsbPayments.setColumnClass(columnIndex++, BigDecimal.class, true); // 6-ConvOpen
+ m_lsbPayments.setColumnClass(columnIndex++, BigDecimal.class, false); // 7-Allocated
+
+ return;
+ }
+
+ /**
+ * Get a all of the columnn names.
+ *
+ * @return vector containing all of the column names
+ */
+ private Vector getPaymentColumnNames()
+ {
+ Vector columnNames = new Vector();
+ columnNames.add(Msg.getMsg(Env.getCtx(), "Select"));
+ columnNames.add(Msg.translate(Env.getCtx(), "Date"));
+ columnNames.add(Util
+ .cleanAmp(Msg.translate(Env.getCtx(), "DocumentNo")));
+ if (m_chbMultiCurrency.isChecked())
+ {
+ columnNames.add(Msg.getMsg(Env.getCtx(), "TrxCurrency"));
+ columnNames.add(Msg.translate(Env.getCtx(), "Amount"));
+ }
+ columnNames.add(Msg.getMsg(Env.getCtx(), "ConvertedAmount"));
+ columnNames.add(Msg.getMsg(Env.getCtx(), "OpenAmt"));
+ columnNames.add(Msg.getMsg(Env.getCtx(), "AppliedAmt"));
+ return columnNames;
+ }
+
+ /**
+ *
+ *
+ */
+ private void loadUnpaidInvoices()
+ {
+ /*
+ * Load unpaid Invoices 1-TrxDate, 2-Value, (3-Currency, 4-InvAmt,)
+ * 5-ConvAmt, 6-ConvOpen, 7-ConvDisc, 8-WriteOff, 9-Applied
+ *
+ * SELECT i.DateInvoiced,i.DocumentNo,i.C_Invoice_ID,c.ISO_Code,
+ * i.GrandTotal*i.MultiplierAP "GrandTotal",
+ * currencyConvert(i.GrandTotal*i.MultiplierAP,i.C_Currency_ID,i.C_Currency_ID,i.DateInvoiced,i.C_ConversionType_ID,i.AD_Client_ID,i.AD_Org_ID)
+ * "GrandTotal $", invoiceOpen(C_Invoice_ID,C_InvoicePaySchedule_ID)
+ * "Open",
+ * currencyConvert(invoiceOpen(C_Invoice_ID,C_InvoicePaySchedule_ID),i.C_Currency_ID,i.C_Currency_ID,i.DateInvoiced,i.C_ConversionType_ID,i.AD_Client_ID,i.AD_Org_ID)*i.MultiplierAP
+ * "Open $",
+ * invoiceDiscount(i.C_Invoice_ID,SysDate,C_InvoicePaySchedule_ID)
+ * "Discount",
+ * currencyConvert(invoiceDiscount(i.C_Invoice_ID,SysDate,C_InvoicePaySchedule_ID),i.C_Currency_ID,i.C_Currency_ID,i.DateInvoiced,i.C_ConversionType_ID,i.AD_Client_ID,i.AD_Org_ID)*i.Multiplier*i.MultiplierAP
+ * "Discount $", i.MultiplierAP, i.Multiplier FROM C_Invoice_v i INNER
+ * JOIN C_Currency c ON (i.C_Currency_ID=c.C_Currency_ID) WHERE --
+ * i.IsPaid='N' AND i.Processed='Y' AND i.C_BPartner_ID=1000001
+ */
+ Vector data = new Vector();
+ // Header Info
+ Vector columnNames = getInvoiceColumnNames();
+ ResultSet rs = null;
+ PreparedStatement pstmt = null;
+
+ try
+ {
+ pstmt = prepareInvoiceStatement();
+ rs = pstmt.executeQuery();
+
+ while (rs.next())
+ {
+ Vector line = new Vector();
+ line.add(new Boolean(false)); // 0-Selection
+ line.add(rs.getTimestamp(1)); // 1-TrxDate
+ KeyNamePair pp = new KeyNamePair(rs.getInt(3), rs.getString(2));
+ line.add(pp); // 2-Value
+ if (m_chbMultiCurrency.isChecked())
+ {
+ line.add(rs.getString(4)); // 3-Currency
+ line.add(rs.getBigDecimal(5)); // 4-Orig Amount
+ }
+ line.add(rs.getBigDecimal(6)); // 3/5-ConvAmt
+ BigDecimal open = rs.getBigDecimal(7);
+ if (open == null) // no conversion rate
+ {
+ open = Env.ZERO;
+ }
+ line.add(open); // 4/6-ConvOpen
+ BigDecimal discount = rs.getBigDecimal(8);
+ if (discount == null) // no conversion rate
+ {
+ discount = Env.ZERO;
+ }
+ line.add(discount); // 5/7-ConvAllowedDisc
+ line.add(Env.ZERO); // 6/8-WriteOff
+ line.add(Env.ZERO); // 7/9-Applied
+
+ // Add when open <> 0 (i.e. not if no conversion rate)
+ if (Env.ZERO.compareTo(open) != 0)
+ {
+ data.add(line);
+ }
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException exception)
+ {
+ logger.log(Level.SEVERE, getInvoiceSql(), exception);
+ }
+
+ // Remove previous listeners
+ // TODO
+ // invoiceTable.getModel().removeTableModelListener(this);
+
+ ListModelTable model = new ListModelTable(data);
+ model.addTableModelListener(this);
+ m_lsbInvoices.setData(model, columnNames);
+
+ // set column data
+ setInvoiceColumnClasses();
+
+ // TODO Table UI
+ // invoiceTable.autoSize();
+
+ return;
+ }
+
+ /**
+ * Prepare the SQL statement for obtaining the unallocated invoices.
+ *
+ * @return the precompiled SQL statement
+ * @throws SQLException
+ */
+ private PreparedStatement prepareInvoiceStatement() throws SQLException
+ {
+ String sql = getInvoiceSql();
+ PreparedStatement pstmt = DB.prepareStatement(sql, null);
+
+ pstmt.setInt(1, m_currencyId);
+ pstmt.setInt(2, m_currencyId);
+ pstmt.setTimestamp(3, (Timestamp) m_wdeDateField.getValue());
+ pstmt.setInt(4, m_currencyId);
+ pstmt.setInt(5, m_businessPartnerId);
+
+ if (!m_chbMultiCurrency.isChecked())
+ {
+ pstmt.setInt(6, m_currencyId);
+ }
+
+ return pstmt;
+ }
+
+ /**
+ * Get all of the columnn names for the invoice table.
+ *
+ * @return vector containing all of the column names
+ */
+ private Vector getInvoiceColumnNames()
+ {
+ Vector columnNames = new Vector();
+
+ columnNames.add(Msg.getMsg(Env.getCtx(), "Select"));
+ columnNames.add(Msg.translate(Env.getCtx(), "Date"));
+ columnNames.add(Util
+ .cleanAmp(Msg.translate(Env.getCtx(), "DocumentNo")));
+ if (m_chbMultiCurrency.isChecked())
+ {
+ columnNames.add(Msg.getMsg(Env.getCtx(), "TrxCurrency"));
+ columnNames.add(Msg.translate(Env.getCtx(), "Amount"));
+ }
+ columnNames.add(Msg.getMsg(Env.getCtx(), "ConvertedAmount"));
+ columnNames.add(Msg.getMsg(Env.getCtx(), "OpenAmt"));
+ columnNames.add(Msg.getMsg(Env.getCtx(), "Discount"));
+ columnNames.add(Msg.getMsg(Env.getCtx(), "WriteOff"));
+ columnNames.add(Msg.getMsg(Env.getCtx(), "AppliedAmt"));
+
+ return columnNames;
+ }
+
+ /**
+ * Set the classes and read-only property for all invoice table columns.
+ */
+ private void setInvoiceColumnClasses()
+ {
+ int columnIndex = 0;
+ m_lsbInvoices.setColumnClass(columnIndex++, Boolean.class, false); // 0-Selection
+ m_lsbInvoices.setColumnClass(columnIndex++, Timestamp.class, true); // 1-TrxDate
+ m_lsbInvoices.setColumnClass(columnIndex++, String.class, true); // 2-Value
+ if (m_chbMultiCurrency.isChecked())
+ {
+ m_lsbInvoices.setColumnClass(columnIndex++, String.class, true); // 3-Currency
+ m_lsbInvoices.setColumnClass(columnIndex++, BigDecimal.class, true); // 4-Amt
+ }
+ m_lsbInvoices.setColumnClass(columnIndex++, BigDecimal.class, true); // 5-ConvAmt
+ m_lsbInvoices.setColumnClass(columnIndex++, BigDecimal.class, true); // 6-ConvAmt
+ // Open
+ m_lsbInvoices.setColumnClass(columnIndex++, BigDecimal.class, false); // 7-Conv
+ // Discount
+ m_lsbInvoices.setColumnClass(columnIndex++, BigDecimal.class, false); // 8-Conv
+ // WriteOff
+ m_lsbInvoices.setColumnClass(columnIndex++, BigDecimal.class, false); // 9-Conv
+ // Applied
+ }
+
+ /**
+ * Create the SQL statement for obtaining unallocated invoices.
+ *
+ * @return the SQL statement for obtaining unallocated invoices
+ */
+ private String getInvoiceSql()
+ {
+ StringBuffer sql = new StringBuffer(
+ "SELECT i.DateInvoiced, "
+ + "i.DocumentNo, "
+ + "i.C_Invoice_ID," // 1..3
+ + "c.ISO_Code, "
+ + "i.GrandTotal * i.MultiplierAP, " // 4..5
+ // Orig
+ // Currency
+ + "currencyConvert(i.GrandTotal * i.MultiplierAP, "
+ + "i.C_Currency_ID, "
+ + "?, "
+ + "i.DateInvoiced, "
+ + "i.C_ConversionType_ID, "
+ + "i.AD_Client_ID, "
+ + "i.AD_Org_ID), " // 6 #1 Converted
+ + "currencyConvert(invoiceOpen(C_Invoice_ID, C_InvoicePaySchedule_ID), "
+ + "i.C_Currency_ID, "
+ + "?, "
+ + "i.DateInvoiced, "
+ + "i.C_ConversionType_ID, "
+ + "i.AD_Client_ID, "
+ + "i.AD_Org_ID) * i.MultiplierAP, " // 7 #2 Converted
+ // Open
+ + "currencyConvert(invoiceDiscount(i.C_Invoice_ID, "
+ + "?, "
+ + "C_InvoicePaySchedule_ID), " // 8 AllowedDiscount
+ + "i.C_Currency_ID, " + "?, " + "i.DateInvoiced, "
+ + "i.C_ConversionType_ID, " + "i.AD_Client_ID, "
+ + "i.AD_Org_ID) * i.Multiplier * i.MultiplierAP, " // #3,
+ // #4
+ + "i.MultiplierAP");
+
+ // FROM
+ sql
+ .append(" FROM C_Invoice_v i" // corrected for CM/Split
+ + " INNER JOIN C_Currency c ON (i.C_Currency_ID=c.C_Currency_ID) ");
+
+ // WHERE
+ sql.append(" WHERE i.IsPaid='N' AND i.Processed='Y'"
+ + " AND i.C_BPartner_ID=?"); // #5
+
+ // additional WHERE
+ if (!m_chbMultiCurrency.isChecked())
+ {
+ sql.append(" AND i.C_Currency_ID=?"); // #6
+ }
+
+ // ORDER BY
+ sql.append(" ORDER BY i.DateInvoiced, i.DocumentNo");
+
+ logger.fine("InvSQL=" + sql.toString());
+
+ return sql.toString();
+ }
+
+ /**
+ * Load Business Partner Info - Payments - Invoices.
+ */
+ private void loadBPartner()
+ {
+ Integer key = null;
+ Thread thread;
+
+ logger.config("BPartner=" + m_businessPartnerId + ", Cur="
+ + m_currencyId);
+
+ // Need to have both values
+ if ((m_businessPartnerId == 0) || (m_currencyId == 0))
+ {
+ return;
+ }
+
+ // Async BPartner Test
+ key = new Integer(m_businessPartnerId);
+ if (!m_bPartnerCheck.contains(key))
+ {
+ thread = new Thread()
+ {
+ public void run()
+ {
+ MPayment.setIsAllocated(Env.getCtx(), m_businessPartnerId,
+ null);
+ MInvoice.setIsPaid(Env.getCtx(), m_businessPartnerId, null);
+ }
+ };
+ thread.start();
+ m_bPartnerCheck.add(key);
+ }
+
+ loadUnallocatedPayments();
+
+ loadUnpaidInvoices();
+
+ setColumnIndices();
+
+ // Calculate Totals
+ calculate();
+
+ return;
+ } // loadBPartner
+
+ /**
+ * Set the column indices, depending on whether multi-currency is checked.
+ */
+ private void setColumnIndices()
+ {
+ final int defaultOpenColIndex = 4;
+ final int defaultDiscountColIndex = 5;
+ final int defaultWriteOffColIndex = 6;
+ final int defaultAppliedColIndex = 7;
+ int colOffset = 0;
+
+ // removed use of tertiary operator to aid readability
+ if (m_chbMultiCurrency.isChecked())
+ {
+ colOffset = 2;
+ }
+ // set column indices
+ m_openColIndex = defaultOpenColIndex + colOffset; // 4 or 6
+ m_discountColIndex = defaultDiscountColIndex + colOffset; // 5 or 7
+ m_writeOffColIndex = defaultWriteOffColIndex + colOffset; // 6 or 8
+ m_appliedColIndex = defaultAppliedColIndex + colOffset; // 7 or 9
+
+ return;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.adempiere.webui.panel.ADForm#onEvent(org.zkoss.zk.ui.event.Event)
+ */
+ public void onEvent(Event event) throws Exception
+ {
+ if (event == null)
+ {
+ return;
+ }
+
+ logger.config("");
+
+ if (event.getTarget().equals(m_chbMultiCurrency))
+ {
+ loadBPartner();
+ }
+ else if (event.getTarget().equals(m_btnAllocate))
+ {
+ m_btnAllocate.setEnabled(false);
+ saveData();
+ loadBPartner();
+ m_btnAllocate.setEnabled(true);
+ }
+
+ return;
+ }
+
+ /**
+ * Calculate Allocation info.
+ */
+ private void calculate()
+ {
+ // TODO refactor this. Function is too long to maintain easily
+ DecimalFormat format = DisplayType.getNumberFormat(DisplayType.Amount);
+ Timestamp allocDate = null;
+ boolean isPaymentSelected = false;
+ boolean isInvoiceSelected = false;
+
+ logger.config("");
+
+ // Payment
+ BigDecimal totalPayment = new BigDecimal(0.0);
+ int rows = m_lsbPayments.getRowCount();
+ m_noSelectedPayments = 0;
+
+ for (int rowIndex = 0; rowIndex < rows; rowIndex++)
+ {
+ isPaymentSelected = isRowSelected(m_lsbPayments, rowIndex);
+ if (isPaymentSelected)
+ {
+ // TODO remove magic number
+ Timestamp ts = (Timestamp) m_lsbPayments.getValueAt(rowIndex,
+ ms_dateColIndex);
+ allocDate = TimeUtil.max(allocDate, ts);
+ BigDecimal bd = (BigDecimal) m_lsbPayments.getValueAt(rowIndex,
+ m_paymentColIndex);
+ totalPayment = totalPayment.add(bd); // Applied Pay
+ m_noSelectedPayments++;
+
+ logger.fine("Payment_" + rowIndex + " = " + bd
+ + " - Total=" + totalPayment);
+ }
+ }
+
+ m_lblPaymentInfo.setValue(String.valueOf(m_noSelectedPayments) + " - "
+ + Msg.getMsg(Env.getCtx(), "Sum") + " "
+ + format.format(totalPayment) + " ");
+
+ // Invoices
+ BigDecimal totalInvoice = new BigDecimal(0.0);
+ rows = m_lsbInvoices.getRowCount();
+ m_noSelectedInvoices = 0;
+
+ for (int rowIndex = 0; rowIndex < rows; rowIndex++)
+ {
+ isInvoiceSelected = isRowSelected(m_lsbInvoices, rowIndex);
+ if (isInvoiceSelected)
+ {
+ Timestamp ts = (Timestamp) m_lsbInvoices.getValueAt(rowIndex,
+ ms_dateColIndex);
+ allocDate = TimeUtil.max(allocDate, ts);
+ BigDecimal bd = (BigDecimal) m_lsbInvoices.getValueAt(rowIndex,
+ m_appliedColIndex);
+ totalInvoice = totalInvoice.add(bd); // Applied Inv
+ m_noSelectedInvoices++;
+
+ logger.fine("Invoice_" + rowIndex + " = " + bd + " - Total="
+ + totalPayment);
+ }
+ }
+ m_lblInvoiceInfo.setValue(String.valueOf(m_noSelectedInvoices) + " - "
+ + Msg.getMsg(Env.getCtx(), "Sum") + " "
+ + format.format(totalInvoice) + " ");
+
+ // Set AllocationDate
+ if (allocDate != null)
+ {
+ m_wdeDateField.setValue(allocDate);
+ }
+ // Set Allocation Currency
+ m_lblAllocCurrency.setValue(m_wedCurrencyPick.getDisplay());
+
+ // TODO extract method
+
+ // modification fabian-subpayments 040506
+ int noInvoices = m_noSelectedInvoices;
+ int noPayments = m_noSelectedPayments;
+ logger.config("Npayments:" + noPayments + " Ninvoice:" + noInvoices);
+ m_totalPayment = totalPayment;
+ m_totalInvoiced = totalInvoice;
+
+ // Difference
+ BigDecimal difference = m_totalPayment.subtract(m_totalInvoiced);
+ m_txbDifferenceField.setText(format.format(difference));
+
+ logger.info("Total-Pay:" + m_totalPayment + " TotalInv: "
+ + m_totalInvoiced + " Diference: " + difference + " npayments="
+ + noPayments + " ninvoices=" + noInvoices);
+
+ m_totalCredit = new BigDecimal("0");
+
+ boolean enableAllocButton = false;
+ m_eIndicator = EIndicator.NONE;
+
+ // isTotalPay
+ if (difference.compareTo(new BigDecimal(0.0)) == 0 && noPayments == 1)
+ {// ----------------------------------
+ m_eIndicator = EIndicator.TOTAL_PAY; // totalpay=totalinvoiced
+ enableAllocButton = true;
+ }
+ // isSubPayment
+ else if (difference.compareTo(new BigDecimal(0.0)) < 0
+ && noPayments == 1 && noInvoices == 1
+ && m_totalPayment.compareTo(new BigDecimal(0.0)) > 0
+ && m_totalInvoiced.compareTo(new BigDecimal(0.0)) > 0)
+ {
+ m_eIndicator = EIndicator.SUBPAYMENT_SO; // subpayment issotrx=y
+ enableAllocButton = true;
+ }
+ // isGreaterPaymentSO
+ else if (difference.compareTo(new BigDecimal(0.0)) > 0
+ && noPayments == 1 && noInvoices == 1
+ && m_totalPayment.compareTo(new BigDecimal(0.0)) > 0
+ && m_totalInvoiced.compareTo(new BigDecimal(0.0)) > 0)
+ {
+ m_eIndicator = EIndicator.GREATER_PAYMENT_SO; // totalpay>totalinvoiced
+ // issotrx=y
+ enableAllocButton = true;
+ }
+ // isCreditMemo
+ else if (difference.compareTo(new BigDecimal(0.0)) <= 0
+ && noPayments == 0 && noInvoices > 0)
+ {
+ m_eIndicator = EIndicator.CREDIT_MEMO; // Credit Memo
+ if (revisionSubcredit())
+ {
+ enableAllocButton = true;
+ }
+ }
+ // isGreaterPaymentPO
+ else if (difference.compareTo(new BigDecimal(0.0)) < 0
+ && noPayments == 1 && noInvoices == 1
+ && m_totalPayment.compareTo(new BigDecimal(0.0)) < 0
+ && m_totalInvoiced.compareTo(new BigDecimal(0.0)) < 0)
+ {
+ m_eIndicator = EIndicator.GREATER_PAYMENT_PO; // totalpay>totalinvoiced
+ // issotrx=n
+ enableAllocButton = true;
+ }
+ // special case vendor subpayments
+ else if (difference.compareTo(new BigDecimal(0.0)) > 0
+ && noPayments == 1 && noInvoices == 1
+ && m_totalPayment.compareTo(new BigDecimal(0.0)) < 0
+ && m_totalInvoiced.compareTo(new BigDecimal(0.0)) < 0)
+ {
+ m_eIndicator = EIndicator.GREATER_INVOICED_PO; // totalpay 0
+ && noPayments == 0 && noInvoices > 0)
+ {
+ m_eIndicator = EIndicator.GREATER_CREDIT;
+ if (revisionSubcredit()) // creditmemo > invoiced
+ {
+ enableAllocButton = true;
+ }
+ }
+
+ logger.info("Enable Allocate Button=" + enableAllocButton
+ + " Indicator=" + m_eIndicator);
+
+ m_btnAllocate.setEnabled(enableAllocButton);
+
+ return;
+ } // calculate
+
+ /**
+ * Query whether the specified row
of the specified
+ * table
is selected.
+ *
+ * @param table The table to query
+ * @param row The row to query
+ * @return true if the row is selected, false otherwise
+ */
+ private boolean isRowSelected(WListbox table, int row)
+ {
+ return ((Boolean) table.getValueAt(row, ms_selectedColIndex))
+ .booleanValue();
+ }
+
+ /**
+ * Queries whether the alocation is a subcredit.
+ *
+ * @return true if the selected allocation represent a subcredit. False otherwise.
+ */
+ private boolean revisionSubcredit()
+ {
+ int noCredits = 0;
+
+ logger.fine("Recalculating grid");
+
+ // TODO factor out
+ calculatePayments();
+
+ // TODO factor out
+ // Invoices
+ noCredits = calculateInvoices();
+
+ if (m_noSelectedInvoices == 1
+ && m_noSelectedPayments == 0
+ && noCredits == 1
+ && m_totalInvoiced.subtract(m_totalCredit).compareTo(Env.ZERO) >= 0)
+ {
+ logger.info("return true");
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Calculate the number of selected payments and the total payment amount.
+ *
+ * @return the number of credits
+ */
+ private int calculateInvoices()
+ {
+ BigDecimal totalInvoice = Env.ZERO;
+ BigDecimal totalCredit = Env.ZERO;
+ int noInvoices = m_lsbInvoices.getRowCount();
+ int noCredits = 0;
+ BigDecimal openAmount = null;
+
+ m_noSelectedInvoices = 0;
+ m_totalCredit = Env.ZERO;
+
+ for (int rowIndex = 0; rowIndex < noInvoices; rowIndex++)
+ {
+ if (isRowSelected(m_lsbInvoices, rowIndex))
+ {
+ openAmount = (BigDecimal) m_lsbInvoices.getValueAt(rowIndex,
+ m_openColIndex);
+
+ logger.info("*Value:" + openAmount);
+
+ if (isNegative(openAmount))
+ {
+ noCredits++;
+ totalCredit = totalCredit.add(openAmount);
+ m_creditIndex = rowIndex;
+ }
+ else
+ {
+ m_noSelectedInvoices++;
+ totalInvoice = totalInvoice.add(openAmount); // Applied
+ // Inv
+ m_invoiceIndex = rowIndex;
+ }
+
+ logger.info("Invoice_" + rowIndex + " = " + openAmount
+ + " - Total=" + totalInvoice);
+ }
+ }
+ m_totalInvoiced = totalInvoice;
+ m_totalCredit = totalCredit;
+
+ logger.info("totalInvoiced= " + m_totalInvoiced
+ + "--totalcredit= " + m_totalCredit);
+
+ logger.info("inv-cr: " + m_totalInvoiced.subtract(m_totalCredit));
+
+ return noCredits;
+ }
+
+ /**
+ * Calculate the number of selected payments and the total payment amount.
+ */
+ private void calculatePayments()
+ {
+ BigDecimal totalPayment = Env.ZERO;
+ int noPayments = m_lsbPayments.getRowCount();
+
+ m_noSelectedPayments = 0;
+ for (int paymentIndex = 0; paymentIndex < noPayments; paymentIndex++)
+ {
+ if (isRowSelected(m_lsbPayments, paymentIndex))
+ {
+ BigDecimal bd = (BigDecimal) m_lsbPayments.getValueAt(
+ paymentIndex, m_paymentColIndex);
+ totalPayment = totalPayment.add(bd); // Applied Pay
+ m_noSelectedPayments++;
+
+ logger.info("Payment_" + paymentIndex + " = " + bd
+ + " - Total=" + totalPayment);
+ }
+ }
+ m_totalPayment = totalPayment;
+
+ return;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.adempiere.webui.event.ValueChangeListener#valueChange(org.adempiere.webui.event.ValueChangeEvent)
+ */
+ public void valueChange(ValueChangeEvent event)
+ {
+ String name = event.getPropertyName();
+ Object value = event.getNewValue();
+
+ logger.config(name + "=" + value);
+
+ if (value == null)
+ {
+ return;
+ }
+
+ // BPartner
+ if (name.equals("C_BPartner_ID"))
+ {
+ m_wedBusinessPartnerSearch.setValue(value);
+ m_businessPartnerId = ((Integer) value).intValue();
+ loadBPartner();
+ }
+ // Currency
+ else if (name.equals("C_Currency_ID"))
+ {
+ m_currencyId = ((Integer) value).intValue();
+ loadBPartner();
+ }
+ // Date for Multi-Currency
+ else if (name.equals("Date") && m_chbMultiCurrency.isChecked())
+ {
+ loadBPartner();
+ }
+
+ return;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.adempiere.webui.event.WTableModelListener#tableChanged(org.adempiere.webui.event.WTableModelEvent)
+ */
+ public void tableChanged(WTableModelEvent event)
+ {
+ // Begin Enable MultiAllocation Fabian Aguilar OFBConsulting
+ boolean isUpdate = (event.getType() == ListDataEvent.CONTENTS_CHANGED);
+ boolean isPayment = false;
+
+ // Not a table update
+ if (!isUpdate)
+ {
+ calculate();
+ return;
+ }
+
+ if (m_isCalculating) // Avoid recursive calls
+ {
+ return;
+ }
+ m_isCalculating = true;
+
+ isPayment = (event.getModel().equals(m_lsbPayments.getModel()));
+
+ logger.config("Row=" + event.getFirstRow() + ", Col="
+ + event.getColumn() + ", InvoiceTable=" + isPayment);
+
+ // Payments
+ if (isPayment)
+ {
+ paymentTableChanged(event);
+ }
+ else
+ {
+ invoiceTableChanged(event);
+ }
+
+ m_isCalculating = false;
+ calculate();
+
+ return;
+ }
+
+ /**
+ * Respond to an event on the invoice table.
+ *
+ * @param event The event to consider
+ */
+ private void invoiceTableChanged(WTableModelEvent event)
+ {
+ boolean isSubPayment = false;
+ int row = event.getFirstRow();
+ int col = event.getColumn();
+ final double thirtyPercent = 0.30;
+
+ // Invoice Selection
+ if (col == ms_selectedColIndex)
+ {
+ // TableModel invoice = invoiceTable.getModel();
+ // selected - set applied amount
+ if (isRowSelected(m_lsbInvoices, row))
+ {
+ BigDecimal amount = (BigDecimal) m_lsbInvoices.getValueAt(row,
+ m_openColIndex); // Open Amount
+ amount = amount.subtract((BigDecimal) m_lsbInvoices.getValueAt(
+ row, m_discountColIndex));
+ m_lsbInvoices.setValueAt(Env.ZERO, row, m_writeOffColIndex); // to
+ // be
+ // sure
+ m_lsbInvoices.setValueAt(amount, row, m_appliedColIndex);
+
+ // Begin Enable MultiAllocation Fabian Aguilar OFBConsulting
+ isSubPayment = revisionSubpayment();
+
+ logger.fine("Invoice-issubpayment: " + isSubPayment);
+
+ m_rowLastInvoice = row;
+ if (isSubPayment)
+ {
+ logger.fine("End Process SubPayment");
+ // TODO factor out to isNegative
+ if (isNegative(amount.subtract(m_totalPayment)))
+ {
+ m_lsbInvoices.setValueAt(amount, row, m_appliedColIndex);
+ }
+ else
+ {
+ m_lsbInvoices.setValueAt(m_totalPayment, row,
+ m_appliedColIndex);
+ }
+ }
+ // ---END----------
+ }
+ else
+ // de-selected
+ {
+ m_lsbInvoices.setValueAt(Env.ZERO, row, m_writeOffColIndex);
+ m_lsbInvoices.setValueAt(Env.ZERO, row, m_appliedColIndex);
+ }
+ m_lsbInvoices.repaint(); // update r/o
+ }
+
+ // Invoice - Try to balance entry
+ else if (m_chbAutoWriteOff.isChecked())
+ {
+ // TableModel invoice = invoiceTable.getModel();
+ // if applied entered, adjust writeOff
+ if (col == m_appliedColIndex)
+ {
+ BigDecimal openAmount = (BigDecimal) m_lsbInvoices.getValueAt(
+ row, m_openColIndex); // Open Amount
+ BigDecimal amount = openAmount
+ .subtract((BigDecimal) m_lsbInvoices.getValueAt(row,
+ m_discountColIndex));
+ amount = amount.subtract((BigDecimal) m_lsbInvoices.getValueAt(
+ row, m_appliedColIndex));
+ m_lsbInvoices.setValueAt(amount, row, m_writeOffColIndex);
+
+ // Warning if > 30%
+ if (amount.doubleValue() / openAmount.doubleValue() > thirtyPercent)
+ {
+ FDialog.warn(m_windowNo, "AllocationWriteOffWarn");
+ }
+ }
+ else
+ // adjust applied
+ {
+ BigDecimal amount = (BigDecimal) m_lsbInvoices.getValueAt(row,
+ m_openColIndex); // Open Amount
+ amount = amount.subtract((BigDecimal) m_lsbInvoices.getValueAt(
+ row, m_discountColIndex));
+ amount = amount.subtract((BigDecimal) m_lsbInvoices.getValueAt(
+ row, m_writeOffColIndex));
+ m_lsbInvoices.setValueAt(amount, row, m_appliedColIndex);
+ }
+ }
+
+ return;
+ }
+
+ /**
+ * Respond to an event on the payment table.
+ *
+ * @param event the event to respond to
+ */
+ private void paymentTableChanged(WTableModelEvent event)
+ {
+ boolean isSubPayment;
+ int row = event.getFirstRow();
+ int col = event.getColumn();
+
+ if (col == ms_selectedColIndex)
+ {
+ // selected - set payment amount
+ if (isRowSelected(m_lsbPayments, row))
+ {
+ BigDecimal amount = (BigDecimal) m_lsbPayments.getValueAt(row,
+ m_openColIndex); // Open Amount
+ m_lsbPayments.setValueAt(amount, row, m_paymentColIndex);
+
+ // Begin Enable MultiAllocation Fabian Aguilar OFBConsulting
+ isSubPayment = revisionSubpayment();
+
+ logger.fine("Payment-issubpayment: " + isSubPayment);
+
+ if (isSubPayment)
+ {
+ m_rowLastInvoice = getRowInvoice();
+
+ if (m_rowLastInvoice > -1)
+ {
+ if (isNegative(m_totalInvoiced.subtract(m_totalPayment)))
+ {
+ m_lsbInvoices.setValueAt(m_totalInvoiced,
+ m_rowLastInvoice, m_appliedColIndex);
+ }
+ else
+ {
+ m_lsbInvoices.setValueAt(m_totalPayment,
+ m_rowLastInvoice, m_appliedColIndex);
+ }
+ }
+ }
+ else if (m_totalPayment == m_totalInvoiced)
+ {
+ m_lsbInvoices.setValueAt((BigDecimal) m_lsbInvoices.getValueAt(m_rowLastInvoice,
+ m_openColIndex), m_rowLastInvoice, m_appliedColIndex);
+ }
+ // -End-------------
+ }
+ else
+ // de-selected
+ {
+ m_lsbPayments.setValueAt(Env.ZERO, row, m_paymentColIndex);
+ }
+ m_lsbPayments.repaint(); // update r/o
+ }
+ }
+
+ /**
+ * Find the index of the row containing the last invoice.
+ *
+ * @return index of the row containing the last invoice.
+ */
+ private int getRowInvoice()
+ {
+ // Invoices
+ // TableModel invoice = invoiceTable.getModel();
+ BigDecimal totalInvoice = Env.ZERO;
+ BigDecimal totalCredit = Env.ZERO;
+ int noInvoices = m_lsbInvoices.getRowCount();
+ int noCredits = 0;
+ int rowInvoice = -1;
+ BigDecimal openAmount = null;
+
+ logger.fine("Finding row");
+
+ m_noSelectedInvoices = 0;
+ m_totalCredit = Env.ZERO;
+
+ for (int invoiceIndex = 0; invoiceIndex < noInvoices; invoiceIndex++)
+ {
+ if (isRowSelected(m_lsbInvoices, invoiceIndex))
+ {
+ openAmount = (BigDecimal) m_lsbInvoices.getValueAt(invoiceIndex,
+ m_openColIndex);
+
+ if (isNegative(openAmount))
+ {
+ noCredits++;
+ totalCredit = totalCredit.add(openAmount);
+ }
+ else
+ {
+ m_noSelectedInvoices++;
+ totalInvoice = totalInvoice.add(openAmount); // Applied
+ // Inv
+ rowInvoice = invoiceIndex;
+ }
+ }
+ }
+
+ logger.fine("totalInvoiced= " + totalInvoice + "--totalcredit= "
+ + totalCredit);
+
+ return rowInvoice;
+ }
+
+ /**
+ * Performs subpayment revision.
+ */
+ // Begin Enable MultiAllocation Fabian Aguilar OFBConsulting
+ private boolean revisionSubpayment()
+ {
+ logger.fine("Recalculating grid");
+
+ // Payment
+ // TableModel payment = paymentTable.getModel();
+ BigDecimal totalPayment = Env.ZERO;
+ int rows = m_lsbPayments.getRowCount();
+
+ m_noSelectedPayments = 0;
+ for (int rowIndex = 0; rowIndex < rows; rowIndex++)
+ {
+ if (isRowSelected(m_lsbPayments, rowIndex))
+ {
+ BigDecimal bd = (BigDecimal) m_lsbPayments.getValueAt(rowIndex,
+ m_paymentColIndex);
+ totalPayment = totalPayment.add(bd); // Applied Pay
+ m_noSelectedPayments++;
+
+ logger.fine("Payment_" + rowIndex + " = " + bd + " - Total="
+ + totalPayment);
+ }
+ }
+
+ // Invoices
+ // TableModel invoice = invoiceTable.getModel();
+ BigDecimal totalInvoice = Env.ZERO;
+ rows = m_lsbInvoices.getRowCount();
+ m_noSelectedInvoices = 0;
+
+ for (int rowIndex = 0; rowIndex < rows; rowIndex++)
+ {
+ if (isRowSelected(m_lsbInvoices, rowIndex))
+ {
+ BigDecimal bd = (BigDecimal) m_lsbInvoices.getValueAt(rowIndex,
+ m_openColIndex);
+ totalInvoice = totalInvoice.add(bd); // Applied Inv
+ m_noSelectedInvoices++;
+
+ logger.fine("Invoice_" + rowIndex + " = " + bd + " - Total="
+ + totalPayment);
+ }
+ }
+ m_totalPayment = totalPayment;
+ m_totalInvoiced = totalInvoice;
+
+ logger.fine("**totalPayment: " + m_totalPayment + " totalInvoiced: "
+ + m_totalInvoiced);
+
+ if ((m_noSelectedInvoices == 1) && (m_noSelectedPayments == 1))
+ {
+ BigDecimal difference = totalPayment.subtract(totalInvoice);
+ if (isNegative(difference))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Query whether the specified value is negative.
+ *
+ * @param value
+ * the value to test for sign
+ * @return true if the value is negative, false otherwise
+ */
+ public static boolean isNegative(BigDecimal value)
+ {
+ return (value.signum() == -1);
+ }
+
+ /**
+ * Query whether the specified value is positive.
+ *
+ * @param value
+ * the value to test for sign
+ * @return true if the value is positive, false otherwise
+ */
+ public static boolean isPositive(BigDecimal value)
+ {
+ return (value.signum() == 1);
+ }
+
+ /**
+ * Query whether the specified value is non-zero.
+ *
+ * @param value
+ * the value to test for sign
+ * @return true if the value is non-zero, false otherwise
+ */
+ public static boolean isNonZero(BigDecimal value)
+ {
+ return (value.signum() != 0);
+ }
+
+ /**
+ * Query whether the specified value is zero.
+ *
+ * @param value
+ * the value to test for sign
+ * @return true if the value is zero, false otherwise
+ */
+ public static boolean isZero(BigDecimal value)
+ {
+ return (value.signum() == 0);
+ }
+
+ /**
+ * Save Data.
+ */
+ private void saveData()
+ {
+ // TODO refactor this
+ // fixed fields
+ final int AD_Client_ID = Env.getContextAsInt(Env.getCtx(), m_windowNo,
+ "AD_Client_ID");
+ final int AD_Org_ID = Env.getContextAsInt(Env.getCtx(), m_windowNo,
+ "AD_Org_ID");
+ final int C_BPartner_ID = m_businessPartnerId;
+ final int C_Currency_ID = m_currencyId; // the allocation currency
+ final int C_Order_ID = 0;
+ final int C_CashLine_ID = 0;
+ final Timestamp DateTrx = (Timestamp) m_wdeDateField.getValue();
+
+ if (m_noSelectedInvoices + m_noSelectedPayments == 0)
+ {
+ return;
+ }
+ //
+ if (AD_Org_ID == 0)
+ {
+ FDialog.error(m_windowNo, "Org0NotAllowed");
+ return;
+ }
+ //
+ logger.config("Client=" + AD_Client_ID + ", Org=" + AD_Org_ID
+ + ", BPartner=" + C_BPartner_ID + ", Date=" + DateTrx);
+
+ Trx trx = Trx.get(Trx.createTrxName("AL"), true);
+
+ /**
+ * Generation of allocations: amount/discount/writeOff - if there is one
+ * payment -- one line per invoice is generated with both the Invoice
+ * and Payment reference Pay=80 Inv=100 Disc=10 WOff=10 => 80/10/10
+ * Pay#1 Inv#1 or Pay=160 Inv=100 Disc=10 WOff=10 => 80/10/10 Pay#1
+ * Inv#1 Pay=160 Inv=100 Disc=10 WOff=10 => 80/10/10 Pay#1 Inv#2 - if
+ * there are multiple payment lines -- the amounts are allocated
+ * starting with the first payment and payment Pay=60 Inv=100 Disc=10
+ * WOff=10 => 60/10/10 Pay#1 Inv#1 Pay=100 Inv=100 Disc=10 WOff=10 =>
+ * 20/0/0 Pay#2 Inv#1 Pay=100 Inv=100 Disc=10 WOff=10 => 80/10/10 Pay#2
+ * Inv#2 - if you apply a credit memo to an invoice Inv=10 Disc=0 WOff=0 =>
+ * 10/0/0 Inv#1 Inv=-10 Disc=0 WOff=0 => -10/0/0 Inv#2 - if you want to
+ * write off a (partial) invoice without applying, enter zero in applied
+ * Inv=10 Disc=1 WOff=9 => 0/1/9 Inv#1 Issues - you cannot write-off a
+ * payment
+ */
+
+ // Payment - Loop and add them to paymentList/amountList
+ int paymentRows = m_lsbPayments.getRowCount();
+ ArrayList paymentList = new ArrayList(paymentRows);
+ ArrayList amountList = new ArrayList(
+ paymentRows);
+
+ BigDecimal paymentAppliedAmt = Env.ZERO;
+
+ for (int rowIndex = 0; rowIndex < paymentRows; rowIndex++)
+ {
+ // Payment line is selected
+ if (isRowSelected(m_lsbPayments, rowIndex))
+ {
+ KeyNamePair pp = (KeyNamePair) m_lsbPayments.getValueAt(
+ rowIndex, ms_valueColIndex); // Value
+ // Payment variables
+ int C_Payment_ID = pp.getKey();
+ paymentList.add(new Integer(C_Payment_ID));
+ //
+ BigDecimal PaymentAmt = (BigDecimal) m_lsbPayments.getValueAt(
+ rowIndex, m_paymentColIndex); // Applied Payment
+ amountList.add(PaymentAmt);
+ //
+ paymentAppliedAmt = paymentAppliedAmt.add(PaymentAmt);
+ //
+ logger.fine("C_Payment_ID=" + C_Payment_ID + " - PaymentAmt="
+ + PaymentAmt); // + " * " + Multiplier + " = " +
+ // PaymentAmtAbs);
+ }
+ }
+
+ logger.config("Number of Payments=" + paymentList.size() + " - Total="
+ + paymentAppliedAmt);
+
+ // Invoices - Loop and generate alloctions
+ int invoiceRows = m_lsbInvoices.getRowCount();
+ BigDecimal totalAppliedAmt = Env.ZERO;
+
+ // Create Allocation - but don't save yet
+ MAllocationHdr alloc = new MAllocationHdr(Env.getCtx(), true, DateTrx,
+ C_Currency_ID, Env.getContext(Env.getCtx(), "#AD_User_Name"),
+ trx.getTrxName()); // manual
+ alloc.setAD_Org_ID(AD_Org_ID);
+
+ // For all invoices
+ int invoiceLines = 0;
+ for (int rowIndex = 0; rowIndex < invoiceRows; rowIndex++)
+ {
+ // Invoice line is selected
+ if (isRowSelected(m_lsbInvoices, rowIndex))
+ {
+ invoiceLines++;
+ KeyNamePair pp = (KeyNamePair) m_lsbInvoices.getValueAt(
+ rowIndex, ms_valueColIndex); // Value
+ // Invoice variables
+ int C_Invoice_ID = pp.getKey();
+ BigDecimal AppliedAmt = (BigDecimal) m_lsbInvoices.getValueAt(
+ rowIndex, m_appliedColIndex);
+ // semi-fixed fields (reset after first invoice)
+ BigDecimal DiscountAmt = (BigDecimal) m_lsbInvoices.getValueAt(
+ rowIndex, m_discountColIndex);
+ BigDecimal WriteOffAmt = (BigDecimal) m_lsbInvoices.getValueAt(
+ rowIndex, m_writeOffColIndex);
+ // OverUnderAmt needs to be in Allocation Currency
+ BigDecimal OverUnderAmt = ((BigDecimal) m_lsbInvoices
+ .getValueAt(rowIndex, m_openColIndex)).subtract(
+ AppliedAmt).subtract(DiscountAmt).subtract(WriteOffAmt);
+
+ // Begin Enable MultiAllocation Fabian Aguilar OFBConsulting
+ if (m_eIndicator == EIndicator.SUBPAYMENT_SO)
+ {
+ OverUnderAmt = ((BigDecimal) m_lsbInvoices.getValueAt(
+ rowIndex, m_openColIndex)).subtract(m_totalPayment);
+ AppliedAmt = m_totalPayment;
+ }
+ else if (m_eIndicator == EIndicator.GREATER_INVOICED_PO)
+ {
+ OverUnderAmt = m_totalInvoiced.subtract(m_totalPayment);
+ AppliedAmt = m_totalPayment;
+ }
+ else if (m_eIndicator == EIndicator.GREATER_PAYMENT_PO)
+ {
+ OverUnderAmt = new BigDecimal("0");
+ AppliedAmt = m_totalInvoiced;
+ }
+ else if (m_eIndicator == EIndicator.GREATER_CREDIT)
+ {
+ OverUnderAmt = new BigDecimal("0");
+ AppliedAmt = m_totalInvoiced;
+ }
+ else if (m_eIndicator == EIndicator.CREDIT_MEMO) // subpayment
+ // with
+ // credit
+ // note
+ {
+ logger.fine("**AppliedAmt: " + AppliedAmt);
+ if (isPositive(AppliedAmt))
+ {
+ OverUnderAmt = AppliedAmt.add(m_totalCredit);
+ AppliedAmt = m_totalCredit.abs();
+ }
+ }
+ // ------END---------------------------
+
+ logger.config("Invoice #" + rowIndex + " - AppliedAmt="
+ + AppliedAmt);// + " -> " + AppliedAbs);
+
+ // loop through all payments until invoice applied
+ int noPayments = 0;
+ for (int paymentIndex = 0; (paymentIndex < paymentList.size())
+ && (isNonZero(AppliedAmt)); paymentIndex++)
+ {
+ int C_Payment_ID = ((Integer) paymentList.get(paymentIndex))
+ .intValue();
+ BigDecimal PaymentAmt = (BigDecimal) amountList
+ .get(paymentIndex);
+ if (isNonZero(PaymentAmt))
+ {
+ logger.config(".. with payment #" + paymentIndex
+ + ", Amt=" + PaymentAmt);
+
+ noPayments++;
+ // use Invoice Applied Amt
+ BigDecimal amount = AppliedAmt;
+ logger.fine("C_Payment_ID=" + C_Payment_ID
+ + ", C_Invoice_ID=" + C_Invoice_ID
+ + ", Amount=" + amount + ", Discount="
+ + DiscountAmt + ", WriteOff=" + WriteOffAmt);
+
+ // Allocation Header
+ if ((alloc.get_ID() == 0) && !alloc.save())
+ {
+ logger.log(Level.SEVERE, "Allocation not created");
+ return;
+ }
+ // Allocation Line
+ MAllocationLine aLine = new MAllocationLine(alloc,
+ amount, DiscountAmt, WriteOffAmt, OverUnderAmt);
+ aLine.setDocInfo(C_BPartner_ID, C_Order_ID,
+ C_Invoice_ID);
+ aLine.setPaymentInfo(C_Payment_ID, C_CashLine_ID);
+
+ if (!aLine.save())
+ {
+ logger.log(Level.SEVERE,
+ "Allocation Line not written - Invoice="
+ + C_Invoice_ID);
+ }
+
+ // Apply Discounts and WriteOff only first time
+ DiscountAmt = Env.ZERO;
+ WriteOffAmt = Env.ZERO;
+ // subtract amount from Payment/Invoice
+ AppliedAmt = AppliedAmt.subtract(amount);
+ PaymentAmt = PaymentAmt.subtract(amount);
+
+ logger.fine("Allocation Amount=" + amount
+ + " - Remaining Applied=" + AppliedAmt
+ + ", Payment=" + PaymentAmt);
+
+ amountList.set(paymentIndex, PaymentAmt); // update
+ } // for all applied amounts
+ } // noop through payments for invoice
+
+ // No Payments allocated and none existing (e.g. Inv/CM)
+ if ((noPayments == 0) && (paymentList.size() == 0))
+ {
+ int C_Payment_ID = 0;
+
+ logger.config(" ... no payment - TotalApplied="
+ + totalAppliedAmt);
+
+ // Begin Enable MultiAllocation Fabian Aguilar OFBConsulting
+ if (m_eIndicator == EIndicator.GREATER_CREDIT)
+ {
+ if (rowIndex == m_creditIndex)
+ {
+ AppliedAmt = AppliedAmt.negate();
+ }
+ }
+ // --------END------------------------
+
+ // Create Allocation
+
+ logger.fine("C_Payment_ID=" + C_Payment_ID
+ + ", C_Invoice_ID=" + C_Invoice_ID + ", Amount="
+ + AppliedAmt + ", Discount=" + DiscountAmt
+ + ", WriteOff=" + WriteOffAmt);
+
+ // Allocation Header
+ if ((alloc.get_ID() == 0) && !alloc.save())
+ {
+ logger.log(Level.SEVERE, "Allocation not created");
+ return;
+ }
+ // Allocation Line
+ MAllocationLine aLine = new MAllocationLine(alloc,
+ AppliedAmt, DiscountAmt, WriteOffAmt, OverUnderAmt);
+ aLine.setDocInfo(C_BPartner_ID, C_Order_ID, C_Invoice_ID);
+ aLine.setPaymentInfo(C_Payment_ID, C_CashLine_ID);
+ if (!aLine.save(trx.getTrxName()))
+ {
+ logger.log(Level.SEVERE,
+ "Allocation Line not written - Invoice="
+ + C_Invoice_ID);
+ }
+
+ logger.fine("Allocation Amount=" + AppliedAmt);
+ }
+ totalAppliedAmt = totalAppliedAmt.add(AppliedAmt);
+ logger.config("TotalRemaining=" + totalAppliedAmt);
+ } // invoice selected
+ } // invoice loop
+
+ // Only Payments and total of 0 (e.g. Payment/Reversal)
+ if ((invoiceLines == 0) && (paymentList.size() > 0)
+ && (isZero(paymentAppliedAmt)))
+ {
+ for (int paymentIndex = 0; paymentIndex < paymentList.size(); paymentIndex++)
+ {
+ int C_Payment_ID = ((Integer) paymentList.get(paymentIndex))
+ .intValue();
+ BigDecimal paymentAmt = (BigDecimal) amountList.get(paymentIndex);
+
+ logger.fine("Payment=" + C_Payment_ID + ", Amount="
+ + paymentAmt); // + ", Abs=" + PaymentAbs);
+
+ // Allocation Header
+ if ((alloc.get_ID() == 0) && !alloc.save())
+ {
+ logger.log(Level.SEVERE, "Allocation not created");
+ return;
+ }
+
+ // Allocation Line
+ MAllocationLine aLine = new MAllocationLine(alloc, paymentAmt,
+ Env.ZERO, Env.ZERO, Env.ZERO);
+ aLine.setDocInfo(C_BPartner_ID, 0, 0);
+ aLine.setPaymentInfo(C_Payment_ID, 0);
+
+ if (!aLine.save(trx.getTrxName()))
+ {
+ logger.log(Level.SEVERE,
+ "Allocation Line not saved - Payment="
+ + C_Payment_ID);
+ }
+ }
+ } // onlyPayments
+
+ if (isNonZero(totalAppliedAmt))
+ {
+ logger.log(Level.SEVERE, "Remaining TotalAppliedAmt="
+ + totalAppliedAmt);
+ }
+
+ // Should start WF
+ if (alloc.get_ID() != 0)
+ {
+ alloc.processIt(DocAction.ACTION_Complete);
+ alloc.save();
+ }
+
+ // Test/Set IsPaid for Invoice - requires that allocation is posted
+ for (int rowIndex = 0; rowIndex < invoiceRows; rowIndex++)
+ {
+ // Invoice line is selected
+ if (isRowSelected(m_lsbInvoices, rowIndex))
+ {
+ KeyNamePair pp = (KeyNamePair) m_lsbInvoices.getValueAt(
+ rowIndex, 2); // Value
+ // Invoice variables
+ int C_Invoice_ID = pp.getKey();
+ String sql = "SELECT invoiceOpen(C_Invoice_ID, 0) "
+ + "FROM C_Invoice " + "WHERE C_Invoice_ID=?";
+
+ BigDecimal open = DB.getSQLValueBD(trx.getTrxName(), sql,
+ C_Invoice_ID);
+
+ // Enable MultiAllocation Fabian Aguilar OFBConsulting
+ if ((open != null)
+ && (isZero(open))
+ && (m_eIndicator != EIndicator.SUBPAYMENT_SO)
+ && (m_eIndicator != EIndicator.GREATER_INVOICED_PO)
+ && ((m_eIndicator != EIndicator.CREDIT_MEMO)
+ && (getRowInvoice() != rowIndex)))
+ {
+ sql = "UPDATE C_Invoice " + "SET IsPaid='Y' "
+ + "WHERE C_Invoice_ID=" + C_Invoice_ID;
+
+ int noAffectedRows = DB.executeUpdate(sql, trx.getTrxName());
+
+ logger.config("Invoice #" + rowIndex
+ + " is paid - updated=" + noAffectedRows);
+ }
+ else
+ {
+ logger.config("Invoice #" + rowIndex + " is not paid - "
+ + open);
+ }
+ }
+ }
+
+ // Test/Set Payment is fully allocated
+ for (int paymentIndex = 0; paymentIndex < paymentList.size(); paymentIndex++)
+ {
+ int C_Payment_ID = ((Integer) paymentList.get(paymentIndex)).intValue();
+ MPayment pay = new MPayment(Env.getCtx(), C_Payment_ID, trx.getTrxName());
+
+ // Enable MultiAllocation Fabian Aguilar OFBConsulting
+ if ((pay.testAllocation() || (m_eIndicator == EIndicator.SUBPAYMENT_SO))
+ && (m_eIndicator != EIndicator.GREATER_PAYMENT_SO)
+ && (m_eIndicator != EIndicator.GREATER_PAYMENT_PO))
+ {
+ pay.save();
+ }
+
+ logger
+ .config("Payment #" + paymentIndex
+ + (pay.isAllocated() ? " not" : " is")
+ + " fully allocated");
+ }
+
+ paymentList.clear();
+ amountList.clear();
+ trx.commit();
+ trx.close();
+
+ return;
+ } // saveData
+
+} // WAllocation
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WArchiveViewer.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WArchiveViewer.java
new file mode 100644
index 0000000000..2295818b31
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WArchiveViewer.java
@@ -0,0 +1,764 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
+ * or via info@compiere.org or http://www.compiere.org/license.html *
+ *****************************************************************************/
+
+/**
+ * 2007, Modified by Posterita Ltd.
+ */
+
+package org.adempiere.webui.apps.form;
+
+import java.io.InputStream;
+import java.sql.Timestamp;
+import java.util.Date;
+import java.util.logging.Level;
+
+import org.adempiere.webui.component.Button;
+import org.adempiere.webui.component.Checkbox;
+import org.adempiere.webui.component.ConfirmPanel;
+import org.adempiere.webui.component.Datebox;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.ListItem;
+import org.adempiere.webui.component.Listbox;
+import org.adempiere.webui.component.Tab;
+import org.adempiere.webui.component.Tabbox;
+import org.adempiere.webui.component.Tabpanel;
+import org.adempiere.webui.component.Tabpanels;
+import org.adempiere.webui.component.Tabs;
+import org.adempiere.webui.component.Textbox;
+import org.adempiere.webui.component.VerticalBox;
+import org.adempiere.webui.editor.WEditor;
+import org.adempiere.webui.editor.WTableDirEditor;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.event.ValueChangeListener;
+import org.adempiere.webui.panel.ADForm;
+import org.adempiere.webui.session.SessionManager;
+import org.compiere.model.MArchive;
+import org.compiere.model.MBPartner;
+import org.compiere.model.MLookup;
+import org.compiere.model.MLookupFactory;
+import org.compiere.model.MRole;
+import org.compiere.util.CLogger;
+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.TimeUtil;
+import org.zkoss.util.media.AMedia;
+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.Hbox;
+import org.zkoss.zul.Iframe;
+import org.zkoss.zul.Separator;
+
+/**
+ * Archive Viewer
+ *
+ * @author Niraj Sohun
+ * @date September 28, 2007
+*/
+
+public class WArchiveViewer extends ADForm implements EventListener, ValueChangeListener
+{
+ private static final long serialVersionUID = 1L;
+
+ /** Window No */
+ private int m_WindowNo = 0;
+
+ /** The Archives */
+ private MArchive[] m_archives = new MArchive[0];
+
+ /** Archive Index */
+ private int m_index = 0;
+
+ /** Table direct */
+ private int m_AD_Table_ID = 0;
+
+ /** Record direct */
+ private int m_Record_ID = 0;
+
+ /** Logger */
+ private static CLogger log = CLogger.getCLogger(WArchiveViewer.class);
+
+
+ private VerticalBox queryPanel = new VerticalBox();
+ private Checkbox reportField = new Checkbox();
+ private Label processLabel = new Label(Msg.translate(Env.getCtx(), "AD_Process_ID"));
+ private Listbox processField = new Listbox();
+ private Label tableLabel = new Label(Msg.translate(Env.getCtx(), "AD_Table_ID"));
+ private Listbox tableField = new Listbox();
+ private Label bPartnerLabel = new Label(Msg.translate(Env.getCtx(), "C_BPartner_ID"));
+ private WEditor bPartnerField = null;
+ private Label nameQLabel = new Label(Msg.translate(Env.getCtx(), "Name"));
+ private Textbox nameQField = new Textbox();
+ private Label descriptionQLabel = new Label(Msg.translate(Env.getCtx(), "Description"));
+ private Textbox descriptionQField = new Textbox();
+ private Label helpQLabel = new Label(Msg.translate(Env.getCtx(), "Help"));
+ private Textbox helpQField = new Textbox();
+ private Label createdByQLabel = new Label(Msg.translate(Env.getCtx(), "CreatedBy"));
+ private Listbox createdByQField = new Listbox();
+ private Label createdQLabel = new Label(Msg.translate(Env.getCtx(), "Created"));
+ private Datebox createdQFrom = new Datebox();
+ private Datebox createdQTo = new Datebox();
+
+ private VerticalBox viewEnterPanel = new VerticalBox();
+ private Button bBack = new Button();
+ private Button bNext = new Button();
+ private Label positionInfo = new Label(".");
+ private Label createdByLabel = new Label(Msg.translate(Env.getCtx(), "CreatedBy"));
+ private Textbox createdByField = new Textbox();
+ private Datebox createdField = new Datebox();
+
+ private Label nameLabel = new Label(Msg.translate(Env.getCtx(), "Name"));
+ private Textbox nameField = new Textbox("Name");
+ private Label descriptionLabel = new Label(Msg.translate(Env.getCtx(), "Description"));
+ private Textbox descriptionField = new Textbox("Description");
+ private Label helpLabel = new Label(Msg.translate(Env.getCtx(), "Help"));
+ private Textbox helpField = new Textbox("Help");
+ private ConfirmPanel confirmPanel = new ConfirmPanel(true);
+ private Button updateArchive = new Button();
+
+ private Tabbox tabbox = new Tabbox();
+ private Tabs tabs = new Tabs();
+ private Tabpanels tabpanels = new Tabpanels();
+
+ private Iframe iframe = new Iframe();
+
+ public WArchiveViewer()
+ {
+ init(super.m_windowNo);
+ }
+
+ /**
+ * Initialize Panel
+ * @param WindowNo window
+ */
+
+ public void init (int WindowNo)
+ {
+ log.info("");
+ m_WindowNo = WindowNo;
+
+ try
+ {
+ dynInit();
+ jbInit();
+ }
+ catch(Exception e)
+ {
+ log.log(Level.SEVERE, "init", e);
+ }
+ }
+
+ /**
+ * Dynamic Init
+ */
+
+ private void dynInit()
+ {
+ int AD_Role_ID = Env.getAD_Role_ID(Env.getCtx());
+
+ //Processes
+ boolean trl = !Env.isBaseLanguage(Env.getCtx(), "AD_Process");
+ String lang = Env.getAD_Language(Env.getCtx());
+ String sql = "SELECT DISTINCT p.AD_Process_ID,"
+ + (trl ? "trl.Name" : "p.Name ")
+ + " FROM AD_Process p INNER JOIN AD_Process_Access pa ON (p.AD_Process_ID=pa.AD_Process_ID) "
+ + (trl ? "LEFT JOIN AD_Process_Trl trl on (trl.AD_Process_ID=p.AD_Process_ID and trl.AD_Language=" + DB.TO_STRING(lang) + ")" : "")
+ + " WHERE pa.AD_Role_ID=" + AD_Role_ID
+ + " AND p.IsReport='Y' AND p.IsActive='Y' AND pa.IsActive='Y' "
+ + "ORDER BY 2";
+
+ processField = new Listbox();
+
+ KeyNamePair[] keyNamePair = DB.getKeyNamePairs(sql, true);
+
+ for (int i = 0; i < keyNamePair.length; i++)
+ {
+ processField.appendItem(keyNamePair[i].getName(), keyNamePair[i]);
+ }
+
+ // Tables
+ trl = !Env.isBaseLanguage(Env.getCtx(), "AD_Table");
+ sql = "SELECT DISTINCT t.AD_Table_ID,"
+ + (trl ? "trl.Name" : "t.Name")
+ + " FROM AD_Table t INNER JOIN AD_Tab tab ON (tab.AD_Table_ID=t.AD_Table_ID)"
+ + " INNER JOIN AD_Window_Access wa ON (tab.AD_Window_ID=wa.AD_Window_ID) "
+ + (trl ? "LEFT JOIN AD_Table_Trl trl on (trl.AD_Table_ID=t.AD_Table_ID and trl.AD_Language=" + DB.TO_STRING(lang) + ")" : "")
+ + " WHERE wa.AD_Role_ID=" + AD_Role_ID
+ + " AND t.IsActive='Y' AND tab.IsActive='Y' "
+ + "ORDER BY 2";
+
+ tableField = new Listbox();
+
+ keyNamePair = DB.getKeyNamePairs(sql, true);
+
+ for (int i = 0; i < keyNamePair.length; i++)
+ {
+ tableField.appendItem(keyNamePair[i].getName(), keyNamePair[i]);
+ }
+
+ // Internal Users
+ sql = "SELECT AD_User_ID, Name "
+ + "FROM AD_User u WHERE EXISTS "
+ +"(SELECT * FROM AD_User_Roles ur WHERE u.AD_User_ID=ur.AD_User_ID) "
+ + "ORDER BY 2";
+
+ createdByQField = new Listbox();
+
+ keyNamePair = DB.getKeyNamePairs(sql, true);
+
+ for (int i = 0; i < keyNamePair.length; i++)
+ {
+ createdByQField.appendItem(keyNamePair[i].getName(), keyNamePair[i]);
+ }
+
+ MLookup lookup = MLookupFactory.get(Env.getCtx(), m_WindowNo,
+ 0, 2762, DisplayType.Search);
+
+ bPartnerField = new WTableDirEditor(lookup, Msg.translate(
+ Env.getCtx(), "C_BPartner_ID"), "", true, false, true);
+
+ bPartnerField.addValueChangeListner(this);
+ } // dynInit
+
+ private void reportViewer(byte[] data)
+ {
+
+ AMedia media = new AMedia("Archive Viewer", "pdf", "application/pdf", data);
+ iframe.setContent(media);
+ }
+
+ /**
+ * Static Init
+ * @throws Exception
+ */
+
+ private void jbInit() throws Exception
+ {
+ tabbox.setWidth("100%");
+ tabbox.appendChild(tabs);
+ tabbox.appendChild(tabpanels);
+
+ processField.setMold("select");
+ processField.setRows(1);
+
+ tableField.setMold("select");
+ tableField.setRows(1);
+
+ createdByQField.setMold("select");
+ createdByQField.setRows(1);
+
+ nameField.addEventListener(Events.ON_CHANGE, this);
+ descriptionField.addEventListener(Events.ON_SELECT, this);
+ helpField.addEventListener(Events.ON_SELECT, this);
+ updateArchive.addEventListener(Events.ON_CLICK, this);
+
+ reportField.setLabel(Msg.translate(Env.getCtx(), "IsReport"));
+ reportField.addEventListener(Events.ON_CLICK, this);
+
+ Hbox boxProcess = new Hbox();
+ boxProcess.setWidth("100%");
+ boxProcess.setWidth("30%, 70%");
+ boxProcess.appendChild(processLabel);
+ boxProcess.appendChild(processField);
+
+ Hbox boxBPartner = new Hbox();
+ boxBPartner.setWidth("100%");
+ boxBPartner.setWidths("30%, 70%");
+ boxBPartner.appendChild(bPartnerLabel);
+ boxBPartner.appendChild(bPartnerField.getComponent());
+
+ Hbox boxTable = new Hbox();
+ boxTable.setWidth("100%");
+ boxTable.setWidths("30%, 70%");
+ boxTable.appendChild(tableLabel);
+ boxTable.appendChild(tableField);
+
+ Hbox boxNameQ = new Hbox();
+ boxNameQ.setWidth("100%");
+ boxNameQ.setWidths("30%, 70%");
+ boxNameQ.appendChild(nameQLabel);
+ boxNameQ.appendChild(nameQField);
+
+ Hbox boxDescritionQ = new Hbox();
+ boxDescritionQ.setWidth("100%");
+ boxDescritionQ.setWidths("30%, 70%");
+ boxDescritionQ.appendChild(descriptionQLabel);
+ boxDescritionQ.appendChild(descriptionQField);
+
+ Hbox boxHelpQ = new Hbox();
+ boxHelpQ.setWidth("100%");
+ boxHelpQ.setWidths("30%, 70%");
+ boxHelpQ.appendChild(helpQLabel);
+ boxHelpQ.appendChild(helpQField);
+
+ Hbox boxCreatedBy = new Hbox();
+ boxCreatedBy.setWidth("100%");
+ boxCreatedBy.setWidths("30%, 70%");
+ boxCreatedBy.appendChild(createdByQLabel);
+ boxCreatedBy.appendChild(createdByQField);
+
+ Hbox boxCreatedQ = new Hbox();
+ boxCreatedQ.setWidth("100%");
+ boxCreatedQ.setWidths("30%, 35%, 35%");
+ boxCreatedQ.appendChild(createdQLabel);
+ boxCreatedQ.appendChild(createdQFrom);
+ boxCreatedQ.appendChild(createdQTo);
+
+ queryPanel.setWidth("50%");
+ queryPanel.appendChild(reportField);
+ queryPanel.appendChild(boxProcess);
+ queryPanel.appendChild(boxBPartner);
+ queryPanel.appendChild(boxTable);
+ queryPanel.appendChild(boxNameQ);
+ queryPanel.appendChild(boxDescritionQ);
+ queryPanel.appendChild(boxHelpQ);
+ queryPanel.appendChild(boxCreatedBy);
+ queryPanel.appendChild(boxCreatedQ);
+
+ Tabpanel tabQueryPanel = new Tabpanel();
+ tabQueryPanel.appendChild(queryPanel);
+
+ Tab tabQuery = new Tab("Query");
+
+ tabpanels.appendChild(tabQueryPanel);
+ tabs.appendChild(tabQuery);
+
+ bBack.addEventListener(Events.ON_CLICK, this);
+ bNext.addEventListener(Events.ON_CLICK, this);
+
+ Hbox boxViewEnter = new Hbox();
+
+ bBack.setImage("/images/Parent24.gif");
+ bNext.setImage("/images/Detail24.gif");
+
+ boxViewEnter.setWidth("100%");
+ boxViewEnter.setWidths("10%, 80%, 10%");
+ boxViewEnter.appendChild(bBack);
+ boxViewEnter.appendChild(positionInfo);
+ boxViewEnter.appendChild(bNext);
+
+ Hbox boxCreatedByV = new Hbox();
+ boxCreatedByV.setWidth("100%");
+ boxCreatedByV.setWidths("30%, 50%, 20%");
+ boxCreatedByV.appendChild(createdByLabel);
+ boxCreatedByV.appendChild(createdByField);
+ boxCreatedByV.appendChild(createdField);
+
+ Hbox boxName = new Hbox();
+ boxName.setWidth("100%");
+ boxName.setWidths("40%, 60%");
+ boxName.appendChild(nameLabel);
+ boxName.appendChild(nameField);
+
+ Hbox boxDescription = new Hbox();
+ boxDescription.setWidth("100%");
+ boxDescription.setWidths("40%, 60%");
+ boxDescription.appendChild(descriptionLabel);
+ boxDescription.appendChild(descriptionField);
+
+ Hbox boxHelp = new Hbox();
+ boxHelp.setWidth("100%");
+ boxHelp.setWidths("40%, 60%");
+ boxHelp.appendChild(helpLabel);
+ boxHelp.appendChild(helpField);
+
+ updateArchive.setImage("/images/Ok24.gif");
+
+ viewEnterPanel.setWidth("100%");
+ viewEnterPanel.appendChild(boxViewEnter);
+ viewEnterPanel.appendChild(boxCreatedByV);
+ viewEnterPanel.appendChild(boxName);
+ viewEnterPanel.appendChild(boxDescription);
+ viewEnterPanel.appendChild(boxHelp);
+ viewEnterPanel.appendChild(updateArchive);
+
+ createdByField.setEnabled(false);
+ createdField.setEnabled(false);
+
+ Tab tabView = new Tab("View");
+
+ Tabpanel tabViewPanel = new Tabpanel();
+ Hbox boxViewSeparator = new Hbox();
+ boxViewSeparator.setWidth("100%");
+ boxViewSeparator.setWidths("50%, 50%");
+ boxViewSeparator.appendChild(iframe);
+ boxViewSeparator.appendChild(viewEnterPanel);
+ tabViewPanel.appendChild(boxViewSeparator);
+
+ tabs.appendChild(tabView);
+ tabpanels.appendChild(tabViewPanel);
+
+ confirmPanel.addActionListener(Events.ON_CLICK, this);
+ updateQDisplay();
+
+ iframe.setId("reportFrame");
+ iframe.setHeight("100%");
+ iframe.setWidth("100%");
+
+ this.setWidth("900px");
+ this.appendChild(tabbox);
+ this.appendChild(new Separator());
+ this.appendChild(confirmPanel);
+ }
+
+ public void onEvent(Event e) throws Exception
+ {
+ log.info(e.getName());
+
+ if (e.getTarget() == updateArchive)
+ cmd_updateArchive();
+ else if (confirmPanel.getButton("Cancel").equals(e.getTarget()))
+ SessionManager.getAppDesktop().removeWindow();
+ else if (confirmPanel.getButton("Ok").equals(e.getTarget()))
+ {
+ if (tabbox.getSelectedIndex() == 1)
+ SessionManager.getAppDesktop().removeWindow();
+ else
+ cmd_query();
+ }
+ else if (e.getTarget() == reportField)
+ updateQDisplay();
+ else if (e.getTarget() == bBack)
+ updateVDisplay(false);
+ else if (e.getTarget() == bNext)
+ updateVDisplay(true);
+ }
+
+ public void valueChange(ValueChangeEvent evt)
+ {
+ if (m_archives.length > 0)
+ updateArchive.setEnabled(true);
+ }
+
+ /**
+ * Update Query Display
+ */
+
+ private void updateQDisplay()
+ {
+ boolean reports = reportField.isChecked();
+ log.config("Reports=" + reports);
+
+ // Show
+ processLabel.setVisible(reports);
+ processField.setVisible(reports);
+
+ // Hide
+ bPartnerLabel.setVisible(!reports);
+ bPartnerField.setVisible(!reports);
+ } // updateQDisplay
+
+ /**
+ * Update View Display
+ * @param next show next Archive
+ */
+
+ private void updateVDisplay (boolean next)
+ {
+ if (m_archives == null)
+ m_archives = new MArchive[0];
+
+ if (next)
+ m_index++;
+ else
+ m_index--;
+
+ if (m_index >= m_archives.length-1)
+ m_index = m_archives.length-1;
+
+ if (m_index < 0)
+ m_index = 0;
+
+ bBack.setEnabled(m_index > 0);
+ bNext.setEnabled(m_index < m_archives.length-1);
+ updateArchive.setEnabled(false);
+
+ log.info("Index=" + m_index + ", Length=" + m_archives.length);
+
+ if (m_archives.length == 0)
+ {
+ positionInfo.setValue("No Record Found");
+ createdByField.setText("");
+ createdField.setValue(null);
+ nameField.setText("");
+ descriptionField.setText("");
+ helpField.setText("");
+ iframe.getChildren().clear();
+ return;
+ }
+
+ positionInfo.setValue(m_index+1 + " of " + m_archives.length);
+ MArchive ar = m_archives[m_index];
+ createdByField.setText(ar.getCreatedByName());
+ createdField.setValue(ar.getCreated());
+ nameField.setText(ar.getName());
+ descriptionField.setText(ar.getDescription());
+ helpField.setText(ar.getHelp());
+
+ try
+ {
+ InputStream in = ar.getInputStream();
+ //pdfViewer.setScale(reportField.isSelected() ? 50 : 75);
+ if (in != null)
+ reportViewer(ar.getBinaryData());//pdfViewer.loadPDF(in);
+ else
+ iframe.getChildren().clear();//pdfViewer.clearDocument();
+ }
+ catch (Exception e)
+ {
+ log.log(Level.SEVERE, "pdf", e);
+ iframe.getChildren().clear();//pdfViewer.clearDocument();
+ }
+ } // updateVDisplay
+
+ /**
+ * Update Archive Info
+ */
+
+ private void cmd_updateArchive()
+ {
+ MArchive ar = m_archives[m_index];
+ boolean update = false;
+
+ if (!isSame(nameField.getText(), ar.getName()))
+ {
+ String newText = nameField.getText();
+ if (newText != null && newText.length() > 0)
+ {
+ ar.setName(newText);
+ update = true;
+ }
+ }
+
+ if (!isSame(descriptionField.getText(), ar.getDescription()))
+ {
+ ar.setDescription(descriptionField.getText());
+ update = true;
+ }
+
+ if (!isSame(helpField.getText(), ar.getHelp()))
+ {
+ ar.setHelp(helpField.getText());
+ update = true;
+ }
+
+ log.info("Update=" + update);
+
+ if (update)
+ ar.save();
+
+ m_index++;
+
+ updateVDisplay(false);
+ } // cmd_updateArchive
+
+ /**
+ * Is it the same
+ * @param s1 s1
+ * @param s2 s1
+ * @return true if the same
+ */
+
+ private boolean isSame (String s1, String s2)
+ {
+ if (s1 == null)
+ return s2 == null;
+ else if (s2 == null)
+ return false;
+ else
+ return s1.equals(s2);
+ } // isSame
+
+ /**
+ * Query Directly
+ * @param isReport report
+ * @param AD_Table_ID table
+ * @param Record_ID tecord
+ */
+
+ public void query (boolean isReport, int AD_Table_ID, int Record_ID)
+ {
+ log.config("Report=" + isReport + ", AD_Table_ID=" + AD_Table_ID + ",Record_ID=" + Record_ID);
+ reportField.setChecked(isReport);
+ m_AD_Table_ID = AD_Table_ID;
+ m_Record_ID = Record_ID;
+ cmd_query();
+ } // query
+
+ /**************************************************************************
+ * Create Query
+ */
+
+ private void cmd_query()
+ {
+ StringBuffer sql = new StringBuffer();
+ boolean reports = reportField.isChecked();
+ MRole role = MRole.getDefault();
+
+ if (!role.isCanReport())
+ {
+ log.warning("User/Role cannot Report AD_User_ID=" + Env.getAD_User_ID(Env.getCtx()));
+ return;
+ }
+ sql.append(" AND IsReport=").append(reports ? "'Y'" : "'N'");
+
+ // Process
+ if (reports)
+ {
+ ListItem listitem = processField.getSelectedItem();
+
+ KeyNamePair nn = null;
+
+ if (listitem != null)
+ nn = (KeyNamePair)listitem.getValue();
+
+ if (nn != null && nn.getKey() > 0)
+ sql.append(" AND AD_Process_ID=").append(nn.getKey());
+ }
+
+ // Table
+ if (m_AD_Table_ID > 0)
+ {
+ sql.append(" AND ((AD_Table_ID=").append(m_AD_Table_ID);
+
+ if (m_Record_ID > 0)
+ sql.append(" AND Record_ID=").append(m_Record_ID);
+ sql.append(")");
+
+ if (m_AD_Table_ID == MBPartner.Table_ID && m_Record_ID > 0)
+ sql.append(" OR C_BPartner_ID=").append(m_Record_ID);
+ sql.append(")");
+
+ // Reset for query
+ m_AD_Table_ID = 0;
+ m_Record_ID = 0;
+ }
+ else
+ {
+ ListItem listitem = tableField.getSelectedItem();
+
+ KeyNamePair nn = null;
+
+ if (listitem != null)
+ nn = (KeyNamePair)listitem.getValue();
+
+ if (nn != null && nn.getKey() > 0)
+ sql.append(" AND AD_Table_ID=").append(nn.getKey());
+ }
+
+ // Business Partner
+ if (!reports)
+ {
+ Integer ii = (Integer)bPartnerField.getValue();
+ if (ii != null)
+ sql.append(" AND C_BPartner_ID=").append(ii);
+ else
+ sql.append(" AND C_BPartner_ID IS NOT NULL");
+ }
+
+ // Name
+ String ss = nameQField.getText();
+ if (ss != null && ss.length() > 0)
+ {
+ if (ss.indexOf('%') != -1 || ss.indexOf('_') != -1)
+ sql.append(" AND Name LIKE ").append(DB.TO_STRING(ss));
+ else
+ sql.append(" AND Name=").append(DB.TO_STRING(ss));
+ }
+
+ // Description
+ ss = descriptionQField.getText();
+ if (ss != null && ss.length() > 0)
+ {
+ if (ss.indexOf('%') != -1 || ss.indexOf('_') != -1)
+ sql.append(" AND Description LIKE ").append(DB.TO_STRING(ss));
+ else
+ sql.append(" AND Description=").append(DB.TO_STRING(ss));
+ }
+
+ // Help
+ ss = helpQField.getText();
+ if (ss != null && ss.length() > 0)
+ {
+ if (ss.indexOf('%') != -1 || ss.indexOf('_') != -1)
+ sql.append(" AND Help LIKE ").append(DB.TO_STRING(ss));
+ else
+ sql.append(" AND Help=").append(DB.TO_STRING(ss));
+ }
+
+ // CreatedBy
+ ListItem listitem = createdByQField.getSelectedItem();
+
+ KeyNamePair nn = null;
+
+ if (listitem != null)
+ nn = (KeyNamePair)listitem.getValue();
+
+ if (nn != null && nn.getKey() > 0)
+ sql.append(" AND CreatedBy=").append(nn.getKey());
+
+ // Created
+ Date date = null;
+ Timestamp tt =null;
+
+ if (createdQFrom.getValue() != null)
+ {
+ date = createdQFrom.getValue();
+ tt = new Timestamp(date.getTime());
+ }
+
+ if (tt != null)
+ sql.append(" AND Created>=").append(DB.TO_DATE(tt, true));
+
+ if (createdQTo.getValue() != null)
+ {
+ date = createdQTo.getValue();
+ tt = new Timestamp(date.getTime());
+ }
+
+ if (tt != null)
+ sql.append(" AND Created<").append(DB.TO_DATE(TimeUtil.addDays(tt,1), true));
+
+ log.fine(sql.toString());
+
+ // Process Access
+ sql.append(" AND (AD_Process_ID IS NULL OR AD_Process_ID IN "
+ + "(SELECT AD_Process_ID FROM AD_Process_Access WHERE AD_Role_ID=")
+ .append(role.getAD_Role_ID()).append("))");
+
+ // Table Access
+ sql.append(" AND (AD_Table_ID IS NULL "
+ + "OR (AD_Table_ID IS NOT NULL AND AD_Process_ID IS NOT NULL) " // Menu Reports
+ + "OR AD_Table_ID IN "
+ + "(SELECT t.AD_Table_ID FROM AD_Tab t"
+ + " INNER JOIN AD_Window_Access wa ON (t.AD_Window_ID=wa.AD_Window_ID) "
+ + "WHERE wa.AD_Role_ID=").append(role.getAD_Role_ID()).append("))");
+
+ log.finest(sql.toString());
+
+ m_archives = MArchive.get(Env.getCtx(), sql.toString());
+ log.info("Length=" + m_archives.length);
+
+ // Display
+ //this.setSelectedIndex(1);
+ m_index = 1;
+ updateVDisplay(false);
+ } // cmd_query
+}
\ No newline at end of file
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WBOMDrop.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WBOMDrop.java
new file mode 100644
index 0000000000..61c6b3ff37
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WBOMDrop.java
@@ -0,0 +1,902 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
+ * or via info@compiere.org or http://www.compiere.org/license.html *
+ *****************************************************************************/
+
+/**
+ * 2007, Modified by Posterita Ltd.
+ */
+
+package org.adempiere.webui.apps.form;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.logging.Level;
+
+import org.adempiere.webui.component.Checkbox;
+import org.adempiere.webui.component.ConfirmPanel;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.ListItem;
+import org.adempiere.webui.component.Listbox;
+import org.adempiere.webui.component.Textbox;
+import org.adempiere.webui.component.VerticalBox;
+import org.adempiere.webui.panel.ADForm;
+import org.adempiere.webui.session.SessionManager;
+import org.compiere.model.MInvoice;
+import org.compiere.model.MInvoiceLine;
+import org.compiere.model.MOrder;
+import org.compiere.model.MOrderLine;
+import org.compiere.model.MProduct;
+import org.compiere.model.MProductBOM;
+import org.compiere.model.MProject;
+import org.compiere.model.MProjectLine;
+import org.compiere.model.MRole;
+import org.compiere.util.CLogger;
+import org.compiere.util.DB;
+import org.compiere.util.Env;
+import org.compiere.util.KeyNamePair;
+import org.compiere.util.Msg;
+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.Caption;
+import org.zkoss.zul.Groupbox;
+import org.zkoss.zul.Hbox;
+import org.zkoss.zul.Radio;
+import org.zkoss.zul.Radiogroup;
+import org.zkoss.zul.Separator;
+
+
+
+public class WBOMDrop extends ADForm implements EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ /** Window No */
+ private int m_WindowNo = 0;
+
+ /** Product to create BOMs from */
+ private MProduct m_product;
+
+ /** BOM Qty */
+ private BigDecimal m_qty = Env.ONE;
+
+ /** Line Counter */
+ private int m_bomLine = 0;
+
+ /** Logger */
+ private static CLogger log = CLogger.getCLogger(WBOMDrop.class);
+
+ /** List of all selectors */
+ private ArrayList m_selectionList = new ArrayList();
+
+ /** List of all quantities */
+ private ArrayList m_qtyList = new ArrayList();
+
+ /** List of all products */
+ private ArrayList m_productList = new ArrayList();
+
+ /** Alternative Group Lists */
+ private HashMap m_buttonGroups = new HashMap();
+
+ private static final int WINDOW_WIDTH = 600; // width of the window
+
+ private ConfirmPanel confirmPanel = new ConfirmPanel(true);
+ private VerticalBox selectionPanel = new VerticalBox();
+ private Listbox productField = new Listbox();
+ private Textbox productQty = new Textbox();
+ private Listbox orderField = new Listbox();
+ private Listbox invoiceField = new Listbox();
+ private Listbox projectField = new Listbox();
+
+ private Groupbox grpSelectionPanel = new Groupbox();
+
+ private Groupbox grpSelectProd = new Groupbox();
+
+ public WBOMDrop()
+ {
+ init(super.m_windowNo);
+ }
+
+ /**
+ * Initialize Panel
+ * @param WindowNo window
+ * @param frame parent frame
+ */
+
+ public void init (int WindowNo)
+ {
+ log.info("");
+ m_WindowNo = WindowNo;
+
+ try
+ {
+ confirmPanel = new ConfirmPanel(true);
+
+ // Top Selection Panel
+ createSelectionPanel(true, true, true);
+
+ // Center
+ createMainPanel();
+
+ confirmPanel.addActionListener(Events.ON_CLICK, this);
+ }
+ catch(Exception e)
+ {
+ log.log(Level.SEVERE, "", e);
+ }
+ //sizeIt();
+ } // init
+
+ /**
+ * Dispose
+ */
+ public void dispose()
+ {
+ if (selectionPanel != null)
+ selectionPanel.getChildren().clear();
+
+ selectionPanel = null;
+
+ if (m_selectionList != null)
+ m_selectionList.clear();
+
+ m_selectionList = null;
+
+ if (m_productList != null)
+ m_productList.clear();
+
+ m_productList = null;
+
+ if (m_qtyList != null)
+ m_qtyList.clear();
+
+ m_qtyList = null;
+
+ if (m_buttonGroups != null)
+ m_buttonGroups.clear();
+ m_buttonGroups = null;
+ } // dispose
+
+ /**************************************************************************
+ * Create Selection Panel
+ * @param order
+ * @param invoice
+ * @param project
+ */
+
+ private void createSelectionPanel (boolean order, boolean invoice, boolean project)
+ {
+ Caption caption = new Caption(Msg.translate(Env.getCtx(), "Selection"));
+
+ grpSelectionPanel.setWidth("100%");
+ grpSelectionPanel.appendChild(caption);
+ grpSelectionPanel.appendChild(selectionPanel);
+
+ productField.setRows(1);
+ productField.setMold("select");
+
+ KeyNamePair[] keyNamePair = getProducts();
+
+ for (int i = 0; i < keyNamePair.length; i++)
+ {
+ productField.appendItem(keyNamePair[i].getName(), keyNamePair[i]);
+ }
+
+ Hbox boxProductQty = new Hbox();
+
+ Label lblProduct = new Label(Msg.translate(Env.getCtx(), "M_Product_ID"));
+ Label lblQty = new Label(Msg.translate(Env.getCtx(), "Qty"));
+ productQty.setValue("1");
+ productField.addEventListener(Events.ON_SELECT, this);
+ productQty.addEventListener(Events.ON_CHANGE, this);
+
+ boxProductQty.setWidth("100%");
+ boxProductQty.setWidths("30%, 30%, 10%, 30%");
+ boxProductQty.appendChild(lblProduct);
+ boxProductQty.appendChild(productField);
+ boxProductQty.appendChild(lblQty);
+ boxProductQty.appendChild(productQty);
+
+ selectionPanel.appendChild(boxProductQty);
+
+ if (order)
+ {
+ keyNamePair = getOrders();
+
+ orderField.setRows(1);
+ orderField.setMold("select");
+
+ for (int i = 0; i < keyNamePair.length; i++)
+ {
+ orderField.appendItem(keyNamePair[i].getName(), keyNamePair[i]);
+ }
+
+ Label lblOrder = new Label(Msg.translate(Env.getCtx(), "C_Order_ID"));
+
+ Hbox boxOrder = new Hbox();
+
+ orderField.addEventListener(Events.ON_CLICK, this);
+
+ boxOrder.setWidth("100%");
+ boxOrder.setWidths("30%, 60%");
+ boxOrder.appendChild(lblOrder);
+ boxOrder.appendChild(orderField);
+
+ selectionPanel.appendChild(boxOrder);
+ }
+
+ if (invoice)
+ {
+ invoiceField.setRows(1);
+ invoiceField.setMold("select");
+
+ keyNamePair = getInvoices();
+
+ for (int i = 0; i < keyNamePair.length; i++)
+ {
+ invoiceField.appendItem(keyNamePair[i].getName(), keyNamePair[i]);
+ }
+
+ Label lblInvoice = new Label(Msg.translate(Env.getCtx(), "C_Invoice_ID"));
+
+ Hbox boxInvoices = new Hbox();
+
+ invoiceField.addEventListener(Events.ON_SELECT, this);
+
+ boxInvoices.setWidth("100%");
+ boxInvoices.setWidths("30%, 60%");
+ boxInvoices.appendChild(lblInvoice);
+ boxInvoices.appendChild(invoiceField);
+
+ selectionPanel.appendChild(boxInvoices);
+ }
+
+ if (project)
+ {
+ projectField.setRows(1);
+ projectField.setMold("select");
+
+ keyNamePair = getProjects();
+
+ for (int i = 0; i < keyNamePair.length; i++)
+ {
+ projectField.appendItem(keyNamePair[i].getName(), this);
+ }
+
+ Label lblProject = new Label(Msg.translate(Env.getCtx(), "C_Project_ID"));
+
+ Hbox boxProject = new Hbox();
+
+ projectField.addEventListener(Events.ON_SELECT, this);
+
+ boxProject.setWidth("100%");
+ boxProject.setWidths("30%, 60%");
+ boxProject.appendChild(lblProject);
+ boxProject.appendChild(projectField);
+
+ selectionPanel.appendChild(boxProject);
+ }
+
+ // Enabled in ActionPerformed
+ confirmPanel.setEnabled("Ok", false);
+ } // createSelectionPanel
+
+ /**
+ * Get Array of BOM Products
+ * @return products
+ */
+
+ private KeyNamePair[] getProducts()
+ {
+ String sql = "SELECT M_Product_ID, Name "
+ + "FROM M_Product "
+ + "WHERE IsBOM='Y' AND IsVerified='Y' AND IsActive='Y' "
+ + "ORDER BY Name";
+
+ return DB.getKeyNamePairs(MRole.getDefault().addAccessSQL(
+ sql, "M_Product", MRole.SQL_NOTQUALIFIED, MRole.SQL_RO), true);
+ } // getProducts
+
+ /**
+ * Get Array of open Orders
+ * @return orders
+ */
+
+ private KeyNamePair[] getOrders()
+ {
+ String sql = "SELECT C_Order_ID, DocumentNo || '_' || GrandTotal "
+ + "FROM C_Order "
+ + "WHERE Processed='N' AND DocStatus='DR' "
+ + "ORDER BY DocumentNo";
+
+ return DB.getKeyNamePairs(MRole.getDefault().addAccessSQL(
+ sql, "C_Order", MRole.SQL_NOTQUALIFIED, MRole.SQL_RO), true);
+ } // getOrders
+
+ /**
+ * Get Array of open non service Projects
+ * @return orders
+ */
+
+ private KeyNamePair[] getProjects()
+ {
+ String sql = "SELECT C_Project_ID, Name "
+ + "FROM C_Project "
+ + "WHERE Processed='N' AND IsSummary='N' AND IsActive='Y'"
+ + " AND ProjectCategory<>'S' "
+ + "ORDER BY Name";
+
+ return DB.getKeyNamePairs(MRole.getDefault().addAccessSQL(
+ sql, "C_Project", MRole.SQL_NOTQUALIFIED, MRole.SQL_RO), true);
+ } // getProjects
+
+ /**
+ * Get Array of open Invoices
+ * @return invoices
+ */
+
+ private KeyNamePair[] getInvoices()
+ {
+ String sql = "SELECT C_Invoice_ID, DocumentNo || '_' || GrandTotal "
+ + "FROM C_Invoice "
+ + "WHERE Processed='N' AND DocStatus='DR' "
+ + "ORDER BY DocumentNo";
+
+ return DB.getKeyNamePairs(MRole.getDefault().addAccessSQL(
+ sql, "C_Invoice", MRole.SQL_NOTQUALIFIED, MRole.SQL_RO), true);
+ } // getInvoices
+
+ /**************************************************************************
+ * Create Main Panel.
+ * Called when changing Product
+ */
+
+ private void createMainPanel ()
+ {
+ log.config(": " + m_product);
+ this.getChildren().clear();
+ //this.invalidate();
+ //this.setBorder(null);
+
+ m_selectionList.clear();
+ m_productList.clear();
+ m_qtyList.clear();
+ m_buttonGroups.clear();
+
+ this.appendChild(new Separator());
+ this.appendChild(grpSelectionPanel);
+ this.appendChild(new Separator());
+ this.appendChild(grpSelectProd);
+ this.appendChild(new Separator());
+ this.appendChild(confirmPanel);
+ this.appendChild(new Separator());
+ this.setBorder("normal");
+
+ Caption title = new Caption(Msg.getMsg(Env.getCtx(), "SelectProduct"));
+
+ grpSelectProd.getChildren().clear();
+ grpSelectProd.appendChild(title);
+
+ if (m_product != null && m_product.get_ID() > 0)
+ {
+ title.setLabel(m_product.getName());
+
+ if (m_product.getDescription() != null && m_product.getDescription().length() > 0)
+ ;//this.setsetToolTipText(m_product.getDescription());
+
+ m_bomLine = 0;
+ addBOMLines(m_product, m_qty);
+ }
+ } // createMainPanel
+
+ /**
+ * Add BOM Lines to this.
+ * Called recursively
+ * @param product product
+ * @param qty quantity
+ */
+
+ private void addBOMLines (MProduct product, BigDecimal qty)
+ {
+ MProductBOM[] bomLines = MProductBOM.getBOMLines(product);
+
+ for (int i = 0; i < bomLines.length; i++)
+ {
+ grpSelectProd.appendChild(new Separator());
+ addBOMLine (bomLines[i], qty);
+ grpSelectProd.appendChild(new Separator());
+ }
+
+ log.fine("#" + bomLines.length);
+ } // addBOMLines
+
+ /**
+ * Add BOM Line to this.
+ * Calls addBOMLines if added product is a BOM
+ * @param line BOM Line
+ * @param qty quantity
+ */
+
+ private void addBOMLine (MProductBOM line, BigDecimal qty)
+ {
+ log.fine(line.toString());
+ String bomType = line.getBOMType();
+
+ if (bomType == null)
+ bomType = MProductBOM.BOMTYPE_StandardPart;
+ //
+ BigDecimal lineQty = line.getBOMQty().multiply(qty);
+ MProduct product = line.getProduct();
+
+ if (product == null)
+ return;
+
+ if (product.isBOM() && product.isVerified())
+ addBOMLines (product, lineQty); // recursive
+ else
+ addDisplay (line.getM_Product_ID(),
+ product.getM_Product_ID(), bomType, product.getName(), lineQty);
+ } // addBOMLine
+
+ /**
+ * Add Line to Display
+ * @param parentM_Product_ID parent product
+ * @param M_Product_ID product
+ * @param bomType bom type
+ * @param name name
+ * @param lineQty qty
+ */
+
+ private void addDisplay (int parentM_Product_ID,
+ int M_Product_ID, String bomType, String name, BigDecimal lineQty)
+ {
+ log.fine("M_Product_ID=" + M_Product_ID + ",Type=" + bomType + ",Name=" + name + ",Qty=" + lineQty);
+
+ boolean selected = true;
+
+ Hbox boxQty = new Hbox();
+ boxQty.setWidth("100%");
+ boxQty.setWidths("10%, 40%, 50%");
+
+ if (MProductBOM.BOMTYPE_StandardPart.equals(bomType))
+ {
+ String title = "";
+ Checkbox cb = new Checkbox();
+ cb.setLabel(title);
+ cb.setChecked(true);
+ cb.setEnabled(false);
+
+ m_selectionList.add(cb);
+ boxQty.appendChild(cb);
+ }
+ else if (MProductBOM.BOMTYPE_OptionalPart.equals(bomType))
+ {
+ String title = Msg.getMsg(Env.getCtx(), "Optional");
+ Checkbox cb = new Checkbox();
+ cb.setLabel(title);
+ cb.setChecked(false);
+ selected = false;
+ cb.addEventListener(Events.ON_CHECK, this);
+
+ m_selectionList.add(cb);
+ boxQty.appendChild(cb);
+ }
+ else // Alternative
+ {
+ String title = Msg.getMsg(Env.getCtx(), "Alternative") + " " + bomType;
+ Radio b = new Radio();
+ b.setLabel(title);
+ String groupName = String.valueOf(parentM_Product_ID) + "_" + bomType;
+ Radiogroup group = (Radiogroup)m_buttonGroups.get(groupName);
+
+ if (group == null)
+ {
+ log.fine("ButtonGroup=" + groupName);
+ group = new Radiogroup();
+ m_buttonGroups.put(groupName, group);
+ group.appendChild(b);
+ b.setSelected(true); // select first one
+ }
+ else
+ {
+ group.appendChild(b);
+ b.setSelected(false);
+ selected = false;
+ }
+ b.addEventListener(Events.ON_CLICK, this);
+ m_selectionList.add(b);
+ boxQty.appendChild(b);
+ }
+
+ // Add to List & display
+ m_productList.add (new Integer(M_Product_ID));
+ Textbox qty = new Textbox();
+ qty.setValue(lineQty.toString());
+ qty.setEnabled(selected);
+ m_qtyList.add(qty);
+
+ Label label = new Label(name);
+
+ boxQty.appendChild(label);
+ boxQty.appendChild(qty);
+
+ grpSelectProd.appendChild(boxQty);
+ } // addDisplay
+
+ /**************************************************************************
+ * Action Listener
+ * @param e event
+ */
+ public void onEvent (Event e) throws Exception
+ {
+ log.config(e.getName());
+
+ Object source = e.getTarget();
+
+ // Toggle Qty Enabled
+ if (source instanceof Checkbox || source instanceof Radio)
+ {
+ cmd_selection (source);
+ // need to de-select the others in group
+ if (source instanceof Radio)
+ {
+ // find Button Group
+ Iterator it = m_buttonGroups.values().iterator();
+
+ while (it.hasNext())
+ {
+ Radiogroup group = (Radiogroup)it.next();
+ Enumeration en = (Enumeration) group.getChildren();
+
+ while (en.hasMoreElements())
+ {
+ // We found the group
+ if (source == en.nextElement())
+ {
+ Enumeration info = (Enumeration) group.getChildren();
+
+ while (info.hasMoreElements())
+ {
+ Object infoObj = info.nextElement();
+ if (source != infoObj)
+ cmd_selection(infoObj);
+ }
+ }
+ }
+ }
+ }
+ } // JCheckBox or JRadioButton
+
+ // Product / Qty
+ else if (source == productField || source == productQty)
+ {
+ m_qty = new BigDecimal(productQty.getValue());
+
+ ListItem listitem = productField.getSelectedItem();
+
+ KeyNamePair pp = null;
+
+ if (listitem != null)
+ pp = (KeyNamePair)listitem.getValue();
+
+ m_product = MProduct.get (Env.getCtx(), pp.getKey());
+ createMainPanel();
+ //sizeIt();
+ }
+
+ // Order
+ else if (source == orderField)
+ {
+ ListItem listitem = orderField.getSelectedItem();
+
+ KeyNamePair pp = null;
+
+ if (listitem != null)
+ pp = (KeyNamePair)listitem.getValue();
+
+ boolean valid = (pp != null && pp.getKey() > 0);
+
+ if (invoiceField != null)
+ invoiceField.setEnabled(!valid);
+ if (projectField != null)
+ projectField.setEnabled(!valid);
+ }
+ // Invoice
+ else if (source == invoiceField)
+ {
+ ListItem listitem = invoiceField.getSelectedItem();
+
+ KeyNamePair pp = null;
+
+ if (listitem != null)
+ pp = (KeyNamePair)listitem.getValue();
+
+ boolean valid = (pp != null && pp.getKey() > 0);
+
+ if (orderField != null)
+ orderField.setEnabled(!valid);
+ if (projectField != null)
+ projectField.setEnabled(!valid);
+ }
+ // Project
+ else if (source == projectField)
+ {
+ ListItem listitem = projectField.getSelectedItem();
+
+ KeyNamePair pp = null;
+
+ if (listitem != null)
+ pp = (KeyNamePair)listitem.getValue();
+
+ boolean valid = (pp != null && pp.getKey() > 0);
+ //
+ if (orderField != null)
+ orderField.setEnabled(!valid);
+ if (invoiceField != null)
+ invoiceField.setEnabled(!valid);
+ }
+ // OK
+ else if (confirmPanel.getButton("Ok").equals(e.getTarget()))
+ {
+ if (cmd_save())
+ SessionManager.getAppDesktop().removeWindow();
+ }
+ else if (confirmPanel.getButton("Cancel").equals(e.getTarget()))
+ SessionManager.getAppDesktop().removeWindow();
+
+ // Enable OK
+ boolean OK = m_product != null;
+
+ if (OK)
+ {
+ KeyNamePair pp = null;
+
+ if (orderField != null)
+ {
+ ListItem listitem = orderField.getSelectedItem();
+
+ if (listitem != null)
+ pp = (KeyNamePair)listitem.getValue();
+ }
+
+ if ((pp == null || pp.getKey() <= 0) && invoiceField != null)
+ {
+ ListItem listitem = invoiceField.getSelectedItem();
+
+ if (listitem != null)
+ pp = (KeyNamePair)listitem.getValue();
+ }
+
+ if ((pp == null || pp.getKey() <= 0) && projectField != null)
+ {
+ ListItem listitem = projectField.getSelectedItem();
+
+ if (listitem != null)
+ pp = (KeyNamePair)listitem.getValue();
+ }
+ OK = (pp != null && pp.getKey() > 0);
+ }
+
+ confirmPanel.setEnabled("Ok", OK);
+ } // actionPerformed
+
+ /**
+ * Enable/disable qty based on selection
+ * @param source JCheckBox or JRadioButton
+ */
+
+ private void cmd_selection (Object source)
+ {
+ for (int i = 0; i < m_selectionList.size(); i++)
+ {
+ if (source == m_selectionList.get(i))
+ {
+ boolean selected = isSelectionSelected(source);
+ Textbox qty = (Textbox)m_qtyList.get(i);
+ qty.setEnabled(selected);
+ return;
+ }
+ }
+ log.log(Level.SEVERE, "not found - " + source);
+ } // cmd_selection
+
+ /**
+ * Is Selection Selected
+ * @param source CheckBox or RadioButton
+ * @return true if selected
+ */
+
+ private boolean isSelectionSelected (Object source)
+ {
+ boolean retValue = false;
+
+ if (source instanceof Checkbox)
+ retValue = ((Checkbox)source).isChecked();
+ else if (source instanceof Radio)
+ retValue = ((Radio)source).isChecked();
+ else
+ log.log(Level.SEVERE, "Not valid - " + source);
+
+ return retValue;
+ } // isSelected
+
+ /**************************************************************************
+ * Save Selection
+ * @return true if saved
+ */
+
+ private boolean cmd_save()
+ {
+ ListItem listitem = orderField.getSelectedItem();
+
+ KeyNamePair pp = null;
+
+ if (listitem != null)
+ pp = (KeyNamePair)listitem.getValue();
+
+ if (pp != null && pp.getKey() > 0)
+ return cmd_saveOrder (pp.getKey());
+
+ listitem = invoiceField.getSelectedItem();
+
+ pp = null;
+
+ if (listitem != null)
+ pp = (KeyNamePair)listitem.getValue();
+
+ if (pp != null && pp.getKey() > 0)
+ return cmd_saveInvoice (pp.getKey());
+
+ listitem = projectField.getSelectedItem();
+
+ pp = null;
+
+ if (listitem != null)
+ pp = (KeyNamePair)listitem.getValue();
+
+ if (pp != null && pp.getKey() > 0)
+ return cmd_saveProject (pp.getKey());
+
+ log.log(Level.SEVERE, "Nothing selected");
+ return false;
+ } // cmd_save
+
+ /**
+ * Save to Order
+ * @param C_Order_ID id
+ * @return true if saved
+ */
+
+ private boolean cmd_saveOrder (int C_Order_ID)
+ {
+ log.config("C_Order_ID=" + C_Order_ID);
+ MOrder order = new MOrder (Env.getCtx(), C_Order_ID, null);
+
+ if (order.get_ID() == 0)
+ {
+ log.log(Level.SEVERE, "Not found - C_Order_ID=" + C_Order_ID);
+ return false;
+ }
+
+ int lineCount = 0;
+
+ // for all bom lines
+ for (int i = 0; i < m_selectionList.size(); i++)
+ {
+ if (isSelectionSelected(m_selectionList.get(i)))
+ {
+ BigDecimal qty = new BigDecimal(((Textbox)m_qtyList.get(i)).getValue());
+ int M_Product_ID = ((Integer)m_productList.get(i)).intValue();
+ // Create Line
+ MOrderLine ol = new MOrderLine (order);
+ ol.setM_Product_ID(M_Product_ID, true);
+ ol.setQty(qty);
+ ol.setPrice();
+ ol.setTax();
+ if (ol.save())
+ lineCount++;
+ else
+ log.log(Level.SEVERE, "Line not saved");
+ } // line selected
+ } // for all bom lines
+
+ log.config("#" + lineCount);
+ return true;
+ } // cmd_saveOrder
+
+ /**
+ * Save to Invoice
+ * @param C_Invoice_ID id
+ * @return true if saved
+ */
+
+ private boolean cmd_saveInvoice (int C_Invoice_ID)
+ {
+ log.config("C_Invoice_ID=" + C_Invoice_ID);
+ MInvoice invoice = new MInvoice (Env.getCtx(), C_Invoice_ID, null);
+ if (invoice.get_ID() == 0)
+ {
+ log.log(Level.SEVERE, "Not found - C_Invoice_ID=" + C_Invoice_ID);
+ return false;
+ }
+ int lineCount = 0;
+
+ // for all bom lines
+ for (int i = 0; i < m_selectionList.size(); i++)
+ {
+ if (isSelectionSelected(m_selectionList.get(i)))
+ {
+ BigDecimal qty = new BigDecimal(((Textbox)m_qtyList.get(i)).getValue());
+ int M_Product_ID = ((Integer)m_productList.get(i)).intValue();
+ // Create Line
+ MInvoiceLine il = new MInvoiceLine (invoice);
+ il.setM_Product_ID(M_Product_ID, true);
+ il.setQty(qty);
+ il.setPrice();
+ il.setTax();
+ if (il.save())
+ lineCount++;
+ else
+ log.log(Level.SEVERE, "Line not saved");
+ } // line selected
+ } // for all bom lines
+
+ log.config("#" + lineCount);
+ return true;
+ } // cmd_saveInvoice
+
+ /**
+ * Save to Project
+ * @param C_Project_ID id
+ * @return true if saved
+ */
+ private boolean cmd_saveProject (int C_Project_ID)
+ {
+ log.config("C_Project_ID=" + C_Project_ID);
+ MProject project = new MProject (Env.getCtx(), C_Project_ID, null);
+ if (project.get_ID() == 0)
+ {
+ log.log(Level.SEVERE, "Not found - C_Project_ID=" + C_Project_ID);
+ return false;
+ }
+ int lineCount = 0;
+
+ // for all bom lines
+ for (int i = 0; i < m_selectionList.size(); i++)
+ {
+ if (isSelectionSelected(m_selectionList.get(i)))
+ {
+ BigDecimal qty = new BigDecimal(((Textbox)m_qtyList.get(i)).getValue());
+ int M_Product_ID = ((Integer)m_productList.get(i)).intValue();
+ // Create Line
+ MProjectLine pl = new MProjectLine (project);
+ pl.setM_Product_ID(M_Product_ID);
+ pl.setPlannedQty(qty);
+
+ if (pl.save())
+ lineCount++;
+ else
+ log.log(Level.SEVERE, "Line not saved");
+ } // line selected
+ } // for all bom lines
+
+ log.config("#" + lineCount);
+ return true;
+ } // cmd_saveProject
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WCharge.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WCharge.java
new file mode 100644
index 0000000000..8a41936e2d
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WCharge.java
@@ -0,0 +1,905 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
+ * or via info@compiere.org or http://www.compiere.org/license.html *
+ *****************************************************************************/
+
+/**
+ * 2007, Modified by Posterita Ltd.
+ */
+
+package org.adempiere.webui.apps.form;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Vector;
+import java.util.logging.Level;
+
+import org.adempiere.webui.component.Button;
+import org.adempiere.webui.component.Checkbox;
+import org.adempiere.webui.component.Column;
+import org.adempiere.webui.component.Columns;
+import org.adempiere.webui.component.Grid;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.ListModelTable;
+import org.adempiere.webui.component.Panel;
+import org.adempiere.webui.component.Row;
+import org.adempiere.webui.component.Rows;
+import org.adempiere.webui.component.Textbox;
+import org.adempiere.webui.component.WConfirmPanel;
+import org.adempiere.webui.component.WListbox;
+import org.adempiere.webui.panel.ADForm;
+import org.adempiere.webui.session.SessionManager;
+import org.adempiere.webui.window.FDialog;
+import org.compiere.model.MAccount;
+import org.compiere.model.MAcctSchema;
+import org.compiere.model.MCharge;
+import org.compiere.model.MElementValue;
+import org.compiere.util.CLogger;
+import org.compiere.util.DB;
+import org.compiere.util.Env;
+import org.compiere.util.KeyNamePair;
+import org.compiere.util.Msg;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zk.ui.event.Events;
+
+/**
+ * This class represents the Custom Form for generating charges
+ * from natural accounts.
+ *
+ * The form is comprised of two parts.
+ * The upper portion can be used to create new charges using the general charge accounts.
+ * The lower portion can be used to create charges based on the natural account.
+ *
+ * @author Andrew Kimball
+ *
+ */
+public class WCharge extends ADForm implements EventListener
+{
+ /** Unique identifier. */
+ private static final long serialVersionUID = 1L;
+ /** AD_Message for "Create". */
+ private static final String AD_MESSAGE_CREATE = "Create";
+ /** Logger. */
+ private static CLogger log = CLogger.getCLogger(WCharge.class);
+
+ /** Account Element identifier. */
+ private int m_elementId = 0;
+ /** Account Schema identifier. */
+ private int m_accountSchemaId = 0;
+ /** Default Charge Tax Category. */
+ private int m_taxCategoryId = 0;
+ /** Identifier for the client. */
+ private int m_clientId = 0;
+ /** Identifier for the organisation. */
+ private int m_organisationId = 0;
+ /** Accounting schema model. */
+ private MAcctSchema m_acctSchema = null;
+
+ /** Panel for holding other panels. */
+ private Panel m_pnlMain = new Panel();
+
+ // new panel
+ /** Grid for components for creating a new charge account. */
+ private Grid m_grdNew = new Grid();
+ /** Title of new charge account grid. */
+ private Column m_clmNewTitle = new Column();
+ /** Value (key) field label. */
+ private Label m_lblValue = new Label();
+ /** Field for specifying value (key) of new account. */
+ private Textbox m_txbValueField = new Textbox();
+ /** Checkbox for specifying whether or not the new account is an expense account. */
+ private Checkbox m_chbIsExpense = new Checkbox();
+ /** Name field label. */
+ private Label m_lblName = new Label();
+ /** Field for specifying name of new account. */
+ private Textbox m_txbNameField = new Textbox();
+ /** Button to create new account. */
+ private Button m_btnNew = new Button();
+
+ // account panel
+ /** Grid for components for creating a charge form a selected account. **/
+ private Grid m_grdAccount = new Grid();
+ /** Title of account grid. */
+ private Column m_clmAccountTitle = new Column();
+ /** Button to create charge from selected account. */
+ private Button m_btnAccount = new Button();
+ /** Table to hold data of accounts. */
+ private WListbox m_tblData = new WListbox();
+
+ /** confirmation panel. */
+ private WConfirmPanel m_pnlConfirm = new WConfirmPanel();
+ /** Confirmation Grid. */
+ private Grid m_grdConfirm = new Grid();
+
+ /** Enumeration of column names and indices. */
+ private enum EColumn
+ {
+ /** Select column to record whether the account is selected. */
+ SELECT(0, "Select"),
+ /** Value column to hold the account key. */
+ VALUE(1, "Value"),
+ /** Name column to hold the account name. */
+ NAME(2, "Name"),
+ /** Expense column to indicate whether or not the account is an expense account. */
+ EXPENSE(3, "Expense");
+
+ /** The column's index. */
+ private final int m_index;
+ /** The column's name. */
+ private final String m_title;
+
+ /**
+ * Constructor.
+ *
+ * @param index index of the column
+ * @param title name of the column
+ */
+ EColumn(int index, String title)
+ {
+ m_index = index;
+ m_title = title;
+ }
+
+ /**
+ * Gets the index of the column.
+ *
+ * @return the column index.
+ */
+ public int index()
+ {
+ return m_index;
+ }
+
+ /**
+ * Gets the name of the column.
+ *
+ * @return the column's name
+ */
+ public String title()
+ {
+ return m_title;
+ }
+
+ /**
+ * Gets the number of columns.
+ *
+ * @return the number of columns.
+ */
+ public static int count()
+ {
+ return values().length;
+ }
+
+ }
+
+ /**
+ * Default constructor.
+ */
+ public WCharge()
+ {
+ super();
+ }
+
+
+ /**
+ * Initialises the panel.
+ *
+ * @param adFormId The Adempiere identifier for the form
+ * @param name The name of the form
+ */
+ public void init(int adFormId, String name)
+ {
+ super.init(adFormId, name);
+ log.info("");
+ try
+ {
+ staticInitialise();
+ dynamicInitialise();
+ this.appendChild(m_pnlMain);
+ //this.appendChild(confirmPanel);
+ }
+ catch(Exception e)
+ {
+ log.log(Level.SEVERE, "", e);
+ }
+
+ return;
+ }
+
+
+ /**
+ * Initialises the static components of the form.
+ */
+ private void staticInitialise()
+ {
+ createNewChargePanel();
+ createAccountPanel();
+ createConfirmPanel();
+ // TODO
+ m_pnlMain.appendChild(m_grdNew);
+ m_pnlMain.appendChild(m_grdAccount);
+ m_pnlMain.appendChild(m_grdConfirm);
+ return;
+ }
+
+ /**
+ * Creates the account panel.
+ *
+ * The account panel contains:
+ * a table detailing all accounts
+ * a button for creating charges for selected accounts
+ */
+ private void createAccountPanel()
+ {
+ Row topRow = new Row();
+ Row bottomRow = new Row();
+ Rows rows = new Rows();
+ Columns header = new Columns();
+
+ // header
+ m_clmAccountTitle.setLabel(Msg.getMsg(Env.getCtx(), "ChargeFromAccount"));
+ header.appendChild(m_clmAccountTitle);
+
+ // top row
+ m_tblData.setRows(20);
+ topRow.appendChild(m_tblData);
+ rows.appendChild(topRow);
+
+ // bottom row
+ bottomRow.setAlign("right");
+ m_btnAccount.setLabel(Msg.getMsg(Env.getCtx(), AD_MESSAGE_CREATE));
+ m_btnAccount.addEventListener(Events.ON_CLICK, this);
+ bottomRow.appendChild(m_btnAccount);
+ rows.appendChild(bottomRow);
+
+ // put it all together
+ m_grdAccount.appendChild(header);
+ m_grdAccount.appendChild(rows);
+
+ return;
+ }
+
+ /**
+ * Creates the New Charge panel.
+ *
+ * The New Charge panel is used to specify the name and key of an account
+ * and whether or not the account is a charge account.
+ */
+ private void createNewChargePanel()
+ {
+ final int nameFieldColumns = 20;
+ final int valueFieldColumns = 10;
+ Row topRow = new Row();
+ Row bottomRow = new Row();
+ Rows rows = new Rows();
+ Columns header = new Columns();
+
+ // header
+ m_clmNewTitle.setLabel(Msg.getMsg(Env.getCtx(), "ChargeNewAccount"));
+ header.appendChild(m_clmNewTitle);
+
+ // top row
+ m_lblValue.setValue(Msg.translate(Env.getCtx(), EColumn.VALUE.title()));
+ m_txbValueField.setCols(valueFieldColumns);
+ m_chbIsExpense.setChecked(true);
+ m_chbIsExpense.setLabel(Msg.getMsg(Env.getCtx(), EColumn.EXPENSE.title()));
+ topRow.appendChild(m_lblValue);
+ topRow.appendChild(m_txbValueField);
+ topRow.appendChild(m_chbIsExpense);
+ rows.appendChild(topRow);
+
+ // bottom row
+ m_lblName.setValue(Msg.translate(Env.getCtx(), EColumn.NAME.title()));
+ m_txbNameField.setCols(nameFieldColumns);
+ m_btnNew.setLabel(Msg.getMsg(Env.getCtx(), AD_MESSAGE_CREATE));
+ m_btnNew.addEventListener(Events.ON_CLICK, this);
+ bottomRow.appendChild(m_lblName);
+ bottomRow.appendChild(m_txbNameField);
+ bottomRow.appendChild(m_btnNew);
+ rows.appendChild(bottomRow);
+
+ // put it all together
+ m_grdNew.appendChild(header);
+ m_grdNew.appendChild(rows);
+
+ return;
+ }
+
+
+ /**
+ * Initialises the dynamic components of the form.
+ * Gets defaults for primary AcctSchema
+ * Creates Table with Accounts
+ */
+ private void dynamicInitialise()
+ {
+ String sql;
+ findChargeElementID();
+
+ if (m_elementId == 0)
+ {
+ return;
+ }
+
+ // Table
+ Vector> data = new Vector>();
+ sql = "SELECT C_ElementValue_ID,Value, Name, AccountType "
+ + "FROM C_ElementValue "
+ + "WHERE AccountType IN ('R','E')"
+ + " AND IsSummary='N'"
+ + " AND C_Element_ID=? "
+ + "ORDER BY 2";
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql, null);
+ pstmt.setInt(1, m_elementId);
+ ResultSet rs = pstmt.executeQuery();
+
+ while (rs.next())
+ {
+ Vector line = createDataLine(rs);
+ data.add(line);
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException exception)
+ {
+ log.log(Level.SEVERE, sql, exception);
+ }
+ // Header Info
+ Vector columnNames = getColumnNames();
+
+ // Set Model
+ ListModelTable model = new ListModelTable(data);
+ m_tblData.setData(model, columnNames);
+ //
+ m_tblData.setColumnClass(EColumn.SELECT.index(), Boolean.class, false); // 0-Selection
+ m_tblData.setColumnClass(EColumn.VALUE.index(), String.class, true); // 1-Value
+ m_tblData.setColumnClass(EColumn.NAME.index(), String.class, true); // 2-Name
+ m_tblData.setColumnClass(EColumn.EXPENSE.index(), Boolean.class, true); // 3-Expense
+ // Table UI
+ //m_tblData.autoSize();
+
+ // Other Defaults
+ m_clientId = Env.getAD_Client_ID(Env.getCtx());
+ m_organisationId = Env.getAD_Org_ID(Env.getCtx());
+
+ // TaxCategory
+ findTaxCategoryID();
+
+ return;
+ } // dynInit
+
+
+ /**
+ * Finds the identifier for the tax category for the client.
+ */
+ private void findTaxCategoryID()
+ {
+ final String sql = "SELECT C_TaxCategory_ID FROM C_TaxCategory "
+ + "WHERE IsDefault='Y' AND AD_Client_ID=?";
+ m_taxCategoryId = 0;
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql, null);
+ pstmt.setInt(1, m_clientId);
+ ResultSet rs = pstmt.executeQuery();
+ if (rs.next())
+ {
+ m_taxCategoryId = rs.getInt(1);
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException exception)
+ {
+ log.log(Level.SEVERE, sql, exception);
+ }
+
+ return;
+ }
+
+
+ /**
+ * Gets a vector of column names.
+ * The column names are used as column headings int he table.
+ * @return a vector of column names.
+ */
+ private Vector getColumnNames()
+ {
+ Vector columnNames = new Vector(EColumn.count());
+
+ columnNames.add(Msg.getMsg(Env.getCtx(), EColumn.SELECT.title()));
+ columnNames.add(Msg.translate(Env.getCtx(), EColumn.VALUE.title()));
+ columnNames.add(Msg.translate(Env.getCtx(), EColumn.NAME.title()));
+ columnNames.add(Msg.getMsg(Env.getCtx(), EColumn.EXPENSE.title()));
+
+ return columnNames;
+ }
+
+ /**
+ * Creates a data line from the given ResultSet
.
+ *
+ * @param rs result set containing details of an account.
+ * @return a vector containing details of an account.
+ * @throws SQLException if a database access error occurred
+ */
+ private Vector createDataLine(ResultSet rs) throws SQLException
+ {
+ final int noFields = EColumn.count();
+ final int valueIdIndex = 1;
+ final int valueIndex = 2;
+ final int nameIndex = 3;
+ final int expenseIndex = 4;
+ final String expenseType = "E";
+ boolean isExpenseType;
+ Vector line = new Vector(noFields);
+
+ // 0-Selection
+ line.add(new Boolean(false));
+
+ // 1-Value
+ KeyNamePair pp = new KeyNamePair(rs.getInt(valueIdIndex),
+ rs.getString(valueIndex));
+ line.add(pp);
+
+ // 2-Name
+ line.add(rs.getString(nameIndex));
+
+ // 3-Expense
+ isExpenseType = rs.getString(expenseIndex).equals(expenseType);
+ line.add(new Boolean(isExpenseType));
+
+ return line;
+ }
+
+
+ /**
+ * Finds the Element Identifier for the current charge.
+ *
+ */
+ private void findChargeElementID()
+ {
+ m_accountSchemaId = Env.getContextAsInt(Env.getCtx(), "$C_AcctSchema_ID");
+ // get Element
+ String sql = "SELECT C_Element_ID "
+ + "FROM C_AcctSchema_Element "
+ + "WHERE ElementType='AC' AND C_AcctSchema_ID=?";
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql, null);
+ pstmt.setInt(1, m_accountSchemaId);
+ ResultSet rs = pstmt.executeQuery();
+ if (rs.next())
+ {
+ m_elementId = rs.getInt(1);
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException exception)
+ {
+ log.log(Level.SEVERE, sql, exception);
+ }
+ }
+
+ /**
+ * Event Listener.
+ *
+ * @param event event that has been fired.
+ */
+ public void onEvent(Event event)
+ {
+ log.info(event.getName());
+ //
+ if (event.getName().equals(WConfirmPanel.A_OK) || m_elementId == 0)
+ {
+ close();
+ }
+ // new Account
+ else if (event.getTarget().equals(m_btnNew))
+ {
+ createNew();
+ }
+ else if (event.getTarget().equals(m_btnAccount))
+ {
+ createAccount();
+ }
+
+ return;
+ }
+
+ /**
+ * Create new Chargeable Account.
+ */
+ private void createNew()
+ {
+ final String backgroundColorStyle = "background-color:";
+ String value;
+ String name;
+
+ log.config("");
+ // Get Input
+ value = m_txbValueField.getValue();
+ if (value.length() == 0)
+ {
+/* m_txbValueField.setStyle(backgroundColorStyle
+ + ZkCssHelper.createHexColorString(AdempierePLAF.getFieldBackground_Error()));*/
+ return;
+ }
+
+ name = m_txbNameField.getText();
+ if (name.length() == 0)
+ {
+/* m_txbNameField.setStyle(backgroundColorStyle
+ + ZkCssHelper.createHexColorString(AdempierePLAF.getFieldBackground_Error()));*/
+ return;
+ }
+
+ // Create Element
+ int elementValueId = createElementValue (value, name, m_chbIsExpense.isChecked());
+ if (elementValueId == 0)
+ {
+ FDialog.error(m_windowNo, this, "ChargeNotCreated", name);
+ return;
+ }
+ // Create Charge
+ int chargeId = createCharge(name, elementValueId);
+ if (chargeId == 0)
+ {
+ FDialog.error(m_windowNo, this, "ChargeNotCreated", name);
+ return;
+ }
+ FDialog.info(m_windowNo, this, "ChargeCreated", name);
+ } // createNew
+
+
+
+ /**
+ * Create Element Value for primary Account Schema.
+ * @param value account key
+ * @param name account name
+ * @param isExpenseType is expense account
+ * @return element value identifier
+ */
+ private int createElementValue (String value, String name, boolean isExpenseType)
+ {
+ MElementValue elementValue;
+
+ log.config(name);
+ //
+ elementValue = new MElementValue(Env.getCtx(),
+ value,
+ name,
+ null,
+ isExpenseType ? MElementValue.ACCOUNTTYPE_Expense
+ : MElementValue.ACCOUNTTYPE_Revenue,
+ MElementValue.ACCOUNTSIGN_Natural,
+ false,
+ false,
+ null);
+
+ elementValue.setAD_Org_ID(m_organisationId);
+ if (!elementValue.save())
+ {
+ log.log(Level.WARNING, "C_ElementValue_ID not created");
+ }
+
+ return elementValue.getC_ElementValue_ID();
+ } // create_ElementValue
+
+ /**
+ * Create Charge and account entries for primary Account Schema.
+ *
+ * @param name charge name
+ * @param elementValueId element value identifier
+ * @return charge identifier, or 0 if no charge created.
+ */
+ private int createCharge(String name, int elementValueId)
+ {
+ MCharge charge;
+ MAccount account;
+
+ log.config(name + " - ");
+ // Charge
+ charge = new MCharge(Env.getCtx(), 0, null);
+ charge.setName(name);
+ charge.setC_TaxCategory_ID(m_taxCategoryId);
+ if (!charge.save())
+ {
+ log.log(Level.SEVERE, name + " not created");
+ return 0;
+ }
+
+ refreshAccountSchema();
+ if (!isAccountSchemaValid())
+ {
+ return 0;
+ }
+
+ // Target Account
+ account = getAccount(elementValueId, charge);
+ if (account == null)
+ {
+ return 0;
+ }
+
+ updateAccount(charge, account);
+
+ return charge.getC_Charge_ID();
+ } // createCharge
+
+
+ /**
+ * Updates the charge account details.
+ * @param charge the charge
+ * @param account the account
+ */
+ private void updateAccount(MCharge charge, MAccount account)
+ {
+ StringBuffer sql = createUpdateAccountSql(charge, account);
+ //
+ int noAffectedRows = DB.executeUpdate(sql.toString(), null);
+ if (noAffectedRows != 1)
+ {
+ log.log(Level.SEVERE, "Update #" + noAffectedRows + "\n" + sql.toString());
+ }
+
+ return;
+ }
+
+
+ /**
+ * Queries whether the current account scheme is valid.
+ * @return false if the current account is null
or
+ * its identifier is 0 (zero).
+ */
+ private boolean isAccountSchemaValid()
+ {
+ if (m_acctSchema == null)
+ {
+ return false;
+ }
+ else if (m_acctSchema.getC_AcctSchema_ID() == 0)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+
+ /**
+ * Creates the SQL statement for updating the account and charge.
+ *
+ * @param charge charge
+ * @param account account
+ * @return the SQL DML statement for updating the specified account and charge.
+ */
+ private StringBuffer createUpdateAccountSql(MCharge charge, MAccount account)
+ {
+ StringBuffer sql = new StringBuffer("UPDATE C_Charge_Acct ");
+ sql.append("SET CH_Expense_Acct=").append(account.getC_ValidCombination_ID());
+ sql.append(", CH_Revenue_Acct=").append(account.getC_ValidCombination_ID());
+ sql.append(" WHERE C_Charge_ID=").append(charge.getC_Charge_ID());
+ sql.append(" AND C_AcctSchema_ID=").append(m_accountSchemaId);
+
+ return sql;
+ }
+
+
+ /**
+ * Refreshes the current account schema.
+ *
+ */
+ private void refreshAccountSchema()
+ {
+ // Get AcctSchama
+ if (m_acctSchema == null)
+ {
+ m_acctSchema = new MAcctSchema(Env.getCtx(), m_accountSchemaId, null);
+ }
+
+ return;
+ }
+
+
+ /**
+ * Gets the account for the specified charge and element value.
+ * The account is created if it doesn't already exist.
+ * @param elementValueId identifier for the element value
+ * @param charge charge
+ * @return the account
+ */
+ private MAccount getAccount(int elementValueId, MCharge charge)
+ {
+ MAccount defaultAccount = MAccount.getDefault(m_acctSchema, true); // optional null
+ MAccount account = MAccount.get(Env.getCtx(),
+ charge.getAD_Client_ID(),
+ charge.getAD_Org_ID(),
+ m_acctSchema.getC_AcctSchema_ID(),
+ elementValueId,
+ defaultAccount.getC_SubAcct_ID(),
+ defaultAccount.getM_Product_ID(),
+ defaultAccount.getC_BPartner_ID(),
+ defaultAccount.getAD_OrgTrx_ID(),
+ defaultAccount.getC_LocFrom_ID(),
+ defaultAccount.getC_LocTo_ID(),
+ defaultAccount.getC_SalesRegion_ID(),
+ defaultAccount.getC_Project_ID(),
+ defaultAccount.getC_Campaign_ID(),
+ defaultAccount.getC_Activity_ID(),
+ defaultAccount.getUser1_ID(),
+ defaultAccount.getUser2_ID(),
+ defaultAccount.getUserElement1_ID(),
+ defaultAccount.getUserElement2_ID());
+
+ return account;
+ }
+
+
+ /**
+ * Creates Charges from Accounts.
+ * Charges are created for the selected accounts.
+ * The selection is cleared upon completion.
+ */
+ private void createAccount()
+ {
+ StringBuffer listCreated = new StringBuffer();
+ StringBuffer listRejected = new StringBuffer();
+
+ log.config("");
+
+ int noCharges = getNoCharges();
+
+ for (int chargeIndex = 0; chargeIndex < noCharges; chargeIndex++)
+ {
+ if (isRowSelected(chargeIndex))
+ {
+ String name = getChargeName(chargeIndex);
+ int chargeId = createCharge(chargeIndex);
+ if (chargeId == 0)
+ {
+ appendName(listRejected, name);
+ }
+ else
+ {
+ appendName(listCreated, name);
+ }
+ setRowUnselected(chargeIndex);
+ }
+ }
+ if (listCreated.length() > 0)
+ {
+ FDialog.info(m_windowNo, this, "ChargeCreated", listCreated.toString());
+ }
+ if (listRejected.length() > 0)
+ {
+ FDialog.error(m_windowNo, this, "ChargeNotCreated", listRejected.toString());
+ }
+
+ return;
+ } // createAccount
+
+
+ /**
+ * Gets the number of charges in the table.
+ * @return the number of charges in the table.
+ */
+ private int getNoCharges()
+ {
+ int noCharges = m_tblData.getRowCount();
+
+ return noCharges;
+ }
+
+ /**
+ * Creates a charge for specified table row.
+ *
+ * @param rowIndex index of the row for which a charge is to be created.
+ * @return the charge identifier.
+ */
+ private int createCharge(int rowIndex)
+ {
+ KeyNamePair pp = (KeyNamePair)m_tblData.getValueAt(rowIndex, EColumn.VALUE.index());
+ int elementValueId = pp.getKey();
+ String name = getChargeName(rowIndex);
+ int chargeID = createCharge(name, elementValueId);
+
+ return chargeID;
+ }
+
+
+ /**
+ * Gets the name for a specified table row.
+ * @param rowIndex the table row for which to get the name.
+ * @return the charge name.
+ */
+ private String getChargeName(int rowIndex)
+ {
+ String name = (String)m_tblData.getValueAt(rowIndex, EColumn.NAME.index());
+
+ return name;
+ }
+
+ /**
+ * Appends the name
to the nameList
.
+ * @param nameList a list of names
+ * @param name the name to append
+ */
+ private void appendName(StringBuffer nameList, String name)
+ {
+ if (nameList.length() > 0)
+ {
+ nameList.append(", ");
+ }
+ nameList.append(name);
+
+ return;
+ }
+
+
+ /**
+ * Sets a row at rowIndex
as unselected.
+ * @param rowIndex index of the row to deselect.
+ */
+ private void setRowUnselected(int rowIndex)
+ {
+ ListModelTable model = m_tblData.getModel();
+ model.setDataAt(Boolean.valueOf(false), rowIndex, EColumn.SELECT.index());
+
+ return;
+ }
+
+ /**
+ * Queries whether a row is selected.
+ * @param rowIndex index of the row to query.
+ * @return true if the row is selected, false otherwise.
+ */
+ private boolean isRowSelected(int rowIndex)
+ {
+ ListModelTable model = m_tblData.getModel();
+ Boolean isSelected = (Boolean)model.getDataAt(rowIndex, EColumn.SELECT.index());
+
+ return isSelected.booleanValue();
+ }
+
+ /**
+ * Create Confirmation Panel with OK Button.
+ */
+ public void createConfirmPanel()
+ {
+ Rows rows = new Rows();
+ Row row = new Row();
+ m_pnlConfirm.addEventListener(this);
+ row.appendChild(m_pnlConfirm);
+ rows.appendChild(row);
+ m_grdConfirm.appendChild(rows);
+
+ return;
+ } // ConfirmPanel
+
+
+ public void close()
+ {
+ SessionManager.getAppDesktop().removeWindow();
+ }
+}
+
+
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFrom.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFrom.java
new file mode 100644
index 0000000000..16b59a8ac5
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFrom.java
@@ -0,0 +1,600 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
+ * or via info@compiere.org or http://www.compiere.org/license.html *
+ *****************************************************************************/
+
+/**
+ * 2007, Modified by Posterita Ltd.
+ */
+
+package org.adempiere.webui.apps.form;
+
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Vector;
+import java.util.logging.Level;
+
+import org.adempiere.webui.apps.AEnv;
+import org.adempiere.webui.component.Button;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.ListModelTable;
+import org.adempiere.webui.component.Listbox;
+import org.adempiere.webui.component.WListbox;
+import org.adempiere.webui.component.Window;
+import org.adempiere.webui.editor.WEditor;
+import org.adempiere.webui.editor.WSearchEditor;
+import org.adempiere.webui.event.ValueChangeListener;
+import org.adempiere.webui.event.WTableModelEvent;
+import org.adempiere.webui.event.WTableModelListener;
+import org.compiere.model.GridTab;
+import org.compiere.model.MLookup;
+import org.compiere.model.MLookupFactory;
+import org.compiere.model.MOrder;
+import org.compiere.util.CLogger;
+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.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zk.ui.event.Events;
+import org.zkoss.zul.Hbox;
+import org.zkoss.zul.Separator;
+import org.zkoss.zul.Vbox;
+
+/**
+ * Create From (Base Class) : Based on VCreateFrom
+ *
+ * @author Niraj Sohun
+ * @date Jul 16, 2007
+ */
+
+public abstract class WCreateFrom extends Window implements EventListener, WTableModelListener, ValueChangeListener
+{
+ private static CLogger s_log = CLogger.getCLogger (WCreateFrom.class);
+ protected CLogger log = CLogger.getCLogger(getClass());
+
+ protected Hbox hboxCommon = new Hbox();
+ protected Vbox parameterShipmentPanel = new Vbox();
+ protected Hbox parameterBankPanel = new Hbox();
+ protected Vbox parameterInvoicePanel = new Vbox();
+ private Vbox bottomPanel = new Vbox();
+
+ protected Listbox shipmentField = new Listbox();
+ protected Listbox orderField = new Listbox();
+ protected Listbox invoiceField = new Listbox();
+
+ protected WEditor bankAccountField;
+ protected WEditor bPartnerField;
+ protected WEditor locatorField;
+
+ protected Button btnCancel = new Button();
+ protected Button btnOk = new Button();
+ protected Button btnSelectAll = new Button();
+
+ private Label bankAccountLabel = new Label();
+ private Label bPartnerLabel = new Label();
+ private Label shipmentLabel = new Label();
+ private Label orderLabel = new Label();
+ private Label invoiceLabel = new Label();
+ private Label locatorLabel = new Label();
+ protected Label lblStatus = new Label();
+
+ protected WListbox dataTable = new WListbox();
+
+ protected int p_WindowNo;
+ protected GridTab p_mTab;
+ private boolean p_initOK;
+
+ protected MOrder p_order = null;
+
+ private void init()
+ {
+ // Common - BP and Purchase Order
+
+ bPartnerLabel.setValue(Msg.getElement(Env.getCtx(), "C_BPartner_ID"));
+
+ orderLabel.setValue(Msg.getElement(Env.getCtx(), "C_Order_ID", false));
+
+ orderField.setRows(0);
+ orderField.setMold("select");
+ orderField.addEventListener(Events.ON_SELECT, this);
+
+ hboxCommon.setWidth("700px");
+ hboxCommon.setWidths("13%, 30%, 12%, 25%");
+
+ hboxCommon.appendChild(bPartnerLabel);
+
+ if (bPartnerField != null)
+ hboxCommon.appendChild(bPartnerField.getComponent());
+
+ hboxCommon.appendChild(orderLabel);
+ hboxCommon.appendChild(orderField);
+
+ //End Common
+
+ // WCreateFromShipment
+
+ invoiceLabel.setValue(Msg.getElement(Env.getCtx(), "C_Invoice_ID", false));
+
+ locatorLabel.setValue(Msg.translate(Env.getCtx(), "M_Locator_ID"));
+
+ invoiceField.setRows(0);
+ invoiceField.setMold("select");
+ invoiceField.addEventListener(Events.ON_SELECT, this);
+
+ Hbox boxShipment = new Hbox();
+ boxShipment.setWidth("100%");
+ boxShipment.setWidths("13%, 30%, 12%, 25%");
+
+ boxShipment.appendChild(locatorLabel);
+
+ if (locatorField != null)
+ boxShipment.appendChild(locatorField.getComponent());
+
+ boxShipment.appendChild(invoiceLabel);
+ boxShipment.appendChild(invoiceField);
+
+ parameterShipmentPanel.setWidth("700px");
+ parameterShipmentPanel.appendChild(boxShipment);
+
+ // WCreateFromInvoice
+
+ shipmentLabel.setValue(Msg.getElement(Env.getCtx(), "M_InOut_ID", false));
+
+ shipmentField.setRows(0);
+ shipmentField.setMold("select");
+ shipmentField.addEventListener(Events.ON_SELECT, this);
+
+ Hbox boxInvoice = new Hbox();
+ boxInvoice.setWidth("100%");
+ boxInvoice.setWidths("13%, 30%, 12%, 25%");
+
+ boxInvoice.appendChild(new Label());
+ boxInvoice.appendChild(new Label());
+ boxInvoice.appendChild(shipmentLabel);
+ boxInvoice.appendChild(shipmentField);
+ //boxInvoice.setStyle("text-align:right");
+
+ parameterInvoicePanel.setWidth("700px");
+ parameterInvoicePanel.appendChild(boxInvoice);
+
+ // End WCreateFromInvoice
+
+ // WCreateFromStatement
+
+ bankAccountLabel.setValue(Msg.translate(Env.getCtx(), "C_BankAccount_ID"));
+
+ Hbox boxStatement = new Hbox();
+ boxStatement.appendChild(bankAccountLabel);
+
+ if (bankAccountField != null)
+ boxStatement.appendChild(bankAccountField.getComponent());
+
+ boxStatement.setStyle("text-align:center");
+
+ parameterBankPanel.setWidth("700px");
+ parameterBankPanel.appendChild(boxStatement);
+
+ // End WCreateFromStatement
+
+ // Listbox
+
+ dataTable.setCheckmark(true);
+ dataTable.setMultiSelection(true);
+
+
+ // Buttons & Status
+
+ Hbox boxButtons = new Hbox();
+ boxButtons.setWidth("100%");
+ boxButtons.setWidths("90%, 5%, 5%" );
+ boxButtons.setStyle("text-align:left");
+
+ btnCancel.addEventListener(Events.ON_CLICK, this);
+ btnCancel.setImage("/images/Cancel24.gif");
+
+ btnOk.addEventListener(Events.ON_CLICK, this);
+ btnOk.setImage("/images/Ok24.gif");
+
+ btnSelectAll.addEventListener(Events.ON_CLICK, this);
+ btnSelectAll.setLabel("Select All");
+
+ boxButtons.appendChild(btnSelectAll);
+ boxButtons.appendChild(btnCancel);
+ boxButtons.appendChild(btnOk);
+
+ bottomPanel.setWidth("700px");
+ bottomPanel.appendChild(boxButtons);
+ bottomPanel.appendChild(lblStatus);
+
+ // End Buttons & Status
+
+ // Window
+
+ this.setWidth("700px");
+ this.setClosable(true);
+ this.setBorder("normal");
+
+ this.appendChild(hboxCommon);
+ this.appendChild(new Separator());
+ this.appendChild(parameterInvoicePanel);
+ this.appendChild(parameterBankPanel);
+ this.appendChild(parameterShipmentPanel);
+ this.appendChild(new Separator());
+ this.appendChild(dataTable);
+ this.appendChild(new Separator());
+ this.appendChild(bottomPanel);
+ }
+
+ public static WCreateFrom create(GridTab mTab)
+ {
+ // Dynamic init preparation
+
+ int AD_Table_ID = Env.getContextAsInt(Env.getCtx(), mTab.getWindowNo(), "BaseTable_ID");
+
+ WCreateFrom retValue = null;
+
+ if (AD_Table_ID == 392) // C_BankStatement
+ retValue = new WCreateFromStatement(mTab);
+ else if (AD_Table_ID == 318) // C_Invoice
+ retValue = new WCreateFromInvoice(mTab);
+ else if (AD_Table_ID == 319) // M_InOut
+ retValue = new WCreateFromShipment(mTab);
+ else if (AD_Table_ID == 426) // C_PaySelection
+ return null; // Ignore - will call process C_PaySelection_CreateFrom
+ else // Not supported CreateFrom
+ {
+ s_log.info("Unsupported AD_Table_ID=" + AD_Table_ID);
+ return null;
+ }
+ return retValue;
+ }
+
+ public WCreateFrom (GridTab mTab)
+ {
+ super();
+
+ log.info(mTab.toString());
+ p_WindowNo = mTab.getWindowNo();
+ p_mTab = mTab;
+
+ try
+ {
+ if (!dynInit())
+ return;
+
+ init();
+
+ //confirmPanel.addActionListener(this);
+
+ // Set status
+
+ //statusBar.setStatusDB("");
+ tableChanged(null);
+ p_initOK = true;
+ }
+ catch(Exception e)
+ {
+ log.log(Level.SEVERE, "", e);
+ p_initOK = false;
+ }
+ AEnv.showWindow(this);
+ }
+
+ /**
+ * Init OK to be able to make changes?
+ * @return on if initialized
+ */
+
+ public boolean isInitOK()
+ {
+ return p_initOK;
+ }
+
+ /**
+ * Dynamic Init
+ * @throws Exception if Lookups cannot be initialized
+ * @return true if initialized
+ */
+
+ abstract boolean dynInit() throws Exception;
+
+ /**
+ * Init Business Partner Details
+ * @param C_BPartner_ID BPartner
+ */
+
+ abstract void initBPDetails(int C_BPartner_ID);
+
+ /**
+ * Add Info
+ */
+
+ abstract void info();
+
+ /**
+ * Save & Insert Data
+ * @return true if saved
+ */
+
+ abstract boolean save();
+
+ public void onEvent(Event e) throws Exception
+ {
+ //log.config("Action=" + e.getActionCommand());
+
+ // OK - Save
+
+ if (e.getTarget() == btnOk)
+ {
+ if (save())
+ this.detach();
+ }
+ // Cancel
+ else if (e.getTarget() == btnCancel)
+ {
+ this.detach();
+ }
+ // Select All
+ // Trifon
+ else if (e.getTarget() == btnSelectAll)
+ {
+ ListModelTable model = dataTable.getModel();
+ int rows = model.size();
+
+ for (int i = 0; i < rows; i++)
+ {
+ //model.setDataAt(new Boolean(true), i, 0);
+ dataTable.addItemToSelection(dataTable.getItemAtIndex(i));
+ //dataTable.setSelectedIndex(i);
+ }
+ info();
+ }
+ // m_action = false;
+ }
+
+ public void tableChanged (WTableModelEvent e)
+ {
+ int type = -1;
+
+ info();
+
+ if (e != null)
+ {
+ type = e.getType();
+
+ if (type != WTableModelEvent.CONTENTS_CHANGED)
+ return;
+ }
+ log.config("Type=" + type);
+ info();
+ }
+
+ protected void initBPartner (boolean forInvoice) throws Exception
+ {
+ // Load BPartner
+
+ int AD_Column_ID = 3499; // C_Invoice.C_BPartner_ID
+ MLookup lookup = MLookupFactory.get (Env.getCtx(), p_WindowNo, 0, AD_Column_ID, DisplayType.Search);
+
+ bPartnerField = new WSearchEditor(lookup, Msg.translate(Env.getCtx(), "C_BPartner_ID"), "", true, false, true);
+ bPartnerField.addValueChangeListner(this);
+
+ int C_BPartner_ID = Env.getContextAsInt(Env.getCtx(), p_WindowNo, "C_BPartner_ID");
+ bPartnerField.setValue(new Integer(C_BPartner_ID));
+
+ // Initial loading
+
+ initBPartnerOIS(C_BPartner_ID, forInvoice);
+ }
+
+ /**
+ * Load PBartner dependent Order/Invoice/Shipment Field.
+ * @param C_BPartner_ID BPartner
+ * @param forInvoice for invoice
+ */
+
+ protected void initBPartnerOIS (int C_BPartner_ID, boolean forInvoice)
+ {
+ log.config("C_BPartner_ID=" + C_BPartner_ID);
+ KeyNamePair pp = new KeyNamePair(0,"");
+
+ // Load PO Orders - Closed, Completed
+
+ orderField.removeEventListener(Events.ON_SELECT, this);
+ orderField.getChildren().clear();
+ orderField.appendItem(pp.getName(), pp);
+
+ // Display
+
+ StringBuffer display = new StringBuffer("o.DocumentNo||' - ' ||")
+ .append(DB.TO_CHAR("o.DateOrdered", DisplayType.Date, Env.getAD_Language(Env.getCtx())))
+ .append("||' - '||")
+ .append(DB.TO_CHAR("o.GrandTotal", DisplayType.Amount, Env.getAD_Language(Env.getCtx())));
+
+ String column = "m.M_InOutLine_ID";
+
+ if (forInvoice)
+ column = "m.C_InvoiceLine_ID";
+
+ StringBuffer sql = new StringBuffer("SELECT o.C_Order_ID,").append(display)
+ .append(" FROM C_Order o "
+ + "WHERE o.C_BPartner_ID=? AND o.IsSOTrx='N' AND o.DocStatus IN ('CL','CO')"
+ + " AND o.C_Order_ID IN "
+ + "(SELECT ol.C_Order_ID FROM C_OrderLine ol"
+ + " LEFT OUTER JOIN M_MatchPO m ON (ol.C_OrderLine_ID=m.C_OrderLine_ID) "
+ + "GROUP BY ol.C_Order_ID,ol.C_OrderLine_ID, ol.QtyOrdered,").append(column)
+ .append(" HAVING (ol.QtyOrdered <> SUM(m.Qty) AND ").append(column)
+ .append(" IS NOT NULL) OR ").append(column).append(" IS NULL) "
+ + "ORDER BY o.DateOrdered");
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql.toString(), null);
+ pstmt.setInt(1, C_BPartner_ID);
+ ResultSet rs = pstmt.executeQuery();
+
+ while (rs.next())
+ {
+ pp = new KeyNamePair(rs.getInt(1), rs.getString(2));
+ orderField.appendItem(pp.getName(), pp);
+ }
+
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql.toString(), e);
+ }
+ orderField.setSelectedIndex(0);
+ orderField.addEventListener(Events.ON_SELECT, this);
+
+ initBPDetails(C_BPartner_ID);
+ }
+
+ protected void loadOrder (int C_Order_ID, boolean forInvoice)
+ {
+ /**
+ * Selected - -
+ * Qty - 0
+ * C_UOM_ID - 1
+ * M_Product_ID - 2
+ * VendorProductNo - 3
+ * OrderLine - 4
+ * ShipmentLine - 5
+ * InvoiceLine - 6
+ */
+
+ log.config("C_Order_ID=" + C_Order_ID);
+ p_order = new MOrder (Env.getCtx(), C_Order_ID, null); // save
+
+ Vector data = new Vector();
+
+ StringBuffer sql = new StringBuffer("SELECT "
+ + "l.QtyOrdered-SUM(COALESCE(m.Qty,0))," // 1
+ + "CASE WHEN l.QtyOrdered=0 THEN 0 ELSE l.QtyEntered/l.QtyOrdered END," // 2
+ + " l.C_UOM_ID,COALESCE(uom.UOMSymbol,uom.Name)," // 3..4
+ + " COALESCE(l.M_Product_ID,0),COALESCE(p.Name,c.Name),po.VendorProductNo," // 5..7
+ + " l.C_OrderLine_ID,l.Line " // 8..9
+ + "FROM C_OrderLine l"
+ + " LEFT OUTER JOIN M_Product_PO po ON (l.M_Product_ID = po.M_Product_ID AND l.C_BPartner_ID = po.C_BPartner_ID) "
+ + " LEFT OUTER JOIN M_MatchPO m ON (l.C_OrderLine_ID=m.C_OrderLine_ID AND ");
+
+ sql.append(forInvoice ? "m.C_InvoiceLine_ID" : "m.M_InOutLine_ID");
+ sql.append(" IS NOT NULL)")
+ .append(" LEFT OUTER JOIN M_Product p ON (l.M_Product_ID=p.M_Product_ID)"
+ + " LEFT OUTER JOIN C_Charge c ON (l.C_Charge_ID=c.C_Charge_ID)");
+
+ if (Env.isBaseLanguage(Env.getCtx(), "C_UOM"))
+ sql.append(" LEFT OUTER JOIN C_UOM uom ON (l.C_UOM_ID=uom.C_UOM_ID)");
+ else
+ sql.append(" LEFT OUTER JOIN C_UOM_Trl uom ON (l.C_UOM_ID=uom.C_UOM_ID AND uom.AD_Language='")
+ .append(Env.getAD_Language(Env.getCtx())).append("')");
+
+ sql.append(" WHERE l.C_Order_ID=? " // #1
+ + "GROUP BY l.QtyOrdered,CASE WHEN l.QtyOrdered=0 THEN 0 ELSE l.QtyEntered/l.QtyOrdered END, "
+ + "l.C_UOM_ID,COALESCE(uom.UOMSymbol,uom.Name),po.VendorProductNo, "
+ + "l.M_Product_ID,COALESCE(p.Name,c.Name), l.Line,l.C_OrderLine_ID "
+ + "ORDER BY l.Line");
+
+ log.finer(sql.toString());
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql.toString(), null);
+ pstmt.setInt(1, C_Order_ID);
+ ResultSet rs = pstmt.executeQuery();
+
+ while (rs.next())
+ {
+ Vector line = new Vector();
+ //line.add(new Boolean(false)); // 0-Selection
+
+ BigDecimal qtyOrdered = rs.getBigDecimal(1);
+ BigDecimal multiplier = rs.getBigDecimal(2);
+ BigDecimal qtyEntered = qtyOrdered.multiply(multiplier);
+ line.add(new Double(qtyEntered.doubleValue())); // 1-Qty
+
+ KeyNamePair pp = new KeyNamePair(rs.getInt(3), rs.getString(4).trim());
+ line.add(pp); // 2-UOM
+
+ pp = new KeyNamePair(rs.getInt(5), rs.getString(6));
+ line.add(pp); // 3-Product
+ line.add(rs.getString(7)); // 4-VendorProductNo
+
+ pp = new KeyNamePair(rs.getInt(8), rs.getString(9));
+ line.add(pp); // 5-OrderLine
+ line.add(null); // 6-Ship
+ line.add(null); // 7-Invoice
+
+ data.add(line);
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (Exception e)
+ {
+ log.log(Level.SEVERE, sql.toString(), e);
+ }
+
+ loadTableOIS (data);
+ }
+
+ /**
+ * Load Order/Invoice/Shipment data into Table
+ * @param data data
+ */
+
+ protected void loadTableOIS (Vector data)
+ {
+ // Header Info
+ Vector columnNames = new Vector(6);
+ //columnNames.add(Msg.getMsg(Env.getCtx(), "Select"));
+ columnNames.add(Msg.translate(Env.getCtx(), "Quantity"));
+ columnNames.add(Msg.translate(Env.getCtx(), "C_UOM_ID"));
+ columnNames.add(Msg.translate(Env.getCtx(), "M_Product_ID"));
+ columnNames.add(Msg.getElement(Env.getCtx(), "VendorProductNo", false));
+ columnNames.add(Msg.getElement(Env.getCtx(), "C_Order_ID", false));
+ columnNames.add(Msg.getElement(Env.getCtx(), "M_InOut_ID", false));
+ columnNames.add(Msg.getElement(Env.getCtx(), "C_Invoice_ID", false));
+
+ // Remove previous listeners
+ //dataTable.getModel().removeTableModelListener(this);
+
+ // Set Model
+ ListModelTable model = new ListModelTable(data);
+ //DefaultTableModel model = new DefaultTableModel(data, columnNames);
+
+ model.addTableModelListener(this);
+ dataTable.setData(model, columnNames);
+
+ //dataTable.setColumnClass(0, Boolean.class, false); // 0-Selection
+ dataTable.setColumnClass(0, Double.class, true); // 1-Qty
+ dataTable.setColumnClass(1, String.class, true); // 2-UOM
+ dataTable.setColumnClass(2, String.class, true); // 3-Product
+ dataTable.setColumnClass(3, String.class, true); // 4-VendorProductNo
+ dataTable.setColumnClass(4, String.class, true); // 5-Order
+ dataTable.setColumnClass(5, String.class, true); // 6-Ship
+ dataTable.setColumnClass(6, String.class, true); // 7-Invoice
+
+ // Table UI
+ //dataTable.autoSize();
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromInvoice.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromInvoice.java
new file mode 100644
index 0000000000..31f9da0d9e
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromInvoice.java
@@ -0,0 +1,487 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
+ * or via info@compiere.org or http://www.compiere.org/license.html *
+ *****************************************************************************/
+
+/**
+ * 2007, Modified by Posterita Ltd.
+ */
+
+package org.adempiere.webui.apps.form;
+
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Vector;
+import java.util.logging.Level;
+
+import org.adempiere.webui.component.ListItem;
+import org.adempiere.webui.component.ListModelTable;
+import org.adempiere.webui.editor.WEditor;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.event.ValueChangeListener;
+import org.adempiere.webui.event.WTableModelListener;
+import org.compiere.model.GridTab;
+import org.compiere.model.MInOut;
+import org.compiere.model.MInOutLine;
+import org.compiere.model.MInvoice;
+import org.compiere.model.MInvoiceLine;
+import org.compiere.model.MOrder;
+import org.compiere.model.MOrderLine;
+import org.compiere.model.MProduct;
+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.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zk.ui.event.Events;
+
+/**
+ * Create From Invoice : Based on VCreateFromInvoice
+ *
+ * @author Niraj Sohun
+ * @date Jul 16, 2007
+ */
+
+public class WCreateFromInvoice extends WCreateFrom implements EventListener, ValueChangeListener, WTableModelListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private MInOut m_inout = null;
+
+ private boolean m_actionActive;
+
+ /**
+ * Protected Constructor
+ * @param mTab MTab
+ */
+
+ public WCreateFromInvoice(GridTab mTab)
+ {
+ super (mTab);
+ log.info(mTab.toString());
+ }
+
+ @Override
+ protected boolean dynInit() throws Exception
+ {
+ log.config("");
+
+ setTitle(Msg.getElement(Env.getCtx(), "C_Invoice_ID", false) + " .. " + Msg.translate(Env.getCtx(), "CreateFrom"));
+
+ parameterBankPanel.setVisible(false);
+ parameterShipmentPanel.setVisible(false);
+
+ initBPartner(true);
+ bPartnerField.addValueChangeListner(this);
+
+ return true;
+ }
+
+ protected void initBPDetails(int C_BPartner_ID)
+ {
+ log.config("C_BPartner_ID" + C_BPartner_ID);
+
+ // Load Shipments (Receipts) - Completed, Closed
+
+ shipmentField.removeEventListener(Events.ON_SELECT, this);
+ shipmentField.getChildren().clear();
+
+ // None
+
+ KeyNamePair pp = new KeyNamePair(0,"");
+ shipmentField.appendItem(pp.getName(), pp);
+
+ // Display
+
+ StringBuffer display = new StringBuffer("s.DocumentNo||' - '||")
+ .append(DB.TO_CHAR("s.MovementDate", DisplayType.Date, Env.getAD_Language(Env.getCtx())));
+
+ StringBuffer sql = new StringBuffer("SELECT s.M_InOut_ID,").append(display)
+ .append(" FROM M_InOut s "
+ + "WHERE s.C_BPartner_ID=? AND s.IsSOTrx='N' AND s.DocStatus IN ('CL','CO')"
+ + " AND s.M_InOut_ID IN "
+ + "(SELECT sl.M_InOut_ID FROM M_InOutLine sl"
+ + " LEFT OUTER JOIN M_MatchInv mi ON (sl.M_InOutLine_ID=mi.M_InOutLine_ID) "
+ + "GROUP BY sl.M_InOut_ID,mi.M_InOutLine_ID,sl.MovementQty "
+ + "HAVING (sl.MovementQty<>SUM(mi.Qty) AND mi.M_InOutLine_ID IS NOT NULL)"
+ + " OR mi.M_InOutLine_ID IS NULL) "
+ + "ORDER BY s.MovementDate");
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql.toString(), null);
+ pstmt.setInt(1, C_BPartner_ID);
+ ResultSet rs = pstmt.executeQuery();
+
+ while (rs.next())
+ {
+ pp = new KeyNamePair(rs.getInt(1), rs.getString(2));
+ shipmentField.appendItem(pp.getName(), pp);
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql.toString(), e);
+ }
+
+ shipmentField.setSelectedIndex(0);
+ shipmentField.addEventListener(Events.ON_SELECT, this);
+ }
+
+ public void onEvent(Event e) throws Exception
+ {
+ super.onEvent(e);
+
+ if (m_actionActive)
+ return;
+
+ m_actionActive = true;
+ log.config("Action=" + e.getTarget());
+
+ // Order
+
+ if (e.getTarget() == orderField)
+ {
+ ListItem listitem = orderField.getSelectedItem();
+ KeyNamePair pp = (KeyNamePair)listitem.getValue();
+ int C_Order_ID = 0;
+
+ if (pp != null)
+ C_Order_ID = pp.getKey();
+
+ // Set Invoice and Shipment to Null
+
+ invoiceField.setSelectedIndex(-1);
+ shipmentField.setSelectedIndex(-1);
+
+ loadOrder(C_Order_ID, true);
+ }
+ // Shipment
+ else if (e.getTarget() == shipmentField)
+ {
+ ListItem listitem = shipmentField.getSelectedItem();
+ KeyNamePair pp = (KeyNamePair)listitem.getValue();
+ int M_InOut_ID = 0;
+
+ if (pp != null)
+ M_InOut_ID = pp.getKey();
+
+ // Set Order and Invoice to Null
+
+ orderField.setSelectedIndex(-1);
+ invoiceField.setSelectedIndex(-1);
+ loadShipment(M_InOut_ID);
+ }
+ m_actionActive = false;
+ }
+
+ public void valueChange(ValueChangeEvent evt)
+ {
+ log.config(evt.getPropertyName() + "=" + evt.getNewValue());
+
+ if (evt == null)
+ return;
+
+ if (evt.getSource() instanceof WEditor)
+ {
+ if (evt.getPropertyName().equals("C_BPartner_ID"))
+ {
+ int C_BPartner_ID = ((Integer)evt.getNewValue()).intValue();
+ initBPartnerOIS (C_BPartner_ID, true);
+ }
+ tableChanged(null);
+ }
+ }
+
+ private void loadShipment(int M_InOut_ID)
+ {
+ log.config("M_InOut_ID=" + M_InOut_ID);
+
+ m_inout = new MInOut(Env.getCtx(), M_InOut_ID, null);
+ p_order = null;
+
+ if (m_inout.getC_Order_ID() != 0)
+ p_order = new MOrder (Env.getCtx(), m_inout.getC_Order_ID(), null);
+
+ Vector> data = new Vector>();
+
+ StringBuffer sql = new StringBuffer("SELECT " // QtyEntered
+ + "l.MovementQty-SUM(NVL(mi.Qty, 0)), l.QtyEntered/l.MovementQty,"
+ + " l.C_UOM_ID, COALESCE(uom.UOMSymbol, uom.Name)," // 3..4
+ + " l.M_Product_ID, p.Name, po.VendorProductNo, l.M_InOutLine_ID, l.Line," // 5..9
+ + " l.C_OrderLine_ID " // 10
+ + " FROM M_InOutLine l "
+ );
+
+ if (Env.isBaseLanguage(Env.getCtx(), "C_UOM"))
+ sql.append(" LEFT OUTER JOIN C_UOM uom ON (l.C_UOM_ID=uom.C_UOM_ID)");
+ else
+ sql.append(" LEFT OUTER JOIN C_UOM_Trl uom ON (l.C_UOM_ID=uom.C_UOM_ID AND uom.AD_Language='")
+ .append(Env.getAD_Language(Env.getCtx())).append("')");
+
+ sql.append(" LEFT OUTER JOIN M_Product p ON (l.M_Product_ID=p.M_Product_ID)")
+ .append(" INNER JOIN M_InOut io ON (l.M_InOut_ID=io.M_InOut_ID)")
+ .append(" LEFT OUTER JOIN M_Product_PO po ON (l.M_Product_ID = po.M_Product_ID AND io.C_BPartner_ID = po.C_BPartner_ID)")
+ .append(" LEFT OUTER JOIN M_MatchInv mi ON (l.M_InOutLine_ID=mi.M_InOutLine_ID)")
+
+ .append(" WHERE l.M_InOut_ID=? ")
+ .append("GROUP BY l.MovementQty, l.QtyEntered/l.MovementQty, "
+ + "l.C_UOM_ID, COALESCE(uom.UOMSymbol, uom.Name), "
+ + "l.M_Product_ID, p.Name, po.VendorProductNo, l.M_InOutLine_ID, l.Line, l.C_OrderLine_ID ")
+ .append("ORDER BY l.Line");
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql.toString(), null);
+ pstmt.setInt(1, M_InOut_ID);
+ ResultSet rs = pstmt.executeQuery();
+
+ while (rs.next())
+ {
+ Vector line = new Vector(7);
+ //line.add(new Boolean(false)); // 0-Selection
+
+ BigDecimal qtyMovement = rs.getBigDecimal(1);
+ BigDecimal multiplier = rs.getBigDecimal(2);
+ BigDecimal qtyEntered = qtyMovement.multiply(multiplier);
+ line.add(new Double(qtyEntered.doubleValue())); // 1-Qty
+
+ KeyNamePair pp = new KeyNamePair(rs.getInt(3), rs.getString(4).trim());
+ line.add(pp); // 2-UOM
+
+ pp = new KeyNamePair(rs.getInt(5), rs.getString(6));
+ line.add(pp); // 3-Product
+ line.add(rs.getString(7)); // 4-VendorProductNo
+
+ int C_OrderLine_ID = rs.getInt(10);
+
+ if (rs.wasNull())
+ line.add(null); // 5-Order
+ else
+ line.add(new KeyNamePair(C_OrderLine_ID,"."));
+
+ pp = new KeyNamePair(rs.getInt(8), rs.getString(9));
+ line.add(pp); // 6-Ship
+ line.add(null); // 7-Invoice
+
+ data.add(line);
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql.toString(), e);
+ }
+ loadTableOIS(data);
+ }
+
+ @Override
+ /**
+ * List number of rows selected
+ */
+ protected void info()
+ {
+ ListModelTable model = dataTable.getModel();
+ int rows = model.size();
+ int count = 0;
+
+ for (int i = 0; i < rows; i++)
+ {
+ if (dataTable.getItemAtIndex(i).isSelected())//(((Boolean)model.getDataAt(i, 0)).booleanValue())
+ count++;
+ }
+ }
+
+ /**
+ * Save - Create Invoice Lines
+ * @return true if saved
+ */
+ protected boolean save()
+ {
+ log.config("");
+ ListModelTable model = dataTable.getModel();
+ int rows = model.size();
+
+ if (rows == 0)
+ return false;
+
+ // Invoice
+
+ Object obj = p_mTab.getValue("C_Invoice_ID");
+
+ if (obj == null)
+ throw new IllegalStateException("Company Agent or Business Partner has not been selected");
+
+ int C_Invoice_ID = ((Integer)p_mTab.getValue("C_Invoice_ID")).intValue();
+ MInvoice invoice = new MInvoice (Env.getCtx(), C_Invoice_ID, null);
+ log.config(invoice.toString());
+
+ if (p_order != null)
+ {
+ invoice.setOrder(p_order); // Overwrite header values
+ invoice.save();
+ }
+
+ // Only first time
+ if (m_inout != null && m_inout.getM_InOut_ID() != 0 && m_inout.getC_Invoice_ID() == 0)
+ {
+ m_inout.setC_Invoice_ID(C_Invoice_ID);
+ m_inout.save();
+ }
+
+ // Lines
+
+ for (int i = 0; i < rows; i++)
+ {
+ if (dataTable.getItemAtIndex(i).isSelected())//(((Boolean)model.getDataAt(i, 0)).booleanValue())
+ {
+ // Variable values
+
+ Double d = (Double)model.getDataAt(i, 0); // 1-Qty
+ BigDecimal QtyEntered = new BigDecimal(d.doubleValue());
+ KeyNamePair pp = (KeyNamePair)model.getDataAt(i, 1); // 2-UOM
+ int C_UOM_ID = pp.getKey();
+ pp = (KeyNamePair)model.getDataAt(i, 2); // 3-Product
+ int M_Product_ID = 0;
+
+ if (pp != null)
+ M_Product_ID = pp.getKey();
+
+ int C_Charge_ID = 0;
+ int C_OrderLine_ID = 0;
+ pp = (KeyNamePair)model.getDataAt(i, 4); // 5-OrderLine
+
+ if (pp != null)
+ C_OrderLine_ID = pp.getKey();
+
+ int M_InOutLine_ID = 0;
+ pp = (KeyNamePair)model.getDataAt(i, 5); // 6-Shipment
+
+ if (pp != null)
+ M_InOutLine_ID = pp.getKey();
+
+ // Precision of Qty UOM
+ int precision = 2;
+
+ if (M_Product_ID != 0)
+ {
+ MProduct product = MProduct.get(Env.getCtx(), M_Product_ID);
+ precision = product.getUOMPrecision();
+ }
+
+ QtyEntered = QtyEntered.setScale(precision, BigDecimal.ROUND_HALF_DOWN);
+ log.fine("Line QtyEntered=" + QtyEntered
+ + ", Product_ID=" + M_Product_ID
+ + ", OrderLine_ID=" + C_OrderLine_ID + ", InOutLine_ID=" + M_InOutLine_ID);
+
+ // Create new Invoice Line
+
+ MInvoiceLine invoiceLine = new MInvoiceLine (invoice);
+ invoiceLine.setM_Product_ID(M_Product_ID, C_UOM_ID); // Line UOM
+ invoiceLine.setQty(QtyEntered); // Invoiced/Entered
+
+ // Info
+
+ MOrderLine orderLine = null;
+
+ if (C_OrderLine_ID != 0)
+ orderLine = new MOrderLine (Env.getCtx(), C_OrderLine_ID, null);
+
+ MInOutLine inoutLine = null;
+
+ if (M_InOutLine_ID != 0)
+ {
+ inoutLine = new MInOutLine (Env.getCtx(), M_InOutLine_ID, null);
+
+ if (orderLine == null && inoutLine.getC_OrderLine_ID() != 0)
+ {
+ C_OrderLine_ID = inoutLine.getC_OrderLine_ID();
+ orderLine = new MOrderLine (Env.getCtx(), C_OrderLine_ID, null);
+ }
+ }
+ else
+ {
+ MInOutLine[] lines = MInOutLine.getOfOrderLine(Env.getCtx(),
+ C_OrderLine_ID, null, null);
+
+ log.fine ("Receipt Lines with OrderLine = #" + lines.length);
+
+ if (lines.length > 0)
+ {
+ for (int j = 0; j < lines.length; j++)
+ {
+ MInOutLine line = lines[j];
+ if (line.getQtyEntered().compareTo(QtyEntered) == 0)
+ {
+ inoutLine = line;
+ M_InOutLine_ID = inoutLine.getM_InOutLine_ID();
+ break;
+ }
+ }
+ if (inoutLine == null)
+ {
+ inoutLine = lines[0]; // First as default
+ M_InOutLine_ID = inoutLine.getM_InOutLine_ID();
+ }
+ }
+ } // Get Ship info
+
+ // Shipment Info
+
+ if (inoutLine != null)
+ {
+ invoiceLine.setShipLine(inoutLine); // Overwrites
+
+ if (inoutLine.getQtyEntered().compareTo(inoutLine.getMovementQty()) != 0)
+ invoiceLine.setQtyInvoiced(QtyEntered
+ .multiply(inoutLine.getMovementQty())
+ .divide(inoutLine.getQtyEntered(), 12, BigDecimal.ROUND_HALF_UP));
+ }
+ else
+ log.fine("No Receipt Line");
+
+ // Order Info
+
+ if (orderLine != null)
+ {
+ invoiceLine.setOrderLine(orderLine); // Overwrites
+
+ if (orderLine.getQtyEntered().compareTo(orderLine.getQtyOrdered()) != 0)
+ invoiceLine.setQtyInvoiced(QtyEntered
+ .multiply(orderLine.getQtyOrdered())
+ .divide(orderLine.getQtyEntered(), 12, BigDecimal.ROUND_HALF_UP));
+ }
+ else
+ {
+ log.fine("No Order Line");
+ invoiceLine.setPrice();
+ invoiceLine.setTax();
+ }
+
+ if (!invoiceLine.save())
+ log.log(Level.SEVERE, "Line NOT created #" + i);
+ } // if selected
+ } // for all rows
+
+ return true;
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromShipment.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromShipment.java
new file mode 100644
index 0000000000..a18aac54f3
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromShipment.java
@@ -0,0 +1,519 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
+ * or via info@compiere.org or http://www.compiere.org/license.html *
+ *****************************************************************************/
+
+/**
+ * 2007, Modified by Posterita Ltd.
+ */
+
+package org.adempiere.webui.apps.form;
+
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Vector;
+import java.util.logging.Level;
+
+import org.adempiere.webui.component.ListItem;
+import org.adempiere.webui.component.ListModelTable;
+import org.adempiere.webui.editor.WEditor;
+import org.adempiere.webui.editor.WLocatorEditor;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.event.ValueChangeListener;
+import org.adempiere.webui.event.WTableModelListener;
+import org.compiere.model.GridTab;
+import org.compiere.model.MInOut;
+import org.compiere.model.MInOutLine;
+import org.compiere.model.MInvoice;
+import org.compiere.model.MInvoiceLine;
+import org.compiere.model.MLocator;
+import org.compiere.model.MLocatorLookup;
+import org.compiere.model.MOrderLine;
+import org.compiere.model.MProduct;
+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.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zk.ui.event.Events;
+
+/**
+ * Create From Shipment : Based on VCreateFromShipment
+ *
+ * @author Niraj Sohun
+ * @date Jul 18, 2007
+ */
+
+public class WCreateFromShipment extends WCreateFrom implements EventListener, ValueChangeListener, WTableModelListener
+{
+ private static final long serialVersionUID = 1L;
+
+ /** Loaded Invoice */
+ private MInvoice m_invoice = null;
+
+ /**
+ * Protected Constructor
+ * @param mTab MTab
+ */
+
+ WCreateFromShipment(GridTab mTab)
+ {
+ super (mTab);
+ }
+
+ protected boolean dynInit() throws Exception
+ {
+ log.config("");
+ setTitle(Msg.getElement(Env.getCtx(), "M_InOut_ID", false) + " .. " + Msg.translate(Env.getCtx(), "CreateFrom"));
+
+ parameterBankPanel.setVisible(false);
+ parameterInvoicePanel.setVisible(false);
+
+ //shipmentLabel.setVisible(false);
+ //shipmentField.setVisible(false);
+
+ // Load Locator
+ int AD_Column_ID = 3537; // M_InOut.M_Locator_ID
+ MLocatorLookup locator = new MLocatorLookup(Env.getCtx(), p_WindowNo);
+ locatorField = new WLocatorEditor ("M_Locator_ID", true, false, true, locator);
+ locatorField.addValueChangeListner(this);
+
+ initBPartner(false);
+ bPartnerField.addValueChangeListner(this);
+
+ return true;
+ }
+
+ protected void initBPDetails(int C_BPartner_ID)
+ {
+ log.config("C_BPartner_ID=" + C_BPartner_ID);
+
+ // Load AP Invoice closed or complete
+
+ invoiceField.removeEventListener(Events.ON_SELECT, this);
+ invoiceField.getChildren().clear();
+
+ // None
+
+ KeyNamePair pp = new KeyNamePair(0,"");
+ invoiceField.appendItem(pp.getName(), pp);
+
+ StringBuffer display = new StringBuffer("i.DocumentNo||' - '||")
+ .append(DB.TO_CHAR("DateInvoiced", DisplayType.Date, Env.getAD_Language(Env.getCtx())))
+ .append("|| ' - ' ||")
+ .append(DB.TO_CHAR("GrandTotal", DisplayType.Amount, Env.getAD_Language(Env.getCtx())));
+
+ StringBuffer sql = new StringBuffer("SELECT i.C_Invoice_ID,").append(display)
+ .append(" FROM C_Invoice i "
+ + "WHERE i.C_BPartner_ID=? AND i.IsSOTrx='N' AND i.DocStatus IN ('CL','CO')"
+ + " AND i.C_Invoice_ID IN "
+ + "(SELECT il.C_Invoice_ID FROM C_InvoiceLine il"
+ + " LEFT OUTER JOIN M_MatchInv mi ON (il.C_InvoiceLine_ID=mi.C_InvoiceLine_ID) "
+ + "GROUP BY il.C_Invoice_ID,mi.C_InvoiceLine_ID,il.QtyInvoiced "
+ + "HAVING (il.QtyInvoiced<>SUM(mi.Qty) AND mi.C_InvoiceLine_ID IS NOT NULL)"
+ + " OR mi.C_InvoiceLine_ID IS NULL) "
+ + "ORDER BY i.DateInvoiced");
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql.toString(), null);
+ pstmt.setInt(1, C_BPartner_ID);
+ ResultSet rs = pstmt.executeQuery();
+
+ while (rs.next())
+ {
+ pp = new KeyNamePair(rs.getInt(1), rs.getString(2));
+ invoiceField.appendItem(pp.getName(), pp);
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql.toString(), e);
+ }
+
+ invoiceField.setSelectedIndex(0);
+ invoiceField.addEventListener(Events.ON_SELECT, this);
+ }
+
+ public void onEvent(Event e) throws Exception
+ {
+ super.onEvent(e);
+
+ log.config("Action=" + e.getTarget());
+
+ // Order
+ if (e.getTarget() == orderField)
+ {
+ ListItem listitem = orderField.getSelectedItem();
+ KeyNamePair pp = (KeyNamePair)listitem.getValue();
+
+ if (pp == null || pp.getKey() == 0)
+ ;
+ else
+ {
+ int C_Order_ID = pp.getKey();
+
+ // Set Invoice and Shipment to Null
+ invoiceField.setSelectedIndex(0);
+ if (shipmentField.getItemCount() > 0)
+ shipmentField.setSelectedIndex(0);
+ loadOrder(C_Order_ID, false);
+ m_invoice = null;
+ }
+ }
+ // Invoice
+ else if (e.getTarget() == invoiceField)
+ {
+ ListItem listitem = invoiceField.getSelectedItem();
+ KeyNamePair pp = (KeyNamePair)listitem.getValue();
+
+ if (pp == null || pp.getKey() == 0)
+ ;
+ else
+ {
+ int C_Invoice_ID = pp.getKey();
+
+ // set Order and Shipment to Null
+ orderField.setSelectedIndex(0);
+ if (shipmentField.getItemCount() > 0)
+ shipmentField.setSelectedIndex(0);
+ loadInvoice(C_Invoice_ID);
+ }
+ }
+ }
+
+ public void valueChange(ValueChangeEvent evt)
+ {
+ log.config(evt.getPropertyName() + "=" + evt.getNewValue());
+
+ if (evt == null)
+ return;
+
+ if (evt.getSource() instanceof WEditor)
+ {
+ // BPartner - load Order/Invoice/Shipment
+
+ if (evt.getPropertyName().equals("C_BPartner_ID"))
+ {
+ int C_BPartner_ID = ((Integer)evt.getNewValue()).intValue();
+ initBPartnerOIS (C_BPartner_ID, false);
+ }
+ tableChanged(null);
+ }
+ }
+
+ /**
+ * Load Data - Invoice
+ * @param C_Invoice_ID Invoice
+ */
+
+ private void loadInvoice(int C_Invoice_ID)
+ {
+ log.config("C_Invoice_ID=" + C_Invoice_ID);
+ m_invoice = new MInvoice(Env.getCtx(), C_Invoice_ID, null); // save
+ p_order = null;
+
+ Vector data = new Vector();
+
+ StringBuffer sql = new StringBuffer("SELECT " // Entered UOM
+ + "l.QtyInvoiced-SUM(NVL(mi.Qty,0)),l.QtyEntered/l.QtyInvoiced,"
+ + " l.C_UOM_ID,COALESCE(uom.UOMSymbol,uom.Name)," // 3..4
+ + " l.M_Product_ID,p.Name, po.VendorProductNo, l.C_InvoiceLine_ID,l.Line," // 5..9
+ + " l.C_OrderLine_ID "
+ + " FROM C_InvoiceLine l "); // 10
+
+ if (Env.isBaseLanguage(Env.getCtx(), "C_UOM"))
+ sql.append(" LEFT OUTER JOIN C_UOM uom ON (l.C_UOM_ID=uom.C_UOM_ID)");
+ else
+ sql.append(" LEFT OUTER JOIN C_UOM_Trl uom ON (l.C_UOM_ID=uom.C_UOM_ID AND uom.AD_Language='")
+ .append(Env.getAD_Language(Env.getCtx())).append("')");
+
+ sql.append(" LEFT OUTER JOIN M_Product p ON (l.M_Product_ID=p.M_Product_ID)")
+ .append(" INNER JOIN C_Invoice inv ON (l.C_Invoice_ID=inv.C_Invoice_ID)")
+ .append(" LEFT OUTER JOIN M_Product_PO po ON (l.M_Product_ID = po.M_Product_ID AND inv.C_BPartner_ID = po.C_BPartner_ID)")
+ .append(" LEFT OUTER JOIN M_MatchInv mi ON (l.C_InvoiceLine_ID=mi.C_InvoiceLine_ID)")
+
+ .append(" WHERE l.C_Invoice_ID=? ")
+ .append("GROUP BY l.QtyInvoiced,l.QtyEntered/l.QtyInvoiced,"
+ + "l.C_UOM_ID,COALESCE(uom.UOMSymbol,uom.Name),"
+ + "l.M_Product_ID,p.Name, po.VendorProductNo, l.C_InvoiceLine_ID,l.Line,l.C_OrderLine_ID ")
+ .append("ORDER BY l.Line");
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql.toString(), null);
+ pstmt.setInt(1, C_Invoice_ID);
+ ResultSet rs = pstmt.executeQuery();
+
+ while (rs.next())
+ {
+ Vector line = new Vector(7);
+ //line.add(new Boolean(false)); // 0-Selection
+
+ BigDecimal qtyInvoiced = rs.getBigDecimal(1);
+ BigDecimal multiplier = rs.getBigDecimal(2);
+ BigDecimal qtyEntered = qtyInvoiced.multiply(multiplier);
+ line.add(new Double(qtyEntered.doubleValue())); // 1-Qty
+
+ KeyNamePair pp = new KeyNamePair(rs.getInt(3), rs.getString(4).trim());
+ line.add(pp); // 2-UOM
+
+ pp = new KeyNamePair(rs.getInt(5), rs.getString(6));
+ line.add(pp); // 3-Product
+ line.add(rs.getString(7)); // 4-VendorProductNo
+
+ int C_OrderLine_ID = rs.getInt(10);
+
+ if (rs.wasNull())
+ line.add(null); // 5-Order
+ else
+ line.add(new KeyNamePair(C_OrderLine_ID, "."));
+
+ line.add(null); // 6-Ship
+
+ pp = new KeyNamePair(rs.getInt(8), rs.getString(9));
+ line.add(pp); // 7-Invoice
+ data.add(line);
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql.toString(), e);
+ }
+
+ loadTableOIS(data);
+ } // loadInvoice
+
+ /**
+ * List number of rows selected
+ */
+
+ protected void info()
+ {
+ ListModelTable model = dataTable.getModel();
+ int rows = model.size();
+ int count = 0;
+
+ for (int i = 0; i < rows; i++)
+ {
+ if (dataTable.getItemAtIndex(i).isSelected())//(((Boolean) model.getDataAt(i, 0)).booleanValue())
+ count++;
+ }
+ lblStatus.setValue(String.valueOf(count));
+ } // info
+
+ /**
+ * Save - create Shipments
+ *
+ * @return true if saved
+ */
+
+ protected boolean save()
+ {
+ log.config("");
+ ListModelTable model = dataTable.getModel();
+ int rows = model.size();
+
+ if (rows == 0)
+ return false;
+
+ MLocator mlocator = (MLocator)locatorField.getValue();
+
+ //Integer loc = (Integer) locatorField.getValue();
+
+ if (mlocator == null || mlocator.getM_Locator_ID()/*.intValue()*/ == 0)
+ {
+/* locatorField.setBackground(AdempierePLAF.getFieldBackground_Error());*/
+ return false;
+ }
+
+ int M_Locator_ID = mlocator.getM_Locator_ID();
+
+ // Get Shipment
+
+ int M_InOut_ID = ((Integer) p_mTab.getValue("M_InOut_ID")).intValue();
+ MInOut inout = new MInOut(Env.getCtx(), M_InOut_ID, null);
+ log.config(inout + ", C_Locator_ID=" + M_Locator_ID);
+
+ // Lines
+
+ for (int i = 0; i < rows; i++)
+ {
+ if (dataTable.getItemAtIndex(i).isSelected())//(((Boolean) model.getDataAt(i, 0)).booleanValue())
+ {
+ // Variable values
+
+ Double d = (Double) model.getDataAt(i, 0); // 1-Qty
+ BigDecimal QtyEntered = new BigDecimal(d.doubleValue());
+ KeyNamePair pp = (KeyNamePair) model.getDataAt(i, 1); // 2-Product
+
+ int C_UOM_ID = pp.getKey();
+ pp = (KeyNamePair) model.getDataAt(i, 2); // 3-Product
+ int M_Product_ID = pp.getKey();
+ int C_OrderLine_ID = 0;
+ pp = (KeyNamePair) model.getDataAt(i, 4); // 5-OrderLine
+
+ if (pp != null)
+ C_OrderLine_ID = pp.getKey();
+ int C_InvoiceLine_ID = 0;
+ MInvoiceLine il = null;
+ pp = (KeyNamePair) model.getDataAt(i, 6); // 7-InvoiceLine
+
+ if (pp != null)
+ C_InvoiceLine_ID = pp.getKey();
+
+ if (C_InvoiceLine_ID != 0)
+ il = new MInvoiceLine (Env.getCtx(), C_InvoiceLine_ID, null);
+
+ boolean isInvoiced = (C_InvoiceLine_ID != 0);
+
+ // Precision of Qty UOM
+ int precision = 2;
+
+ if (M_Product_ID != 0)
+ {
+ MProduct product = MProduct.get(Env.getCtx(), M_Product_ID);
+ precision = product.getUOMPrecision();
+ }
+
+ QtyEntered = QtyEntered.setScale(precision, BigDecimal.ROUND_HALF_DOWN);
+
+ log.fine("Line QtyEntered=" + QtyEntered
+ + ", Product=" + M_Product_ID
+ + ", OrderLine=" + C_OrderLine_ID + ", InvoiceLine=" + C_InvoiceLine_ID);
+
+ // Credit Memo - negative Qty
+
+ if (m_invoice != null && m_invoice.isCreditMemo())
+ QtyEntered = QtyEntered.negate();
+
+ // Create new InOut Line
+ MInOutLine iol = new MInOutLine (inout);
+
+ iol.setM_Product_ID(M_Product_ID, C_UOM_ID); // Line UOM
+ iol.setQty(QtyEntered); // Movement/Entered
+
+ MOrderLine ol = null;
+
+ if (C_OrderLine_ID != 0)
+ {
+ iol.setC_OrderLine_ID(C_OrderLine_ID);
+ ol = new MOrderLine (Env.getCtx(), C_OrderLine_ID, null);
+
+ if (ol.getQtyEntered().compareTo(ol.getQtyOrdered()) != 0)
+ {
+ iol.setMovementQty(QtyEntered
+ .multiply(ol.getQtyOrdered())
+ .divide(ol.getQtyEntered(), 12, BigDecimal.ROUND_HALF_UP));
+ iol.setC_UOM_ID(ol.getC_UOM_ID());
+ }
+
+ iol.setM_AttributeSetInstance_ID(ol.getM_AttributeSetInstance_ID());
+ iol.setDescription(ol.getDescription());
+
+ iol.setC_Project_ID(ol.getC_Project_ID());
+ iol.setC_ProjectPhase_ID(ol.getC_ProjectPhase_ID());
+ iol.setC_ProjectTask_ID(ol.getC_ProjectTask_ID());
+ iol.setC_Activity_ID(ol.getC_Activity_ID());
+ iol.setC_Campaign_ID(ol.getC_Campaign_ID());
+ iol.setAD_OrgTrx_ID(ol.getAD_OrgTrx_ID());
+ iol.setUser1_ID(ol.getUser1_ID());
+ iol.setUser2_ID(ol.getUser2_ID());
+ }
+ else if (il != null)
+ {
+ if (il.getQtyEntered().compareTo(il.getQtyInvoiced()) != 0)
+ {
+ iol.setQtyEntered(QtyEntered
+ .multiply(il.getQtyInvoiced())
+ .divide(il.getQtyEntered(), 12, BigDecimal.ROUND_HALF_UP));
+ iol.setC_UOM_ID(il.getC_UOM_ID());
+ }
+
+ iol.setDescription(il.getDescription());
+ iol.setC_Project_ID(il.getC_Project_ID());
+ iol.setC_ProjectPhase_ID(il.getC_ProjectPhase_ID());
+ iol.setC_ProjectTask_ID(il.getC_ProjectTask_ID());
+ iol.setC_Activity_ID(il.getC_Activity_ID());
+ iol.setC_Campaign_ID(il.getC_Campaign_ID());
+ iol.setAD_OrgTrx_ID(il.getAD_OrgTrx_ID());
+ iol.setUser1_ID(il.getUser1_ID());
+ iol.setUser2_ID(il.getUser2_ID());
+ }
+
+ // Charge
+
+ if (M_Product_ID == 0)
+ {
+ if (ol != null && ol.getC_Charge_ID() != 0) // from order
+ iol.setC_Charge_ID(ol.getC_Charge_ID());
+ else if (il != null && il.getC_Charge_ID() != 0) // from invoice
+ iol.setC_Charge_ID(il.getC_Charge_ID());
+ }
+
+ iol.setM_Locator_ID(M_Locator_ID);
+
+ if (!iol.save())
+ log.log(Level.SEVERE, "Line NOT created #" + i);
+ // Create Invoice Line Link
+ else if (il != null)
+ {
+ il.setM_InOutLine_ID(iol.getM_InOutLine_ID());
+ il.save();
+ }
+ } // if selected
+ } // for all rows
+
+ /**
+ * Update Header
+ * - if linked to another order/invoice - remove link
+ * - if no link set it
+ */
+
+ if (p_order != null && p_order.getC_Order_ID() != 0)
+ {
+ inout.setC_Order_ID (p_order.getC_Order_ID());
+ inout.setAD_OrgTrx_ID(p_order.getAD_OrgTrx_ID());
+ inout.setC_Project_ID(p_order.getC_Project_ID());
+ inout.setC_Campaign_ID(p_order.getC_Campaign_ID());
+ inout.setC_Activity_ID(p_order.getC_Activity_ID());
+ inout.setUser1_ID(p_order.getUser1_ID());
+ inout.setUser2_ID(p_order.getUser2_ID());
+ }
+
+ if (m_invoice != null && m_invoice.getC_Invoice_ID() != 0)
+ {
+ if (inout.getC_Order_ID() == 0)
+ inout.setC_Order_ID (m_invoice.getC_Order_ID());
+ inout.setC_Invoice_ID (m_invoice.getC_Invoice_ID());
+ inout.setAD_OrgTrx_ID(m_invoice.getAD_OrgTrx_ID());
+ inout.setC_Project_ID(m_invoice.getC_Project_ID());
+ inout.setC_Campaign_ID(m_invoice.getC_Campaign_ID());
+ inout.setC_Activity_ID(m_invoice.getC_Activity_ID());
+ inout.setUser1_ID(m_invoice.getUser1_ID());
+ inout.setUser2_ID(m_invoice.getUser2_ID());
+ }
+ inout.save();
+ return true;
+ } // save
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromStatement.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromStatement.java
new file mode 100644
index 0000000000..33f07f1823
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromStatement.java
@@ -0,0 +1,314 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
+ * or via info@compiere.org or http://www.compiere.org/license.html *
+ *****************************************************************************/
+
+/**
+ * 2007, Modified by Posterita Ltd.
+ */
+
+package org.adempiere.webui.apps.form;
+
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.text.DecimalFormat;
+import java.util.Vector;
+import java.util.logging.Level;
+
+import org.adempiere.webui.component.ListModelTable;
+import org.adempiere.webui.editor.WEditor;
+import org.adempiere.webui.editor.WSearchEditor;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.event.ValueChangeListener;
+import org.adempiere.webui.event.WTableModelListener;
+import org.adempiere.webui.window.FDialog;
+import org.compiere.model.GridTab;
+import org.compiere.model.MBankStatement;
+import org.compiere.model.MBankStatementLine;
+import org.compiere.model.MLookup;
+import org.compiere.model.MLookupFactory;
+import org.compiere.model.MPayment;
+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.zkoss.zk.ui.event.EventListener;
+
+/**
+ * Create From Statement : Based on VCreateFromStatement
+ *
+ * @author Niraj Sohun
+ * @date Jul 20, 2007
+ */
+
+public class WCreateFromStatement extends WCreateFrom implements EventListener, ValueChangeListener, WTableModelListener
+{
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Protected Constructor
+ * @param mTab MTab
+ */
+
+ WCreateFromStatement(GridTab mTab)
+ {
+ super(mTab);
+ //log.info("");
+ }
+
+ /**
+ * Dynamic Init
+ * @throws Exception if Lookups cannot be initialized
+ * @return true if initialized
+ */
+
+ protected boolean dynInit() throws Exception
+ {
+ if (p_mTab.getValue("C_BankStatement_ID") == null)
+ {
+ FDialog.error(0, this, "SaveErrorRowNotFound");
+ return false;
+ }
+
+ setTitle(Msg.translate(Env.getCtx(), "C_BankStatement_ID") + " .. " + Msg.translate(Env.getCtx(), "CreateFrom"));
+
+ parameterShipmentPanel.setVisible(false);
+ parameterInvoicePanel.setVisible(false);
+ hboxCommon.setVisible(false);
+
+ int AD_Column_ID = 4917; // C_BankStatement.C_BankAccount_ID
+ MLookup lookup = MLookupFactory.get (Env.getCtx(), p_WindowNo, 0, AD_Column_ID, DisplayType.TableDir);
+ bankAccountField = new WSearchEditor(lookup, "label","desc", true, false, true);
+ bankAccountField.addValueChangeListner(this);
+
+ // Set Default
+
+ int C_BankAccount_ID = Env.getContextAsInt(Env.getCtx(), p_WindowNo, "C_BankAccount_ID");
+ bankAccountField.setValue(new Integer(C_BankAccount_ID));
+
+ // Initial Loading
+ loadBankAccount(C_BankAccount_ID);
+
+ return true;
+ }
+
+ /**
+ * Init Details (never called)
+ * @param C_BPartner_ID BPartner
+ */
+
+ protected void initBPDetails(int C_BPartner_ID)
+ {
+ }
+
+ public void valueChange(ValueChangeEvent evt)
+ {
+ log.config(evt.getPropertyName() + "=" + evt.getNewValue());
+
+ if (evt == null)
+ return;
+
+ if (evt.getSource() instanceof WEditor)
+ {
+ // BankAccount
+
+ if (evt.getPropertyName().equals("C_BankAccount_ID"))
+ {
+ int C_BankAccount_ID = ((Integer)evt.getNewValue()).intValue();
+ loadBankAccount(C_BankAccount_ID);
+ }
+ tableChanged(null);
+ }
+ }
+
+ /**
+ * Load Data - Bank Account
+ * @param C_BankAccount_ID Bank Account
+ */
+
+ private void loadBankAccount (int C_BankAccount_ID)
+ {
+ log.config ("C_BankAccount_ID=" + C_BankAccount_ID);
+ /**
+ * Selected - -
+ * Date - 1
+ * C_Payment_ID - 2
+ * C_Currenncy - 3
+ * Amt - 4
+ */
+
+ Vector> data = new Vector>();
+ String sql = "SELECT p.DateTrx,p.C_Payment_ID,p.DocumentNo, p.C_Currency_ID,c.ISO_Code, p.PayAmt,"
+ + "currencyConvert(p.PayAmt,p.C_Currency_ID,ba.C_Currency_ID,?,null,p.AD_Client_ID,p.AD_Org_ID)," // #1
+ + " bp.Name "
+ + "FROM C_BankAccount ba"
+ + " INNER JOIN C_Payment_v p ON (p.C_BankAccount_ID=ba.C_BankAccount_ID)"
+ + " INNER JOIN C_Currency c ON (p.C_Currency_ID=c.C_Currency_ID)"
+ + " LEFT OUTER JOIN C_BPartner bp ON (p.C_BPartner_ID=bp.C_BPartner_ID) "
+ + "WHERE p.Processed='Y' AND p.IsReconciled='N'"
+ + " AND p.DocStatus IN ('CO','CL','RE','VO') AND p.PayAmt<>0" // Bug 1564453 Added Voided payment to bank statement payement selection
+ + " AND p.C_BankAccount_ID=?" // #2
+ + " AND NOT EXISTS (SELECT * FROM C_BankStatementLine l "
+ // Voided Bank Statements have 0 StmtAmt
+ + "WHERE p.C_Payment_ID=l.C_Payment_ID AND l.StmtAmt <> 0)";
+
+ // Get StatementDate
+
+ Timestamp ts = (Timestamp)p_mTab.getValue("StatementDate");
+
+ if (ts == null)
+ ts = new Timestamp(System.currentTimeMillis());
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql.toString(), null);
+ pstmt.setTimestamp(1, ts);
+ pstmt.setInt(2, C_BankAccount_ID);
+ ResultSet rs = pstmt.executeQuery();
+
+ while (rs.next())
+ {
+ Vector line = new Vector(6);
+ //line.add(new Boolean(false)); // 0-Selection
+ line.add(rs.getTimestamp(1)); // 1-DateTrx
+
+ KeyNamePair pp = new KeyNamePair(rs.getInt(2), rs.getString(3));
+ line.add(pp); // 2-C_Payment_ID
+
+ pp = new KeyNamePair(rs.getInt(4), rs.getString(5));
+ line.add(pp); // 3-Currency
+ line.add(rs.getBigDecimal(6)); // 4-PayAmt
+ line.add(rs.getBigDecimal(7)); // 5-Conv Amt
+ line.add(rs.getString(8)); // 6-BParner
+ data.add(line);
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql, e);
+ }
+
+ if (data.size() == 0)
+ return;
+
+ // Header Info
+
+ Vector columnNames = new Vector(6);
+ //columnNames.add(Msg.getMsg(Env.getCtx(), "Select"));
+ columnNames.add(Msg.translate(Env.getCtx(), "Date"));
+ columnNames.add(Msg.getElement(Env.getCtx(), "C_Payment_ID"));
+ columnNames.add(Msg.translate(Env.getCtx(), "C_Currency_ID"));
+ columnNames.add(Msg.translate(Env.getCtx(), "Amount"));
+ columnNames.add(Msg.translate(Env.getCtx(), "ConvertedAmount"));
+ columnNames.add(Msg.translate(Env.getCtx(), "C_BPartner_ID"));
+
+ // Remove previous listeners
+ //dataTable.getModel().removeListDataListener(this);
+
+ // Set Model
+ ListModelTable model = new ListModelTable(data);
+ model.addTableModelListener(this);
+ dataTable.setData(model, columnNames);
+
+ //dataTable.setColumnClass(0, Boolean.class, false); // 0-Selection
+ dataTable.setColumnClass(0, Timestamp.class, true); // 1-TrxDate
+ dataTable.setColumnClass(1, String.class, true); // 2-Payment
+ dataTable.setColumnClass(2, String.class, true); // 3-Currency
+ dataTable.setColumnClass(3, BigDecimal.class, true); // 4-Amount
+ dataTable.setColumnClass(4, BigDecimal.class, true); // 5-ConvAmount
+ dataTable.setColumnClass(5, String.class, true); // 6-BPartner
+
+ // Table UI
+ //dataTable.autoSize();
+ } // loadBankAccount
+
+ /**
+ * List total amount
+ */
+
+ protected void info()
+ {
+ DecimalFormat format = DisplayType.getNumberFormat(DisplayType.Amount);
+
+ ListModelTable model = dataTable.getModel();
+ BigDecimal total = new BigDecimal(0.0);
+ int rows = model.size();
+ int count = 0;
+
+ for (int i = 0; i < rows; i++)
+ {
+ if (dataTable.getItemAtIndex(i).isSelected())//(((Boolean)model.getDataAt(i, 0)).booleanValue())
+ {
+ total = total.add((BigDecimal)model.getDataAt(i, 4));
+ count++;
+ }
+ }
+ lblStatus.setValue(String.valueOf(count) + " - " + Msg.getMsg(Env.getCtx(), "Sum") + " " + format.format(total));
+ } // infoStatement
+
+ /**
+ * Save Statement - Insert Data
+ * @return true if saved
+ */
+ protected boolean save()
+ {
+ log.config("");
+
+ ListModelTable model = dataTable.getModel();
+ int rows = model.size();
+
+ if (rows == 0)
+ return false;
+
+ // Fixed values
+
+ int C_BankStatement_ID = ((Integer)p_mTab.getValue("C_BankStatement_ID")).intValue();
+ MBankStatement bs = new MBankStatement (Env.getCtx(), C_BankStatement_ID, null);
+ log.config(bs.toString());
+
+ // Lines
+
+ for (int i = 0; i < rows; i++)
+ {
+ if (dataTable.getItemAtIndex(i).isSelected())//(((Boolean)model.getDataAt(i, 0)).booleanValue())
+ {
+ Timestamp trxDate = (Timestamp)model.getDataAt(i, 0); // 1-DateTrx
+ KeyNamePair pp = (KeyNamePair)model.getDataAt(i, 1); // 2-C_Payment_ID
+ int C_Payment_ID = pp.getKey();
+ pp = (KeyNamePair)model.getDataAt(i, 2); // 3-Currency
+ int C_Currency_ID = pp.getKey();
+ BigDecimal TrxAmt = (BigDecimal)model.getDataAt(i, 3); // 4-PayAmt
+ // BigDecimal StmtAmt = (BigDecimal)model.getValueAt(i, 5);// 5-Conv Amt
+
+ log.fine("Line Date=" + trxDate
+ + ", Payment=" + C_Payment_ID + ", Currency=" + C_Currency_ID + ", Amt=" + TrxAmt);
+
+ MBankStatementLine bsl = new MBankStatementLine (bs);
+ bsl.setStatementLineDate(trxDate);
+ bsl.setPayment(new MPayment(Env.getCtx(), C_Payment_ID, null));
+
+ if (!bsl.save())
+ log.log(Level.SEVERE, "Line not created #" + i);
+ } // if selected
+ } // for all rows
+ return true;
+ } // save
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WFileImport.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WFileImport.java
new file mode 100644
index 0000000000..38293dbefa
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WFileImport.java
@@ -0,0 +1,573 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
+ * or via info@compiere.org or http://www.compiere.org/license.html *
+ *****************************************************************************/
+
+/**
+ * 2007, Modified by Posterita Ltd.
+ */
+
+package org.adempiere.webui.apps.form;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StringBufferInputStream;
+import java.nio.charset.Charset;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.logging.Level;
+
+import org.adempiere.webui.component.Button;
+import org.adempiere.webui.component.ConfirmPanel;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.ListItem;
+import org.adempiere.webui.component.Listbox;
+import org.adempiere.webui.component.Panel;
+import org.adempiere.webui.component.Textbox;
+import org.adempiere.webui.component.VerticalBox;
+import org.adempiere.webui.panel.ADForm;
+import org.adempiere.webui.session.SessionManager;
+import org.adempiere.webui.window.FDialog;
+import org.compiere.impexp.ImpFormat;
+import org.compiere.impexp.ImpFormatRow;
+import org.compiere.model.MRole;
+import org.compiere.util.CLogger;
+import org.compiere.util.DB;
+import org.compiere.util.Env;
+import org.compiere.util.Ini;
+import org.compiere.util.Msg;
+import org.zkoss.util.media.Media;
+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.Fileupload;
+import org.zkoss.zul.Hbox;
+import org.zkoss.zul.Separator;
+
+/**
+ * Fixed length file import
+ *
+ * @author Niraj Sohun
+ * Aug 16, 2007
+ *
+ */
+
+public class WFileImport extends ADForm implements EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ /** Logger */
+ private static CLogger log = CLogger.getCLogger(WFileImport.class);
+
+ /** Window No */
+ private int m_WindowNo = 0;
+
+ private int m_record = -1;
+
+ private Listbox pickFormat = new Listbox();
+ private Listbox fCharset = new Listbox();
+
+ private ArrayList m_data = new ArrayList();
+ private static final String s_none = "----"; // no format indicator
+
+ private ImpFormat m_format;
+
+ private ConfirmPanel confirmPanel = new ConfirmPanel(true);
+
+ private Button bFile = new Button();
+ private Button bNext = new Button();
+ private Button bPrevious = new Button();
+
+ private InputStream m_file_istream;
+
+ private Textbox rawData = new Textbox();
+ private Textbox[] m_fields;
+
+ private Label info = new Label();
+ private Label[] m_labels;
+ private Label record = new Label();
+ private Label labelFormat = new Label();
+
+ private VerticalBox previewPanel = new VerticalBox();
+
+ private Hbox northPanel = new Hbox();
+
+ private Panel rawDataPane = new Panel();
+
+ private VerticalBox centerPanel = new VerticalBox();
+
+ public WFileImport()
+ {
+ init(super.m_windowNo);
+ }
+
+ /**
+ * Initialize Panel
+ * @param WindowNo window
+ */
+
+ public void init (int WindowNo)
+ {
+ log.info("");
+ m_WindowNo = WindowNo;
+ try
+ {
+ jbInit();
+ dynInit();
+
+ this.setWidth("100%");
+ this.setClosable(true);
+ this.setTitle("Import File Loader");
+ this.setBorder("normal");
+
+ this.appendChild(northPanel);
+ this.appendChild(new Separator());
+ this.appendChild(centerPanel);
+ this.appendChild(new Separator());
+ this.appendChild(confirmPanel);
+ }
+ catch(Exception e)
+ {
+ log.log(Level.SEVERE, "init", e);
+ }
+ } // init
+
+ /**
+ * Static Init
+ * @throws Exception
+ */
+
+ private void jbInit() throws Exception
+ {
+ Charset[] charsets = Ini.getAvailableCharsets();
+
+ for (int i = 0; i < charsets.length; i++)
+ fCharset.appendItem(charsets[i].displayName(), charsets[i]);
+
+ bFile.setLabel(Msg.getMsg(Env.getCtx(), "FileImportFile"));
+ bFile.setTooltiptext(Msg.getMsg(Env.getCtx(), "FileImportFileInfo"));
+ bFile.addEventListener(Events.ON_CLICK, this);
+
+ fCharset.setMold("select");
+ fCharset.setRows(0);
+ fCharset.setTooltiptext(Msg.getMsg(Env.getCtx(), "Charset", false));
+
+ info.setValue(" ");
+
+ labelFormat.setValue(Msg.translate(Env.getCtx(), "AD_ImpFormat_ID"));
+
+ pickFormat.setMold("select");
+ pickFormat.setRows(0);
+
+ bNext.setTooltiptext(Msg.getMsg(Env.getCtx(), "Next"));
+ //bNext.setMargin(new Insets(2, 2, 2, 2));
+ bNext.setLabel(">");
+ bNext.addEventListener(Events.ON_CLICK, this);
+
+ record.setValue("-");
+
+ bPrevious.setTooltiptext(Msg.getMsg(Env.getCtx(), "Previous"));
+ //bPrevious.setMargin(new Insets(2, 2, 2, 2));
+ bPrevious.setLabel("<");
+ bPrevious.addEventListener(Events.ON_CLICK, this);
+
+ northPanel.appendChild(bFile);
+ northPanel.appendChild(fCharset);
+ northPanel.appendChild(info);
+ northPanel.appendChild(labelFormat);
+ northPanel.appendChild(pickFormat);
+ northPanel.appendChild(bPrevious);
+ northPanel.appendChild(record);
+ northPanel.appendChild(bNext);
+
+ //rawData.setFont(new java.awt.Font("Monospaced", 0, 10));
+ //rawData.setColumns(80);
+
+ rawData.setWidth("100%");
+ rawData.setCols(80);
+ rawData.setRows(5);
+
+ previewPanel.setWidth("100%");
+
+ //rawDataPane.appendChild(rawData);
+ centerPanel.appendChild(rawData);
+ centerPanel.appendChild(new Separator());
+ centerPanel.appendChild(previewPanel);
+
+ //previewPanel.setLayout(previewLayout);
+ //previewPane.getViewport().add(previewPanel, null);
+ //previewPane.setPreferredSize(new Dimension(700,80));
+
+ //confirmPanel.getButton("Ok").addEventListener(Events.ON_CLICK, this);
+ //confirmPanel.getButton("Cancel").addEventListener(Events.ON_CLICK, this);
+ confirmPanel.addActionListener(Events.ON_CLICK, this);
+ }
+
+ /**
+ * Dynamic Init
+ */
+
+ private void dynInit()
+ {
+ // Load Formats
+ pickFormat.appendItem(s_none, s_none);
+
+ String sql = MRole.getDefault().addAccessSQL("SELECT Name FROM AD_ImpFormat", "AD_ImpFormat",
+ MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO);
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql, null);
+ ResultSet rs = pstmt.executeQuery();
+
+ while (rs.next())
+ pickFormat.appendItem(rs.getString(1), rs.getString(1));
+
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql, e);
+ }
+
+ pickFormat.setSelectedIndex(0);
+ pickFormat.addEventListener(Events.ON_SELECT, this);
+
+ Charset charset = Ini.getCharset();
+
+ for (int i = 0; i < fCharset.getItemCount(); i++)
+ {
+ ListItem listitem = fCharset.getItemAtIndex(i);
+ Charset compare = (Charset)listitem.getValue();
+
+ if (charset == compare)
+ {
+ fCharset.setSelectedIndex(i);
+ break;
+ }
+ }
+
+ fCharset.addEventListener(Events.ON_SELECT, this);
+
+ confirmPanel.setEnabled("Ok", false);
+ } // dynInit
+
+
+ public void onEvent(Event e) throws Exception
+ {
+ if (e.getTarget() == bFile)
+ {
+ cmd_loadFile();
+ invalidate();
+ }
+ else if (e.getTarget() == fCharset)
+ {
+ int record = m_record;
+ cmd_reloadFile();
+ m_record = record - 1;
+ cmd_applyFormat(true);
+ }
+ else if (e.getTarget() == pickFormat)
+ {
+ cmd_loadFormat();
+ invalidate();
+ }
+ else if (e.getTarget() == bNext )
+ cmd_applyFormat(true);
+ else if (e.getTarget() == bPrevious )
+ cmd_applyFormat(false);
+
+ else if (e.getTarget() == confirmPanel.getButton("Ok"))
+ {
+ confirmPanel.setEnabled("Ok", false);
+
+ cmd_process();
+
+ /*org.compiere.apps.SwingWorker worker = new org.compiere.apps.SwingWorker()
+ {
+ public Object construct()
+ {
+ cmd_process();
+ return Boolean.TRUE;
+ }
+ };*/
+ //worker.start();
+
+ // when you need the result:
+ // x = worker.get(); // this blocks the UI !!
+ }
+ else if (e.getTarget() == confirmPanel.getButton("Cancel"))
+ {
+ SessionManager.getAppDesktop().removeWindow();
+ return;
+ }
+
+ if (m_data != null && m_data.size() > 0 // file loaded
+ && m_format != null && m_format.getRowCount() > 0) // format loaded
+ confirmPanel.getButton("Ok").setEnabled(true);
+ else
+ confirmPanel.getButton("Ok").setEnabled(false);
+ }
+
+ /**************************************************************************
+ * Load File
+ */
+
+ private void cmd_loadFile()
+ {
+ String directory = org.compiere.Adempiere.getAdempiereHome()
+ + File.separator + "data"
+ + File.separator + "import";
+ log.config(directory);
+
+ Media media = null;
+
+ try
+ {
+ media = Fileupload.get();
+ }
+ catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+
+ //JFileChooser chooser = new JFileChooser(directory);
+ //chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
+ //chooser.setMultiSelectionEnabled(false);
+ //chooser.setDialogTitle(Msg.getMsg(Env.getCtx(), "FileImportFileInfo"));
+ //if (chooser.showOpenDialog(this) != JFileChooser.APPROVE_OPTION)
+ // return;
+
+ if (media == null)
+ return;
+
+ if (Env.isWindows())
+ m_file_istream = new ByteArrayInputStream(media.getByteData());
+ else
+ m_file_istream = new StringBufferInputStream(media.getStringData());
+
+ log.config(media.getName());
+ bFile.setLabel(media.getName());
+
+ cmd_reloadFile();
+ }
+
+ /**
+ * Reload/Load file
+ */
+
+ private void cmd_reloadFile()
+ {
+ if (m_file_istream == null)
+ return;
+
+ m_data.clear();
+ rawData .setText("");
+
+ try
+ {
+ // see NaturalAccountMap
+
+ ListItem listitem = fCharset.getSelectedItem();
+ Charset charset = null;
+
+ if (listitem == null)
+ return;
+
+ charset = (Charset)listitem.getValue();
+ BufferedReader in = new BufferedReader(new InputStreamReader(m_file_istream, charset), 10240);
+
+ // not safe see p108 Network pgm
+ String s = null;
+ String concat = "";
+
+ while ((s = in.readLine()) != null)
+ {
+ m_data.add(s);
+
+ concat += s;
+ concat += "\n";
+
+ if (m_data.size() < 100)
+ {
+ rawData.setValue(concat);
+ //rawData.append("\n");
+ }
+ }
+ in.close();
+ //rawData.setCaretPosition(0);
+ }
+ catch (Exception e)
+ {
+ log.log(Level.SEVERE, "", e);
+ bFile.setLabel(Msg.getMsg(Env.getCtx(), "FileImportFile"));
+ }
+
+ int index = 1; // second line as first may be heading
+
+ if (m_data.size() == 1)
+ index = 0;
+
+ int length = 0;
+
+ if (m_data.size() > 0)
+ length = m_data.get(index).toString().length();
+
+ info.setValue(Msg.getMsg(Env.getCtx(), "Records") + "=" + m_data.size()
+ + ", " + Msg.getMsg(Env.getCtx(), "Length") + "=" + length + " ");
+
+ //setCursor (Cursor.getDefaultCursor());
+
+ log.config("Records=" + m_data.size() + ", Length=" + length);
+ } // cmd_loadFile
+
+ /**
+ * Load Format
+ */
+
+ private void cmd_loadFormat()
+ {
+ // clear panel
+ previewPanel.getChildren().clear();
+
+ ListItem listitem = pickFormat.getSelectedItem();
+
+ String formatName = (String)listitem.getValue();
+
+ if (formatName.equals(s_none))
+ return;
+
+ m_format = ImpFormat.load (formatName);
+
+ if (m_format == null)
+ {
+ FDialog.error(m_WindowNo, this, formatName);
+ return;
+ }
+
+ // pointers
+
+ int size = m_format.getRowCount();
+ m_labels = new Label[size];
+ m_fields = new Textbox[size];
+
+ for (int i = 0; i < size; i++)
+ {
+ ImpFormatRow row = m_format.getRow(i);
+
+ m_labels[i] = new Label(row.getColumnName());
+
+ Hbox hbox = new Hbox();
+ hbox.setWidth("100%");
+ hbox.setWidths("30%, 70%");
+
+ //previewPanel.add(m_labels[i], new GridBagConstraints(i, 0, 1, 1, 1.0, 1.0,
+ // GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
+
+ hbox.appendChild(m_labels[i]);
+
+ int length = row.getEndNo() - row.getStartNo();
+
+ if (length <= 5)
+ length = 5;
+ else if (length > 20)
+ length = 20;
+
+ m_fields[i] = new Textbox();
+
+ hbox.appendChild(m_fields[i]);
+
+ //previewPanel.add(m_fields[i], new GridBagConstraints(i, 1, 1, 1, 1.0, 1.0,
+ // GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+
+ previewPanel.appendChild(hbox);
+ }
+ m_record = -1;
+ record.setValue("-");
+ previewPanel.invalidate();
+ } // cmd_format
+
+ /**
+ * Apply Current Pattern
+ * @param next next
+ */
+
+ private void cmd_applyFormat (boolean next)
+ {
+ if (m_format == null)
+ return;
+
+ // set position
+ if (next)
+ m_record++;
+ else
+ m_record--;
+
+ if (m_record < 0)
+ m_record = 0;
+ else if (m_record >= m_data.size())
+ m_record = m_data.size() - 1;
+
+ record.setValue(" " + String.valueOf(m_record+1) + " ");
+
+ // Line Info
+
+ String[] lInfo = m_format.parseLine(m_data.get(m_record).toString(), false, true, false); // no label, trace, no ignore
+
+ int size = m_format.getRowCount();
+
+ if (lInfo.length != size)
+ log.log(Level.SEVERE, "FormatElements=" + size + " != Fields=" + lInfo.length);
+
+ for (int i = 0; i < size; i++)
+ {
+ m_fields[i].setText(lInfo[i]);
+ //m_fields[i].setCaretPosition(0);
+ }
+ } // cmd_applyFormat
+
+ /**************************************************************************
+ * Process File
+ */
+
+ private void cmd_process()
+ {
+ if (m_format == null)
+ {
+ FDialog.error(m_WindowNo, this, "FileImportNoFormat");
+ return;
+ }
+
+ log.config(m_format.getName());
+
+ // For all rows - update/insert DB table
+
+ int row = 0;
+ int imported = 0;
+
+ for (row = 0; row < m_data.size(); row++)
+ if (m_format.updateDB(Env.getCtx(), m_data.get(row).toString(), null))
+ imported++;
+
+ FDialog.info(m_WindowNo, this, "FileImportR/I", row + " / " + imported + "#");
+
+ SessionManager.getAppDesktop().removeWindow();
+ } // cmd_process
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WInOutGen.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WInOutGen.java
new file mode 100644
index 0000000000..7432bae45e
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WInOutGen.java
@@ -0,0 +1,692 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
+ * or via info@compiere.org or http://www.compiere.org/license.html *
+ *****************************************************************************/
+
+/**
+ * 2007, Modified by Posterita Ltd.
+ */
+
+package org.adempiere.webui.apps.form;
+
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.logging.Level;
+
+import org.adempiere.webui.component.Button;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.ListHead;
+import org.adempiere.webui.component.ListHeader;
+import org.adempiere.webui.component.ListItem;
+import org.adempiere.webui.component.Listbox;
+import org.adempiere.webui.component.Panel;
+import org.adempiere.webui.component.Tab;
+import org.adempiere.webui.component.Tabbox;
+import org.adempiere.webui.component.Tabpanel;
+import org.adempiere.webui.component.Tabpanels;
+import org.adempiere.webui.component.Tabs;
+import org.adempiere.webui.component.WListbox;
+import org.adempiere.webui.editor.WEditor;
+import org.adempiere.webui.editor.WSearchEditor;
+import org.adempiere.webui.editor.WTableDirEditor;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.event.ValueChangeListener;
+import org.adempiere.webui.event.WTableModelEvent;
+import org.adempiere.webui.event.WTableModelListener;
+import org.adempiere.webui.panel.ADForm;
+import org.adempiere.webui.session.SessionManager;
+import org.compiere.apps.ProcessCtl;
+import org.compiere.minigrid.IDColumn;
+import org.compiere.model.MLookup;
+import org.compiere.model.MLookupFactory;
+import org.compiere.model.MOrder;
+import org.compiere.model.MPInstance;
+import org.compiere.model.MPInstancePara;
+import org.compiere.model.MPrivateAccess;
+import org.compiere.process.ProcessInfo;
+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.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zk.ui.event.Events;
+import org.zkoss.zul.Hbox;
+import org.zkoss.zul.Listcell;
+import org.zkoss.zul.Separator;
+
+/**
+ * Generate Shipments Manual : Based on VInOutGen
+ *
+ * @author Niraj Sohun
+ * @date Jul 9, 2007
+ */
+
+public class WInOutGen extends ADForm implements EventListener, ValueChangeListener, WTableModelListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private Separator separator;
+
+ private Tabbox tabbox;
+
+ private Tabs tabs;
+ private Tab tabSelect;
+ private Tab tabGenerate;
+
+ private Tabpanels tabpanels;
+ private Tabpanel pnlSelect;
+ private Tabpanel pnlGenerate;
+
+ // Panel Select
+
+ private WEditor warehouseSearch;
+ private WEditor bPartnerSearch;
+ private WListbox lstSelect;
+
+ // Panel Generate
+
+ private Label lblGenerate;
+ private Label lblNote;
+ private Listbox lstGenerate;
+
+ private Button btnOk;
+ private Button btnCancel;
+
+ private Label lblStatus;
+ private Label lblNumSelected;
+
+ private boolean m_selectionActive = true;
+ private ArrayList selections = null;
+
+ @SuppressWarnings("unused")
+ private Object m_C_BPartner_ID;
+ private Object m_M_Warehouse_ID;
+
+ private static CLogger log = CLogger.getCLogger(WInvoiceGen.class);
+
+ public WInOutGen()
+ {
+ init();
+ initComponents();
+ }
+
+ private void init()
+ {
+ separator = new Separator();
+ separator.setHeight("5px");
+
+ tabbox = new Tabbox();
+ tabbox.setWidth("700px");
+
+ tabs = new Tabs();
+
+ tabSelect = new Tab();
+ tabSelect.setLabel("Select");
+ tabSelect.addEventListener(Events.ON_SELECT, this);
+
+ tabGenerate = new Tab();
+ tabGenerate.setLabel("Generate");
+ tabGenerate.addEventListener(Events.ON_SELECT, this);
+
+ tabpanels = new Tabpanels();
+
+ pnlSelect = new Tabpanel();
+ pnlGenerate = new Tabpanel();
+
+ lstSelect = new WListbox();
+ lstSelect.setWidth("690px");
+ lstSelect.setHeight("250px");
+ lstSelect.addEventListener(Events.ON_CLICK, this);
+ lstSelect.getModel().addTableModelListener(this);
+
+ btnCancel = new Button();
+ btnCancel.setImage("/images/Cancel24.gif");
+ btnCancel.addEventListener(Events.ON_CLICK, this);
+
+ btnOk = new Button();
+ btnOk.setImage("/images/Ok24.gif");
+ btnOk.addEventListener(Events.ON_CLICK, this);
+
+ lblGenerate = new Label();
+ lblGenerate.setWidth("690px");
+ lblGenerate.setMultiline(true);
+
+ lblNote = new Label();
+ lblNote.setWidth("690px");
+ lblNote.setMultiline(true);
+
+ lblStatus = new Label(" ");
+ lblNumSelected = new Label("Number of Records Selected : 0");
+
+ lstGenerate = new Listbox();
+ lstGenerate.setWidth("300px");
+
+ populateWarehouse();
+ showBusinessPartner();
+ }
+
+ private void initComponents()
+ {
+ this.setWidth("710px");
+
+ tabs.appendChild(tabSelect);
+ tabs.appendChild(tabGenerate);
+
+ tabpanels.appendChild(pnlSelect);
+ tabpanels.appendChild(pnlGenerate);
+
+ tabbox.appendChild(tabs);
+ tabbox.appendChild(tabpanels);
+
+ Hbox mainBox = new Hbox();
+ mainBox.setWidth("100%");
+ mainBox.setStyle("text-align:center");
+
+ Hbox hOrg = new Hbox();
+ hOrg.setWidth("100%");
+
+ Hbox hBP = new Hbox();
+ hBP.setWidth("100%");
+
+ mainBox.appendChild(hOrg);
+ mainBox.appendChild(hBP);
+
+ Panel pnl1 = new Panel();
+ pnl1.appendChild(warehouseSearch.getLabel());
+ pnl1.setStyle("text-align:right");
+
+ Panel pnl2 = new Panel();
+ pnl2.appendChild(warehouseSearch.getComponent());
+ pnl2.setStyle("text-align:left");
+
+ Panel pnl3 = new Panel();
+ pnl3.appendChild(bPartnerSearch.getLabel());
+ pnl3.setStyle("text-align:right");
+
+ Panel pnl4 = new Panel();
+ pnl4.appendChild(bPartnerSearch.getComponent());
+ pnl4.setStyle("text-align:left");
+
+ hOrg.appendChild(pnl1);
+ hOrg.appendChild(pnl2);
+
+ hBP.appendChild(pnl3);
+ hBP.appendChild(pnl4);
+
+ pnlSelect.setStyle("text-align:center");
+ pnlSelect.appendChild(mainBox);
+ pnlSelect.appendChild(new Separator());
+ pnlSelect.appendChild(lstSelect);
+ pnlSelect.appendChild(new Separator());
+ pnlSelect.addEventListener(Events.ON_SELECT, this);
+
+ pnlGenerate.appendChild(lblGenerate);
+ pnlGenerate.appendChild(lblNote);
+ pnlGenerate.appendChild(new Separator());
+ pnlGenerate.appendChild(lstGenerate);
+
+ this.appendChild(tabbox);
+ this.appendChild(new Separator());
+
+ Hbox hbox = new Hbox();
+ hbox.setWidth("80px");
+ hbox.appendChild(btnCancel);
+ hbox.appendChild(btnOk);
+
+ this.appendChild(hbox);
+ this.appendChild(new Separator());
+
+ hbox = new Hbox();
+ hbox.setWidth("700px");
+
+ Panel p = new Panel();
+ p.setStyle("text-align:left");
+ p.appendChild(lblStatus);
+ hbox.appendChild(p);
+
+ p = new Panel();
+ p.setStyle("text-align:right");
+ p.appendChild(lblNumSelected);
+ hbox.appendChild(p);
+
+ this.appendChild(hbox);
+
+ prepareTable();
+ }
+
+ private void prepareTable()
+ {
+ // Create Columns
+
+ ListHead listhead = new ListHead();
+ listhead.setSizable(true);
+
+ listhead.appendChild(new ListHeader(""));
+ listhead.appendChild(new ListHeader("Organization"));
+ listhead.appendChild(new ListHeader("Document Type"));
+ listhead.appendChild(new ListHeader("Document No"));
+ listhead.appendChild(new ListHeader("Business Partner"));
+ listhead.appendChild(new ListHeader("Date Ordered"));
+ listhead.appendChild(new ListHeader("Total Lines"));
+
+ lstSelect.appendChild(listhead);
+
+ lstSelect.addColumn("C_Order_ID");
+ lstSelect.addColumn("AD_Org_ID");
+ lstSelect.addColumn("C_DocType_ID");
+ lstSelect.addColumn("DocumentNo");
+ lstSelect.addColumn("C_BPartner_ID");
+ lstSelect.addColumn("DateOrdered");
+ lstSelect.addColumn("TotalLines");
+
+ lstSelect.setMultiSelection(true);
+
+ // Set Details
+
+ lstSelect.setColumnClass(0, IDColumn.class, false, " ");
+ lstSelect.setColumnClass(1, String.class, true, Msg.translate(Env.getCtx(), "AD_Org_ID"));
+ lstSelect.setColumnClass(2, String.class, true, Msg.translate(Env.getCtx(), "C_DocType_ID"));
+ lstSelect.setColumnClass(3, String.class, true, Msg.translate(Env.getCtx(), "DocumentNo"));
+ lstSelect.setColumnClass(4, String.class, true, Msg.translate(Env.getCtx(), "C_BPartner_ID"));
+ lstSelect.setColumnClass(5, Timestamp.class, true, Msg.translate(Env.getCtx(), "DateOrdered"));
+ lstSelect.setColumnClass(6, BigDecimal.class, true, Msg.translate(Env.getCtx(), "TotalLines"));
+
+ // Set Status
+
+ lblStatus.setValue(Msg.getMsg(Env.getCtx(), "InvGenerateSel"));
+ //statusBar.setStatusDB(" ");
+ }
+
+ private void populateWarehouse()
+ {
+ final int AD_Column_ID = 2223;
+
+ MLookup lookupBP = MLookupFactory.get(Env.getCtx(), super.m_windowNo,
+ 0, AD_Column_ID, DisplayType.TableDir);
+
+ warehouseSearch = new WTableDirEditor(lookupBP, Msg.translate(
+ Env.getCtx(), "M_Warehouse_ID"), "", true, false, true);
+
+ warehouseSearch.addValueChangeListner(this);
+ }
+
+ private void showBusinessPartner()
+ {
+ final int AD_BPartner_ID = 3499;
+
+ MLookup lookupBP = MLookupFactory.get(Env.getCtx(), super.m_windowNo,
+ 0, AD_BPartner_ID, DisplayType.Search);
+
+ bPartnerSearch = new WSearchEditor(lookupBP, Msg.translate(
+ Env.getCtx(), "C_BPartner_ID"), "", true, false, true);
+
+ bPartnerSearch.addValueChangeListner(this);
+ }
+
+
+ private void executeQuery()
+ {
+ log.info("");
+
+ int AD_Client_ID = Env.getAD_Client_ID(Env.getCtx());
+
+ // Create SQL
+
+ StringBuffer sql = new StringBuffer(
+ "SELECT C_Order_ID, o.Name, dt.Name, DocumentNo, bp.Name, DateOrdered, TotalLines "
+ + "FROM M_InOut_Candidate_v ic, AD_Org o, C_BPartner bp, C_DocType dt "
+ + "WHERE ic.AD_Org_ID=o.AD_Org_ID"
+ + " AND ic.C_BPartner_ID=bp.C_BPartner_ID"
+ + " AND ic.C_DocType_ID=dt.C_DocType_ID"
+ + " AND ic.AD_Client_ID=?");
+
+ if (m_M_Warehouse_ID != null)
+ sql.append(" AND ic.M_Warehouse_ID=").append(m_M_Warehouse_ID);
+
+ if (m_C_BPartner_ID != null)
+ sql.append(" AND ic.C_BPartner_ID=").append(m_C_BPartner_ID);
+
+ // bug - [ 1713317 ] Generate Shipments (manual) show locked records
+
+ /* begin - Exclude locked records; @Trifon */
+
+ int AD_User_ID = Env.getContextAsInt(Env.getCtx(), "#AD_User_ID");
+ String lockedIDs = MPrivateAccess.getLockedRecordWhere(MOrder.Table_ID, AD_User_ID);
+
+ if (lockedIDs != null)
+ {
+ if (sql.length() > 0)
+ sql.append(" AND ");
+ sql.append("C_Order_ID").append(lockedIDs);
+ }
+
+ /* end - Exclude locked records; @Trifon */
+
+ sql.append(" ORDER BY o.Name,bp.Name,DateOrdered");
+ log.fine(sql.toString());
+
+ // Reset table
+
+ int row = 0;
+
+ if (lstSelect != null)
+ lstSelect.clearTable();
+
+ // Execute
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql.toString(), null);
+ pstmt.setInt(1, AD_Client_ID);
+ ResultSet rs = pstmt.executeQuery();
+
+ while (rs.next())
+ {
+ // Extend table
+
+ lstSelect.setRowCount(row+1);
+
+ // Set values
+
+ lstSelect.setValueAt(new IDColumn(rs.getInt(1)), row, 0); // C_Order_ID
+ lstSelect.setValueAt(rs.getString(2), row, 1); // Org
+ lstSelect.setValueAt(rs.getString(3), row, 2); // DocType
+ lstSelect.setValueAt(rs.getString(4), row, 3); // Doc No
+ lstSelect.setValueAt(rs.getString(5), row, 4); // BPartner
+ lstSelect.setValueAt(rs.getTimestamp(6), row, 5); // DateOrdered
+ lstSelect.setValueAt(rs.getBigDecimal(7), row, 6); // TotalLines
+
+ // Prepare next
+ row++;
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql.toString(), e);
+ }
+ }
+
+ private void saveSelection()
+ {
+ log.info("");
+
+ // Array of Integers
+
+ ArrayList results = new ArrayList();
+
+ if (selections != null)
+ selections.clear();
+
+ // Get Selected Entries
+
+ int rows = lstSelect.getItemCount();
+
+ for (int i = 0; i < rows; i++)
+ {
+ // ID in Column 0
+
+ IDColumn id = (IDColumn)lstSelect.getValueAt(i, 0);
+
+ if (id != null && id.isSelected())
+ results.add(id.getRecord_ID());
+ }
+
+ if (results.size() == 0)
+ return;
+
+ selections = results;
+ }
+
+ private void generateShipments()
+ {
+ log.info("M_Warehouse_ID=" + m_M_Warehouse_ID);
+
+ // Trx needs to be committed too
+ String trxName = Trx.createTrxName("IOG");
+ Trx trx = Trx.get(trxName, true);
+
+ // Prevents from being called twice
+ m_selectionActive = false;
+
+ //lblStatus.setValue(Msg.getMsg(Env.getCtx(), "InOutGenerateGen"));
+ //statusBar.setStatusDB(String.valueOf(selection.size()));
+
+ // Prepare Process
+
+ // M_InOutCreate
+
+ int AD_Process_ID = 199;
+ MPInstance instance = new MPInstance(Env.getCtx(), AD_Process_ID, 0);
+
+ if (!instance.save())
+ {
+ //info.setText(Msg.getMsg(Env.getCtx(), "ProcessNoInstance"));
+ return;
+ }
+
+ // Insert selection
+
+ StringBuffer insert = new StringBuffer();
+ insert.append("INSERT INTO T_SELECTION(AD_PINSTANCE_ID, T_SELECTION_ID) ");
+ int counter = 0;
+
+ for(Integer selectedId : selections)
+ {
+ counter++;
+
+ if (counter > 1)
+ insert.append(" UNION ");
+
+ insert.append("SELECT ");
+ insert.append(instance.getAD_PInstance_ID());
+ insert.append(", ");
+ insert.append(selectedId);
+ insert.append(" FROM DUAL ");
+
+ if (counter == 1000)
+ {
+ if ( DB.executeUpdate(insert.toString(), trxName) < 0 )
+ {
+ String msg = "No Shipments"; // not translated!
+ log.config(msg);
+ //info.setText(msg);
+ trx.rollback();
+ return;
+ }
+
+ insert = new StringBuffer();
+ insert.append("INSERT INTO T_SELECTION(AD_PINSTANCE_ID, T_SELECTION_ID) ");
+ counter = 0;
+ }
+ }
+
+ if (counter > 0)
+ {
+ if ( DB.executeUpdate(insert.toString(), trxName) < 0 )
+ {
+ String msg = "No Shipments"; // not translated!
+ log.config(msg);
+ //info.setText(msg);
+ trx.rollback();
+ return;
+ }
+ }
+
+ // Call process
+
+ ProcessInfo pi = new ProcessInfo ("WInOutGen", AD_Process_ID);
+ pi.setAD_PInstance_ID (instance.getAD_PInstance_ID());
+
+ // Add Parameter - Selection = Y
+
+ MPInstancePara ip = new MPInstancePara(instance, 10);
+ ip.setParameter("Selection","Y");
+
+ if (!ip.save())
+ {
+ String msg = "No Parameter added"; // not translated
+ //info.setText(msg);
+ log.log(Level.SEVERE, msg);
+ return;
+ }
+
+ // Add Parameter - M_Warehouse_ID = x
+
+ ip = new MPInstancePara(instance, 20);
+ ip.setParameter("M_Warehouse_ID", Integer.parseInt(m_M_Warehouse_ID.toString()));
+
+ if (!ip.save())
+ {
+ String msg = "No Parameter added"; // not translated
+ //info.setText(msg);
+ log.log(Level.SEVERE, msg);
+ return;
+ }
+
+ // Execute Process
+ ProcessCtl worker = new ProcessCtl(null, super.m_windowNo, pi, trx);
+ worker.start(); // complete tasks in unlockUI / generateShipments_complete
+
+ lstSelect.clearTable();
+
+ displayInfo();
+ }
+
+ private void displayInfo()
+ {
+ lblGenerate.setValue("Created = " + selections.size());
+ lblNote.setValue("(Shipments are generated depending on the 'Delivery Rule' selection in the Order)");
+
+ lstGenerate.getChildren().clear();
+
+ for (int i = 0; i < selections.size(); i++)
+ {
+ ListItem listitem = new ListItem();
+ Timestamp time = new Timestamp(System.currentTimeMillis());
+ listitem.appendChild(new Listcell(time.toString()));
+ listitem.appendChild(new Listcell(selections.get(i).toString()));
+
+ lstGenerate.appendChild(listitem);
+ }
+
+ tabbox.setSelectedPanel(pnlGenerate);
+ }
+
+ private void generateInvoiceComplete (ProcessInfo pi)
+ {
+ }
+
+
+
+ public void onEvent(Event evt)
+ {
+ if (evt != null)
+ {
+ if (evt.getTarget() == tabSelect)
+ {
+ m_selectionActive = true;
+
+ executeQuery();
+ }
+
+ if ((evt.getTarget() == warehouseSearch) || (evt.getTarget() == bPartnerSearch))
+ {
+ if (evt.getTarget() == warehouseSearch)
+ {
+ m_M_Warehouse_ID = warehouseSearch.getValue();
+ }
+
+ if (evt.getTarget() == bPartnerSearch)
+ {
+ m_C_BPartner_ID = bPartnerSearch.getValue();
+ }
+
+ executeQuery();
+ }
+
+ if ((evt.getTarget() == btnOk) || (evt.getTarget() == btnCancel))
+ {
+ if (evt.getTarget() == btnCancel)
+ {
+ SessionManager.getAppDesktop().removeWindow();
+ }
+
+ saveSelection();
+
+ if (selections != null && selections.size() > 0 && m_selectionActive)
+ generateShipments();
+ else
+ SessionManager.getAppDesktop().removeWindow();
+ }
+ }
+ }
+
+ public void valueChange(ValueChangeEvent evt)
+ {
+ if (evt == null)
+ return;
+
+ if (evt.getSource() instanceof WEditor)
+ {
+ String name = evt.getPropertyName();
+ Object value = evt.getNewValue() == null ? "" : evt.getNewValue();
+
+ if (name.equals("C_BPartner_ID"))
+ {
+ bPartnerSearch.setValue(value);
+ m_C_BPartner_ID = ((Integer) value).intValue();
+
+ executeQuery();
+ }
+
+ if (name.equals("M_Warehouse_ID"))
+ {
+ warehouseSearch.setValue(value);
+ m_M_Warehouse_ID = ((Integer) value).intValue();
+
+ executeQuery();
+ }
+ }
+ }
+
+ public void tableChanged(WTableModelEvent event)
+ {
+ int rowsSelected = 0;
+ int rows = lstSelect.getItemCount();
+
+ for (int i = 0; i < rows; i++)
+ {
+ // ID in column 0
+ IDColumn id = (IDColumn)lstSelect.getValueAt(i, 0);
+
+ if (id != null && id.isSelected())
+ rowsSelected++;
+ }
+
+ // Set Status
+
+ Integer size = rowsSelected;
+ lblNumSelected.setValue("Number of Records Selected : " + size.toString());
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WInvoiceGen.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WInvoiceGen.java
new file mode 100644
index 0000000000..9b7cf2f33a
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WInvoiceGen.java
@@ -0,0 +1,724 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
+ * or via info@compiere.org or http://www.compiere.org/license.html *
+ *****************************************************************************/
+
+/**
+ * 2007, Modified by Posterita Ltd.
+ */
+
+package org.adempiere.webui.apps.form;
+
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.logging.Level;
+
+import org.adempiere.webui.component.Button;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.ListHead;
+import org.adempiere.webui.component.ListHeader;
+import org.adempiere.webui.component.ListItem;
+import org.adempiere.webui.component.Listbox;
+import org.adempiere.webui.component.Panel;
+import org.adempiere.webui.component.Tab;
+import org.adempiere.webui.component.Tabbox;
+import org.adempiere.webui.component.Tabpanel;
+import org.adempiere.webui.component.Tabpanels;
+import org.adempiere.webui.component.Tabs;
+import org.adempiere.webui.component.WListbox;
+import org.adempiere.webui.editor.WEditor;
+import org.adempiere.webui.editor.WSearchEditor;
+import org.adempiere.webui.editor.WTableDirEditor;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.event.ValueChangeListener;
+import org.adempiere.webui.event.WTableModelEvent;
+import org.adempiere.webui.event.WTableModelListener;
+import org.adempiere.webui.panel.ADForm;
+import org.adempiere.webui.session.SessionManager;
+import org.compiere.apps.ProcessCtl;
+import org.compiere.minigrid.IDColumn;
+import org.compiere.model.MLookup;
+import org.compiere.model.MLookupFactory;
+import org.compiere.model.MOrder;
+import org.compiere.model.MPInstance;
+import org.compiere.model.MPInstancePara;
+import org.compiere.model.MPrivateAccess;
+import org.compiere.process.ProcessInfo;
+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.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zk.ui.event.Events;
+import org.zkoss.zul.Hbox;
+import org.zkoss.zul.Listcell;
+import org.zkoss.zul.Separator;
+
+/**
+ * Generate Invoices Manual : Based on VInvoiceGen
+ *
+ * @author Niraj Sohun
+ * @date Jul 5, 2007
+ */
+
+public class WInvoiceGen extends ADForm implements EventListener, ValueChangeListener, WTableModelListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private Separator separator;
+
+ private Tabbox tabbox;
+
+ private Tabs tabs;
+ private Tab tabSelect;
+ private Tab tabGenerate;
+
+ private Tabpanels tabpanels;
+ private Tabpanel pnlSelect;
+ private Tabpanel pnlGenerate;
+
+ // Panel Select
+
+ private WEditor organizationSearch;
+ private WEditor bPartnerSearch;
+ private WListbox lstSelect;
+
+ // Panel Generate
+
+ private Label lblGenerate;
+ private Label lblNote;
+ private Listbox lstGenerate;
+
+ private Button btnOk;
+ private Button btnCancel;
+
+ private Label lblStatus;
+ private Label lblNumSelected;
+
+ private boolean m_selectionActive = true;
+ private ArrayList selections = null;
+
+ @SuppressWarnings("unused")
+ private Object m_AD_Org_ID;
+
+ @SuppressWarnings("unused")
+ private Object m_C_BPartner_ID;
+
+ private static CLogger log = CLogger.getCLogger(WInvoiceGen.class);
+
+ public WInvoiceGen()
+ {
+ init();
+ initComponents();
+ }
+
+ private void init()
+ {
+ separator = new Separator();
+ separator.setHeight("5px");
+
+ tabbox = new Tabbox();
+ tabbox.setWidth("700px");
+
+ tabs = new Tabs();
+
+ tabSelect = new Tab();
+ tabSelect.setLabel("Select");
+ tabSelect.addEventListener(Events.ON_SELECT, this);
+
+ tabGenerate = new Tab();
+ tabGenerate.setLabel("Generate");
+ tabGenerate.addEventListener(Events.ON_SELECT, this);
+
+ tabpanels = new Tabpanels();
+
+ pnlSelect = new Tabpanel();
+ pnlGenerate = new Tabpanel();
+
+ lstSelect = new WListbox();
+ lstSelect.setWidth("690px");
+ lstSelect.setHeight("250px");
+ lstSelect.addEventListener(Events.ON_SELECT, this);
+ lstSelect.getModel().addTableModelListener(this);
+
+ btnCancel = new Button();
+ btnCancel.setImage("/images/Cancel24.gif");
+ btnCancel.addEventListener(Events.ON_CLICK, this);
+
+ btnOk = new Button();
+ btnOk.setImage("/images/Ok24.gif");
+ btnOk.addEventListener(Events.ON_CLICK, this);
+
+ lblGenerate = new Label();
+ lblGenerate.setWidth("450px");
+ lblGenerate.setMultiline(true);
+
+ lblNote = new Label();
+ lblNote.setWidth("450px");
+ lblNote.setMultiline(true);
+
+ lblStatus = new Label(" ");
+ lblNumSelected = new Label("Number of Records Selected : 0");
+
+ lstGenerate = new Listbox();
+ lstGenerate.setWidth("300px");
+
+ populateOrganisation();
+ showBusinessPartner();
+ }
+
+ private void initComponents()
+ {
+ this.setWidth("710px");
+
+ tabs.appendChild(tabSelect);
+ tabs.appendChild(tabGenerate);
+
+ tabpanels.appendChild(pnlSelect);
+ tabpanels.appendChild(pnlGenerate);
+
+ tabbox.appendChild(tabs);
+ tabbox.appendChild(tabpanels);
+
+ Hbox mainBox = new Hbox();
+ mainBox.setWidth("100%");
+ mainBox.setStyle("text-align:center");
+
+ Hbox hOrg = new Hbox();
+ hOrg.setWidth("100%");
+
+ Hbox hBP = new Hbox();
+ hBP.setWidth("100%");
+
+ mainBox.appendChild(hOrg);
+ mainBox.appendChild(hBP);
+
+ Panel pnl1 = new Panel();
+ pnl1.appendChild(organizationSearch.getLabel());
+ pnl1.setStyle("text-align:right");
+
+ Panel pnl2 = new Panel();
+ pnl2.appendChild(organizationSearch.getComponent());
+ pnl2.setStyle("text-align:left");
+
+ Panel pnl3 = new Panel();
+ pnl3.appendChild(bPartnerSearch.getLabel());
+ pnl3.setStyle("text-align:right");
+
+ Panel pnl4 = new Panel();
+ pnl4.appendChild(bPartnerSearch.getComponent());
+ pnl4.setStyle("text-align:left");
+
+ hOrg.appendChild(pnl1);
+ hOrg.appendChild(pnl2);
+
+ hBP.appendChild(pnl3);
+ hBP.appendChild(pnl4);
+
+ pnlSelect.setStyle("text-align:center");
+ pnlSelect.appendChild(mainBox);
+ pnlSelect.appendChild(new Separator());
+ pnlSelect.appendChild(lstSelect);
+ pnlSelect.appendChild(new Separator());
+
+ pnlSelect.addEventListener(Events.ON_SELECT, this);
+
+ pnlGenerate.appendChild(lblGenerate);
+ pnlGenerate.appendChild(lblNote);
+ pnlGenerate.appendChild(new Separator());
+ pnlGenerate.appendChild(lstGenerate);
+
+ this.appendChild(tabbox);
+ this.appendChild(new Separator());
+
+ Hbox hbox = new Hbox();
+ hbox.setWidth("80px");
+ hbox.appendChild(btnCancel);
+ hbox.appendChild(btnOk);
+
+ //pnlSelect.appendChild(hbox);
+ //pnlSelect.appendChild(new Separator());
+
+ this.appendChild(hbox);
+ this.appendChild(new Separator());
+
+ hbox = new Hbox();
+ hbox.setWidth("700px");
+
+ Panel p = new Panel();
+ p.setStyle("text-align:left");
+ p.appendChild(lblStatus);
+ hbox.appendChild(p);
+
+ p = new Panel();
+ p.setStyle("text-align:right");
+ p.appendChild(lblNumSelected);
+ hbox.appendChild(p);
+
+ //pnlSelect.appendChild(hbox);
+ this.appendChild(hbox);
+
+ prepareTable();
+ populateOrganisation();
+ }
+
+ private void prepareTable()
+ {
+ // Create Columns
+
+ ListHead listhead = new ListHead();
+ listhead.setSizable(true);
+
+ listhead.appendChild(new ListHeader(""));
+ listhead.appendChild(new ListHeader("Organization"));
+ listhead.appendChild(new ListHeader("Document Type"));
+ listhead.appendChild(new ListHeader("Document No"));
+ listhead.appendChild(new ListHeader("Business Partner"));
+ listhead.appendChild(new ListHeader("Date Ordered"));
+ listhead.appendChild(new ListHeader("Total Lines"));
+
+ lstSelect.appendChild(listhead);
+
+ lstSelect.addColumn("C_Order_ID");
+ lstSelect.addColumn("AD_Org_ID");
+ lstSelect.addColumn("C_DocType_ID");
+ lstSelect.addColumn("DocumentNo");
+ lstSelect.addColumn("C_BPartner_ID");
+ lstSelect.addColumn("DateOrdered");
+ lstSelect.addColumn("TotalLines");
+
+ lstSelect.setMultiSelection(true);
+
+ // Set Details
+
+ lstSelect.setColumnClass(0, IDColumn.class, false, " ");
+ lstSelect.setColumnClass(1, String.class, true, Msg.translate(Env.getCtx(), "AD_Org_ID"));
+ lstSelect.setColumnClass(2, String.class, true, Msg.translate(Env.getCtx(), "C_DocType_ID"));
+ lstSelect.setColumnClass(3, String.class, true, Msg.translate(Env.getCtx(), "DocumentNo"));
+ lstSelect.setColumnClass(4, String.class, true, Msg.translate(Env.getCtx(), "C_BPartner_ID"));
+ lstSelect.setColumnClass(5, Timestamp.class, true, Msg.translate(Env.getCtx(), "DateOrdered"));
+ lstSelect.setColumnClass(6, BigDecimal.class, true, Msg.translate(Env.getCtx(), "TotalLines"));
+
+ // Set Status
+
+ lblStatus.setValue(Msg.getMsg(Env.getCtx(), "InvGenerateSel"));
+ //statusBar.setStatusDB(" ");
+ }
+
+ private void populateOrganisation()
+ {
+ final int AD_Column_ID = 2163;
+
+ MLookup lookupBP = MLookupFactory.get(Env.getCtx(), super.m_windowNo,
+ 0, AD_Column_ID, DisplayType.TableDir);
+
+ organizationSearch = new WTableDirEditor(lookupBP, Msg.translate(
+ Env.getCtx(), "AD_Org_ID"), "", true, false, true);
+
+ organizationSearch.addValueChangeListner(this);
+ }
+
+ private void showBusinessPartner()
+ {
+ final int AD_Column_ID = 3499;
+
+ MLookup lookupBP = MLookupFactory.get(Env.getCtx(), super.m_windowNo,
+ 0, AD_Column_ID, DisplayType.Search);
+
+ bPartnerSearch = new WSearchEditor(lookupBP, Msg.translate(
+ Env.getCtx(), "C_BPartner_ID"), "", true, false, true);
+
+ bPartnerSearch.addValueChangeListner(this);
+ }
+
+
+ private void executeQuery()
+ {
+ log.info("");
+
+ int AD_Client_ID = Env.getAD_Client_ID(Env.getCtx());
+
+ // Create SQL
+
+ StringBuffer sql = new StringBuffer(
+ "SELECT C_Order_ID, o.Name, dt.Name, DocumentNo, bp.Name, DateOrdered, TotalLines "
+ + "FROM C_Invoice_Candidate_v ic, AD_Org o, C_BPartner bp, C_DocType dt "
+ + "WHERE ic.AD_Org_ID=o.AD_Org_ID"
+ + " AND ic.C_BPartner_ID=bp.C_BPartner_ID"
+ + " AND ic.C_DocType_ID=dt.C_DocType_ID"
+ + " AND ic.AD_Client_ID=?");
+
+ if (organizationSearch.getValue() != null)
+ {
+ sql.append(" AND ic.AD_Org_ID=").append(organizationSearch.getValue().toString());
+ }
+
+ if (bPartnerSearch.getDisplay() != "")
+ {
+ sql.append(" AND ic.C_BPartner_ID=").append(bPartnerSearch.getValue().toString());
+ }
+
+ // bug - [ 1713337 ] "Generate Invoices (manual)" show locked records.
+
+ /* begin - Exclude locked records; @Trifon */
+
+ int AD_User_ID = Env.getContextAsInt(Env.getCtx(), "#AD_User_ID");
+ String lockedIDs = MPrivateAccess.getLockedRecordWhere(MOrder.Table_ID, AD_User_ID);
+
+ if (lockedIDs != null)
+ {
+ if (sql.length() > 0)
+ sql.append(" AND ");
+
+ sql.append("C_Order_ID").append(lockedIDs);
+ }
+
+ /* end - Exclude locked records; @Trifon */
+
+ sql.append(" ORDER BY o.Name,bp.Name,DateOrdered");
+
+ // Reset Table
+
+ int row = 0;
+ lstSelect.clearTable();
+
+ // Execute
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql.toString(), null);
+ pstmt.setInt(1, AD_Client_ID);
+ ResultSet rs = pstmt.executeQuery();
+
+ while (rs.next())
+ {
+ // Extend table
+
+ lstSelect.setRowCount(row+1);
+
+ // Set values
+
+ lstSelect.setValueAt(new IDColumn(rs.getInt(1)), row, 0); // C_Order_ID
+ lstSelect.setValueAt(rs.getString(2), row, 1); // Org
+ lstSelect.setValueAt(rs.getString(3), row, 2); // DocType
+ lstSelect.setValueAt(rs.getString(4), row, 3); // Doc No
+ lstSelect.setValueAt(rs.getString(5), row, 4); // BPartner
+ lstSelect.setValueAt(rs.getTimestamp(6), row, 5); // DateOrdered
+ lstSelect.setValueAt(rs.getBigDecimal(7), row, 6); // TotalLines
+
+ // Prepare next
+
+ row++;
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql.toString(), e);
+ }
+
+ // Set Status
+
+ //statusBar.setStatusDB(String.valueOf(miniTable.getRowCount()));
+ }
+
+ private void saveSelection()
+ {
+ log.info("");
+
+ // Array of Integers
+
+ ArrayList results = new ArrayList();
+
+ if (selections != null)
+ selections.clear();
+
+ // Get Selected Entries
+
+ int rows = lstSelect.getItemCount();
+
+ for (int i = 0; i < rows; i++)
+ {
+ // ID in Column 0
+
+ IDColumn id = (IDColumn)lstSelect.getValueAt(i, 0);
+
+ if (id != null && id.isSelected())
+ results.add(id.getRecord_ID());
+ }
+
+ if (results.size() == 0)
+ return;
+
+ selections = results;
+ }
+
+ private void generateInvoices()
+ {
+ String trxName = Trx.createTrxName("IVG");
+ Trx trx = Trx.get(trxName, true); // Trx needs to be committed too
+
+ m_selectionActive = false; // Prevents from being called twice
+
+ // Set Status
+
+ //lblStatus.setValue(Msg.getMsg(Env.getCtx(), "InvGenerateGen"));
+ //statusBar.setStatusDB(String.valueOf(selections.size()));
+
+ // Prepare Process
+
+ int AD_Process_ID = 134; // C_InvoiceCreate
+
+ MPInstance instance = new MPInstance(Env.getCtx(), AD_Process_ID, 0);
+
+ if (!instance.save())
+ {
+ return;
+ }
+
+ // Insert selection
+
+ StringBuffer insert = new StringBuffer();
+ insert.append("INSERT INTO T_SELECTION(AD_PINSTANCE_ID, T_SELECTION_ID) ");
+
+ int counter = 0;
+
+ for(Integer selectedId : selections)
+ {
+ counter++;
+
+ if (counter > 1)
+ insert.append(" UNION ");
+
+ insert.append("SELECT ");
+ insert.append(instance.getAD_PInstance_ID());
+ insert.append(", ");
+ insert.append(selectedId);
+ insert.append(" FROM DUAL ");
+
+ if (counter == 1000)
+ {
+ if ( DB.executeUpdate(insert.toString(), trxName) < 0 )
+ {
+ String msg = "No Shipments"; // Not translated!
+ log.config(msg);
+
+ trx.rollback();
+ return;
+ }
+
+ insert = new StringBuffer();
+ insert.append("INSERT INTO T_SELECTION(AD_PINSTANCE_ID, T_SELECTION_ID) ");
+ counter = 0;
+ }
+ }
+
+ if (counter > 0)
+ {
+ if ( DB.executeUpdate(insert.toString(), trxName) < 0 )
+ {
+ String msg = "No Shipments"; // Not translated!
+ log.config(msg);
+
+ trx.rollback();
+ return;
+ }
+ }
+
+ ProcessInfo pi = new ProcessInfo ("", AD_Process_ID);
+ pi.setAD_PInstance_ID (instance.getAD_PInstance_ID());
+
+ // Add Parameters
+
+ MPInstancePara para = new MPInstancePara(instance, 10);
+ para.setParameter("Selection", "Y");
+
+ if (!para.save())
+ {
+ String msg = "No Selection Parameter added"; // Not translated
+ log.log(Level.SEVERE, msg);
+ return;
+ }
+
+ para = new MPInstancePara(instance, 20);
+ para.setParameter("DocAction", "CO");
+
+ if (!para.save())
+ {
+ String msg = "No DocAction Parameter added"; // Not translated
+ log.log(Level.SEVERE, msg);
+ return;
+ }
+
+ // Execute Process
+
+ ProcessCtl worker = new ProcessCtl(null, super.m_windowNo, pi, trx);
+ worker.start();
+
+ lstSelect.clearTable();
+
+ displayInfo();
+ }
+
+ private void displayInfo()
+ {
+ lblGenerate.setValue("Created = " + selections.size());
+ lblNote.setValue("(Invoices are generated depending on the 'Invoice Rule' selection in the Order)");
+
+ lstGenerate.getChildren().clear();
+
+ for (int i = 0; i < selections.size(); i++)
+ {
+ ListItem listitem = new ListItem();
+ Timestamp time = new Timestamp(System.currentTimeMillis());
+ listitem.appendChild(new Listcell(time.toString()));
+ listitem.appendChild(new Listcell(selections.get(i).toString()));
+
+ lstGenerate.appendChild(listitem);
+ }
+
+ tabbox.setSelectedPanel(pnlGenerate);
+ }
+
+ private void generateInvoiceComplete (ProcessInfo pi)
+ {
+ // Print invoices
+
+ int AD_Process_ID = 134;
+
+/* for (int i = 0; i < selections.size(); i++)
+ {
+ ProcessModalDialog dialog = new ProcessModalDialog(
+ null, this.getTitle(), null, 0, AD_Process_ID,
+ table_ID, selections.get(i), true);
+
+ if (dialog.isValid())
+ {
+ dialog.setPosition("center");
+
+ try
+ {
+ dialog.doModal();
+ }
+ catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }*/
+ }
+
+
+
+ public void onEvent(Event evt)
+ {
+ if (evt != null)
+ {
+ if (evt.getTarget() == tabSelect)
+ {
+ m_selectionActive = true;
+
+ executeQuery();
+ }
+
+ if ((evt.getTarget() == organizationSearch) || (evt.getTarget() == bPartnerSearch))
+ {
+ if (evt.getTarget() == organizationSearch)
+ {
+ m_AD_Org_ID = organizationSearch.getValue();
+ }
+
+ if (evt.getTarget() == bPartnerSearch)
+ {
+ m_C_BPartner_ID = bPartnerSearch.getValue();
+ }
+
+ executeQuery();
+ }
+
+ if ((evt.getTarget() == btnOk) || (evt.getTarget() == btnCancel))
+ {
+ if (evt.getTarget() == btnCancel)
+ {
+ SessionManager.getAppDesktop().removeWindow();
+ }
+
+ saveSelection();
+
+ if (selections != null && selections.size() > 0 && m_selectionActive)
+ generateInvoices();
+ else
+ SessionManager.getAppDesktop().removeWindow();
+ }
+ }
+ }
+
+
+ public void valueChange(ValueChangeEvent evt)
+ {
+ if (evt == null)
+ return;
+
+ if (evt.getSource() instanceof WEditor)
+ {
+ String name = evt.getPropertyName();
+ Object value = evt.getNewValue() == null ? "" : evt.getNewValue();
+
+ if (name.equals("C_BPartner_ID"))
+ {
+ bPartnerSearch.setValue(value);
+ m_C_BPartner_ID = ((Integer) value).intValue();
+
+ executeQuery();
+ }
+
+ if (name.equals("AD_Org_ID"))
+ {
+ organizationSearch.setValue(value);
+ m_AD_Org_ID = ((Integer) value).intValue();
+
+ executeQuery();
+ }
+ }
+ }
+
+ public void tableChanged(WTableModelEvent event)
+ {
+ int rowsSelected = 0;
+ int rows = lstSelect.getItemCount();
+
+ for (int i = 0; i < rows; i++)
+ {
+ // ID in column 0
+ IDColumn id = (IDColumn)lstSelect.getValueAt(i, 0);
+
+ if (id != null && id.isSelected())
+ rowsSelected++;
+ }
+
+ // Set Status
+
+ Integer size = rowsSelected;
+ lblNumSelected.setValue("Number of Records Selected : " + size.toString());
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WMatch.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WMatch.java
new file mode 100644
index 0000000000..df68898616
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WMatch.java
@@ -0,0 +1,1039 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
+ * or via info@compiere.org or http://www.compiere.org/license.html *
+ *****************************************************************************/
+
+/**
+ * 2007, Modified by Posterita Ltd.
+ */
+
+package org.adempiere.webui.apps.form;
+
+import java.math.BigDecimal;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Timestamp;
+import java.util.Date;
+import java.util.Vector;
+import java.util.logging.Level;
+
+import org.adempiere.webui.component.Button;
+import org.adempiere.webui.component.Checkbox;
+import org.adempiere.webui.component.Datebox;
+import org.adempiere.webui.component.Grid;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.ListItem;
+import org.adempiere.webui.component.Listbox;
+import org.adempiere.webui.component.Row;
+import org.adempiere.webui.component.Rows;
+import org.adempiere.webui.component.Textbox;
+import org.adempiere.webui.component.WListbox;
+import org.adempiere.webui.editor.WEditor;
+import org.adempiere.webui.editor.WSearchEditor;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.event.ValueChangeListener;
+import org.adempiere.webui.event.WTableModelEvent;
+import org.adempiere.webui.event.WTableModelListener;
+import org.adempiere.webui.panel.ADForm;
+import org.compiere.minigrid.ColumnInfo;
+import org.compiere.minigrid.IDColumn;
+import org.compiere.model.MInOutLine;
+import org.compiere.model.MInvoiceLine;
+import org.compiere.model.MLookup;
+import org.compiere.model.MLookupFactory;
+import org.compiere.model.MMatchInv;
+import org.compiere.model.MMatchPO;
+import org.compiere.model.MOrderLine;
+import org.compiere.model.MRole;
+import org.compiere.model.MStorage;
+import org.compiere.util.CLogger;
+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.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zk.ui.event.Events;
+import org.zkoss.zul.Hbox;
+import org.zkoss.zul.Separator;
+
+/**
+ * Match PO-Invoice-Receipt Custom Form : Based on VMatch
+ *
+ * @author Niraj Sohun
+ * @date Jul 2, 2007
+ */
+
+public class WMatch extends ADForm implements EventListener, ValueChangeListener, WTableModelListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private Grid grdParameters;
+ private Grid grdMatch;
+ private Grid grdProcess;
+
+ private Rows rows;
+ private Row row;
+
+ private Listbox lstInvoice;
+ private Listbox lstReceipt;
+
+ private Button cmdSearch;
+ private Button cmdProcess;
+
+ private Datebox dateFrom;
+ private Datebox dateTo;
+
+ private Listbox lstMatchFrom;
+ private Listbox lstMatchTo;
+ private Listbox lstSearchMode;
+
+ private Checkbox chkSameBP;
+ private Checkbox chkSameProduct;
+ private Checkbox chkSameQty;
+
+ private Textbox txtToBeMatched;
+ private Textbox txtMatching;
+ private Textbox txtDifference;
+
+ private Label lblMatchFrom;
+ private Label lblMatchTo;
+ private Label lblStatus;
+
+ private String[] m_matchOptions = new String[] {
+ Msg.getElement(Env.getCtx(), "C_Invoice_ID", false),
+ Msg.getElement(Env.getCtx(), "M_InOut_ID", false),
+ Msg.getElement(Env.getCtx(), "C_Order_ID", false) };
+
+ private static final int MATCH_INVOICE = 0;
+ private static final int MATCH_SHIPMENT = 1;
+ private static final int MATCH_ORDER = 2;
+
+ private String[] m_matchMode = new String[] {
+ Msg.translate(Env.getCtx(), "NotMatched"),
+ Msg.translate(Env.getCtx(), "Matched")};
+
+ private static final int MODE_NOTMATCHED = 0;
+ private static final int MODE_MATCHED = 1;
+
+ private static final int I_BPartner = 3;
+ private static final int I_Line = 4;
+ private static final int I_Product = 5;
+ private static final int I_QTY = 6;
+ private static final int I_MATCHED = 7;
+
+ private StringBuffer m_sql = null;
+ private String m_dateColumn = "";
+ private String m_qtyColumn = "";
+ private String m_groupBy = "";
+
+ private BigDecimal m_xMatched = Env.ZERO;
+ private BigDecimal m_xMatchedTo = Env.ZERO;
+
+ private WEditor bPartnerSearch = null;
+ private WEditor productSearch = null;
+
+ //private int m_C_BPartner_ID;
+ //private int productID;
+
+ private WListbox xMatchedTable;
+ private WListbox xMatchedToTable;
+
+ @SuppressWarnings("unused")
+ private String strMatchedTable;
+
+ @SuppressWarnings("unused")
+ private String strMatchedToTable;
+
+ private static CLogger log = CLogger.getCLogger(WMatch.class);
+
+ public WMatch()
+ {
+ init();
+ initComponents();
+ }
+
+ private void init()
+ {
+ try
+ {
+ new Thread()
+ {
+ public void run()
+ {
+ log.info("Starting ...");
+ MMatchPO.consolidate(Env.getCtx());
+ log.info("... Done");
+ }
+ }.start();
+ }
+ catch(Exception e)
+ {
+ log.log(Level.SEVERE, "", e);
+ }
+
+ grdParameters = new Grid();
+ grdParameters.setWidth("700px");
+
+ grdMatch = new Grid();
+ grdMatch.setWidth("700px");
+
+ grdProcess = new Grid();
+ grdProcess.setWidth("700px");
+
+ lstInvoice = new Listbox();
+ lstInvoice.setWidth("700px");
+
+ lstReceipt = new Listbox();
+ lstReceipt.setWidth("700px");
+
+ cmdSearch = new Button();
+ cmdSearch.setImage("/images/FindX24.gif");
+ cmdSearch.addEventListener(Events.ON_CLICK, this);
+
+ cmdProcess = new Button();
+ cmdProcess.setImage("/images/Process24.gif");
+ cmdProcess.addEventListener(Events.ON_CLICK, this);
+
+ dateFrom = new Datebox();
+ dateTo = new Datebox();
+
+ lstMatchFrom = new Listbox();
+ lstMatchFrom.setRows(0);
+ lstMatchFrom.setMold("select");
+ lstMatchFrom.addEventListener(Events.ON_SELECT, this);
+
+ lstMatchTo = new Listbox();
+ lstMatchTo.setRows(0);
+ lstMatchTo.setMold("select");
+ lstMatchTo.addEventListener(Events.ON_SELECT, this);
+
+ lstSearchMode = new Listbox();
+ lstSearchMode.setRows(1);
+ lstSearchMode.setMold("select");
+ //lstSearchMode.addEventListener(Events.ON_SELECT, this);
+
+ chkSameBP = new Checkbox();
+ chkSameBP.setLabel("Same Business Partner");
+ chkSameBP.setChecked(true);
+ chkSameBP.addEventListener(Events.ON_CHECK, this);
+
+ chkSameProduct = new Checkbox();
+ chkSameProduct.setLabel("Same Product");
+ chkSameProduct.setChecked(true);
+ chkSameProduct.addEventListener(Events.ON_CHECK, this);
+
+ chkSameQty = new Checkbox();
+ chkSameQty.setLabel("Same Quantity");
+ chkSameQty.setChecked(false);
+ chkSameQty.addEventListener(Events.ON_CHECK, this);
+
+ txtToBeMatched = new Textbox();
+ txtToBeMatched.setEnabled(false);
+
+ txtMatching = new Textbox();
+ txtMatching.setEnabled(false);
+
+ txtDifference = new Textbox();
+ txtDifference.setEnabled(false);
+
+ lblMatchFrom = new Label(" ");
+
+ lblMatchTo = new Label(" ");
+
+ lblStatus = new Label("Invoice#");
+ lblStatus.setWidth("700px");
+
+ xMatchedTable = new WListbox();
+ xMatchedTable.setWidth("700px");
+ xMatchedTable.setHeight("150px");
+ xMatchedTable.getModel().addTableModelListener(this);
+ xMatchedTable.addEventListener(Events.ON_SELECT, this);
+
+ xMatchedToTable = new WListbox();
+ xMatchedToTable.setWidth("700px");
+ xMatchedToTable.setHeight("150px");
+ xMatchedToTable.getModel().addTableModelListener(this);
+ xMatchedToTable.addEventListener(Events.ON_SELECT, this);
+ }
+
+ private void initComponents()
+ {
+ this.setWidth("710px");
+ this.setHeight("100%");
+ //this.setBorder("normal");
+
+ rows = new Rows();
+
+ // Row 1
+ row = new Row();
+ row.appendChild(new Label("Match From"));
+ row.appendChild(lstMatchFrom);
+ row.appendChild(new Label("Match To"));
+ row.appendChild(lstMatchTo);
+ rows.appendChild(row);
+
+ // Row 2
+ row = new Row();
+ row.appendChild(new Label("Search Mode"));
+ row.appendChild(lstSearchMode);
+ rows.appendChild(row);
+
+ // Row 3
+ row = new Row();
+ row.appendChild(new Label("Business Partner"));
+ showBusinessPartner();
+ row.appendChild(bPartnerSearch.getComponent());
+ row.appendChild(new Label("Product"));
+ showProduct();
+ row.appendChild(productSearch.getComponent());
+ rows.appendChild(row);
+
+ // Row 4
+ row = new Row();
+ row.appendChild(new Label("Date From"));
+ row.appendChild(dateFrom);
+ row.appendChild(new Label("Date To"));
+ row.appendChild(dateTo);
+ rows.appendChild(row);
+
+ grdParameters.appendChild(rows);
+ this.appendChild(grdParameters);
+ this.appendChild(new Separator());
+
+ Hbox hbox = new Hbox();
+ hbox.appendChild(cmdSearch);
+ hbox.appendChild(cmdProcess);
+
+ this.appendChild(hbox);
+ this.appendChild(new Separator());
+
+ // Listbox Invoice
+
+ this.appendChild(new Label(" "));
+ this.appendChild(lblMatchFrom);
+ this.appendChild(new Separator());
+ this.appendChild(new Label(" "));
+ this.appendChild(xMatchedTable);
+ this.appendChild(new Separator());
+
+ // Match Parameters
+
+ rows = new Rows();
+
+ this.appendChild(new Label(" "));
+ row = new Row();
+ row.appendChild(chkSameBP);
+ row.appendChild(chkSameProduct);
+ row.appendChild(chkSameQty);
+ rows.appendChild(row);
+
+ grdMatch.appendChild(rows);
+ this.appendChild(grdMatch);
+ this.appendChild(new Separator());
+
+ // Listbox Receipt
+ this.appendChild(new Label(" "));
+ this.appendChild(lblMatchTo);
+ this.appendChild(new Separator());
+ this.appendChild(new Label(" "));
+ this.appendChild(xMatchedToTable);
+ this.appendChild(new Separator());
+
+ // Process Parameters
+
+ rows = new Rows();
+
+ row = new Row();
+ row.appendChild(new Label("To Be Matched"));
+ row.appendChild(txtToBeMatched);
+ row.appendChild(new Label("Matching"));
+ row.appendChild(txtMatching);
+ row.appendChild(new Label("Difference"));
+ row.appendChild(txtDifference);
+ rows.appendChild(row);
+
+ grdProcess.appendChild(rows);
+ this.appendChild(grdProcess);
+
+ this.appendChild(new Separator());
+ this.appendChild(lblStatus);
+
+ populateMatchFrom();
+ populateMatchTo();
+ populateSearchMode();
+ prepareTable();
+ }
+
+ private void populateMatchFrom()
+ {
+ for (int i = 0; i < m_matchOptions.length; i++)
+ {
+ String temp = m_matchOptions[i];
+ lstMatchFrom.appendItem(temp, temp);
+ }
+
+ lstMatchFrom.setSelectedIndex(0);
+ lblMatchFrom.setValue(m_matchOptions[0]);
+ }
+
+ private void populateMatchTo()
+ {
+ lstMatchTo.getChildren().clear();
+
+ ListItem lstIteMatchFromSelection = lstMatchFrom.getSelectedItem();
+ String selection = (String)lstIteMatchFromSelection.getValue();
+
+ Vector vector = new Vector(2);
+
+ if (selection.equals(m_matchOptions[MATCH_INVOICE]))
+ vector.add(m_matchOptions[MATCH_SHIPMENT]);
+ else if (selection.equals(m_matchOptions[MATCH_ORDER]))
+ vector.add(m_matchOptions[MATCH_SHIPMENT]);
+ else
+ {
+ vector.add(m_matchOptions[MATCH_INVOICE]);
+ vector.add(m_matchOptions[MATCH_ORDER]);
+ }
+
+ for (int i = 0; i < vector.size(); i++)
+ {
+ String temp = vector.get(i).toString();
+ lstMatchTo.appendItem(temp, temp);
+ }
+
+ lstMatchTo.setSelectedIndex(0);
+ lblMatchTo.setValue(vector.get(0).toString());
+
+ // Reset Table
+
+ //xMatchedTable.setRowCount(0);
+ //xMatchedToTable.setRowCount(0);
+ }
+
+ private void populateSearchMode()
+ {
+ for (int i = 0; i < m_matchMode.length; i++)
+ {
+ lstSearchMode.appendItem(m_matchMode[i], m_matchMode[i]);
+ }
+
+ lstSearchMode.setSelectedIndex(0);
+ }
+
+ private void showBusinessPartner()
+ {
+ final int AD_Column_ID = 3499;
+
+ MLookup lookupBP = MLookupFactory.get(Env.getCtx(), super.m_windowNo,
+ 0, AD_Column_ID, DisplayType.Search);
+
+ bPartnerSearch = new WSearchEditor(lookupBP, Msg.translate(
+ Env.getCtx(), "C_BPartner_ID"), "", true, false, true);
+
+ bPartnerSearch.addValueChangeListner(this);
+ }
+
+ private void showProduct()
+ {
+ final int AD_Column_ID = 3840;
+
+ MLookup lookupP = MLookupFactory.get(Env.getCtx(), super.m_windowNo,
+ 0, AD_Column_ID, DisplayType.Search);
+
+ productSearch = new WSearchEditor(lookupP, Msg.translate(
+ Env.getCtx(), "M_Product_ID"), "", true, false, true);
+
+ productSearch.addValueChangeListner(this);
+ }
+
+ private void prepareTable()
+ {
+ ColumnInfo[] layout = new ColumnInfo[] {
+ new ColumnInfo(" ", ".", IDColumn.class, false, false, ""),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "DocumentNo"), ".", String.class), // 1
+ new ColumnInfo(Msg.translate(Env.getCtx(), "Date"), ".", Timestamp.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "C_BPartner_ID"),".", KeyNamePair.class, "."), // 3
+ new ColumnInfo(Msg.translate(Env.getCtx(), "Line"), ".", KeyNamePair.class, "."),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "M_Product_ID"), ".", KeyNamePair.class, "."), // 5
+ new ColumnInfo(Msg.translate(Env.getCtx(), "Qty"), ".", Double.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "Matched"), ".", Double.class)
+ };
+
+ strMatchedTable = xMatchedTable.prepareTable(layout, "", "", false, "");
+ strMatchedToTable = xMatchedToTable.prepareTable(layout, "", "", true, "");
+ }
+
+ private void searchRecords()
+ {
+ int display = lstMatchFrom.getSelectedIndex();
+
+ ListItem lstIteMatchTo = lstMatchTo.getSelectedItem();
+ String matchToString = (String)lstIteMatchTo.getValue();
+ int matchToType = MATCH_INVOICE;
+
+ if (matchToString.equals(m_matchOptions[MATCH_SHIPMENT]))
+ matchToType = MATCH_SHIPMENT;
+ else if (matchToString.equals(m_matchOptions[MATCH_ORDER]))
+ matchToType = MATCH_ORDER;
+
+ tableInit(display, matchToType); // sets m_sql
+
+ // Where Clause
+ // Product
+
+ if (productSearch.getDisplay() != "")
+ {
+ Integer Product = (Integer)productSearch.getValue();
+ m_sql.append(" AND lin.M_Product_ID=").append(Product);
+ }
+
+ // Business Partner
+
+ if (bPartnerSearch.getDisplay() != "")
+ {
+ Integer Vendor = (Integer)bPartnerSearch.getValue();
+ m_sql.append(" AND hdr.C_BPartner_ID=").append(Vendor);
+ }
+
+ Date f =null;
+ Timestamp from =null;
+
+ if (dateFrom.getValue() != null)
+ {
+ f = dateFrom.getValue();
+ from = new Timestamp(f.getTime());
+ }
+
+ Date t = null;
+ Timestamp to = null;
+
+ if (dateTo.getValue() != null)
+ {
+ t = dateTo.getValue();
+ to = new Timestamp(t.getTime());
+ }
+
+ if (from != null && to != null)
+ m_sql.append(" AND ").append(m_dateColumn).append(" BETWEEN ")
+ .append(DB.TO_DATE(from)).append(" AND ").append(DB.TO_DATE(to));
+ else if (from != null)
+ m_sql.append(" AND ").append(m_dateColumn).append(" >= ").append(DB.TO_DATE(from));
+ else if (to != null)
+ m_sql.append(" AND ").append(m_dateColumn).append(" <= ").append(DB.TO_DATE(to));
+
+ // Load Table
+ tableLoad (xMatchedTable);
+ txtMatching.setText(Env.ZERO.toString());
+
+ // Status Info
+ ListItem lstIteMatchFrom = lstMatchFrom.getSelectedItem();
+ Integer rowCount = xMatchedTable.getItemCount();
+
+ lblStatus.setValue(lstIteMatchFrom.getLabel() + "# = " + rowCount.toString());
+ // xMatchedTable.getRowCount() == 0);
+ //statusBar.setStatusDB(0);
+ }
+
+ private void process()
+ {
+ // Matched From
+ int matchedRow = xMatchedTable.getSelectedRow();
+
+ if (matchedRow < 0)
+ return;
+
+ //KeyNamePair BPartner = (KeyNamePair)xMatchedTable.getValueAt(matchedRow, I_BPartner);
+ KeyNamePair lineMatched = (KeyNamePair)xMatchedTable.getValueAt(matchedRow, I_Line);
+ KeyNamePair Product = (KeyNamePair)xMatchedTable.getValueAt(matchedRow, I_Product);
+
+ //int M_Product_ID = Product.getKey();
+ double totalQty = m_xMatched.doubleValue();
+
+ // Matched To
+ for (int row = 0; row < xMatchedToTable.getItemCount(); row++)
+ {
+ IDColumn id = (IDColumn)xMatchedToTable.getValueAt(row, 0);
+ if (id != null && id.isSelected())
+ {
+ // Need to be the same product
+ KeyNamePair ProductCompare = (KeyNamePair)xMatchedToTable.getValueAt(row, I_Product);
+
+ if (Product.getKey() != ProductCompare.getKey())
+ continue;
+
+ KeyNamePair lineMatchedTo = (KeyNamePair)xMatchedToTable.getValueAt(row, I_Line);
+
+ // Qty
+ double qty = 0.0;
+
+ if (lstSearchMode.getSelectedIndex() == MODE_NOTMATCHED)
+ qty = ((Double)xMatchedToTable.getValueAt(row, I_QTY)).doubleValue(); // doc
+
+ qty -= ((Double)xMatchedToTable.getValueAt(row, I_MATCHED)).doubleValue(); // matched
+
+ if (qty > totalQty)
+ qty = totalQty;
+
+ totalQty -= qty;
+
+ // Invoice or PO
+ boolean invoice = true;
+ if (lstMatchFrom.getSelectedIndex() == MATCH_ORDER ||
+ lstMatchTo.getSelectedItem().equals(m_matchOptions[MATCH_ORDER]))
+ invoice = false;
+
+ // Get Shipment_ID
+ int M_InOutLine_ID = 0;
+ int Line_ID = 0;
+
+ if (lstMatchFrom.getSelectedIndex() == MATCH_SHIPMENT)
+ {
+ M_InOutLine_ID = lineMatched.getKey(); // upper table
+ Line_ID = lineMatchedTo.getKey();
+ }
+ else
+ {
+ M_InOutLine_ID = lineMatchedTo.getKey(); // lower table
+ Line_ID = lineMatched.getKey();
+ }
+
+ // Create it
+ createMatchRecord(invoice, M_InOutLine_ID, Line_ID, new BigDecimal(qty));
+ }
+ }
+ // Requery
+ searchRecords();
+ }
+
+ public void tableChanged(WTableModelEvent e)
+ {
+ if (e.getColumn() != 0)
+ return;
+
+ log.config("Row=" + e.getFirstRow() + "-" + e.getLastRow() + ", Col=" + e.getColumn()
+ + ", Type=" + e.getType());
+ //setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+
+ // Matched From
+ int matchedRow = xMatchedTable.getSelectedRow();
+ if (matchedRow == -1)
+ {
+ return;
+ }
+ KeyNamePair Product = (KeyNamePair)xMatchedTable.getValueAt(matchedRow, 5);
+
+ // Matched To
+ double qty = 0.0;
+ Integer noRows = 0;
+
+ for (int row = 0; row < xMatchedToTable.getItemCount(); row++)
+ {
+ IDColumn id = (IDColumn)xMatchedToTable.getValueAt(row, 0);
+
+ if (id != null && id.isSelected())
+ {
+ KeyNamePair ProductCompare = (KeyNamePair)xMatchedToTable.getValueAt(row, 5);
+ if (Product.getKey() != ProductCompare.getKey())
+ {
+ id.setSelected(false);
+ }
+ else
+ {
+ if (lstSearchMode.getSelectedIndex() == MODE_NOTMATCHED)
+ qty += ((Double)xMatchedToTable.getValueAt(row, I_QTY)).doubleValue(); // doc
+
+ qty -= ((Double)xMatchedToTable.getValueAt(row, I_MATCHED)).doubleValue(); // matched
+ noRows++;
+ }
+ }
+ }
+
+ // Update qualtities
+ m_xMatchedTo = new BigDecimal(qty);
+ txtMatching.setValue(m_xMatchedTo.toString());
+ txtDifference.setValue(m_xMatched.subtract(m_xMatchedTo).toString());
+ cmdProcess.setEnabled(noRows != 0);
+
+ //setCursor(Cursor.getDefaultCursor());
+ // Status
+ //lblStatus.setValue(noRows.toString());
+ }
+
+ private void tableInit(int display, int matchToType)
+ {
+ boolean matched = lstSearchMode.getSelectedIndex() == MODE_MATCHED;
+
+ m_sql = new StringBuffer ();
+
+ if (display == MATCH_INVOICE)
+ {
+ m_dateColumn = "hdr.DateInvoiced";
+ m_qtyColumn = "lin.QtyInvoiced";
+ m_sql.append("SELECT hdr.C_Invoice_ID,hdr.DocumentNo, hdr.DateInvoiced, bp.Name,hdr.C_BPartner_ID,"
+ + " lin.Line,lin.C_InvoiceLine_ID, p.Name,lin.M_Product_ID,"
+ + " lin.QtyInvoiced,SUM(NVL(mi.Qty,0)) "
+ + "FROM C_Invoice hdr"
+ + " INNER JOIN C_BPartner bp ON (hdr.C_BPartner_ID=bp.C_BPartner_ID)"
+ + " INNER JOIN C_InvoiceLine lin ON (hdr.C_Invoice_ID=lin.C_Invoice_ID)"
+ + " INNER JOIN M_Product p ON (lin.M_Product_ID=p.M_Product_ID)"
+ + " INNER JOIN C_DocType dt ON (hdr.C_DocType_ID=dt.C_DocType_ID AND dt.DocBaseType IN ('API','APC'))"
+ + " FULL JOIN M_MatchInv mi ON (lin.C_InvoiceLine_ID=mi.C_InvoiceLine_ID) "
+ + "WHERE hdr.DocStatus IN ('CO','CL')");
+ m_groupBy = " GROUP BY hdr.C_Invoice_ID,hdr.DocumentNo,hdr.DateInvoiced,bp.Name,hdr.C_BPartner_ID,"
+ + " lin.Line,lin.C_InvoiceLine_ID,p.Name,lin.M_Product_ID,lin.QtyInvoiced "
+ + "HAVING "
+ + (matched ? "0" : "lin.QtyInvoiced")
+ + "<>SUM(NVL(mi.Qty,0))";
+ }
+ else if (display == MATCH_ORDER)
+ {
+ m_dateColumn = "hdr.DateOrdered";
+ m_qtyColumn = "lin.QtyOrdered";
+ m_sql.append("SELECT hdr.C_Order_ID,hdr.DocumentNo, hdr.DateOrdered, bp.Name,hdr.C_BPartner_ID,"
+ + " lin.Line,lin.C_OrderLine_ID, p.Name,lin.M_Product_ID,"
+ + " lin.QtyOrdered,SUM(COALESCE(mo.Qty,0)) "
+ + "FROM C_Order hdr"
+ + " INNER JOIN C_BPartner bp ON (hdr.C_BPartner_ID=bp.C_BPartner_ID)"
+ + " INNER JOIN C_OrderLine lin ON (hdr.C_Order_ID=lin.C_Order_ID)"
+ + " INNER JOIN M_Product p ON (lin.M_Product_ID=p.M_Product_ID)"
+ + " INNER JOIN C_DocType dt ON (hdr.C_DocType_ID=dt.C_DocType_ID AND dt.DocBaseType='POO')"
+ + " FULL JOIN M_MatchPO mo ON (lin.C_OrderLine_ID=mo.C_OrderLine_ID) "
+ + "WHERE mo.")
+ .append(matchToType == MATCH_SHIPMENT ? "M_InOutLine_ID" : "C_InvoiceLine_ID")
+ .append(matched ? " IS NOT NULL" : " IS NULL"
+ + " AND hdr.DocStatus IN ('CO','CL')");
+ m_groupBy = " GROUP BY hdr.C_Order_ID,hdr.DocumentNo,hdr.DateOrdered,bp.Name,hdr.C_BPartner_ID,"
+ + " lin.Line,lin.C_OrderLine_ID,p.Name,lin.M_Product_ID,lin.QtyOrdered "
+ + "HAVING "
+ + (matched ? "0" : "lin.QtyOrdered")
+ + "<>SUM(COALESCE(mo.Qty,0))";
+ }
+ else // Shipment
+ {
+ m_dateColumn = "hdr.MovementDate";
+ m_qtyColumn = "lin.MovementQty";
+ m_sql.append("SELECT hdr.M_InOut_ID,hdr.DocumentNo, hdr.MovementDate, bp.Name,hdr.C_BPartner_ID,"
+ + " lin.Line,lin.M_InOutLine_ID, p.Name,lin.M_Product_ID,"
+ + " lin.MovementQty,SUM(NVL(m.Qty,0)) "
+ + "FROM M_InOut hdr"
+ + " INNER JOIN C_BPartner bp ON (hdr.C_BPartner_ID=bp.C_BPartner_ID)"
+ + " INNER JOIN M_InOutLine lin ON (hdr.M_InOut_ID=lin.M_InOut_ID)"
+ + " INNER JOIN M_Product p ON (lin.M_Product_ID=p.M_Product_ID)"
+ + " INNER JOIN C_DocType dt ON (hdr.C_DocType_ID = dt.C_DocType_ID AND dt.DocBaseType='MMR')"
+ + " FULL JOIN ")
+ .append(matchToType == MATCH_ORDER ? "M_MatchPO" : "M_MatchInv")
+ .append(" m ON (lin.M_InOutLine_ID=m.M_InOutLine_ID) "
+ + "WHERE hdr.DocStatus IN ('CO','CL')");
+ m_groupBy = " GROUP BY hdr.M_InOut_ID,hdr.DocumentNo,hdr.MovementDate,bp.Name,hdr.C_BPartner_ID,"
+ + " lin.Line,lin.M_InOutLine_ID,p.Name,lin.M_Product_ID,lin.MovementQty "
+ + "HAVING "
+ + (matched ? "0" : "lin.MovementQty")
+ + "<>SUM(NVL(m.Qty,0))";
+ }
+ }
+
+ private void tableLoad(WListbox table)
+ {
+ log.finest(m_sql + " - " + m_groupBy);
+ String sql = MRole.getDefault().addAccessSQL(
+ m_sql.toString(), "hdr", MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO)
+ + m_groupBy;
+ log.finest(sql);
+
+ try
+ {
+ Statement stmt = DB.createStatement();
+ ResultSet rs = stmt.executeQuery(sql);
+ table.loadTable(rs);
+ stmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql, e);
+ }
+ }
+
+ private boolean createMatchRecord (boolean invoice, int M_InOutLine_ID, int Line_ID,
+ BigDecimal qty)
+ {
+ if (qty.compareTo(Env.ZERO) == 0)
+ return true;
+
+ log.fine("IsInvoice=" + invoice
+ + ", M_InOutLine_ID=" + M_InOutLine_ID + ", Line_ID=" + Line_ID
+ + ", Qty=" + qty);
+
+ boolean success = false;
+ MInOutLine sLine = new MInOutLine (Env.getCtx(), M_InOutLine_ID, null);
+
+ if (invoice) // Shipment - Invoice
+ {
+ // Update Invoice Line
+
+ MInvoiceLine iLine = new MInvoiceLine (Env.getCtx(), Line_ID, null);
+ iLine.setM_InOutLine_ID(M_InOutLine_ID);
+
+ if (sLine.getC_OrderLine_ID() != 0)
+ iLine.setC_OrderLine_ID(sLine.getC_OrderLine_ID());
+
+ iLine.save();
+
+ // Create Shipment - Invoice Link
+ if (iLine.getM_Product_ID() != 0)
+ {
+ MMatchInv match = new MMatchInv (iLine, null, qty);
+ match.setM_InOutLine_ID(M_InOutLine_ID);
+ if (match.save())
+ success = true;
+ else
+ log.log(Level.SEVERE, "Inv Match not created: " + match);
+ }
+ else
+ success = true;
+
+ // Create PO - Invoice Link = corrects PO
+ if (iLine.getC_OrderLine_ID() != 0 && iLine.getM_Product_ID() != 0)
+ {
+ MMatchPO matchPO = MMatchPO.create(iLine, sLine, null, qty);
+ matchPO.setC_InvoiceLine_ID(iLine);
+ matchPO.setM_InOutLine_ID(M_InOutLine_ID);
+
+ if (!matchPO.save())
+ {
+ log.log(Level.SEVERE, "PO(Inv) Match not created: " + matchPO);
+ }
+ }
+ }
+ else // Shipment - Order
+ {
+ // Update Shipment Line
+ sLine.setC_OrderLine_ID(Line_ID);
+ sLine.save();
+
+ // Update Order Line
+ MOrderLine oLine = new MOrderLine(Env.getCtx(), Line_ID, null);
+
+ if (oLine.get_ID() != 0) // other in MInOut.completeIt
+ {
+ oLine.setQtyReserved(oLine.getQtyReserved().subtract(qty));
+ if(!oLine.save())
+ ;//log.severe("QtyReserved not updated - C_OrderLine_ID=" + Line_ID);
+ }
+
+ // Create PO - Shipment Link
+ if (sLine.getM_Product_ID() != 0)
+ {
+ MMatchPO match = new MMatchPO (sLine, null, qty);
+ if (!match.save())
+ ;// log.log(Level.SEVERE, "PO Match not created: " + match);
+ else
+ {
+ success = true;
+
+ // Correct Ordered Qty for Stocked Products (see MOrder.reserveStock / MInOut.processIt)
+ if (sLine.getProduct() != null && sLine.getProduct().isStocked())
+ success = MStorage.add (Env.getCtx(), sLine.getM_Warehouse_ID(),
+ sLine.getM_Locator_ID(),
+ sLine.getM_Product_ID(),
+ sLine.getM_AttributeSetInstance_ID(), oLine.getM_AttributeSetInstance_ID(),
+ null, null, qty.negate(), null);
+ }
+ }
+ else
+ success = true;
+ }
+ return success;
+ }
+
+ private void searchTo()
+ {
+ int row = xMatchedTable.getSelectedRow();
+ log.config("Row=" + row);
+
+ double qty = 0.0;
+
+ if (row < 0)
+ {
+ xMatchedToTable.setRowCount(0);
+ }
+ else
+ {
+ // ** Create SQL **
+ ListItem lstIteDisplayStr = lstMatchTo.getSelectedItem();
+ String displayString = (String)lstIteDisplayStr.getValue();
+ int display = MATCH_INVOICE;
+
+ if (displayString.equals(m_matchOptions[MATCH_SHIPMENT]))
+ display = MATCH_SHIPMENT;
+ else if (displayString.equals(m_matchOptions[MATCH_ORDER]))
+ display = MATCH_ORDER;
+
+ int matchToType = lstMatchFrom.getSelectedIndex();
+
+ tableInit (display, matchToType); // sets m_sql
+
+ // ** Add Where Clause **
+ KeyNamePair BPartner = (KeyNamePair)xMatchedTable.getValueAt(row, I_BPartner);
+ KeyNamePair Product = (KeyNamePair)xMatchedTable.getValueAt(row, I_Product);
+ log.fine("BPartner=" + BPartner + " - Product=" + Product);
+
+ if (chkSameBP.isChecked())
+ m_sql.append(" AND hdr.C_BPartner_ID=").append(BPartner.getKey());
+
+ if (chkSameProduct.isChecked())
+ m_sql.append(" AND lin.M_Product_ID=").append(Product.getKey());
+
+ // Calculate qty
+ double docQty = ((Double)xMatchedTable.getValueAt(row, I_QTY)).doubleValue();
+ double matchedQty = ((Double)xMatchedTable.getValueAt(row, I_MATCHED)).doubleValue();
+ qty = docQty - matchedQty;
+
+ if (chkSameQty.isChecked())
+ m_sql.append(" AND ").append(m_qtyColumn).append("=").append(docQty);
+
+ // ** Load Table **
+ tableLoad (xMatchedToTable);
+ }
+
+ // Display To be Matched Qty
+ m_xMatched = new BigDecimal (qty);
+ txtToBeMatched.setValue(m_xMatched.toString());
+ txtMatching.setValue(Env.ZERO.toString());
+ txtDifference.setValue(m_xMatched.toString());
+
+ // Status Info
+ ListItem lstIteMatchFrom = lstMatchFrom.getSelectedItem();
+ ListItem lstIteMatchTo = lstMatchTo.getSelectedItem();
+
+ Integer matchedRowCount = xMatchedTable.getItemCount();
+ Integer matchToRowCount = xMatchedToTable.getItemCount();
+
+ String stat = lstIteMatchFrom.getLabel() + "# = " + matchedRowCount.toString() + " - "
+ + lstIteMatchTo.getLabel() + "# = " + matchToRowCount.toString();
+
+ lblStatus.setValue(stat);
+ // xMatchedToTable.getRowCount() == 0);
+ //statusBar.setStatusDB(0);
+ }
+
+ public void onEvent(Event evt) throws Exception
+ {
+ if (evt != null)
+ {
+ if (evt.getTarget() == lstMatchFrom)
+ {
+ populateMatchTo();
+
+ ListItem lstIteMatchFrom = lstMatchFrom.getSelectedItem();
+ lblMatchFrom.setValue(lstIteMatchFrom.getLabel());
+
+ ListItem lstIteMatchTo = lstMatchTo.getSelectedItem();
+ lblMatchTo.setValue(lstIteMatchTo.getLabel());
+
+ xMatchedTable.clear();
+ xMatchedToTable.clear();
+ }
+
+ if (evt.getTarget() == lstMatchTo)
+ {
+ ListItem lstIteMatchTo = lstMatchTo.getSelectedItem();
+ lblMatchTo.setValue(lstIteMatchTo.getLabel());
+
+ xMatchedTable.clear();
+ xMatchedToTable.clear();
+ }
+
+ if (evt.getTarget() == chkSameBP)
+ {
+ searchTo();
+ }
+
+ if (evt.getTarget() == chkSameProduct)
+ {
+ searchTo();
+ }
+
+ if (evt.getTarget() == chkSameQty)
+ {
+ searchTo();
+ }
+
+ if (evt.getTarget() == cmdSearch)
+ {
+ xMatchedTable.clear();
+ xMatchedToTable.clear();
+ searchRecords();
+ }
+
+ if (evt.getTarget() == cmdProcess)
+ {
+ process();
+
+ xMatchedTable.clear();
+ xMatchedToTable.clear();
+
+ txtMatching.setValue("");
+ txtToBeMatched.setValue("");
+ txtDifference.setValue("");
+
+ lblStatus.setValue("");
+
+ searchRecords();
+ }
+
+ if (evt.getTarget() == xMatchedTable)
+ {
+ searchTo();
+ }
+ }
+ }
+
+ //public void tableChanged(WTableModelEvent event)
+ //{
+ //if (event.getColumn() == 0)
+ //{
+ // searchTo();
+ //}
+ //}
+
+ public void valueChange(ValueChangeEvent evt)
+ {
+ if (evt == null)
+ return;
+
+ if (evt.getSource() instanceof WEditor)
+ {
+ String name = evt.getPropertyName();
+ Object value = evt.getNewValue() == null ? "" : evt.getNewValue();
+
+ xMatchedTable.clear();
+ xMatchedToTable.clear();
+
+ if (name.equals("C_BPartner_ID"))
+ {
+ bPartnerSearch.setValue(value);
+ //m_C_BPartner_ID = ((Integer) value).intValue();
+ }
+ else if (name.equals("M_Product_ID"))
+ {
+ productSearch.setValue(value);
+ //productID = new Integer(value);
+ }
+ }
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WMerge.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WMerge.java
new file mode 100644
index 0000000000..69d3ff1bc6
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WMerge.java
@@ -0,0 +1,572 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
+ * or via info@compiere.org or http://www.compiere.org/license.html *
+ *****************************************************************************/
+
+/**
+ * 2007, Modified by Posterita Ltd.
+ */
+
+package org.adempiere.webui.apps.form;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+
+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.WConfirmPanel;
+import org.adempiere.webui.editor.WEditor;
+import org.adempiere.webui.editor.WSearchEditor;
+import org.adempiere.webui.editor.WTableDirEditor;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.event.ValueChangeListener;
+import org.adempiere.webui.panel.ADForm;
+import org.adempiere.webui.session.SessionManager;
+import org.adempiere.webui.window.FDialog;
+import org.compiere.model.MBPartner;
+import org.compiere.model.MInvoice;
+import org.compiere.model.MLookup;
+import org.compiere.model.MLookupFactory;
+import org.compiere.model.MPayment;
+import org.compiere.model.X_M_Cost;
+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.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
+
+/**
+ * Merge Entities : Based on VMerge
+ *
+ * @author Niraj Sohun
+ * @date Jul 28, 2007
+ */
+
+public class WMerge extends ADForm implements EventListener, ValueChangeListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private static CLogger log = CLogger.getCLogger(WInvoiceGen.class);
+
+ private Grid grdAll;
+ private Rows rows;
+ private Row row;
+
+ /** Confirmation panel containing Ok and Cancel button. */
+ private WConfirmPanel m_pnlConfirm;
+
+ private WEditor[] from = new WEditor[4];
+ private WEditor[] to = new WEditor[4];
+
+ private int[] fromIDs = new int[4];
+ private int[] toIDs = new int[4];
+
+ private int[] AD_Column_ID = new int[] {2163, 2762, 971, 2221};
+ private String[] text = new String[] {"AD_Org_ID", "C_BPartner_ID", "AD_User_ID", "M_Product_ID"};
+
+ private int m_totalCount;
+
+ private StringBuffer m_errorLog;
+
+ private Trx m_trx;
+
+ static private String AD_ORG_ID = "AD_Org_ID";
+ static private String C_BPARTNER_ID = "C_BPartner_ID";
+ static private String AD_USER_ID = "AD_User_ID";
+ static private String M_PRODUCT_ID = "M_Product_ID";
+
+ /** Tables to delete (not update) for AD_Org */
+ static private String[] s_delete_Org = new String[] {"AD_OrgInfo"};
+
+ /** Tables to delete (not update) for AD_User */
+ static private String[] s_delete_User = new String[] {"AD_User_Roles"};
+
+ /** Tables to delete (not update) for C_BPartner */
+ static private String[] s_delete_BPartner = new String[] {"C_BP_Employee_Acct",
+ "C_BP_Vendor_Acct", "C_BP_Customer_Acct", "T_Aging"};
+
+ /** Tables to delete (not update) for M_Product */
+ static private String[] s_delete_Product = new String[] {"M_Product_PO", "M_Replenish", "T_Replenish",
+ "M_ProductPrice", "M_Product_Costing",
+ "M_Cost", // teo_sarca [ 1704554 ]
+ "M_Product_Trl", "M_Product_Acct"}; // M_Storage
+
+ private String[] m_columnName = new String[]{"AD_Org_ID", "C_BPartner_ID", "AD_User_ID", "M_Product_ID"};
+ private String[] m_deleteTables = null;
+
+ public WMerge()
+ {
+ init();
+ initComponents();
+ }
+
+ public void init()
+ {
+ grdAll = new Grid();
+ grdAll.setWidth("700px");
+
+ /*btnCancel = new Button();
+ btnCancel.setImage("/images/Cancel24.gif");
+ btnCancel.addEventListener(Events.ON_CLICK, this);
+
+ btnOk = new Button();
+ btnOk.setImage("/images/Ok24.gif");
+ btnOk.addEventListener(Events.ON_CLICK, this);*/
+
+ m_pnlConfirm = new WConfirmPanel(true);
+ m_pnlConfirm.addEventListener(this);
+
+ }
+
+ public void initComponents()
+ {
+ this.setWidth("710px");
+ this.setBorder("normal");
+
+ components();
+
+ rows = new Rows();
+
+ // Row 1
+ row = new Row();
+ row.appendChild(new Label(""));
+ row.appendChild(new Label("Merge From (Deleted)"));
+ row.appendChild(new Label("Merge To (Surviving)"));
+ rows.appendChild(row);
+
+ for (int i = 0; i < 4; i++)
+ {
+ row = new Row();
+ row.appendChild(from[i].getLabel());
+ row.appendChild(from[i].getComponent());
+ row.appendChild(to[i].getComponent());
+ rows.appendChild(row);
+ }
+
+ grdAll.appendChild(rows);
+ this.appendChild(grdAll);
+
+ // Row 6
+ this.appendChild(m_pnlConfirm);
+ }
+
+ private void components()
+ {
+ MLookup lookup = MLookupFactory.get(Env.getCtx(), super.m_windowNo,
+ 0, AD_Column_ID[0], DisplayType.TableDir);
+
+ from[0] = new WTableDirEditor(lookup, Msg.translate(
+ Env.getCtx(), text[0]), "from", true, false, true);
+
+ from[0].addValueChangeListner(this);
+
+ to[0] = new WTableDirEditor(lookup, Msg.translate(
+ Env.getCtx(), text[0]), "to", true, false, true);
+
+ to[0].addValueChangeListner(this);
+
+
+ // Search Editors
+
+ for (int i = 1; i < AD_Column_ID.length; i++)
+ {
+ lookup = MLookupFactory.get(Env.getCtx(), super.m_windowNo,
+ 0, AD_Column_ID[i], DisplayType.Search);
+
+ from[i] = new WSearchEditor(lookup, Msg.translate(
+ Env.getCtx(), text[i]), "from", true, false, true);
+
+ from[i].addValueChangeListner(this);
+
+ to[i] = new WSearchEditor(lookup, Msg.translate(
+ Env.getCtx(), text[i]), "to", true, false, true);
+
+ to[i].addValueChangeListner(this);
+ }
+ }
+
+ public void valueChange(ValueChangeEvent evt)
+ {
+ if (evt == null)
+ {
+ return;
+ }
+
+ WEditor edit = (WEditor)evt.getSource();
+ String des = edit.getDescription();
+
+ String name = evt.getPropertyName();
+ Object value = evt.getNewValue();
+
+
+ if (name.equals("AD_Org_ID"))
+ {
+ if (des == "from")
+ {
+ from[0].setValue(value);
+ fromIDs[0] = ((Integer)value).intValue();
+ }
+ else
+ {
+ to[0].setValue(value);
+ toIDs[0] = ((Integer)value).intValue();
+ }
+ }
+ else if (name.equals("C_BPartner_ID"))
+ {
+ if (des == "from")
+ {
+ from[1].setValue(value);
+ fromIDs[1] = ((Integer)value).intValue();
+ }
+ else
+ {
+ to[1].setValue(value);
+ toIDs[1] = ((Integer)value).intValue();
+ }
+ }
+ else if (name.equals("M_Product_ID"))
+ {
+ if (des == "from")
+ {
+ from[3].setValue(value);
+ fromIDs[3] = ((Integer)value).intValue();
+ }
+ else
+ {
+ to[3].setValue(value);
+ toIDs[3] = ((Integer)value).intValue();
+ }
+ }
+ else if (name.equals("AD_User_ID"))
+ {
+ if (des == "from")
+ {
+ from[2].setValue(value);
+ fromIDs[2] = ((Integer)value).intValue();
+ }
+ else
+ {
+ to[2].setValue(value);
+ toIDs[2] = ((Integer)value).intValue();
+ }
+ }
+ }
+
+ private boolean merge (String ColumnName, int from_ID, int to_ID)
+ {
+ String TableName = ColumnName.substring(0, ColumnName.length()-3);
+
+ //log.config(ColumnName + " - From=" + from_ID + ",To=" + to_ID);
+
+ boolean success = true;
+ m_totalCount = 0;
+ m_errorLog = new StringBuffer();
+
+ String sql = "SELECT t.TableName, c.ColumnName "
+ + "FROM AD_Table t"
+ + " INNER JOIN AD_Column c ON (t.AD_Table_ID=c.AD_Table_ID) "
+ + "WHERE t.IsView='N'"
+ + " AND t.TableName NOT IN ('C_TaxDeclarationAcct')"
+ + " AND ("
+ + "(c.ColumnName=? AND c.IsKey='N')" // #1 - direct
+ + " OR "
+ + "c.AD_Reference_Value_ID IN " // Table Reference
+ + "(SELECT rt.AD_Reference_ID FROM AD_Ref_Table rt"
+ + " INNER JOIN AD_Column cc ON (rt.AD_Table_ID=cc.AD_Table_ID AND rt.AD_Key=cc.AD_Column_ID) "
+ + "WHERE cc.IsKey='Y' AND cc.ColumnName=?)" // #2
+ + ") "
+ + "ORDER BY t.LoadSeq DESC";
+
+ PreparedStatement pstmt = null;
+
+ try
+ {
+
+ m_trx = Trx.get(Trx.createTrxName("merge"), true);
+
+ pstmt = DB.prepareStatement(sql, Trx.createTrxName());
+ pstmt.setString(1, ColumnName);
+ pstmt.setString(2, ColumnName);
+ ResultSet rs = pstmt.executeQuery();
+
+ while (rs.next())
+ {
+ String tName = rs.getString(1);
+ String cName = rs.getString(2);
+
+ if (!TableName.equals(tName)) // to be sure - sql should prevent it
+ {
+ int count = mergeTable (tName, cName, from_ID, to_ID);
+
+ if (count < 0)
+ success = false;
+ else
+ m_totalCount += count;
+ }
+ }
+ rs.close();
+ pstmt.close();
+ pstmt = null;
+
+ //log.config("Success=" + success + " - " + ColumnName + " - From=" + from_ID + ",To=" + to_ID);
+
+ if (success)
+ {
+ sql = "DELETE " + TableName + " WHERE " + ColumnName + "=" + from_ID;
+
+ if ( DB.executeUpdate(sql, m_trx.getTrxName()) < 0 )
+ {
+ m_errorLog.append(Env.NL).append("DELETE ").append(TableName).append(" - ");
+ success = false;
+ //log.config(m_errorLog.toString());
+ m_trx.rollback();
+ return false;
+ }
+
+ }
+
+ if (success)
+ m_trx.commit();
+ else
+ m_trx.rollback();
+
+ m_trx.close();
+
+ }
+ catch (Exception ex)
+ {
+ // log.log(Level.SEVERE, ColumnName, ex);
+ }
+
+ // Cleanup
+ try
+ {
+ if (pstmt != null)
+ pstmt.close();
+ }
+ catch (Exception ex)
+ {
+ }
+
+ pstmt = null;
+ return success;
+ }
+
+ /**
+ * Merge Table
+ * @param TableName table
+ * @param ColumnName column
+ * @param from_ID from
+ * @param to_ID to
+ * @return -1 for error or number of changes
+ */
+
+ private int mergeTable (String TableName, String ColumnName, int from_ID, int to_ID)
+ {
+ // log.fine(TableName + "." + ColumnName + " - From=" + from_ID + ",To=" + to_ID);
+
+ String sql = "UPDATE " + TableName
+ + " SET " + ColumnName + "=" + to_ID
+ + " WHERE " + ColumnName + "=" + from_ID;
+
+ boolean delete = false;
+
+ for (int i = 0; i < m_deleteTables.length; i++)
+ {
+ if (m_deleteTables[i].equals(TableName))
+ {
+ delete = true;
+ sql = "DELETE " + TableName + " WHERE " + ColumnName + "=" + from_ID;
+ }
+ }
+
+ // Delete newly created MCost records - teo_sarca [ 1704554 ]
+ if (delete && X_M_Cost.Table_Name.equals(TableName) && M_PRODUCT_ID.equals(ColumnName))
+ {
+ sql += " AND " + X_M_Cost.COLUMNNAME_CurrentCostPrice + "=0"
+ + " AND " + X_M_Cost.COLUMNNAME_CurrentQty + "=0"
+ + " AND " + X_M_Cost.COLUMNNAME_CumulatedAmt + "=0"
+ + " AND " + X_M_Cost.COLUMNNAME_CumulatedQty + "=0";
+ }
+
+ int count = DB.executeUpdate(sql, m_trx.getTrxName());
+
+
+ if ( count < 0 )
+ {
+ count = -1;
+ m_errorLog.append(Env.NL).append(delete ? "DELETE " : "UPDATE ").append(TableName).append(" - ").append(" - ").append(sql);
+ //log.config(m_errorLog.toString());
+ m_trx.rollback();
+
+ }
+ //log.fine(count + (delete ? " -Delete- " : " -Update- ") + TableName);
+
+ return count;
+ }
+
+ /**
+ * Post Merge
+ * @param ColumnName column name
+ * @param to_ID ID
+ */
+
+ private void postMerge (String ColumnName, int to_ID)
+ {
+ if (ColumnName.equals(AD_ORG_ID))
+ {
+
+ }
+ else if (ColumnName.equals(AD_USER_ID))
+ {
+
+ }
+ else if (ColumnName.equals(C_BPARTNER_ID))
+ {
+ MBPartner bp = new MBPartner (Env.getCtx(), to_ID, null);
+ if (bp.get_ID() != 0)
+ {
+ MPayment[] payments = MPayment.getOfBPartner(Env.getCtx(), bp.getC_BPartner_ID(), null);
+ for (int i = 0; i < payments.length; i++)
+ {
+ MPayment payment = payments[i];
+ if (payment.testAllocation())
+ payment.save();
+ }
+ MInvoice[] invoices = MInvoice.getOfBPartner(Env.getCtx(), bp.getC_BPartner_ID(), null);
+ for (int i = 0; i < invoices.length; i++)
+ {
+ MInvoice invoice = invoices[i];
+ if (invoice.testAllocation())
+ invoice.save();
+ }
+ bp.setTotalOpenBalance();
+ bp.setActualLifeTimeValue();
+ bp.save();
+ }
+ }
+ else if (ColumnName.equals(M_PRODUCT_ID))
+ {
+
+ }
+ }
+
+ private void process()
+ {
+ String columnName = null;
+ String from_Info = null;
+ String to_Info = null;
+ int from_ID = 0;
+ int to_ID = 0;
+
+ for (int i = 0; (i < m_columnName.length && from_ID == 0 && to_ID == 0); i++)
+ {
+ Object value;
+
+ value = from[i].getValue();
+
+ if (value != null)
+ {
+ if (value instanceof Integer)
+ from_ID = ((Integer)value).intValue();
+ else
+ continue;
+
+ value = to[i].getValue();
+
+ if (value != null && value instanceof Integer)
+ to_ID = ((Integer)value).intValue();
+ else
+ from_ID = 0;
+
+ if (from_ID != 0)
+ {
+ columnName = m_columnName[i];
+
+ from_Info = from[i].getDisplay ();
+ to_Info = to[i].getDisplay ();
+ }
+ }
+ } // get first merge pair
+
+ if (from_ID == 0 || from_ID == to_ID)
+ return;
+
+ String msg = Msg.getMsg(Env.getCtx(), "MergeFrom") + " = " + from_Info
+ + "\n" + Msg.getMsg(Env.getCtx(), "MergeTo") + " = " + to_Info;
+
+ //if (!FDialog.ask(super.m_windowNo, this, msg))
+ // return;
+
+ // ** Update **
+
+ if (columnName.equals(AD_ORG_ID))
+ m_deleteTables = s_delete_Org;
+ else if (columnName.equals(AD_USER_ID))
+ m_deleteTables = s_delete_User;
+ else if (columnName.equals(C_BPARTNER_ID))
+ m_deleteTables = s_delete_BPartner;
+ else if (columnName.equals(M_PRODUCT_ID))
+ m_deleteTables = s_delete_Product;
+
+ //setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+ //confirmPanel.getOKButton().setEnabled(false);
+
+ boolean success = merge (columnName, from_ID, to_ID);
+ postMerge(columnName, to_ID);
+
+ //confirmPanel.getOKButton().setEnabled(true);
+ //setCursor(Cursor.getDefaultCursor());
+ //
+
+ if (success)
+ {
+ FDialog.info (super.m_windowNo, this, msg);
+ }
+ else
+ {
+ FDialog.error(super.m_windowNo, this, "MergeError", m_errorLog.toString());
+ return;
+ }
+ }
+
+ /**
+ * React to Ok and Cancel buttons being triggered.
+ *
+ * @param event the event to which to respond
+ * @throws Exception if an exception occurred
+ */
+ public void onEvent(Event event) throws Exception
+ {
+ if (event != null)
+ {
+ if (event.getName().equals(WConfirmPanel.A_CANCEL))
+ {
+ SessionManager.getAppDesktop().removeWindow();
+ return;
+ }
+ else if (event.getName().equals(WConfirmPanel.A_OK))
+ {
+ process();
+ }
+ }
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WPayPrint.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WPayPrint.java
new file mode 100644
index 0000000000..090d56b59a
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WPayPrint.java
@@ -0,0 +1,706 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
+ * or via info@compiere.org or http://www.compiere.org/license.html *
+ *****************************************************************************/
+
+/**
+ * 2007, Modified by Posterita Ltd.
+ */
+
+package org.adempiere.webui.apps.form;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.logging.Level;
+
+import org.adempiere.webui.component.Button;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.ListItem;
+import org.adempiere.webui.component.Listbox;
+import org.adempiere.webui.component.Textbox;
+import org.adempiere.webui.component.VerticalBox;
+import org.adempiere.webui.panel.ADForm;
+import org.adempiere.webui.session.SessionManager;
+import org.adempiere.webui.window.FDialog;
+import org.compiere.model.MLookupFactory;
+import org.compiere.model.MLookupInfo;
+import org.compiere.model.MPaySelectionCheck;
+import org.compiere.model.MPaymentBatch;
+import org.compiere.print.ReportCtl;
+import org.compiere.print.ReportEngine;
+import org.compiere.util.CLogger;
+import org.compiere.util.DB;
+import org.compiere.util.Env;
+import org.compiere.util.Ini;
+import org.compiere.util.KeyNamePair;
+import org.compiere.util.Language;
+import org.compiere.util.Msg;
+import org.compiere.util.ValueNamePair;
+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.Filedownload;
+import org.zkoss.zul.Hbox;
+
+public class WPayPrint extends ADForm implements EventListener
+{
+ /** Window No */
+ private int m_WindowNo = 0;
+
+ /** Used Bank Account */
+ private int m_C_BankAccount_ID = -1;
+
+ /** Payment Information */
+ private MPaySelectionCheck[] m_checks = null;
+
+ /** Payment Batch */
+ private MPaymentBatch m_batch = null;
+
+ /** Logger */
+ private static CLogger log = CLogger.getCLogger(WPayPrint.class);
+
+ // Static Variables
+ private Hbox centerPanel = new Hbox();
+ private Hbox southPanel = new Hbox();
+
+ private Button bPrint = new Button();
+ private Button bExport = new Button();
+ private Button bCancel = new Button();
+ private Button bProcess = new Button();//(Msg.getMsg(Env.getCtx(), "VPayPrintProcess"));
+ private Label lPaySelect = new Label();
+ private Listbox fPaySelect = new Listbox();
+ private Label lBank = new Label();
+ private Label fBank = new Label();
+ private Label lPaymentRule = new Label();
+ private Listbox fPaymentRule = new Listbox();
+ private Label lDocumentNo = new Label();
+ private Textbox fDocumentNo = new Textbox();
+ private Label lNoPayments = new Label();
+ private Label fNoPayments = new Label();
+ private Label lBalance = new Label();
+ private Textbox fBalance = new Textbox();
+ private Label lCurrency = new Label();
+ private Label fCurrency = new Label();
+
+ public WPayPrint()
+ {
+ init(super.m_windowNo);
+ }
+
+ public void init (int WindowNo)
+ {
+ log.info("");
+ m_WindowNo = WindowNo;
+
+ try
+ {
+ jbInit();
+ dynInit();
+
+ this.appendChild(centerPanel);
+ this.appendChild(southPanel);
+
+ fPaySelect.setSelectedIndex(0);
+ loadPaySelectInfo();
+ }
+ catch(Exception e)
+ {
+ log.log(Level.SEVERE, "", e);
+ }
+ } // init
+
+ /**
+ * Static Init
+ * @throws Exception
+ */
+ private void jbInit() throws Exception
+ {
+ fPaySelect.setRows(1);
+ fPaySelect.setMold("select");
+
+ fPaymentRule.setRows(1);
+ fPaymentRule.setMold("select");
+
+ bCancel.setImage("/images/Cancel24.gif");
+ bPrint.setImage("/images/Print24.gif");
+ bExport.setImage("/images/ExportX24.gif");
+
+ bPrint.addEventListener(Events.ON_CLICK, this);
+ bExport.addEventListener(Events.ON_CLICK, this);
+ bCancel.addEventListener(Events.ON_CLICK, this);
+
+ bProcess.setLabel(Msg.getMsg(Env.getCtx(), "EFT"));
+ bProcess.setEnabled(false);
+ bProcess.addEventListener(Events.ON_CLICK, this);
+
+ lPaySelect.setValue(Msg.translate(Env.getCtx(), "C_PaySelection_ID"));
+ fPaySelect.addEventListener(Events.ON_SELECT, this);
+
+ lBank.setValue(Msg.translate(Env.getCtx(), "C_BankAccount_ID"));
+
+ lPaymentRule.setValue(Msg.translate(Env.getCtx(), "PaymentRule"));
+ fPaymentRule.addEventListener(Events.ON_SELECT, this);
+
+ lDocumentNo.setValue(Msg.translate(Env.getCtx(), "DocumentNo"));
+ lNoPayments.setValue(Msg.getMsg(Env.getCtx(), "NoOfPayments"));
+ fNoPayments.setValue("0");
+ lBalance.setValue(Msg.translate(Env.getCtx(), "CurrentBalance"));
+ fBalance.setEnabled(false);
+ lCurrency.setValue(Msg.translate(Env.getCtx(), "C_Currency_ID"));
+
+ Hbox boxPaySelect = new Hbox();
+
+ fPaySelect.setWidth("100%");
+
+ boxPaySelect.setWidth("100%");
+ boxPaySelect.setWidths("40%, 60%");
+ boxPaySelect.appendChild(lPaySelect);
+ boxPaySelect.appendChild(fPaySelect);
+
+ Hbox boxBank = new Hbox();
+ boxBank.setWidth("100%");
+ boxBank.setWidths("40%, 60%");
+ boxBank.appendChild(lBank);
+ boxBank.appendChild(fBank);
+
+ Hbox boxPaymentRule = new Hbox();
+ boxPaymentRule.setWidth("100%");
+ boxPaymentRule.setWidths("40%, 60%");
+ boxPaymentRule.appendChild(lPaymentRule);
+ boxPaymentRule.appendChild(fPaymentRule);
+
+ Hbox boxDocNo = new Hbox();
+ boxDocNo.setWidth("100%");
+ boxDocNo.setWidths("40%, 60%");
+ boxDocNo.appendChild(lDocumentNo);
+ boxDocNo.appendChild(fDocumentNo);
+
+ Hbox boxNoPayments = new Hbox();
+ boxNoPayments.setWidth("100%");
+ boxNoPayments.setWidths("50%, 50%");
+ boxNoPayments.appendChild(lNoPayments);
+ boxNoPayments.appendChild(fNoPayments);
+
+ Hbox boxBalance = new Hbox();
+ boxBalance.setWidth("100%");
+ boxBalance.setWidths("50%, 50%");
+ boxBalance.appendChild(lBalance);
+ boxBalance.appendChild(fBalance);
+
+ Hbox boxCurrency = new Hbox();
+ boxCurrency.setWidth("100%");
+ boxCurrency.setWidths("50%, 50%");
+ boxCurrency.appendChild(lCurrency);
+ boxCurrency.appendChild(fCurrency);
+
+ centerPanel.setWidth("100%");
+ centerPanel.setWidths("65%, 35%");
+
+ VerticalBox vBox1 = new VerticalBox();
+ vBox1.setWidth("100%");
+ vBox1.appendChild(boxPaySelect);
+ vBox1.appendChild(boxBank);
+ vBox1.appendChild(boxPaymentRule);
+ vBox1.appendChild(boxDocNo);
+
+ VerticalBox vBox2 = new VerticalBox();
+ vBox2.setWidth("100%");
+ vBox2.appendChild(new Label(""));
+ vBox2.appendChild(boxBalance);
+ vBox2.appendChild(boxCurrency);
+ vBox2.appendChild(boxNoPayments);
+
+ centerPanel.appendChild(vBox1);
+ centerPanel.appendChild(vBox2);
+
+ southPanel.appendChild(bCancel);
+ southPanel.appendChild(bExport);
+ southPanel.appendChild(bPrint);
+ southPanel.appendChild(bProcess);
+ } // WPayPrint
+
+ /**
+ * Dynamic Init
+ */
+
+ private void dynInit()
+ {
+ log.config("");
+ int AD_Client_ID = Env.getAD_Client_ID(Env.getCtx());
+
+ // Load PaySelect
+ String sql = "SELECT C_PaySelection_ID, Name || ' - ' || TotalAmt FROM C_PaySelection "
+ + "WHERE AD_Client_ID=? AND Processed='Y' AND IsActive='Y'"
+ + "ORDER BY PayDate DESC";
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql, null);
+ pstmt.setInt(1, AD_Client_ID);
+ ResultSet rs = pstmt.executeQuery();
+
+ while (rs.next())
+ {
+ KeyNamePair pp = new KeyNamePair(rs.getInt(1), rs.getString(2));
+ fPaySelect.appendItem(pp.getName(), pp);
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql, e);
+ }
+
+ if (fPaySelect.getItemCount() == 0)
+ FDialog.info(m_WindowNo, this, "VPayPrintNoRecords");
+ } // dynInit
+
+ /**
+ * Set Payment Selection
+ * @param C_PaySelection_ID id
+ */
+ public void setPaySelection (int C_PaySelection_ID)
+ {
+ if (C_PaySelection_ID == 0)
+ return;
+ //
+ for (int i = 0; i < fPaySelect.getItemCount(); i++)
+ {
+ ListItem listitem = fPaySelect.getItemAtIndex(i);
+
+ KeyNamePair pp = null;
+
+ if (listitem != null)
+ pp = (KeyNamePair)listitem.getValue();
+
+ if (pp.getKey() == C_PaySelection_ID)
+ {
+ fPaySelect.setSelectedIndex(i);
+ return;
+ }
+ }
+ } // setsetPaySelection
+
+
+ /**************************************************************************
+ * Action Listener
+ * @param e event
+ */
+
+ public void onEvent(Event e)
+ {
+ if (e.getTarget() == fPaySelect)
+ loadPaySelectInfo();
+ else if (e.getTarget() == fPaymentRule)
+ loadPaymentRuleInfo();
+ else if (e.getTarget() == bCancel)
+ SessionManager.getAppDesktop().removeWindow();
+ else if (e.getTarget() == bExport)
+ cmd_export();
+ else if (e.getTarget() == bProcess)
+ cmd_EFT();
+ else if (e.getTarget() == bPrint)
+ cmd_print();
+ } // actionPerformed
+
+ /**
+ * PaySelect changed - load Bank
+ */
+
+ private void loadPaySelectInfo()
+ {
+ log.info( "VPayPrint.loadPaySelectInfo");
+ if (fPaySelect.getSelectedIndex() == -1)
+ return;
+
+ // load Banks from PaySelectLine
+
+ ListItem listitem = fPaySelect.getSelectedItem();
+
+ KeyNamePair key = null;
+
+ if (listitem != null)
+ key = (KeyNamePair)listitem.getValue();
+
+ int C_PaySelection_ID = key.getKey();
+ m_C_BankAccount_ID = -1;
+ String sql = "SELECT ps.C_BankAccount_ID, b.Name || ' ' || ba.AccountNo," // 1..2
+ + " c.ISO_Code, CurrentBalance " // 3..4
+ + "FROM C_PaySelection ps"
+ + " INNER JOIN C_BankAccount ba ON (ps.C_BankAccount_ID=ba.C_BankAccount_ID)"
+ + " INNER JOIN C_Bank b ON (ba.C_Bank_ID=b.C_Bank_ID)"
+ + " INNER JOIN C_Currency c ON (ba.C_Currency_ID=c.C_Currency_ID) "
+ + "WHERE ps.C_PaySelection_ID=? AND ps.Processed='Y' AND ba.IsActive='Y'";
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql, null);
+ pstmt.setInt(1, C_PaySelection_ID);
+ ResultSet rs = pstmt.executeQuery();
+
+ if (rs.next())
+ {
+ m_C_BankAccount_ID = rs.getInt(1);
+ fBank.setValue(rs.getString(2));
+ fCurrency.setValue(rs.getString(3));
+ fBalance.setValue(rs.getBigDecimal(4).toString());
+ }
+ else
+ {
+ m_C_BankAccount_ID = -1;
+ fBank.setValue("");
+ fCurrency.setValue("");
+ fBalance.setValue("0");
+ log.log(Level.SEVERE, "No active BankAccount for C_PaySelection_ID=" + C_PaySelection_ID);
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql, e);
+ }
+
+ loadPaymentRule();
+ } // loadPaySelectInfo
+
+ /**
+ * Bank changed - load PaymentRule
+ */
+ private void loadPaymentRule()
+ {
+ log.info("");
+
+ if (m_C_BankAccount_ID == -1)
+ return;
+
+ // load PaymentRule for Bank
+
+ ListItem listitem = fPaySelect.getSelectedItem();
+
+ KeyNamePair kp = null;
+
+ if (listitem != null)
+ kp = (KeyNamePair)listitem.getValue();
+ else
+ return;
+
+ int C_PaySelection_ID = kp.getKey();
+ fPaymentRule.getChildren().clear();
+ int AD_Reference_ID = 195; // MLookupInfo.getAD_Reference_ID("All_Payment Rule");
+ Language language = Language.getLanguage(Env.getAD_Language(Env.getCtx()));
+ MLookupInfo info = MLookupFactory.getLookup_List(language, AD_Reference_ID);
+ String sql = info.Query.substring(0, info.Query.indexOf(" ORDER BY"))
+ + " AND " + info.KeyColumn
+ + " IN (SELECT PaymentRule FROM C_PaySelectionCheck WHERE C_PaySelection_ID=?) "
+ + info.Query.substring(info.Query.indexOf(" ORDER BY"));
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql, null);
+ pstmt.setInt(1, C_PaySelection_ID);
+ ResultSet rs = pstmt.executeQuery();
+
+ while (rs.next())
+ {
+ ValueNamePair pp = new ValueNamePair(rs.getString(2), rs.getString(3));
+ fPaymentRule.appendItem(pp.getName(), pp);
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql, e);
+ }
+
+ if (fPaymentRule.getItemCount() == 0)
+ log.config("PaySel=" + C_PaySelection_ID + ", BAcct=" + m_C_BankAccount_ID + " - " + sql);
+
+ fPaymentRule.setSelectedIndex(0);
+
+ loadPaymentRuleInfo();
+ } // loadPaymentRule
+
+ /**
+ * PaymentRule changed - load DocumentNo, NoPayments,
+ * enable/disable EFT, Print
+ */
+
+ private void loadPaymentRuleInfo()
+ {
+ ListItem listitem = fPaymentRule.getSelectedItem();
+
+ ValueNamePair pp = null;
+
+ if (listitem != null)
+ pp = (ValueNamePair)listitem.getValue();
+
+ if (pp == null)
+ return;
+
+ String PaymentRule = pp.getValue();
+
+ log.info("PaymentRule=" + PaymentRule);
+ fNoPayments.setValue(" ");
+
+ listitem = fPaySelect.getSelectedItem();
+
+ KeyNamePair kp = null;
+
+ if (listitem != null)
+ kp = (KeyNamePair)listitem.getValue();
+
+ int C_PaySelection_ID = kp.getKey();
+
+ String sql = "SELECT COUNT(*) "
+ + "FROM C_PaySelectionCheck "
+ + "WHERE C_PaySelection_ID=?";
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql, null);
+ pstmt.setInt(1, C_PaySelection_ID);
+ ResultSet rs = pstmt.executeQuery();
+
+ if (rs.next())
+ fNoPayments.setValue(String.valueOf(rs.getInt(1)));
+
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql, e);
+ }
+
+ bProcess.setEnabled(PaymentRule.equals("T"));
+
+ // DocumentNo
+ sql = "SELECT CurrentNext "
+ + "FROM C_BankAccountDoc "
+ + "WHERE C_BankAccount_ID=? AND PaymentRule=? AND IsActive='Y'";
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql, null);
+ pstmt.setInt(1, m_C_BankAccount_ID);
+ pstmt.setString(2, PaymentRule);
+ ResultSet rs = pstmt.executeQuery();
+
+ if (rs.next())
+ fDocumentNo.setValue(new Integer(rs.getInt(1)).toString());
+ else
+ {
+ log.log(Level.SEVERE, "VPayPrint.loadPaymentRuleInfo - No active BankAccountDoc for C_BankAccount_ID="
+ + m_C_BankAccount_ID + " AND PaymentRule=" + PaymentRule);
+ FDialog.error(m_WindowNo, this, "VPayPrintNoDoc");
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql, e);
+ }
+ } // loadPaymentRuleInfo
+
+ /**************************************************************************
+ * Export payments to file
+ */
+
+ private void cmd_export()
+ {
+ ListItem listitem = fPaymentRule.getSelectedItem();
+
+ ValueNamePair vp = null;
+
+ if (listitem != null)
+ vp = (ValueNamePair)listitem.getValue();
+
+ String PaymentRule = null;
+
+ if (vp != null)
+ PaymentRule = vp.getValue();
+
+ log.info(PaymentRule);
+
+ if (!getChecks(PaymentRule))
+ return;
+
+ File file = null;
+ FileInputStream fstream = null;
+ int no = -1;
+
+ try
+ {
+ file = File.createTempFile("temp", "txt");
+ no = MPaySelectionCheck.exportToFile(m_checks, file);
+ fstream = new FileInputStream(file);
+ }
+ catch (IOException e1)
+ {
+ e1.printStackTrace();
+ }
+
+ Filedownload.save(fstream, "", file.getAbsolutePath());
+
+ // Create File
+
+ FDialog.info(m_WindowNo, this, "Saved",
+ file.getAbsolutePath() + "\n"
+ + Msg.getMsg(Env.getCtx(), "NoOfLines") + "=" + no);
+
+ if (FDialog.ask(m_WindowNo, this, "VPayPrintSuccess?"))
+ {
+ // int lastDocumentNo =
+ MPaySelectionCheck.confirmPrint (m_checks, m_batch);
+ // document No not updated
+ }
+
+ SessionManager.getAppDesktop().removeWindow();
+ } // cmd_export
+
+ /**
+ * Create EFT payment
+ */
+
+ private void cmd_EFT()
+ {
+ ListItem listitem = fPaymentRule.getSelectedItem();
+
+ ValueNamePair vp = null;
+
+ if (listitem != null)
+ vp = (ValueNamePair)listitem.getValue();
+
+ String PaymentRule = vp.getValue();
+ log.info(PaymentRule);
+
+ if (!getChecks(PaymentRule))
+ return;
+
+ SessionManager.getAppDesktop().removeWindow();
+ } // cmd_EFT
+
+ /**
+ * Print Checks and/or Remittance
+ */
+
+ private void cmd_print()
+ {
+ ListItem listitem = fPaymentRule.getSelectedItem();
+
+ ValueNamePair vp = null;
+
+ if (listitem != null)
+ vp = (ValueNamePair)listitem.getValue();
+
+ String PaymentRule = vp.getValue();
+ log.info(PaymentRule);
+
+ if (!getChecks(PaymentRule))
+ return;
+
+ boolean somethingPrinted = false;
+ boolean directPrint = !Ini.isPropertyBool(Ini.P_PRINTPREVIEW);
+
+ // for all checks
+ for (int i = 0; i < m_checks.length; i++)
+ {
+ MPaySelectionCheck check = m_checks[i];
+ // ReportCtrl will check BankAccountDoc for PrintFormat
+ boolean ok = ReportCtl.startDocumentPrint(ReportEngine.CHECK, check.get_ID(), null, super.m_windowNo, directPrint);
+ if (!somethingPrinted && ok)
+ somethingPrinted = true;
+ }
+
+ // Confirm Print and Update BankAccountDoc
+ if (somethingPrinted && FDialog.ask(m_WindowNo, this, "VPayPrintSuccess?"))
+ {
+ int lastDocumentNo = MPaySelectionCheck.confirmPrint (m_checks, m_batch);
+ if (lastDocumentNo != 0)
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append("UPDATE C_BankAccountDoc SET CurrentNext=").append(++lastDocumentNo)
+ .append(" WHERE C_BankAccount_ID=").append(m_C_BankAccount_ID)
+ .append(" AND PaymentRule='").append(PaymentRule).append("'");
+ DB.executeUpdate(sb.toString(), null);
+ }
+ } // confirm
+
+ if (FDialog.ask(m_WindowNo, this, "VPayPrintPrintRemittance"))
+ {
+ for (int i = 0; i < m_checks.length; i++)
+ {
+ MPaySelectionCheck check = m_checks[i];
+ ReportCtl.startDocumentPrint(ReportEngine.REMITTANCE, check.get_ID(), null, super.m_windowNo, directPrint);
+ }
+ } // remittance
+
+ SessionManager.getAppDesktop().removeWindow();
+ } // cmd_print
+
+ /**************************************************************************
+ * Get Checks
+ * @param PaymentRule Payment Rule
+ * @return true if payments were created
+ */
+
+ private boolean getChecks(String PaymentRule)
+ {
+ // do we have values
+ if (fPaySelect.getSelectedIndex() == -1 || m_C_BankAccount_ID == -1
+ || fPaymentRule.getSelectedIndex() == -1 || fDocumentNo.getValue() == null)
+ {
+ FDialog.error(m_WindowNo, this, "VPayPrintNoRecords",
+ "(" + Msg.translate(Env.getCtx(), "C_PaySelectionLine_ID") + "=0)");
+
+ return false;
+ }
+
+ // get data
+
+ ListItem listitem = fPaySelect.getSelectedItem();
+
+ KeyNamePair kp = null;
+
+ if (listitem != null)
+ kp = (KeyNamePair)listitem.getValue();
+
+ int C_PaySelection_ID = kp.getKey();
+
+ int startDocumentNo = new Integer(fDocumentNo.getValue());
+
+ log.config("C_PaySelection_ID=" + C_PaySelection_ID + ", PaymentRule=" + PaymentRule + ", DocumentNo=" + startDocumentNo);
+
+ // get Selections
+ m_checks = MPaySelectionCheck.get(C_PaySelection_ID, PaymentRule, startDocumentNo, null);
+
+ if (m_checks == null || m_checks.length == 0)
+ {
+ FDialog.error(m_WindowNo, this, "VPayPrintNoRecords",
+ "(" + Msg.translate(Env.getCtx(), "C_PaySelectionLine_ID") + " #0");
+ return false;
+ }
+ m_batch = MPaymentBatch.getForPaySelection (Env.getCtx(), C_PaySelection_ID, null);
+
+ return true;
+ } // getChecks
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WPaySelect.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WPaySelect.java
new file mode 100644
index 0000000000..0e311f8ef0
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WPaySelect.java
@@ -0,0 +1,840 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
+ * or via info@compiere.org or http://www.compiere.org/license.html *
+ *****************************************************************************/
+
+/**
+ * 2007, Modified by Posterita Ltd.
+ */
+
+package org.adempiere.webui.apps.form;
+
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.text.DecimalFormat;
+import java.util.List;
+import java.util.Properties;
+import java.util.logging.Level;
+
+import org.adempiere.webui.apps.ProcessModalDialog;
+import org.adempiere.webui.component.Button;
+import org.adempiere.webui.component.Checkbox;
+import org.adempiere.webui.component.Datebox;
+import org.adempiere.webui.component.Grid;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.ListItem;
+import org.adempiere.webui.component.Listbox;
+import org.adempiere.webui.component.Row;
+import org.adempiere.webui.component.Rows;
+import org.adempiere.webui.component.WListbox;
+import org.adempiere.webui.event.WTableModelEvent;
+import org.adempiere.webui.event.WTableModelListener;
+import org.adempiere.webui.panel.ADForm;
+import org.adempiere.webui.window.FDialog;
+
+import org.compiere.minigrid.ColumnInfo;
+import org.compiere.minigrid.IDColumn;
+import org.compiere.model.MLookupFactory;
+import org.compiere.model.MLookupInfo;
+import org.compiere.model.MPaySelection;
+import org.compiere.model.MPaySelectionLine;
+import org.compiere.model.MRole;
+import org.compiere.model.X_C_Order;
+import org.compiere.model.X_C_PaySelection;
+import org.compiere.util.CLogger;
+import org.compiere.util.DB;
+import org.compiere.util.DisplayType;
+import org.compiere.util.Env;
+import org.compiere.util.KeyNamePair;
+import org.compiere.util.Language;
+import org.compiere.util.Msg;
+import org.compiere.util.ValueNamePair;
+
+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.Hbox;
+import org.zkoss.zul.Listcell;
+import org.zkoss.zul.Separator;
+
+/**
+ * Pay Selection Manual Custom Form : Based on VPaySelect
+ *
+ * @author Niraj Sohun
+ * @date Jun 25, 2007
+ */
+public class WPaySelect extends ADForm implements EventListener, WTableModelListener
+{
+ private static final long serialVersionUID = 1L;
+
+ /** Logger */
+ private static CLogger log = CLogger.getCLogger(WPaySelect.class);
+
+ // Input Part of Form
+
+ private Grid parameters;
+ private Rows rows;
+ private Row row1;
+ private Row row2;
+ private Row row3;
+
+ // Labels
+
+ private Label lblBalanceAmt;
+ private Label lblBottom;
+
+ // Components
+
+ private Listbox lstBankAccount;
+ private Listbox lstBusinessPartner;
+ private Checkbox dueInvoices;
+ private Datebox date;
+ private Listbox lstPaymentRule;
+ private Button refresh;
+ private Button btnProcess;
+
+ // Data Grid
+
+ private WListbox dataTable;
+
+ private int m_AD_Client_ID = 0;
+ private String m_sql = "";
+ private DecimalFormat m_format = DisplayType.getNumberFormat(DisplayType.Amount);
+ private Float currentBalance;
+
+ /**
+ *
+ *
+ */
+ public WPaySelect()
+ {
+ init();
+ }
+
+ /**
+ *
+ *
+ */
+ private void init()
+ {
+ dataTable = new WListbox();
+ dataTable.setWidth("700px");
+ dataTable.setMultiple(true);
+
+ // Input Part of Form
+
+ parameters = new Grid();
+ parameters.setWidth("700px");
+ parameters.setAlign("center");
+
+ rows = new Rows();
+ row1 = new Row();
+ row2 = new Row();
+ row3 = new Row();
+
+ // Components
+
+ lblBalanceAmt = new Label();
+ lblBottom = new Label();
+
+ lstBankAccount = new Listbox();
+ lstBankAccount.setWidth("150px");
+ lstBankAccount.setRows(1);
+ lstBankAccount.setMold("select");
+ lstBankAccount.addEventListener(Events.ON_SELECT, this);
+
+ lstBusinessPartner = new Listbox();
+ lstBusinessPartner.setWidth("150px");
+ lstBusinessPartner.setRows(1);
+ lstBusinessPartner.setMold("select");
+ lstBusinessPartner.addEventListener(Events.ON_SELECT, this);
+
+ dueInvoices = new Checkbox();
+ dueInvoices.setLabel(Msg.getMsg(Env.getCtx(), "OnlyDue"));
+ dueInvoices.addEventListener(Events.ON_SELECT, this);
+
+ date = new Datebox();
+ date.setWidth("150px");
+ date.setValue(new Timestamp(System.currentTimeMillis()));
+ date.addEventListener(Events.ON_SELECT, this);
+
+ lstPaymentRule = new Listbox();
+ lstPaymentRule.setWidth("150px");
+ lstPaymentRule.setWidth("150px");
+ lstPaymentRule.setRows(1);
+ lstPaymentRule.setMold("select");
+ lstPaymentRule.addEventListener(Events.ON_SELECT, this);
+
+ refresh = new Button();
+ refresh.setImage("/images/Refresh24.gif");
+ refresh.addEventListener(Events.ON_CLICK, this);
+
+ btnProcess = new Button();
+ btnProcess.setImage("/images/Process24.gif");
+ btnProcess.setEnabled(false);
+ btnProcess.addEventListener(Events.ON_CLICK, this);
+
+ display();
+ }
+
+ /**
+ *
+ *
+ */
+
+ private void display()
+ {
+ row1.appendChild(new Label("Bank Account"));
+ row1.appendChild(lstBankAccount);
+
+ row1.appendChild(new Label("Current Balance"));
+ row1.appendChild(lblBalanceAmt);
+
+ row2.setSpans(",2,");
+ row2.appendChild(new Label("Business Partner"));
+ row2.appendChild(lstBusinessPartner);
+
+ row2.appendChild(dueInvoices);
+
+ row3.appendChild(new Label("Payment Date"));
+ row3.appendChild(date);
+ row3.appendChild(new Label("Payment Rule"));
+ row3.appendChild(lstPaymentRule);
+
+ rows.appendChild(row1);
+ rows.appendChild(row2);
+ rows.appendChild(row3);
+ parameters.appendChild(rows);
+
+ Hbox mainBox = new Hbox();
+ mainBox.setWidth("700px");
+
+ Hbox hboxButtons = new Hbox();
+ hboxButtons.setWidth("80px");
+ hboxButtons.appendChild(btnProcess);
+ hboxButtons.appendChild(refresh);
+
+ Hbox hLbl = new Hbox();
+ hLbl.appendChild(lblBottom);
+
+ mainBox.appendChild(hboxButtons);
+ mainBox.appendChild(hLbl);
+
+ this.setHeight("710px");
+ this.setWidth("100%");
+ this.setBorder("normal");
+ this.appendChild(parameters);
+ this.appendChild(new Separator());
+ this.appendChild(dataTable);
+ this.appendChild(new Separator());
+ this.appendChild(mainBox);
+
+ populateBankAccount();
+ populateBusinessPartner();
+ populateGrid();
+ }
+
+ /**
+ *
+ *
+ */
+ private void process()
+ {
+ int adProcessId = 155;
+ String trxName = null;
+
+ calculateSelection();
+
+ MPaySelection m_ps = new MPaySelection(Env.getCtx(), 0, trxName);
+
+ ListItem payRule = lstPaymentRule.getSelectedItem();
+ Timestamp payDate = (Timestamp)date.getValue();
+
+ m_ps.setName (Msg.getMsg(Env.getCtx(), "WPaySelect")
+ + " - " + ((ValueNamePair)payRule.getValue()).getName()
+ + " - " + payDate);
+
+ m_ps.setPayDate (payDate);
+
+ BankInfo bi = getSelectedBankAccount();
+ m_ps.setC_BankAccount_ID(bi.C_BankAccount_ID);
+ m_ps.setIsApproved(true);
+
+ if (!m_ps.save())
+ {
+ FDialog.error(super.m_windowNo, this, "SaveError", Msg.translate(Env.getCtx(), "C_PaySelection_ID"));
+ m_ps = null;
+ return;
+ }
+
+ // Create Lines
+
+ int rows = dataTable.getItemCount();
+ int line = 0;
+
+ ListItem pyRule = lstPaymentRule.getSelectedItem();
+ String strPayRule = ((ValueNamePair)pyRule.getValue()).getValue();
+
+ for (int i = 0; i < rows; i++)
+ {
+ if (dataTable.getItemAtIndex(i).isSelected())
+ {
+ line += 10;
+
+ MPaySelectionLine psl = new MPaySelectionLine (m_ps, line, strPayRule);
+
+// List celllist = (List)(dataTable.getItemAtIndex(i).getChildren());
+
+// ListCell invID = celllist.get(0);
+// ListCell openAmt = celllist.get(8);
+// ListCell payAmt = celllist.get(9);
+ IDColumn id = (IDColumn)dataTable.getValueAt(i, 0);
+
+ Integer C_Invoice_ID = id.getRecord_ID();
+ BigDecimal OpenAmt = new BigDecimal(dataTable.getValueAt(i, 8).toString());
+ BigDecimal PayAmt = new BigDecimal(dataTable.getValueAt(i, 9).toString());
+
+ boolean isSOTrx = false;
+
+ psl.setInvoice(C_Invoice_ID, isSOTrx, OpenAmt, PayAmt, OpenAmt.subtract(PayAmt));
+
+ if (!psl.save(trxName))
+ {
+ FDialog.error(this.m_windowNo, this, "SaveError", Msg.translate(Env.getCtx(), "C_PaySelectionLine_ID"));
+ return;
+ }
+ log.fine("C_Invoice_ID=" + C_Invoice_ID
+ + ", PayAmt=" + PayAmt);
+ }
+ }
+
+ // Ask to Post it
+
+ if (!FDialog.ask(this.m_windowNo, this, "(" + m_ps.getName() + ")"))
+ {
+ return;
+ }
+
+ ProcessModalDialog msg = new ProcessModalDialog(
+ this, "Payment Selection Manual", null, this.m_windowNo, adProcessId,
+ X_C_PaySelection.Table_ID, m_ps.getC_PaySelection_ID(), true);
+
+ if (msg.isValid())
+ {
+ msg.setTitle("Payment Selection (Manual)");
+ msg.setPage(this.getPage());
+ msg.setClosable(true);
+ msg.setWidth("500px");
+
+ try
+ {
+ msg.doModal();
+ }
+ catch (InterruptedException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private void calculateSelection()
+ {
+ int noSelected = 0;
+ BigDecimal invoiceAmt = new BigDecimal(0.0);
+
+ int rows = dataTable.getRowCount();
+
+ for (int rowIndex = 0; rowIndex < rows; rowIndex++)
+ {
+ // TODO remove this magic number
+ IDColumn id = (IDColumn)dataTable.getValueAt(rowIndex, 0);
+
+ if (id.isSelected())
+ {
+ // TODO remove this magic number
+ BigDecimal amt = (BigDecimal)dataTable.getValueAt(rowIndex, 9);
+ invoiceAmt = invoiceAmt.add(amt);
+ noSelected++;
+ }
+ }
+
+ // Information
+
+ BankInfo bi = getSelectedBankAccount();
+ BigDecimal remaining = bi.Balance.subtract(invoiceAmt);
+
+ StringBuffer info = new StringBuffer();
+ info.append(noSelected).append(" ").append(Msg.getMsg(Env.getCtx(), "Selected")).append(" - ");
+ info.append(m_format.format(invoiceAmt)).append(", ");
+ info.append(Msg.getMsg(Env.getCtx(), "Remaining")).append(" ").append(m_format.format(remaining));
+
+ lblBottom.setValue(info.toString());
+
+ if (noSelected == 0)
+ {
+ btnProcess.setEnabled(false);
+ }
+ else
+ {
+ btnProcess.setEnabled(true);
+ }
+
+ return;
+ }
+
+ /**
+ * Obtain details of the selected bank account
+ *
+ * @return the BankInfo of the selected account
+ */
+ private BankInfo getSelectedBankAccount()
+ {
+ ListItem bankAccountItem = lstBankAccount.getSelectedItem();
+ BankInfo bi = (BankInfo)bankAccountItem.getValue();
+
+ return bi;
+ }
+
+ private void populateBankAccount()
+ {
+ String sql = MRole.getDefault().addAccessSQL(
+ "SELECT ba.C_BankAccount_ID," // 1
+ + "b.Name || ' ' || ba.AccountNo AS Name," // 2
+ + "ba.C_Currency_ID, c.ISO_Code," // 3..4
+ + "ba.CurrentBalance " // 5
+ + "FROM C_Bank b, C_BankAccount ba, C_Currency c "
+ + "WHERE b.C_Bank_ID=ba.C_Bank_ID"
+ + " AND ba.C_Currency_ID=c.C_Currency_ID "
+ + " AND EXISTS (SELECT * FROM C_BankAccountDoc d WHERE d.C_BankAccount_ID=ba.C_BankAccount_ID) "
+ + "ORDER BY 2",
+ "b", MRole.SQL_FULLYQUALIFIED, MRole.SQL_RW);
+
+ BankInfo bi = null;
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql, null);
+ ResultSet rs = pstmt.executeQuery();
+ while (rs.next())
+ {
+ boolean Transfers = false;
+ bi = new BankInfo (rs.getInt(1), rs.getInt(3), rs.getString(2), rs.getString(4), rs.getBigDecimal(5), Transfers);
+ lstBankAccount.appendItem(bi.Name, bi);
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql, e);
+ }
+
+ if (lstBankAccount.getItemCount() == 0)
+ {
+ throw new IllegalStateException("No Bank Account has been found");
+ }
+ else
+ {
+ // Selecting the first item
+ lstBankAccount.setSelectedIndex(0);
+ populatePaymentRule();
+
+ updateCurrentBalance();
+ }
+ }
+
+ private void updateCurrentBalance()
+ {
+ BankInfo bnkInf = getSelectedBankAccount();
+ currentBalance = bnkInf.Balance.floatValue();
+ lblBalanceAmt.setValue(currentBalance.toString() + " " + bnkInf.Currency);
+
+ lblBottom.setValue("");
+ }
+
+ /**
+ * Query the database for Business Partners and populate the Business
+ * Partner combobox with the returned resultset
+ */
+ private void populateBusinessPartner()
+ {
+ KeyNamePair pp = new KeyNamePair(0, "");
+ lstBusinessPartner.appendItem(pp.getName(), pp);
+
+ String sql = MRole.getDefault().addAccessSQL(
+ "SELECT bp.C_BPartner_ID, bp.Name FROM C_BPartner bp", "bp",
+ MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO)
+ + " AND EXISTS (SELECT * FROM C_Invoice i WHERE bp.C_BPartner_ID=i.C_BPartner_ID"
+ + " AND (i.IsSOTrx='N' OR (i.IsSOTrx='Y' AND i.PaymentRule='D'))"
+ + " AND i.IsPaid<>'Y') "
+ + "ORDER BY 2";
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql, null);
+ ResultSet rs = pstmt.executeQuery();
+ while (rs.next())
+ {
+ pp = new KeyNamePair(rs.getInt(1), rs.getString(2));
+ lstBusinessPartner.appendItem(pp.getName(), pp);
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ // TODO need to do something with this exception
+ log.log(Level.SEVERE, sql, e);
+ }
+
+ lstBusinessPartner.setSelectedIndex(0);
+ }
+
+
+ /**
+ * Query the database for Payment Rules and populate the Payment
+ * Rules combobox with the returned resultset
+ */
+ private void populatePaymentRule()
+ {
+ ListItem temp = lstBankAccount.getSelectedItem();
+ BankInfo bankInfo = (BankInfo)temp.getValue();
+
+ if (bankInfo == null)
+ {
+ return;
+ }
+
+ // PaymentRule
+
+ lstPaymentRule.getChildren().clear();
+
+ int AD_Reference_ID = 195; //TODO: Find this reference in the models
+ Language language = Env.getLanguage(Env.getCtx());
+ MLookupInfo info = MLookupFactory.getLookup_List(language, AD_Reference_ID);
+ String sql = info.Query.substring(0, info.Query.indexOf(" ORDER BY"))
+ + " AND " + info.KeyColumn
+ + " IN (SELECT PaymentRule FROM C_BankAccountDoc WHERE C_BankAccount_ID=?) "
+ + info.Query.substring(info.Query.indexOf(" ORDER BY"));
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql, null);
+ pstmt.setInt(1, bankInfo.C_BankAccount_ID);
+ ResultSet rs = pstmt.executeQuery();
+ ValueNamePair vp = null;
+ while (rs.next())
+ {
+ vp = new ValueNamePair(rs.getString(2), rs.getString(3)); // returns also not active
+ lstPaymentRule.appendItem(vp.getName(), vp);
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql, e);
+ }
+
+ lstPaymentRule.setSelectedIndex(0);
+ }
+
+ /**
+ * Prepare the data table
+ *
+ */
+ private void prepareGrid()
+ {
+ // FROM VPaySelect.dynInit
+
+ // MiniTable Parameters
+
+ Properties ctx = Env.getCtx();
+
+ ColumnInfo[] columnInfo = new ColumnInfo[10];
+ columnInfo[0] = new ColumnInfo(" ", "i.C_Invoice_ID", IDColumn.class, false, false, null);
+ columnInfo[1] = new ColumnInfo(Msg.translate(ctx, "DueDate"), "paymentTermDueDate(i.C_PaymentTerm_ID, i.DateInvoiced) AS DateDue", Timestamp.class, true, true, null);
+ columnInfo[2] = new ColumnInfo(Msg.translate(ctx, "C_BPartner_ID"), "bp.Name", KeyNamePair.class, true, false, "i.C_BPartner_ID");
+ columnInfo[3] = new ColumnInfo(Msg.translate(ctx, "DocumentNo"), "i.DocumentNo", String.class);
+ columnInfo[4] = new ColumnInfo(Msg.translate(ctx, "C_Currency_ID"), "c.ISO_Code", KeyNamePair.class, true, false, "i.C_Currency_ID");
+ columnInfo[5] = new ColumnInfo(Msg.translate(ctx, "GrandTotal"), "i.GrandTotal", BigDecimal.class);
+ columnInfo[6] = new ColumnInfo(Msg.translate(ctx, "DiscountAmt"), "paymentTermDiscount(i.GrandTotal,i.C_Currency_ID,i.C_PaymentTerm_ID,i.DateInvoiced, ?)", BigDecimal.class);
+ columnInfo[7] = new ColumnInfo(Msg.getMsg(ctx, "DiscountDate"), "SysDate-paymentTermDueDays(i.C_PaymentTerm_ID,i.DateInvoiced,SysDate)", Timestamp.class);
+ columnInfo[8] = new ColumnInfo(Msg.getMsg(ctx, "AmountDue"), "currencyConvert(invoiceOpen(i.C_Invoice_ID,i.C_InvoicePaySchedule_ID),i.C_Currency_ID, ?,?,i.C_ConversionType_ID, i.AD_Client_ID,i.AD_Org_ID)", BigDecimal.class);
+ columnInfo[9] = new ColumnInfo(Msg.getMsg(ctx, "AmountPay"), "currencyConvert(invoiceOpen(i.C_Invoice_ID,i.C_InvoicePaySchedule_ID)-paymentTermDiscount(i.GrandTotal,i.C_Currency_ID,i.C_PaymentTerm_ID,i.DateInvoiced, ?),i.C_Currency_ID, ?,?,i.C_ConversionType_ID, i.AD_Client_ID,i.AD_Org_ID)", BigDecimal.class);
+
+ String fromClause = "C_Invoice_v i"
+ + " INNER JOIN C_BPartner bp ON (i.C_BPartner_ID=bp.C_BPartner_ID)"
+ + " INNER JOIN C_Currency c ON (i.C_Currency_ID=c.C_Currency_ID)"
+ + " INNER JOIN C_PaymentTerm p ON (i.C_PaymentTerm_ID=p.C_PaymentTerm_ID)";
+
+ String whereClause = "i.IsSOTrx=? AND IsPaid='N'"
+ + " AND NOT EXISTS (SELECT * FROM C_PaySelectionLine psl"
+ + " WHERE i.C_Invoice_ID=psl.C_Invoice_ID AND psl.C_PaySelectionCheck_ID IS NOT NULL)"
+ + " AND i.DocStatus IN ('CO','CL')"
+ + " AND i.AD_Client_ID=?";
+
+ boolean multiSelect = true;
+
+ String tableName = "i";
+
+ // Create MiniTable
+
+ m_sql = dataTable.prepareTable(columnInfo, fromClause, whereClause, multiSelect,tableName);
+
+ dataTable.getModel().addTableModelListener(this);
+
+ //TODO
+ //fieldPayDate.setMandatory(true);
+
+ m_AD_Client_ID = Env.getAD_Client_ID(Env.getCtx());
+ }
+
+ private void populateGrid()
+ {
+ prepareGrid();
+
+ // FROM VPaySelect.loadTableInfo
+
+ if (m_sql == null)
+ {
+ return;
+ }
+
+ String sql = m_sql;
+
+ // Parameters
+
+ Timestamp payDate = (Timestamp)date.getValue();
+ dataTable.setColorCompare(payDate);
+ log.config("PayDate=" + payDate);
+
+ // Bank Account
+ BankInfo bi = getSelectedBankAccount();
+
+ String isSOTrx = "N";
+
+ // Payment Rule
+
+ ListItem selectedRule = lstPaymentRule.getSelectedItem();
+ ValueNamePair vp = (ValueNamePair)selectedRule.getValue();
+
+ if (vp != null && X_C_Order.PAYMENTRULE_DirectDebit.equals(vp.getValue()))
+ {
+ isSOTrx = "Y";
+ sql += " AND i.PaymentRule='" + X_C_Order.PAYMENTRULE_DirectDebit + "'";
+ }
+
+ if (dueInvoices.isChecked())
+ {
+ sql += " AND paymentTermDueDate(i.C_PaymentTerm_ID, i.DateInvoiced) <= ?";
+ }
+
+ // Business Partner
+
+ ListItem selectedBPartner = lstBusinessPartner.getSelectedItem();
+ KeyNamePair pp = (KeyNamePair)selectedBPartner.getValue();
+
+ int C_BPartner_ID = pp.getKey();
+
+ if (C_BPartner_ID != 0)
+ sql += " AND i.C_BPartner_ID=?";
+
+ sql += " ORDER BY 2,3";
+
+ log.finest(sql + " - C_Currecny_ID=" + bi.C_Currency_ID + ", C_BPartner_ID=" + C_BPartner_ID);
+
+ //int m_AD_Client_ID = Env.getAD_Client_ID(Env.getCtx());
+
+ // Get Open Invoices
+
+ try
+ {
+ int columnIndex = 1;
+ PreparedStatement pstmt = DB.prepareStatement(sql, null);
+ pstmt.setTimestamp(columnIndex++, payDate); // DiscountAmt
+ pstmt.setInt(columnIndex++, bi.C_Currency_ID); // DueAmt
+ pstmt.setTimestamp(columnIndex++, payDate);
+ pstmt.setTimestamp(columnIndex++, payDate); // PayAmt
+ pstmt.setInt(columnIndex++, bi.C_Currency_ID);
+ pstmt.setTimestamp(columnIndex++, payDate);
+ pstmt.setString(columnIndex++, isSOTrx); // IsSOTrx
+ pstmt.setInt(columnIndex++, m_AD_Client_ID); // Client
+
+ if (dueInvoices.isChecked())
+ {
+ pstmt.setTimestamp(columnIndex++, payDate);
+ }
+
+ if (C_BPartner_ID != 0)
+ {
+ pstmt.setInt(columnIndex++, C_BPartner_ID);
+ }
+
+ ResultSet rs = pstmt.executeQuery();
+ dataTable.loadTable(rs);
+ rs.close();
+ pstmt.close();
+
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql, e);
+ }
+ }
+
+ public void onEvent(Event evt) throws Exception
+ {
+ if (evt != null)
+ {
+ if (evt.getTarget() == lstBankAccount)
+ {
+ populatePaymentRule();
+ updateCurrentBalance();
+ dataTable.getItems().clear();
+ populateGrid();
+ }
+
+ if (evt.getTarget() == lstBusinessPartner)
+ {
+ dataTable.getItems().clear();
+ populateGrid();
+ }
+
+ if (evt.getTarget() == lstPaymentRule)
+ {
+ dataTable.getItems().clear();
+ populateGrid();
+ }
+
+ if (evt.getTarget() == dueInvoices)
+ {
+ dataTable.getItems().clear();
+ populateGrid();
+ }
+
+ if (evt.getTarget() == date)
+ {
+ dataTable.getItems().clear();
+ populateGrid();
+ }
+
+ if (evt.getTarget() == refresh)
+ {
+ dataTable.clear();
+ populateGrid();
+ }
+
+ if (evt.getTarget() == btnProcess)
+ {
+ if (dataTable.getSelectedCount() <= 0)
+ {
+ btnProcess.setEnabled(false);
+ throw new IllegalArgumentException("No records selected");
+ }
+
+ process();
+ }
+
+ if (evt.getTarget() instanceof ListItem)
+ {
+ btnProcess.setEnabled(true);
+
+ ListItem lstitem = (ListItem)(evt.getTarget());
+
+ if (lstitem.isSelected())
+ {
+ dataTable.addItemToSelection(lstitem);
+ }
+ Integer size = dataTable.getSelectedCount();
+
+ Float amt = calculateTotalAmount();
+ Float remaining = currentBalance - amt;
+
+ lblBottom.setValue(size.toString() + " Selected :: " + amt.toString() + ", Remaining " + remaining.toString());
+ }
+ }
+ }
+
+ private Float calculateTotalAmount()
+ {
+ Float amount = new Float(0);
+
+ for (int i = 0; i < dataTable.getItemCount(); i++)
+ {
+ if (dataTable.getItemAtIndex(i).isSelected())
+ {
+ List celllist = (List)(dataTable.getItemAtIndex(i).getChildren());
+ Listcell payAmt = celllist.get(9);
+ amount += new Float(payAmt.getLabel());
+ }
+ }
+
+ return amount;
+ }
+
+ /* (non-Javadoc)
+ * @see org.adempiere.webui.event.WTableModelListener#tableChanged(org.adempiere.webui.event.WTableModelEvent)
+ */
+ public void tableChanged(WTableModelEvent event)
+ {
+ if (event.getColumn() == 0)
+ {
+ calculateSelection();
+ }
+ }
+
+ public class BankInfo
+ {
+ /**
+ * BankInfo
+ * @param newC_BankAccount_ID
+ * @param newC_Currency_ID
+ * @param newName
+ * @param newCurrency
+ * @param newBalance
+ * @param newTransfers
+ */
+ public BankInfo (int newC_BankAccount_ID, int newC_Currency_ID, String newName, String newCurrency, BigDecimal newBalance, boolean newTransfers)
+ {
+ C_BankAccount_ID = newC_BankAccount_ID;
+ C_Currency_ID = newC_Currency_ID;
+ Name = newName;
+ Currency = newCurrency;
+ Balance = newBalance;
+ }
+
+ int C_BankAccount_ID;
+ int C_Currency_ID;
+ String Name;
+ String Currency;
+ BigDecimal Balance;
+ boolean Transfers;
+
+ /**
+ * to String
+ * @return info
+ */
+
+ public String toString()
+ {
+ return Name;
+ }
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WPayment.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WPayment.java
new file mode 100644
index 0000000000..9a640a1e2b
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WPayment.java
@@ -0,0 +1,1931 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
+ * or via info@compiere.org or http://www.compiere.org/license.html *
+ *****************************************************************************/
+
+/**
+ * 2007, Modified by Posterita Ltd.
+ */
+
+package org.adempiere.webui.apps.form;
+
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.text.DecimalFormat;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.logging.Level;
+
+import org.adempiere.webui.component.Button;
+import org.adempiere.webui.component.Datebox;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.ListItem;
+import org.adempiere.webui.component.Listbox;
+import org.adempiere.webui.component.Textbox;
+import org.adempiere.webui.component.VerticalBox;
+import org.adempiere.webui.component.Window;
+import org.adempiere.webui.editor.WButtonEditor;
+import org.adempiere.webui.window.FDialog;
+import org.compiere.model.GridTab;
+import org.compiere.model.MCash;
+import org.compiere.model.MCashLine;
+import org.compiere.model.MConversionRate;
+import org.compiere.model.MInvoice;
+import org.compiere.model.MOrder;
+import org.compiere.model.MPayment;
+import org.compiere.model.MPaymentValidate;
+import org.compiere.model.MRole;
+import org.compiere.model.X_C_Order;
+import org.compiere.process.DocAction;
+import org.compiere.util.CLogger;
+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.TimeUtil;
+import org.compiere.util.ValueNamePair;
+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.Hbox;
+import org.zkoss.zul.Separator;
+
+/**
+ * Display (and process) Payment Options.
+ *
+ * Payment Rule
+ * -B- Cash (Date) -> Cash Entry
+ * -P- Payment Term (Term)
+ * -S- Check (Routing, ..) -> Payment Entry
+ * -K- CreditCard (No) -> Payment Entry
+ * -U- ACH Transfer (Routing) -> Payment Entry
+ *
+ * When processing:
+ * - If an invoice is a S/K/U, but has no Payment Entry, it is changed to P
+ * - If an invoive is B and has no Cash Entry, it is created
+ * - An invoice is "Open" if it is "P" and no Payment
+ *
+ * Entry:
+ * - If not processed, an invoice has no Cash or Payment entry
+ * - The entry is created, during "Online" and when Saving
+ *
+ * Changes/Reversals:
+ * - existing Cash Entries are reversed and newly created
+ * - existing Payment Entries are not changed and then "hang there" and need to be allocated
+ *
+ *
+ * @author Niraj Sohun
+ * Payment Rule : Based on VPayment
+ */
+
+public class WPayment extends Window implements EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ /** Window */
+ private int m_WindowNo = 0;
+
+ /** Tab */
+ private GridTab m_mTab;
+
+ // Data from Order/Invoice
+ private String m_DocStatus = null;
+
+ /** Start Payment Rule */
+ private String m_PaymentRule = "";
+
+ /** Start Payment Term */
+ private int m_C_PaymentTerm_ID = 0;
+
+ /** Start Acct Date */
+ private Timestamp m_DateAcct = null;
+
+ /** Start Payment */
+ private int m_C_Payment_ID = 0;
+
+ private MPayment m_mPayment = null;
+ private MPayment m_mPaymentOriginal = null;
+
+ /** Start CashBook Line */
+ private int m_C_CashLine_ID = 0;
+
+ private MCashLine m_cashLine = null;
+
+ /** Start CreditCard */
+ private String m_CCType = "";
+
+ /** Start Bank Account */
+ private int m_C_BankAccount_ID = 0;
+
+ /** Start CashBook */
+ private int m_C_CashBook_ID = 0;
+
+ /** Is SOTrx */
+ private boolean m_isSOTrx = true;
+
+ /** Invoice Currency */
+ private int m_C_Currency_ID = 0;
+
+ private int m_AD_Client_ID = 0;
+ private int m_AD_Org_ID = 0;
+ private int m_C_BPartner_ID = 0;
+
+ // Payment Amount
+ private BigDecimal m_Amount = Env.ZERO;
+
+ private boolean m_initOK = false;
+
+ /** Only allow changing Rule */
+ private boolean m_onlyRule = false;
+
+ private DecimalFormat m_Format = DisplayType.getNumberFormat(DisplayType.Amount);
+
+ // EMU Currencies
+ private static Hashtable s_Currencies = null;
+
+ private boolean m_needSave = false;
+
+ /** Logger */
+ private static CLogger log = CLogger.getCLogger(WPayment.class);
+
+ /** Date Editor */
+ Datebox bDateField = new Datebox();
+
+ private Textbox bAmountField = new Textbox();
+ private Textbox sAmountField = new Textbox();
+ private Textbox kAmountField = new Textbox();
+ private Textbox kNumberField = new Textbox();
+ private Textbox kExpField = new Textbox();
+ private Textbox kApprovalField = new Textbox();
+ private Textbox sRoutingField = new Textbox();
+ private Textbox sNumberField = new Textbox();
+ private Textbox sCheckField = new Textbox();
+ private Textbox tRoutingField = new Textbox();
+ private Textbox tNumberField = new Textbox();
+
+ private Label kStatus = new Label();
+ private Label sStatus = new Label();
+ private Label tStatus = new Label();
+ private Label bCurrencyLabel = new Label();
+ private Label sCurrencyLabel = new Label();
+ private Label paymentLabel = new Label();
+ private Label kNumberLabel = new Label();
+ private Label kExpLabel = new Label();
+ private Label kApprovalLabel = new Label();
+ private Label kAmountLabel = new Label();
+ private Label kTypeLabel = new Label();
+ private Label tRoutingText = new Label();
+ private Label tNumberText = new Label();
+ private Label tAccountLabel = new Label();
+ private Label sBankAccountLabel = new Label();
+ private Label sAmountLabel = new Label();
+ private Label sRoutingLabel = new Label();
+ private Label sNumberLabel = new Label();
+ private Label sCheckLabel = new Label();
+ private Label pTermLabel = new Label();
+ private Label bAmountLabel = new Label();
+ private Label bDateLabel = new Label();
+ private Label bCashBookLabel = new Label();
+
+ private Listbox kTypeCombo = new Listbox();
+ private Listbox bCurrencyCombo = new Listbox();
+ private Listbox sCurrencyCombo = new Listbox();
+ private Listbox paymentCombo = new Listbox();
+ private Listbox pTermCombo = new Listbox();
+ private Listbox tAccountCombo = new Listbox();
+ private Listbox sBankAccountCombo = new Listbox();
+ private Listbox bCashBookCombo = new Listbox();
+
+ private Button kOnline = new Button();
+ private Button sOnline = new Button();
+ private Button btnOk = new Button();
+ private Button btnCancel = new Button();
+ private Button tOnline = new Button();
+
+ private VerticalBox mainPanel = new VerticalBox();
+ private Hbox northPanel = new Hbox();
+ private VerticalBox centerPanel = new VerticalBox();
+ private VerticalBox kPanel = new VerticalBox();
+ private VerticalBox tPanel = new VerticalBox();
+ private VerticalBox sPanel = new VerticalBox();
+ private Hbox pPanel = new Hbox();
+ private VerticalBox bPanel = new VerticalBox();
+
+ /**
+ * Constructor
+ *
+ * @param WindowNo owning window
+ * @param mTab owning tab
+ * @param button button with access information
+ */
+
+ public WPayment (int WindowNo, GridTab mTab, WButtonEditor button)
+ {
+ super();
+
+ m_WindowNo = WindowNo;
+ m_isSOTrx = "Y".equals(Env.getContext(Env.getCtx(), WindowNo, "IsSOTrx"));
+ m_mTab = mTab;
+
+ try
+ {
+ //bDateField = new WDateEditor("DateAcc", "", false, false, true);
+ bDateField.setValue(new Date(System.currentTimeMillis()));
+
+ jbInit();
+ m_initOK = dynInit(button); // Null Pointer if order/invoice not saved yet
+ }
+ catch(Exception ex)
+ {
+ log.log(Level.SEVERE, "WPayment", ex);
+ m_initOK = false;
+ }
+
+ this.setVisible(true);
+ //show
+ } // VPayment
+
+ /**
+ * Static Init
+ * @throws Exception
+ */
+
+ private void jbInit() throws Exception
+ {
+ this.setBorder("normal");
+ this.setWidth("400px");
+ this.setTitle("Payment");
+ this.setClosable(true);
+ this.appendChild(mainPanel);
+
+ centerPanel.setWidth("100%");
+
+ mainPanel.setWidth("100%");
+ mainPanel.appendChild(northPanel);
+ mainPanel.appendChild(new Separator());
+ mainPanel.appendChild(centerPanel);
+
+ paymentLabel.setValue(Msg.translate(Env.getCtx(), "PaymentRule"));
+
+ paymentCombo.setRows(0);
+ paymentCombo.setMold("select");
+ paymentCombo.addEventListener(Events.ON_SELECT, this);
+
+ northPanel.setWidth("100%");
+ northPanel.setWidths("40%, 60%");
+ northPanel.appendChild(paymentLabel);
+ northPanel.appendChild(paymentCombo);
+
+ // Credit Card
+
+ kPanel.setWidth("100%");
+
+ kTypeLabel.setValue(Msg.translate(Env.getCtx(), "CreditCardType"));
+ kNumberLabel.setValue(Msg.translate(Env.getCtx(), "CreditCardNumber"));
+ kExpLabel.setValue(Msg.getMsg(Env.getCtx(), "Expires"));
+ kApprovalLabel.setValue(Msg.translate(Env.getCtx(), "VoiceAuthCode"));
+ kAmountLabel.setValue(Msg.getMsg(Env.getCtx(), "Amount"));
+ kAmountField.setText("");
+ kOnline.setLabel(Msg.getMsg(Env.getCtx(), "Online"));
+ kOnline.addEventListener(Events.ON_CLICK, this);
+ kStatus.setValue(" ");
+ centerPanel.appendChild(kPanel);
+
+ Hbox boxKType = new Hbox();
+
+ kTypeCombo.setRows(0);
+ kTypeCombo.setMold("select");
+ kTypeCombo.addEventListener(Events.ON_SELECT, this);
+
+ boxKType.setWidth("100%");
+ boxKType.setWidths("50%, 50%");
+ boxKType.appendChild(kTypeLabel);
+ boxKType.appendChild(kTypeCombo);
+ kPanel.appendChild(boxKType);
+
+ Hbox boxKNumber = new Hbox();
+ boxKNumber.setWidth("100%");
+ boxKNumber.setWidths("50%, 50%");
+ boxKNumber.appendChild(kNumberLabel);
+ boxKNumber.appendChild(kNumberField);
+ kPanel.appendChild(boxKNumber);
+
+ Hbox boxKExp = new Hbox();
+ boxKExp.setWidth("100%");
+ boxKExp.setWidths("50%, 50%");
+ boxKExp.appendChild(kExpLabel);
+ boxKExp.appendChild(kExpField);
+ kPanel.appendChild(boxKExp);
+
+ Hbox boxKAmount = new Hbox();
+ boxKAmount.setWidth("100%");
+ boxKAmount.setWidths("50%, 50%");
+ boxKAmount.appendChild(kAmountLabel);
+ boxKAmount.appendChild(kAmountField);
+ kPanel.appendChild(boxKAmount);
+
+ Hbox boxKApproval = new Hbox();
+ boxKApproval.setWidth("100%");
+ boxKApproval.setWidths("50%, 50%");
+ boxKApproval.appendChild(kApprovalLabel);
+ boxKApproval.appendChild(kApprovalField);
+ kPanel.appendChild(boxKApproval);
+
+ kPanel.appendChild(kStatus);
+ kPanel.appendChild(kOnline);
+
+ // Direct Debit/Credit
+
+ tPanel.setWidth("100%");
+
+ tAccountLabel.setValue(Msg.translate(Env.getCtx(), "C_BP_BankAccount_ID"));
+ //tRoutingField.setColumns(8);
+ //tNumberField.setColumns(10);
+ tRoutingText.setValue(Msg.translate(Env.getCtx(), "RoutingNo"));
+ tNumberText.setValue(Msg.translate(Env.getCtx(), "AccountNo"));
+ tOnline.setLabel(Msg.getMsg(Env.getCtx(), "Online"));
+ tOnline.addEventListener(Events.ON_CLICK, this);
+ tStatus.setValue(" ");
+ centerPanel.appendChild(tPanel);
+
+ Hbox boxTAccount = new Hbox();
+
+ tAccountCombo.setRows(0);
+ tAccountCombo.setMold("select");
+ tAccountCombo.addEventListener(Events.ON_SELECT, this);
+
+ boxTAccount.setWidth("100%");
+ boxTAccount.setWidths("45%, 55%");
+ boxTAccount.appendChild(tAccountLabel);
+ boxTAccount.appendChild(tAccountCombo);
+ tPanel.appendChild(boxTAccount);
+
+ Hbox boxTRouting = new Hbox();
+ boxTRouting.setWidth("100%");
+ boxTRouting.setWidths("45%, 55%");
+ boxTRouting.appendChild(tRoutingText);
+ boxTRouting.appendChild(tRoutingField);
+ tPanel.appendChild(boxTRouting);
+
+ Hbox boxTNumber = new Hbox();
+ boxTNumber.setWidth("100%");
+ boxTNumber.setWidths("45%, 55%");
+ boxTNumber.appendChild(tNumberText);
+ boxTNumber.appendChild(tNumberField);
+ tPanel.appendChild(boxTNumber);
+
+ tPanel.appendChild(tStatus);
+ tPanel.appendChild(tOnline);
+
+ // Cheque
+
+ sPanel.setWidth("100%");
+
+ sBankAccountLabel.setValue(Msg.translate(Env.getCtx(), "C_BankAccount_ID"));
+ sAmountLabel.setValue(Msg.getMsg(Env.getCtx(), "Amount"));
+ sAmountField.setText("");
+ sRoutingLabel.setValue(Msg.translate(Env.getCtx(), "RoutingNo"));
+ sNumberLabel.setValue(Msg.translate(Env.getCtx(), "AccountNo"));
+ sCheckLabel.setValue(Msg.translate(Env.getCtx(), "CheckNo"));
+ //sCheckField.setColumns(8);
+ sCurrencyLabel.setValue(Msg.translate(Env.getCtx(), "C_Currency_ID"));
+ //sNumberField.setPreferredSize(new Dimension(100, 21));
+ //sRoutingField.setPreferredSize(new Dimension(70, 21));
+ sStatus.setValue(" ");
+ sOnline.setLabel(Msg.getMsg(Env.getCtx(), "Online"));
+ sOnline.addEventListener(Events.ON_CLICK, this);
+ centerPanel.appendChild(sPanel);
+
+ Hbox boxSBankAccount = new Hbox();
+
+ sBankAccountCombo.setRows(0);
+ sBankAccountCombo.setMold("select");
+ sBankAccountCombo.addEventListener(Events.ON_SELECT, this);
+
+ boxSBankAccount.setWidth("100%");
+ boxSBankAccount.setWidths("40%, 60%");
+ boxSBankAccount.appendChild(sBankAccountLabel);
+ boxSBankAccount.appendChild(sBankAccountCombo);
+ sPanel.appendChild(boxSBankAccount);
+
+ Hbox boxSCurrency = new Hbox();
+
+ sCurrencyCombo.setRows(0);
+ sCurrencyCombo.setMold("select");
+ sCurrencyCombo.addEventListener(Events.ON_SELECT, this);
+
+ boxSCurrency.setWidth("100%");
+ boxSCurrency.setWidths("40%, 60%");
+ boxSCurrency.appendChild(sCurrencyLabel);
+ boxSCurrency.appendChild(sCurrencyCombo);
+ sPanel.appendChild(boxSCurrency);
+
+ Hbox boxSAmount = new Hbox();
+ boxSAmount.setWidth("100%");
+ boxSAmount.setWidths("40%, 60%");
+ boxSAmount.appendChild(sAmountLabel);
+ boxSAmount.appendChild(sAmountField);
+ sPanel.appendChild(boxSAmount);
+
+ Hbox boxSRouting = new Hbox();
+ boxSRouting.setWidth("100%");
+ boxSRouting.setWidths("40%, 60%");
+ boxSRouting.appendChild(sRoutingLabel);
+ boxSRouting.appendChild(sRoutingField);
+ sPanel.appendChild(boxSRouting);
+
+ Hbox boxSNumber = new Hbox();
+ boxSNumber.setWidth("100%");
+ boxSNumber.setWidths("40%, 60%");
+ boxSNumber.appendChild(sNumberLabel);
+ boxSNumber.appendChild(sNumberField);
+ sPanel.appendChild(boxSNumber);
+
+ Hbox boxSCheck = new Hbox();
+ boxSCheck.setWidth("100%");
+ boxSCheck.setWidths("40%, 60%");
+ boxSCheck.appendChild(sCheckLabel);
+ boxSCheck.appendChild(sCheckField);
+ sPanel.appendChild(boxSCheck);
+
+ sPanel.appendChild(sOnline);
+ sPanel.appendChild(sStatus);
+
+ // Cash
+
+ pPanel.setWidth("100%");
+ pPanel.setWidths("40%, 60%");
+
+ pTermLabel.setValue(Msg.translate(Env.getCtx(), "C_PaymentTerm_ID"));
+ centerPanel.appendChild(pPanel);
+
+ pTermCombo.setRows(0);
+ pTermCombo.setMold("select");
+ pTermCombo.addEventListener(Events.ON_SELECT, this);
+
+ pPanel.appendChild(pTermLabel);
+ pPanel.appendChild(pTermCombo);
+
+ //
+
+ bPanel.setWidth("100%");
+
+ bCashBookLabel.setValue(Msg.translate(Env.getCtx(), "C_CashBook_ID"));
+ bCurrencyLabel.setValue(Msg.translate(Env.getCtx(), "C_Currency_ID"));
+ bAmountLabel.setValue(Msg.getMsg(Env.getCtx(), "Amount"));
+ bAmountField.setText("");
+ bDateLabel.setValue(Msg.translate(Env.getCtx(), "DateAcct"));
+ centerPanel.appendChild(bPanel);
+
+ Hbox boxBCashBook = new Hbox();
+
+ bCashBookCombo.setRows(0);
+ bCashBookCombo.setMold("select");
+ bCashBookCombo.addEventListener(Events.ON_SELECT, this);
+
+ boxBCashBook.setWidth("100%");
+ boxBCashBook.setWidths("40%, 60%");
+ boxBCashBook.appendChild(bCashBookLabel);
+ boxBCashBook.appendChild(bCashBookCombo);
+ bPanel.appendChild(boxBCashBook);
+
+ Hbox boxBCurrency = new Hbox();
+
+ bCurrencyCombo.setRows(0);
+ bCurrencyCombo.setMold("select");
+ bCurrencyCombo.addEventListener(Events.ON_SELECT, this);
+
+ boxBCurrency.setWidth("100%");
+ boxBCurrency.setWidths("40%, 60%");
+ boxBCurrency.appendChild(bCurrencyLabel);
+ boxBCurrency.appendChild(bCurrencyCombo);
+ bPanel.appendChild(boxBCurrency);
+
+ Hbox boxBDate = new Hbox();
+ boxBDate.setWidth("100%");
+ boxBDate.setWidths("40%, 60%");
+ boxBDate.appendChild(bDateLabel);
+ boxBDate.appendChild(bDateField);
+ bPanel.appendChild(boxBDate);
+
+ Hbox boxBAmount = new Hbox();
+ boxBAmount.setWidth("100%");
+ boxBAmount.setWidths("40%, 60%");
+ boxBAmount.appendChild(bAmountLabel);
+ boxBAmount.appendChild(bAmountField);
+ bPanel.appendChild(boxBAmount);
+
+ Hbox boxButtons = new Hbox();
+
+ btnCancel.setImage("/images/Cancel24.gif");
+ btnCancel.addEventListener(Events.ON_CLICK, this);
+ btnOk.setImage("/images/Ok24.gif");
+ btnOk.addEventListener(Events.ON_CLICK, this);
+
+ boxButtons.appendChild(btnCancel);
+ boxButtons.appendChild(btnOk);
+ mainPanel.appendChild(new Separator());
+ mainPanel.appendChild(boxButtons);
+ }
+
+ /**************************************************************************
+ * Dynamic Init.
+ * B (Cash) (Currency)
+ * K (CreditCard) Type, Number, Exp, Approval
+ * L (DirectDebit) BPartner_Bank
+ * P (PaymentTerm) PaymentTerm
+ * S (Check) (Currency) CheckNo, Routing
+ *
+ * Currencies are shown, if member of EMU
+ * @param button payment type button
+ * @return true if init OK
+ * @throws Exception
+ */
+
+ private boolean dynInit (WButtonEditor button) throws Exception
+ {
+ m_DocStatus = (String)m_mTab.getValue("DocStatus");
+ log.config(m_DocStatus);
+
+ if (m_mTab.getValue("C_BPartner_ID") == null)
+ {
+ FDialog.error(0, this, "SaveErrorRowNotFound");
+ return false;
+ }
+
+ // Is the Trx posted?
+ // String Posted = (String)m_mTab.getValue("Posted");
+ // if (Posted != null && Posted.equals("Y"))
+ // return false;
+
+ // DocStatus
+
+ m_DocStatus = (String)m_mTab.getValue("DocStatus");
+
+ if (m_DocStatus == null)
+ m_DocStatus = "";
+
+ // Is the Trx closed? Reversed / Voided / Cloased
+
+ if (m_DocStatus.equals("RE") || m_DocStatus.equals("VO") || m_DocStatus.equals("CL"))
+ return false;
+
+ // Document is not complete - allow to change the Payment Rule only
+ if (m_DocStatus.equals("CO") || m_DocStatus.equals("WP") )
+ m_onlyRule = false;
+ else
+ m_onlyRule = true;
+
+ // PO only Rule
+
+ if (!m_onlyRule // Only order has Warehouse
+ && !m_isSOTrx && m_mTab.getValue("M_Warehouse_ID") != null)
+ m_onlyRule = true;
+
+ centerPanel.setVisible(!m_onlyRule);
+
+ // Amount
+
+ m_Amount = (BigDecimal)m_mTab.getValue("GrandTotal");
+
+ if (!m_onlyRule && m_Amount.compareTo(Env.ZERO) == 0)
+ {
+ FDialog.error(m_WindowNo, this, "PaymentZero");
+ return false;
+ }
+
+ bAmountField.setText(m_Format.format(m_Amount));
+ sAmountField.setText(m_Format.format(m_Amount));
+ kAmountField.setText(m_Format.format(m_Amount));
+
+ /**
+ * Get Data from Grid
+ */
+
+ m_AD_Client_ID = ((Integer)m_mTab.getValue("AD_Client_ID")).intValue();
+ m_AD_Org_ID = ((Integer)m_mTab.getValue("AD_Org_ID")).intValue();
+ m_C_BPartner_ID = ((Integer)m_mTab.getValue("C_BPartner_ID")).intValue();
+ m_PaymentRule = (String)m_mTab.getValue("PaymentRule");
+ m_C_Currency_ID = ((Integer)m_mTab.getValue("C_Currency_ID")).intValue();
+ m_DateAcct = (Timestamp)m_mTab.getValue("DateAcct");
+
+ if (m_mTab.getValue("C_PaymentTerm_ID") != null)
+ m_C_PaymentTerm_ID = ((Integer)m_mTab.getValue("C_PaymentTerm_ID")).intValue();
+
+ // Existing Payment
+
+ if (m_mTab.getValue("C_Payment_ID") != null)
+ {
+ m_C_Payment_ID = ((Integer)m_mTab.getValue("C_Payment_ID")).intValue();
+
+ if (m_C_Payment_ID != 0)
+ {
+ m_mPayment = new MPayment(Env.getCtx(), m_C_Payment_ID, null);
+ m_mPaymentOriginal = new MPayment(Env.getCtx(), m_C_Payment_ID, null); // full copy
+
+ // CreditCard
+ m_CCType = m_mPayment.getCreditCardType();
+ kNumberField.setText(m_mPayment.getCreditCardNumber());
+ kExpField.setText(m_mPayment.getCreditCardExp(null));
+ kApprovalField.setText(m_mPayment.getVoiceAuthCode());
+ kStatus.setValue(m_mPayment.getR_PnRef());
+ kAmountField.setText(m_Format.format(m_mPayment.getPayAmt()));
+
+ // if approved/paid, don't let it change
+
+ kTypeCombo.setEnabled(!m_mPayment.isApproved());
+ kNumberField.setEnabled(!m_mPayment.isApproved());
+ kExpField.setEnabled(!m_mPayment.isApproved());
+ kApprovalField.setEnabled(!m_mPayment.isApproved());
+ kOnline.setEnabled(!m_mPayment.isApproved());
+ kAmountField.setEnabled(!m_mPayment.isApproved());
+
+ // Check
+
+ m_C_BankAccount_ID = m_mPayment.getC_BankAccount_ID();
+ sRoutingField.setText(m_mPayment.getRoutingNo());
+ sNumberField.setText(m_mPayment.getAccountNo());
+ sCheckField.setText(m_mPayment.getCheckNo());
+ sStatus.setValue(m_mPayment.getR_PnRef());
+ sAmountField.setText(m_Format.format(m_mPayment.getPayAmt()));
+
+ // Transfer
+
+ tRoutingField.setText(m_mPayment.getRoutingNo());
+ tNumberField.setText(m_mPayment.getAccountNo());
+ tStatus.setValue(m_mPayment.getR_PnRef());
+ }
+ }
+ if (m_mPayment == null)
+ {
+ m_mPayment = new MPayment (Env.getCtx (), 0, null);
+ m_mPayment.setAD_Org_ID(m_AD_Org_ID);
+ m_mPayment.setAmount (m_C_Currency_ID, m_Amount);
+ }
+
+ // Existing Cashbook entry
+
+ m_cashLine = null;
+ m_C_CashLine_ID = 0;
+
+ if (m_mTab.getValue("C_CashLine_ID") != null)
+ {
+ m_C_CashLine_ID = ((Integer)m_mTab.getValue("C_CashLine_ID")).intValue();
+
+ if (m_C_CashLine_ID == 0)
+ m_cashLine = null;
+ else
+ {
+ m_cashLine = new MCashLine (Env.getCtx(), m_C_CashLine_ID, null);
+ m_DateAcct = m_cashLine.getStatementDate();
+ bAmountField.setText(m_cashLine.getAmount().toString());
+ }
+ }
+
+ // Accounting Date
+
+ bDateField.setValue(m_DateAcct);
+
+ if (s_Currencies == null)
+ loadCurrencies();
+
+ // Is the currency an EMU currency?
+
+ Integer C_Currency_ID = new Integer(m_C_Currency_ID);
+
+ if (s_Currencies.containsKey(C_Currency_ID))
+ {
+ Enumeration en = s_Currencies.keys();
+ while (en.hasMoreElements())
+ {
+ Object key = en.nextElement();
+ bCurrencyCombo.appendItem(key.toString(), s_Currencies.get(key));
+ sCurrencyCombo.appendItem(key.toString(), s_Currencies.get(key));
+ }
+
+ ListItem listitem = new ListItem();
+ listitem.setValue(s_Currencies.get(C_Currency_ID));
+
+ sCurrencyCombo.addEventListener(Events.ON_SELECT, this);
+ sCurrencyCombo.setSelectedItem(listitem);
+
+ bCurrencyCombo.addEventListener(Events.ON_SELECT, this);
+ bCurrencyCombo.setSelectedItem(listitem);
+ }
+ else // No EMU Currency
+ {
+ bCurrencyLabel.setVisible(false); // Cash
+ bCurrencyCombo.setVisible(false);
+ sCurrencyLabel.setVisible(false); // Check
+ sCurrencyCombo.setVisible(false);
+ }
+
+ /**
+ * Payment Combo
+ */
+
+ if (m_PaymentRule == null)
+ m_PaymentRule = "";
+
+ ValueNamePair vp = null;
+ HashMap values = button.getValues();
+ Object[] a = values.keySet().toArray();
+
+ for (int i = 0; i < a.length; i++)
+ {
+ String PaymentRule = (String)a[i]; // used for Panel selection
+
+ if (X_C_Order.PAYMENTRULE_DirectDebit.equals(PaymentRule) // SO
+ && !m_isSOTrx)
+ continue;
+ else if (X_C_Order.PAYMENTRULE_DirectDeposit.equals(PaymentRule) // PO
+ && m_isSOTrx)
+ continue;
+
+ ValueNamePair pp = new ValueNamePair(PaymentRule, (String)values.get(a[i]));
+ paymentCombo.appendItem(pp.getName(), pp);
+
+ if (PaymentRule.toString().equals(m_PaymentRule)) // to select
+ vp = pp;
+ }
+
+ // Set PaymentRule
+
+ paymentCombo.addEventListener(Events.ON_SELECT, this);
+
+ if (vp != null)
+ {
+ for (int i = 0; i < paymentCombo.getItemCount(); i++)
+ {
+ ListItem item = paymentCombo.getItemAtIndex(i);
+ ValueNamePair v = (ValueNamePair)item.getValue();
+
+ if (v == vp)
+ {
+ paymentCombo.setSelectedIndex(i);
+ break;
+ }
+ }
+ }
+
+ Event evt = new Event(Events.ON_SELECT, paymentCombo);
+ onEvent(evt);
+
+ /**
+ * Load Payment Terms
+ */
+
+ String SQL = MRole.getDefault().addAccessSQL(
+ "SELECT C_PaymentTerm_ID, Name FROM C_PaymentTerm WHERE IsActive='Y' ORDER BY Name",
+ "C_PaymentTerm", MRole.SQL_NOTQUALIFIED, MRole.SQL_RO);
+
+ KeyNamePair kp = null;
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(SQL, null);
+ ResultSet rs = pstmt.executeQuery();
+ while (rs.next())
+ {
+ int key = rs.getInt(1);
+ String name = rs.getString(2);
+ KeyNamePair pp = new KeyNamePair(key, name);
+ pTermCombo.appendItem(pp.getName(), pp);
+
+ if (key == m_C_PaymentTerm_ID)
+ kp = pp;
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException ept)
+ {
+ log.log(Level.SEVERE, SQL, ept);
+ }
+
+ // Set Selection
+
+ if (kp != null)
+ {
+ for (int i = 0; i < pTermCombo.getItemCount(); i++)
+ {
+ ListItem item = pTermCombo.getItemAtIndex(i);
+ KeyNamePair k = (KeyNamePair)item.getValue();
+
+ if (k == kp)
+ {
+ pTermCombo.setSelectedIndex(i);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Load Accounts
+ */
+
+ SQL = "SELECT a.C_BP_BankAccount_ID, NVL(b.Name, ' ')||a.AccountNo AS Acct "
+ + "FROM C_BP_BankAccount a,C_Bank b "
+ + "WHERE C_BPartner_ID=? AND a.IsActive='Y'";
+
+ kp = null;
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(SQL, null);
+ pstmt.setInt(1, m_C_BPartner_ID);
+ ResultSet rs = pstmt.executeQuery();
+
+ while (rs.next())
+ {
+ int key = rs.getInt(1);
+ String name = rs.getString(2);
+ KeyNamePair pp = new KeyNamePair(key, name);
+ tAccountCombo.appendItem(pp.getName(), pp);
+ // kp = pp;
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException eac)
+ {
+ log.log(Level.SEVERE, SQL, eac);
+ }
+
+ // Set Selection
+
+ if (kp != null)
+ {
+ for (int i = 0; i < tAccountCombo.getItemCount(); i++)
+ {
+ ListItem item = tAccountCombo.getItemAtIndex(i);
+ KeyNamePair k = (KeyNamePair)item.getValue();
+
+ if (k == kp)
+ {
+ tAccountCombo.setSelectedIndex(i);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Load Credit Cards
+ */
+
+ ValueNamePair[] ccs = m_mPayment.getCreditCards();
+ vp = null;
+
+ for (int i = 0; i < ccs.length; i++)
+ {
+ kTypeCombo.appendItem(ccs[i].getName(), ccs[i]);
+
+ if (ccs[i].getValue().equals(m_CCType))
+ vp = ccs[i];
+ }
+
+ // Set Selection
+
+ if (vp != null)
+ {
+ for (int i = 0; i < kTypeCombo.getItemCount(); i++)
+ {
+ ListItem item = kTypeCombo.getItemAtIndex(i);
+ ValueNamePair v = (ValueNamePair)item.getValue();
+
+ if (v == vp)
+ {
+ kTypeCombo.setSelectedIndex(i);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Load Bank Accounts
+ */
+
+ SQL = MRole.getDefault().addAccessSQL(
+ "SELECT C_BankAccount_ID, Name || ' ' || AccountNo, IsDefault "
+ + "FROM C_BankAccount ba"
+ + " INNER JOIN C_Bank b ON (ba.C_Bank_ID=b.C_Bank_ID) "
+ + "WHERE b.IsActive='Y'",
+ "ba", MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO);
+
+ kp = null;
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(SQL, null);
+ ResultSet rs = pstmt.executeQuery();
+ while (rs.next())
+ {
+ int key = rs.getInt(1);
+ String name = rs.getString(2);
+ KeyNamePair pp = new KeyNamePair(key, name);
+ sBankAccountCombo.appendItem(pp.getName(), pp);
+
+ if (key == m_C_BankAccount_ID)
+ kp = pp;
+
+ if (kp == null && rs.getString(3).equals("Y")) // Default
+ kp = pp;
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException ept)
+ {
+ log.log(Level.SEVERE, SQL, ept);
+ }
+
+ // Set Selection
+
+ if (kp != null)
+ {
+ for (int i = 0; i < sBankAccountCombo.getItemCount(); i++)
+ {
+ ListItem item = sBankAccountCombo.getItemAtIndex(i);
+ KeyNamePair k = (KeyNamePair)item.getValue();
+
+ if (k == kp)
+ {
+ sBankAccountCombo.setSelectedIndex(i);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Load Cash Books
+ */
+
+ SQL = MRole.getDefault().addAccessSQL(
+ "SELECT C_CashBook_ID, Name, AD_Org_ID FROM C_CashBook WHERE IsActive='Y'",
+ "C_CashBook", MRole.SQL_NOTQUALIFIED, MRole.SQL_RO);
+
+ kp = null;
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(SQL, null);
+ ResultSet rs = pstmt.executeQuery();
+ while (rs.next())
+ {
+ int key = rs.getInt(1);
+ String name = rs.getString(2);
+ KeyNamePair pp = new KeyNamePair(key, name);
+ bCashBookCombo.appendItem(pp.getName(), pp);
+
+ if (key == m_C_CashBook_ID)
+ kp = pp;
+
+ if (kp == null && key == m_AD_Org_ID) // Default Org
+ kp = pp;
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException epc)
+ {
+ log.log(Level.SEVERE, SQL, epc);
+ }
+
+ // Set Selection
+
+ if (kp != null)
+ {
+ for (int i = 0; i < bCashBookCombo.getItemCount(); i++)
+ {
+ ListItem item = bCashBookCombo.getItemAtIndex(i);
+ KeyNamePair k = (KeyNamePair)item.getValue();
+
+ if (k == kp)
+ {
+ bCashBookCombo.setSelectedIndex(i);
+ break;
+ }
+ }
+
+ if (m_C_CashBook_ID == 0)
+ m_C_CashBook_ID = kp.getKey(); // set to default to avoid 'cashbook changed' message
+ }
+
+ return true;
+ } // dynInit
+
+ /**
+ * Init OK to be able to make changes?
+ * @return true if init OK
+ */
+
+ public boolean isInitOK()
+ {
+ return m_initOK;
+ } // isInitOK
+
+ /**
+ * Fill s_Currencies with EMU currencies
+ */
+
+ private void loadCurrencies()
+ {
+ s_Currencies = new Hashtable(12); // Currenly only 10+1
+ String SQL = "SELECT C_Currency_ID, ISO_Code FROM C_Currency "
+ + "WHERE (IsEMUMember='Y' AND EMUEntryDate " + newPaymentRule);
+
+ // We had a CashBook Entry
+
+ if (m_PaymentRule.equals(X_C_Order.PAYMENTRULE_Cash))
+ {
+ log.fine("Old Cash - " + m_cashLine);
+
+ if (m_cashLine != null)
+ {
+ MCashLine cl = m_cashLine.createReversal();
+
+ if (cl.save())
+ log.config( "CashCancelled");
+ else
+ FDialog.error(m_WindowNo, this, "PaymentError", "CashNotCancelled");
+ }
+ newC_CashLine_ID = 0; // reset
+ }
+
+ // We had a change in Payment type (e.g. Check to CC)
+
+ else if ("KTSD".indexOf(m_PaymentRule) != -1 && "KTSD".indexOf(newPaymentRule) != -1 && m_mPaymentOriginal != null)
+ {
+ log.fine("Old Payment(1) - " + m_mPaymentOriginal);
+ m_mPaymentOriginal.setDocAction(DocAction.ACTION_Reverse_Correct);
+ boolean ok = m_mPaymentOriginal.processIt(DocAction.ACTION_Reverse_Correct);
+ m_mPaymentOriginal.save();
+
+ if (ok)
+ log.info( "Payment Canecelled - " + m_mPaymentOriginal);
+ else
+ FDialog.error(m_WindowNo, this, "PaymentError", "PaymentNotCancelled " + m_mPaymentOriginal.getDocumentNo());
+
+ m_mPayment.resetNew();
+ }
+ // We had a Payment and something else (e.g. Check to Cash)
+
+ else if ("KTSD".indexOf(m_PaymentRule) != -1 && "KTSD".indexOf(newPaymentRule) == -1)
+ {
+ log.fine("Old Payment(2) - " + m_mPaymentOriginal);
+
+ if (m_mPaymentOriginal != null)
+ {
+ m_mPaymentOriginal.setDocAction(DocAction.ACTION_Reverse_Correct);
+ boolean ok = m_mPaymentOriginal.processIt(DocAction.ACTION_Reverse_Correct);
+ m_mPaymentOriginal.save();
+
+ if (ok) // Cancel Payment
+ {
+ log.fine("PaymentCancelled " + m_mPayment.getDocumentNo ());
+ m_mTab.getTableModel().dataSave(true);
+ m_mPayment.resetNew();
+ m_mPayment.setAmount(m_C_Currency_ID, m_Amount);
+ }
+ else
+ FDialog.error(m_WindowNo, this, "PaymentError", "PaymentNotCancelled " + m_mPayment.getDocumentNo());
+ }
+ }
+ }
+
+ // Get Order and optionally Invoice
+
+ int C_Order_ID = Env.getContextAsInt(Env.getCtx(), m_WindowNo, "C_Order_ID");
+ int C_Invoice_ID = Env.getContextAsInt(Env.getCtx(), m_WindowNo, "C_Invoice_ID");
+ if (C_Invoice_ID == 0 && m_DocStatus.equals("CO"))
+ C_Invoice_ID = getInvoiceID (C_Order_ID);
+
+ // Amount sign negative, if ARC (Credit Memo) or API (AP Invoice)
+
+ boolean negateAmt = false;
+ MInvoice invoice = null;
+
+ if (C_Invoice_ID != 0)
+ {
+ invoice = new MInvoice (Env.getCtx(), C_Invoice_ID, null);
+ negateAmt = invoice.isCreditMemo();
+ }
+
+ MOrder order = null;
+
+ if (invoice == null && C_Order_ID != 0)
+ order = new MOrder (Env.getCtx(), C_Order_ID, null);
+
+ BigDecimal payAmount = m_Amount;
+
+ if (negateAmt)
+ payAmount = m_Amount.negate();
+
+ // Info
+
+ log.config("C_Order_ID=" + C_Order_ID + ", C_Invoice_ID=" + C_Invoice_ID + ", NegateAmt=" + negateAmt);
+
+ /***********************
+ * CashBook
+ */
+
+ if (newPaymentRule.equals(X_C_Order.PAYMENTRULE_Cash))
+ {
+ log.fine("Cash");
+ String description = (String)m_mTab.getValue("DocumentNo");
+
+ if (C_Invoice_ID == 0 && order == null)
+ {
+ log.config("No Invoice!");
+ FDialog.error(m_WindowNo, this, "PaymentError", "CashNotCreated");
+ }
+ else
+ {
+ payAmount = new BigDecimal(bAmountField.getText());
+
+ // Changed Amount
+
+ if (m_cashLine != null
+ && payAmount.compareTo(m_cashLine.getAmount()) != 0)
+ {
+ log.config("Changed CashBook Amount");
+
+ //m_cashLine.setAmount(payAmount);
+
+ m_cashLine.setAmount(new BigDecimal(bAmountField.getText()));
+
+ // ADialog.info(m_WindowNo, this, "m_cashLine - Changed Amount", "Amount: "+m_cashLine.getAmount());
+
+ if (m_cashLine.save())
+ log.config("CashAmt Changed");
+ }
+
+ // Different Date/CashBook
+
+ if (m_cashLine != null
+ && (newC_CashBook_ID != m_C_CashBook_ID
+ || !TimeUtil.isSameDay(m_cashLine.getStatementDate(), newDateAcct)))
+ {
+ log.config("Changed CashBook/Date: " + m_C_CashBook_ID + "->" + newC_CashBook_ID);
+ MCashLine reverse = m_cashLine.createReversal();
+
+ if (!reverse.save())
+ FDialog.error(m_WindowNo, this, "PaymentError", "CashNotCancelled");
+
+ m_cashLine = null;
+ }
+
+ // Create new
+
+ if (m_cashLine == null)
+ {
+ log.config("New CashBook");
+ int C_Currency_ID = 0;
+
+ if (invoice != null)
+ C_Currency_ID = invoice.getC_Currency_ID();
+
+ if (C_Currency_ID == 0 && order != null)
+ C_Currency_ID = order.getC_Currency_ID();
+
+ MCash cash = null;
+
+ if (newC_CashBook_ID != 0)
+ cash = MCash.get (Env.getCtx(), newC_CashBook_ID, newDateAcct, null);
+ else // Default
+ cash = MCash.get (Env.getCtx(), m_AD_Org_ID, newDateAcct, C_Currency_ID, null);
+
+ if (cash == null || cash.get_ID() == 0)
+ FDialog.error(m_WindowNo, this, "PaymentError", "CashNotCreated");
+ else
+ {
+ MCashLine cl = new MCashLine (cash);
+
+ // cl.setAmount(new BigDecimal(bAmountField.getText()));
+ //ADialog.info(m_WindowNo, this, "m_cashLine - New Cashbook", "Amount: "+cl.getAmount());
+
+ if (invoice != null)
+ cl.setInvoice(invoice); // overrides amount
+ if (order != null)
+ {
+ cl.setOrder(order, null); // overrides amount
+ m_needSave = true;
+ }
+
+ cl.setAmount(new BigDecimal(bAmountField.getText()));
+
+ if (cl.save())
+ {
+ log.config("CashCreated");
+
+ if (invoice == null && C_Invoice_ID != 0)
+ {
+ invoice = new MInvoice (Env.getCtx(), C_Invoice_ID, null);
+ }
+
+ if (invoice != null)
+ {
+ invoice.setC_CashLine_ID(cl.getC_CashLine_ID());
+ invoice.save();
+ }
+
+ if (order == null && C_Order_ID != 0)
+ {
+ order = new MOrder (Env.getCtx(), C_Order_ID, null);
+ }
+
+ if (order != null)
+ {
+ order.setC_CashLine_ID(cl.getC_CashLine_ID());
+ order.save();
+ }
+
+ log.config("Update Order & Invoice with CashLine");
+ }
+ else
+ FDialog.error(m_WindowNo, this, "PaymentError", "CashNotCreated");
+ }
+ }
+ } // have invoice
+ }
+
+ /***********************
+ * Payments
+ */
+
+ if ("KS".indexOf(newPaymentRule) != -1)
+ {
+ log.fine("Payment - " + newPaymentRule);
+
+ // Set Amount
+
+ m_mPayment.setAmount(m_C_Currency_ID, payAmount);
+
+ if (newPaymentRule.equals(MOrder.PAYMENTRULE_CreditCard))
+ {
+ m_mPayment.setCreditCard(MPayment.TRXTYPE_Sales, newCCType,
+ kNumberField.getText(), "", kExpField.getText());
+
+ // Get changes to credit card amount
+
+ m_mPayment.setAmount(m_C_Currency_ID, new BigDecimal(kAmountField.getText()));
+ m_mPayment.setPaymentProcessor();
+ }
+ else if (newPaymentRule.equals(MOrder.PAYMENTRULE_DirectDeposit)
+ || newPaymentRule.equals(MOrder.PAYMENTRULE_DirectDebit))
+ {
+ m_mPayment.setBankACH(newC_BankAccount_ID, m_isSOTrx, newPaymentRule,
+ tRoutingField.getText(), tNumberField.getText());
+
+ m_mPayment.setAmount(m_C_Currency_ID, payAmount);
+ }
+ else if (newPaymentRule.equals(MOrder.PAYMENTRULE_Check))
+ {
+ m_mPayment.setBankCheck(newC_BankAccount_ID, m_isSOTrx, sRoutingField.getText(),
+ sNumberField.getText(), sCheckField.getText());
+
+ // Get changes to check amount
+
+ m_mPayment.setAmount(m_C_Currency_ID, new BigDecimal(sAmountField.getText()));
+ }
+
+ m_mPayment.setC_BPartner_ID(m_C_BPartner_ID);
+ m_mPayment.setC_Invoice_ID(C_Invoice_ID);
+
+ if (order != null)
+ {
+ m_mPayment.setC_Order_ID(C_Order_ID);
+ m_needSave = true;
+ }
+
+ m_mPayment.setDateTrx(m_DateAcct);
+ m_mPayment.setDateAcct(m_DateAcct);
+ m_mPayment.save();
+
+ // Save/Post
+
+ if (MPayment.DOCSTATUS_Drafted.equals(m_mPayment.getDocStatus()))
+ {
+ boolean ok = m_mPayment.processIt(DocAction.ACTION_Complete);
+ m_mPayment.save();
+
+ if (ok)
+ FDialog.info(m_WindowNo, this, "PaymentCreated", m_mPayment.getDocumentNo());
+ else
+ FDialog.error(m_WindowNo, this, "PaymentError", "PaymentNotCreated");
+ }
+ else
+ log.fine("NotDraft " + m_mPayment);
+ }
+
+
+ /**********************
+ * Save Values to mTab
+ */
+
+ log.config("Saving changes");
+
+ if (!newPaymentRule.equals(m_PaymentRule))
+ m_mTab.setValue("PaymentRule", newPaymentRule);
+
+ if (!newDateAcct.equals(m_DateAcct))
+ m_mTab.setValue("DateAcct", newDateAcct);
+
+ if (newC_PaymentTerm_ID != m_C_PaymentTerm_ID)
+ m_mTab.setValue("C_PaymentTerm_ID", new Integer(newC_PaymentTerm_ID));
+
+ // Set Payment
+
+ if (m_mPayment.getC_Payment_ID() != m_C_Payment_ID)
+ {
+ if (m_mPayment.getC_Payment_ID() == 0)
+ m_mTab.setValue("C_Payment_ID", null);
+ else
+ m_mTab.setValue("C_Payment_ID", new Integer(m_mPayment.getC_Payment_ID()));
+ }
+
+ // Set Cash
+
+ if (newC_CashLine_ID != m_C_CashLine_ID)
+ {
+ if (newC_CashLine_ID == 0)
+ m_mTab.setValue("C_CashLine_ID", null);
+ else
+ m_mTab.setValue("C_CashLine_ID", new Integer(newC_CashLine_ID));
+ }
+ return true;
+ } // saveChanges
+
+ /**
+ * Check Mandatory
+ * @return true if all mandatory items are OK
+ */
+
+ private boolean checkMandatory()
+ {
+ log.config( "WPayment.checkMandatory");
+
+ ListItem listitem = new ListItem();
+ listitem = paymentCombo.getSelectedItem();
+ ValueNamePair vp = (ValueNamePair)listitem.getValue();
+ String PaymentRule = vp.getValue();
+
+ // only Payment Rule
+
+ if (m_onlyRule)
+ return true;
+
+ Timestamp DateAcct = m_DateAcct;
+ int C_PaymentTerm_ID = m_C_PaymentTerm_ID;
+ int C_CashBook_ID = m_C_CashBook_ID;
+ String CCType = m_CCType;
+ int C_BankAccount_ID = 0;
+
+ /***********************
+ * Mandatory Data Check
+ */
+
+ boolean dataOK = true;
+
+ // B (Cash) (Currency)
+
+ if (PaymentRule.equals(MOrder.PAYMENTRULE_Cash))
+ {
+ listitem = new ListItem();
+ listitem = bCashBookCombo.getSelectedItem();
+
+ KeyNamePair kp = null;
+
+ if (listitem != null)
+ kp = (KeyNamePair)listitem.getValue();
+
+ if (kp != null)
+ C_CashBook_ID = kp.getKey();
+
+ DateAcct = (Timestamp)bDateField.getValue();
+ }
+
+ // K (CreditCard) Type, Number, Exp, Approval
+
+ else if (PaymentRule.equals(MOrder.PAYMENTRULE_CreditCard))
+ {
+ listitem = kTypeCombo.getSelectedItem();
+
+ if (listitem != null)
+ vp = (ValueNamePair)listitem.getValue();
+ else
+ vp = null;
+
+ if (vp != null)
+ CCType = vp.getValue();
+
+ String error = MPaymentValidate.validateCreditCardNumber(kNumberField.getText(), CCType);
+
+ if (error.length() != 0)
+ {
+ //kNumberField.setBackground(AdempierePLAF.getFieldBackground_Error());
+
+ if (error.indexOf('?') == -1)
+ {
+ FDialog.error(m_WindowNo, this, error);
+ dataOK = false;
+ }
+ else // warning
+ {
+ if (!FDialog.ask(m_WindowNo, this, error))
+ dataOK = false;
+ }
+ }
+
+ error = MPaymentValidate.validateCreditCardExp(kExpField.getText());
+
+ if (error.length() != 0)
+ {
+ //kExpField.setBackground(AdempierePLAF.getFieldBackground_Error());
+ FDialog.error(m_WindowNo, this, error);
+ dataOK = false;
+ }
+ }
+
+ // T (Transfer) BPartner_Bank
+
+ else if (PaymentRule.equals(X_C_Order.PAYMENTRULE_DirectDeposit)
+ || PaymentRule.equals(X_C_Order.PAYMENTRULE_DirectDebit))
+ {
+ listitem = tAccountCombo.getSelectedItem();
+
+ KeyNamePair bpba = null;
+
+ if (listitem != null)
+ bpba = (KeyNamePair)listitem.getValue();
+
+ if (bpba == null)
+ {
+ //tAccountCombo.setBackground(AdempierePLAF.getFieldBackground_Error());
+ FDialog.error(m_WindowNo, this, "PaymentBPBankNotFound");
+ dataOK = false;
+ }
+ } // Direct
+
+ // P (PaymentTerm) PaymentTerm
+
+ else if (PaymentRule.equals(X_C_Order.PAYMENTRULE_OnCredit))
+ {
+ listitem = pTermCombo.getSelectedItem();
+
+ KeyNamePair kp = null;
+
+ if (listitem != null)
+ kp = (KeyNamePair)listitem.getValue();
+
+ if (kp != null)
+ C_PaymentTerm_ID = kp.getKey();
+ }
+
+ // S (Check) (Currency) CheckNo, Routing
+
+ else if (PaymentRule.equals(MOrder.PAYMENTRULE_Check))
+ {
+ // sCurrencyCombo.getSelectedItem();
+ listitem = sBankAccountCombo.getSelectedItem();
+
+ KeyNamePair kp = null;
+
+ if (listitem != null)
+ kp = (KeyNamePair)listitem.getValue();
+
+ if (kp != null)
+ C_BankAccount_ID = kp.getKey();
+
+ String error = MPaymentValidate.validateRoutingNo(sRoutingField.getText());
+
+ if (error.length() != 0)
+ {
+ //sRoutingField.setBackground(AdempierePLAF.getFieldBackground_Error());
+ FDialog.error(m_WindowNo, this, error);
+ dataOK = false;
+ }
+
+ error = MPaymentValidate.validateAccountNo(sNumberField.getText());
+
+ if (error.length() != 0)
+ {
+ //sNumberField.setBackground(AdempierePLAF.getFieldBackground_Error());
+ FDialog.error(m_WindowNo, this, error);
+ dataOK = false;
+ }
+
+ error = MPaymentValidate.validateCheckNo(sCheckField.getText());
+
+ if (error.length() != 0)
+ {
+ //sCheckField.setBackground(AdempierePLAF.getFieldBackground_Error());
+ FDialog.error(m_WindowNo, this, error);
+ dataOK = false;
+ }
+ }
+ else
+ {
+ log.log(Level.SEVERE, "Unknown PaymentRule " + PaymentRule);
+ return false;
+ }
+
+ // find Bank Account if not qualified yet
+
+ if ("KTSD".indexOf(PaymentRule) != -1 && C_BankAccount_ID == 0)
+ {
+ String tender = MPayment.TENDERTYPE_CreditCard;
+
+ if (PaymentRule.equals(MOrder.PAYMENTRULE_DirectDeposit))
+ tender = MPayment.TENDERTYPE_DirectDeposit;
+ else if (PaymentRule.equals(MOrder.PAYMENTRULE_DirectDebit))
+ tender = MPayment.TENDERTYPE_DirectDebit;
+ else if (PaymentRule.equals(MOrder.PAYMENTRULE_Check))
+ tender = MPayment.TENDERTYPE_Check;
+
+ // Check must have a bank account
+
+ if (C_BankAccount_ID == 0 && "S".equals(PaymentRule))
+ {
+ FDialog.error(m_WindowNo, this, "PaymentNoProcessor");
+ dataOK = false;
+ }
+ }
+
+ log.config("OK=" + dataOK);
+ return dataOK;
+ } // checkMandatory
+
+ /**
+ * Get Invoice ID for Order
+ * @param C_Order_ID order
+ * @return C_Invoice_ID or 0 if not found
+ */
+
+ private static int getInvoiceID (int C_Order_ID)
+ {
+ int retValue = 0;
+ String sql = "SELECT C_Invoice_ID FROM C_Invoice WHERE C_Order_ID=? "
+ + "ORDER BY C_Invoice_ID DESC"; // last invoice
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql, null);
+ pstmt.setInt(1, C_Order_ID);
+ ResultSet rs = pstmt.executeQuery();
+
+ if (rs.next())
+ retValue = rs.getInt(1);
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql, e);
+ }
+ return retValue;
+ } // getInvoiceID
+
+ /**************************************************************************
+ * Process Online (sales only) - if approved - exit
+ */
+
+ private void processOnline()
+ {
+ log.config("");
+
+ if (!checkMandatory())
+ return;
+
+ boolean approved = false;
+ String info = "";
+
+ ListItem listitem = new ListItem();
+ listitem = paymentCombo.getSelectedItem();
+ ValueNamePair vp = (ValueNamePair)listitem.getValue();
+ String PaymentRule = vp.getValue();
+
+ // -- CreditCard
+
+ if (PaymentRule.equals(X_C_Order.PAYMENTRULE_CreditCard))
+ {
+ listitem = kTypeCombo.getSelectedItem();
+ vp = (ValueNamePair)listitem.getValue();
+ String CCType = vp.getValue();
+
+ m_mPayment.setCreditCard(MPayment.TRXTYPE_Sales, CCType,
+ kNumberField.getText(), "", kExpField.getText());
+ m_mPayment.setAmount(m_C_Currency_ID, m_Amount);
+ m_mPayment.setPaymentProcessor();
+ m_mPayment.setC_BPartner_ID(m_C_BPartner_ID);
+
+ int C_Invoice_ID = Env.getContextAsInt(Env.getCtx(), m_WindowNo, "C_Invoice_ID");
+
+ if (C_Invoice_ID == 0 && m_DocStatus.equals("CO"))
+ {
+ int C_Order_ID = Env.getContextAsInt(Env.getCtx(), m_WindowNo, "C_Order_ID");
+ C_Invoice_ID = getInvoiceID (C_Order_ID);
+ }
+
+ m_mPayment.setC_Invoice_ID(C_Invoice_ID);
+ m_mPayment.setDateTrx(m_DateAcct);
+
+ // Set Amount
+
+ m_mPayment.setAmount(m_C_Currency_ID, m_Amount);
+
+ approved = m_mPayment.processOnline();
+ info = m_mPayment.getR_RespMsg() + " (" + m_mPayment.getR_AuthCode()
+ + ") ID=" + m_mPayment.getR_PnRef();
+ boolean saved = m_mPayment.save();
+
+ if (approved)
+ {
+ boolean ok = m_mPayment.processIt(DocAction.ACTION_Complete);
+ m_mPayment.save();
+
+ if (ok)
+ FDialog.info(m_WindowNo, this, "PaymentProcessed", info + "\n" + m_mPayment.getDocumentNo());
+ else
+ FDialog.error(m_WindowNo, this, "PaymentError", "PaymentNotCreated");
+
+ saveChanges();
+ //dispose();
+ }
+ else
+ {
+ FDialog.error(m_WindowNo, this, "PaymentNotProcessed", info);
+ }
+ }
+ else
+ FDialog.error(m_WindowNo, this, "PaymentNoProcessor");
+ } // online
+
+ /**
+ * Need Save record (payment with waiting order)
+ * @return true if payment with waiting order
+ */
+
+ public boolean needSave()
+ {
+ return m_needSave;
+ } // needSave
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WSQLProcess.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WSQLProcess.java
new file mode 100644
index 0000000000..004ed3c752
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WSQLProcess.java
@@ -0,0 +1,175 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
+ * or via info@compiere.org or http://www.compiere.org/license.html *
+ *****************************************************************************/
+
+/**
+ * 2007, Modified by Posterita Ltd.
+ */
+
+package org.adempiere.webui.apps.form;
+
+import org.adempiere.webui.component.Button;
+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.panel.ADForm;
+import org.compiere.apps.form.VSQLProcess;
+import org.compiere.util.CLogger;
+import org.compiere.util.Env;
+import org.compiere.util.Msg;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zk.ui.event.Events;
+
+/**
+ * A Custom Form to specify and process SQL statements.
+ *
+ * The range of statement types that can be performed can be restricted
+ * by allowing or disallowing DML statements.
+ *
+ * @author Andrew Kimball
+ *
+ */
+public class WSQLProcess extends ADForm implements EventListener
+{
+
+ /** Serial Version Unique Identifier. */
+ private static final long serialVersionUID = 1L;
+
+ /** Log. */
+ private static CLogger log = CLogger.getCLogger(VSQLProcess.class);
+
+ /** Grid used to layout components. */
+ private Grid m_grdMain = new Grid();
+ /** SQL label. */
+ private Label m_lblSql = new Label("SQL");
+ /** SQL statement field. */
+ private Textbox m_txbSqlField = new Textbox();
+ /** Process button. */
+ private Button m_btnSql = createProcessButton();
+ /** Field to hold result of SQL statement execution. */
+ private Textbox m_txbResultField = new Textbox();
+
+ /**
+ * Default constructor.
+ */
+ public WSQLProcess()
+ {
+ super();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.adempiere.webui.panel.ADForm#init(int, java.lang.String)
+ */
+ public void init(int adFormId, String name)
+ {
+ Row rwTop = new Row();
+ Row rwBottom = new Row();
+ Rows rows = new Rows();
+ final int noColumns = 60;
+ final int maxStatementLength = 9000;
+ final int noStatementRows = 3;
+ final int noResultRows = 20;
+
+ super.init(adFormId, name);
+
+ m_grdMain.setWidth("80%");
+
+ // create the top row of components
+ m_txbSqlField.setMultiline(true);
+ m_txbSqlField.setMaxlength(maxStatementLength);
+ m_txbSqlField.setRows(noStatementRows);
+ m_txbSqlField.setCols(noColumns);
+ m_txbSqlField.setReadonly(false);
+
+ m_btnSql.addEventListener(Events.ON_CLICK, this);
+
+ rwTop.appendChild(m_lblSql);
+ rwTop.appendChild(m_txbSqlField);
+ rwTop.appendChild(m_btnSql);
+
+ rows.appendChild(rwTop);
+
+ // create the bottom row of components
+ m_txbResultField.setCols(noColumns);
+ m_txbResultField.setRows(noResultRows);
+ m_txbResultField.setReadonly(true);
+
+ rwBottom.appendChild(m_txbResultField);
+ rwBottom.setSpans("3");
+ rwBottom.setAlign("center");
+
+ rows.appendChild(rwBottom);
+
+ // put it all together
+ m_grdMain.appendChild(rows);
+
+ this.appendChild(m_grdMain);
+
+ return;
+ }
+
+ /**
+ * Create Process Button.
+ * @return button
+ */
+ public static final Button createProcessButton()
+ {
+ Button btnProcess = new Button();
+
+ btnProcess.setImage("/images/Process24.gif");
+ btnProcess.setName(Msg.getMsg(Env.getCtx(), "Process"));
+
+ return btnProcess;
+ } // createProcessButton
+
+ /**
+ * Process a semicolon delimitted list of SQL Statements.
+ *
+ * @param sqlStatements one or more statements separated by a semicolon (';')
+ * @param allowDML whether to allow DML statements
+ * @return a string summarising the results
+ */
+ public static String processStatements (String sqlStatements, boolean allowDML)
+ {
+ return VSQLProcess.processStatements(sqlStatements, allowDML);
+ }
+
+ /**
+ * Process SQL Statements.
+ *
+ * @param sqlStatement a single SQL statement
+ * @param allowDML whether to allow DML statements
+ * @return a string summarising the results
+ */
+ public static String processStatement (String sqlStatement, boolean allowDML)
+ {
+ return VSQLProcess.processStatement(sqlStatement, allowDML);
+ }
+
+
+ /*
+ * (non-Javadoc)
+ * @see org.adempiere.webui.panel.ADForm#onEvent(org.zkoss.zk.ui.event.Event)
+ */
+ public void onEvent(Event event) throws Exception
+ {
+ m_txbResultField.setText(processStatements (m_txbSqlField.getText(), false));
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WTrxMaterial.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WTrxMaterial.java
new file mode 100644
index 0000000000..b6a74129c3
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/apps/form/WTrxMaterial.java
@@ -0,0 +1,628 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
+ * or via info@compiere.org or http://www.compiere.org/license.html *
+ *****************************************************************************/
+
+/**
+ * 2007, Modified by Posterita Ltd.
+ */
+
+package org.adempiere.webui.apps.form;
+
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Properties;
+import java.util.logging.Level;
+
+import javax.swing.table.AbstractTableModel;
+
+import org.adempiere.webui.apps.AEnv;
+import org.adempiere.webui.component.ConfirmPanel;
+import org.adempiere.webui.component.Datebox;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.Panel;
+import org.adempiere.webui.component.VerticalBox;
+import org.adempiere.webui.component.WStatusBar;
+import org.adempiere.webui.editor.WEditor;
+import org.adempiere.webui.editor.WLocatorEditor;
+import org.adempiere.webui.editor.WSearchEditor;
+import org.adempiere.webui.editor.WTableDirEditor;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.event.ValueChangeListener;
+import org.adempiere.webui.panel.ADForm;
+import org.compiere.model.GridField;
+import org.compiere.model.GridTab;
+import org.compiere.model.GridTable;
+import org.compiere.model.GridWindow;
+import org.compiere.model.GridWindowVO;
+import org.compiere.model.MLocatorLookup;
+import org.compiere.model.MLookup;
+import org.compiere.model.MLookupFactory;
+import org.compiere.model.MQuery;
+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.NamePair;
+import org.zkforge.yuiext.grid.Column;
+import org.zkforge.yuiext.grid.Columns;
+import org.zkforge.yuiext.grid.Grid;
+import org.zkforge.yuiext.grid.Row;
+import org.zkforge.yuiext.grid.Rows;
+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.Hbox;
+import org.zkoss.zul.Separator;
+
+public class WTrxMaterial extends ADForm implements EventListener, ValueChangeListener
+{
+ private static final long serialVersionUID = 1L;
+
+ /** Window No */
+ private int m_WindowNo = 0;
+
+ /** FormFrame */
+ //private FormFrame m_frame;
+
+ /** GridController */
+ private Grid m_gridController = new Grid();
+ private Columns columns = new Columns();
+ private Rows rows = new Rows();
+
+ /** MWindow */
+ private GridWindow m_mWindow = null;
+
+ /** MTab pointer */
+ private GridTab m_mTab = null;
+
+ private MQuery m_staticQuery = null;
+
+ /** Logger */
+ private static CLogger log = CLogger.getCLogger(WTrxMaterial.class);
+
+ private VerticalBox mainPanel = new VerticalBox();
+ private Hbox parameterPanel = new Hbox();
+ private Label orgLabel = new Label();
+ private WEditor orgField;
+ private Label locatorLabel = new Label();
+ private WLocatorEditor locatorField;
+ private Label productLabel = new Label();
+ private WEditor productField;
+ private Label dateFLabel = new Label();
+ private Datebox dateFField;
+ private Label dateTLabel = new Label();
+ private Datebox dateTField;
+ private Label mtypeLabel = new Label();
+ private WEditor mtypeField;
+ private Panel southPanel = new Panel();
+ private ConfirmPanel confirmPanel = new ConfirmPanel(true, true, false, false, false, true);
+ private WStatusBar statusBar = new WStatusBar();
+
+ public WTrxMaterial()
+ {
+ init(super.m_windowNo);
+ }
+
+ /**
+ * Initialize Panel
+ * @param WindowNo window
+ * @param frame frame
+ */
+
+ public void init (int WindowNo)
+ {
+ log.info("");
+ m_WindowNo = WindowNo;
+
+ try
+ {
+ dynParameter();
+ jbInit();
+ dynInit();
+
+ this.appendChild(mainPanel);
+ this.appendChild(statusBar);
+ }
+ catch(Exception ex)
+ {
+ log.log(Level.SEVERE, "", ex);
+ }
+ } // init
+
+ /**
+ * Static Init
+ * @throws Exception
+ */
+
+ void jbInit() throws Exception
+ {
+ orgLabel.setValue(Msg.translate(Env.getCtx(), "AD_Org_ID"));
+ locatorLabel.setValue(Msg.translate(Env.getCtx(), "M_Locator_ID"));
+ productLabel.setValue(Msg.translate(Env.getCtx(), "Product"));
+ dateFLabel.setValue(Msg.translate(Env.getCtx(), "DateFrom"));
+ dateTLabel.setValue(Msg.translate(Env.getCtx(), "DateTo"));
+ mtypeLabel.setValue(Msg.translate(Env.getCtx(), "MovementType"));
+
+ m_gridController.setWidth("900px");
+ m_gridController.setHeight("550px");
+
+ mainPanel.setWidth("100%");
+ mainPanel.appendChild(new Separator());
+ mainPanel.appendChild(parameterPanel);
+ mainPanel.appendChild(new Separator());
+ mainPanel.appendChild(m_gridController);
+ mainPanel.appendChild(new Separator());
+
+ Hbox boxOrg = new Hbox();
+ boxOrg.setWidth("100%");
+ boxOrg.setWidth("35%, 75%");
+ boxOrg.appendChild(orgLabel);
+ boxOrg.appendChild(orgField.getComponent());
+
+ Hbox boxMType = new Hbox();
+ boxMType.setWidth("100%");
+ boxMType.setWidth("35%, 75%");
+ boxMType.appendChild(mtypeLabel);
+ boxMType.appendChild(mtypeField.getComponent());
+
+ Hbox boxDateF = new Hbox();
+ boxDateF.setWidth("100%");
+ boxDateF.setWidth("35%, 75%");
+ boxDateF.appendChild(dateFLabel);
+ boxDateF.appendChild(dateFField);
+
+ Hbox boxLocator = new Hbox();
+ boxLocator.setWidth("100%");
+ boxLocator.setWidth("35%, 75%");
+ boxLocator.appendChild(locatorLabel);
+ boxLocator.appendChild(locatorField.getComponent());
+
+ Hbox boxProduct = new Hbox();
+ boxProduct.setWidth("100%");
+ boxProduct.setWidth("35%, 75%");
+ boxProduct.appendChild(productLabel);
+ boxProduct.appendChild(productField.getComponent());
+
+ Hbox boxDateT = new Hbox();
+ boxDateT.setWidth("100%");
+ boxDateT.setWidth("35%, 75%");
+ boxDateT.appendChild(dateTLabel);
+ boxDateT.appendChild(dateTField);
+
+ VerticalBox boxCol1 = new VerticalBox();
+ boxCol1.setWidth("100%");
+ boxCol1.appendChild(boxOrg);
+ boxCol1.appendChild(boxLocator);
+
+ VerticalBox boxCol2 = new VerticalBox();
+ boxCol2.setWidth("100%");
+ boxCol2.appendChild(boxMType);
+ boxCol2.appendChild(boxProduct);
+
+ VerticalBox boxCol3 = new VerticalBox();
+ boxCol3.setWidth("100%");
+ boxCol3.appendChild(boxDateF);
+ boxCol3.appendChild(boxDateT);
+
+ parameterPanel.setWidth("100%");
+ parameterPanel.setStyle("text-align:right");
+ parameterPanel.appendChild(boxCol1);
+ parameterPanel.appendChild(new Separator());
+ parameterPanel.appendChild(boxCol2);
+ parameterPanel.appendChild(new Separator());
+ parameterPanel.appendChild(boxCol3);
+
+ southPanel.appendChild(confirmPanel);
+ southPanel.appendChild(new Separator());
+ southPanel.appendChild(statusBar);
+
+ mainPanel.appendChild(southPanel);
+
+ this.setWidth("100%");
+ this.appendChild(mainPanel);
+ }
+
+ /**
+ * Initialize Parameter fields
+ * @throws Exception if Lookups cannot be initialized
+ */
+
+ private void dynParameter() throws Exception
+ {
+ Properties ctx = Env.getCtx();
+ // Organization
+
+ MLookup orgLookup = MLookupFactory.get (ctx, m_WindowNo, 0, 3660, DisplayType.TableDir);
+ orgField = new WTableDirEditor(orgLookup, "AD_Org_ID", "", false, false, true);
+ orgField.addValueChangeListner(this);
+
+ // Locator
+ MLocatorLookup locatorLookup = new MLocatorLookup(ctx, m_WindowNo);
+ locatorField = new WLocatorEditor ("M_Locator_ID", false, false, true, locatorLookup);
+ locatorField.addValueChangeListner(this);
+
+ // Product
+ MLookup productLookup = MLookupFactory.get (ctx, m_WindowNo, 0, 3668, DisplayType.Search);
+ productField = new WSearchEditor(productLookup, "M_Product_ID", "", false, false, true);
+ productField.addValueChangeListner(this);
+
+ // Movement Type
+ MLookup mtypeLookup = MLookupFactory.get (ctx, m_WindowNo, 0, 3666, DisplayType.List);
+ mtypeField = new WTableDirEditor(mtypeLookup, "MovementType", "", false, false, true);
+ mtypeField.addValueChangeListner(this);
+
+ // Dates
+ dateFField = new Datebox();//"DateFrom", false, false, true, DisplayType.Date, Msg.getMsg(Env.getCtx(), "DateFrom"));
+ dateTField = new Datebox();//"DateTo", false, false, true, DisplayType.Date, Msg.getMsg(Env.getCtx(), "DateTo"));
+
+ confirmPanel.addActionListener(Events.ON_CLICK, this);
+ statusBar.setStatusLine("");
+ } // dynParameter
+
+ /**
+ * Dynamic Layout (Grid).
+ * Based on AD_Window: Material Transactions
+ */
+ private void dynInit()
+ {
+ m_staticQuery = new MQuery();
+ m_staticQuery.addRestriction("AD_Client_ID", MQuery.EQUAL, Env.getAD_Client_ID(Env.getCtx()));
+ int AD_Window_ID = 223; // Hardcoded
+ GridWindowVO wVO = AEnv.getMWindowVO (m_WindowNo, AD_Window_ID, 0);
+
+ if (wVO == null)
+ return;
+
+ m_mWindow = new GridWindow (wVO);
+ m_mTab = m_mWindow.getTab(0);
+ m_mWindow.initTab(0);
+
+ populateGrid();
+
+ //m_gridController.initGrid(m_mTab, true, m_WindowNo, null, null);
+ //mainPanel.add(m_gridController, BorderLayout.CENTER);
+
+ m_mTab.setQuery(MQuery.getEqualQuery("1", "2"));
+ m_mTab.query(false);
+ statusBar.setStatusLine(" ", false);
+ statusBar.setStatusDB(" ");
+ } // dynInit
+
+ private void populateGrid()
+ {
+ m_gridController.getChildren().clear();
+ m_gridController.appendChild(columns);
+ m_gridController.appendChild(rows);
+
+ columns.getChildren().clear();
+
+ Column column = new Column();
+
+ AbstractTableModel tableModel = m_mTab.getTableModel();
+ GridField[] gridfields = ((GridTable)tableModel).getFields();
+
+ for (int i = 0; i < gridfields.length; i++)
+ {
+ if (gridfields[i].isDisplayed())
+ {
+ column = new Column(gridfields[i].getHeader());
+ columns.appendChild(column);
+ }
+ }
+
+ rows.getChildren().clear();
+
+ for (int i = 0; i < tableModel.getRowCount(); i++)
+ {
+ Row row = new Row();
+
+ for (int j = 0; j < tableModel.getColumnCount(); j++)
+ {
+ org.zkforge.yuiext.grid.Label lab = new org.zkforge.yuiext.grid.Label();
+
+ Label label = new Label("");
+
+ if (!gridfields[j].isDisplayed())
+ break;
+
+ Object obj = tableModel.getValueAt(i, j);
+
+ if (obj != null)
+ {
+ if (tableModel.getColumnClass(j).equals(String.class))
+ {
+ label.setValue(obj.toString());
+ }
+ else if (tableModel.getColumnClass(j).equals(BigDecimal.class))
+ {
+ label.setValue(obj.toString());
+ }
+ else if (tableModel.getColumnClass(j).equals(Integer.class))
+ {
+ if (gridfields[j].isLookup())
+ {
+ MLookup lookup = MLookupFactory.get(Env.getCtx(), super.m_windowNo,
+ 0, gridfields[j].getAD_Column_ID(), gridfields[j].getDisplayType());
+
+ NamePair namepair = lookup.get(obj);
+
+ if (namepair != null)
+ label.setValue(namepair.getName());
+ else
+ label.setValue("");
+ }
+ }
+ else if (tableModel.getColumnClass(j).equals(Timestamp.class))
+ {
+ SimpleDateFormat dateFormat = DisplayType.getDateFormat(DisplayType.Date);
+ label.setValue(dateFormat.format((Timestamp)obj));
+ }
+ else
+ label.setValue("Missing Class");
+ }
+
+ lab = new org.zkforge.yuiext.grid.Label(label.getValue());
+ row.appendChild(lab);
+ }
+ rows.appendChild(row);
+ }
+ }
+
+ /**
+ * Dispose
+ */
+ public void dispose()
+ {
+ /*if (m_gridController != null)
+ m_gridController.dispose();
+ */
+ m_gridController = null;
+ m_mTab = null;
+
+ if (m_mWindow != null)
+ m_mWindow.dispose();
+
+ m_mWindow = null;
+
+ orgField = null;
+ locatorField = null;
+ productField = null;
+ mtypeField = null;
+ dateFField = null;
+ dateTField = null;
+ } // dispose
+
+
+ /**************************************************************************
+ * Action Listener
+ * @param e event
+ */
+
+ public void onEvent(Event event) throws Exception
+ {
+ if (confirmPanel.getButton("Cancel").equals(event.getTarget()))
+ dispose();
+ else if (confirmPanel.getButton("Refresh").equals(event.getTarget())
+ || confirmPanel.getButton("Ok").equals(event.getTarget()))
+ refresh();
+ else if (confirmPanel.getButton("Zoom").equals(event.getTarget()))
+ zoom();
+
+ }
+
+ /**************************************************************************
+ * Property Listener
+ * @param e event
+ */
+
+ public void valueChange(ValueChangeEvent evt)
+ {
+ if (evt.getPropertyName().equals("M_Product_ID"))
+ productField.setValue(evt.getNewValue());
+ }
+
+ /**************************************************************************
+ * Refresh - Create Query and refresh grid
+ */
+
+ private void refresh()
+ {
+ /**
+ * Create Where Clause
+ */
+
+ MQuery query = m_staticQuery.deepCopy();
+
+ // Organization
+ Object value = null;
+ if (orgField.getDisplay() != "")
+ value = orgField.getValue();
+ if (value != null && value.toString().length() > 0)
+ query.addRestriction("AD_Org_ID", MQuery.EQUAL, value);
+
+ // Locator
+ value = null;
+ if (locatorField.getDisplay() != "")
+ value = locatorField.getValue();
+ if (value != null && value.toString().length() > 0)
+ query.addRestriction("M_Locator_ID", MQuery.EQUAL, value);
+
+ // Product
+ value = null;
+ if (productField.getDisplay() != "")
+ value = productField.getValue();
+ if (value != null && value.toString().length() > 0)
+ query.addRestriction("M_Product_ID", MQuery.EQUAL, value);
+
+ // MovementType
+ value = null;
+ if (mtypeField.getDisplay() != "")
+ value = mtypeField.getValue();
+ if (value != null && value.toString().length() > 0)
+ query.addRestriction("MovementType", MQuery.EQUAL, value);
+
+ // DateFrom
+ Date f = null;
+ Timestamp ts =null;
+
+ if (dateFField.getValue() != null)
+ {
+ f = dateFField.getValue();
+ ts = new Timestamp(f.getTime());
+ }
+
+ if (ts != null)
+ query.addRestriction("TRUNC(MovementDate)", MQuery.GREATER_EQUAL, ts);
+
+ // DateTO
+ Date t = null;
+ ts = null;
+
+ if (dateTField.getValue() != null)
+ {
+ t = dateTField.getValue();
+ ts = new Timestamp(t.getTime());
+ }
+
+ if (ts != null)
+ query.addRestriction("TRUNC(MovementDate)", MQuery.LESS_EQUAL, ts);
+ log.info( "VTrxMaterial.refresh query=" + query.toString());
+
+ /**
+ * Refresh/Requery
+ */
+
+ statusBar.setStatusLine(Msg.getMsg(Env.getCtx(), "StartSearch"), false);
+
+ m_mTab.setQuery(query);
+ m_mTab.query(false);
+
+ int no = m_mTab.getRowCount();
+ statusBar.setStatusLine(" ", false);
+ statusBar.setStatusDB(Integer.toString(no));
+
+ populateGrid();
+ } // refresh
+
+ /**
+ * Zoom
+ */
+
+ private void zoom()
+ {
+ log.info("");
+
+ int AD_Window_ID = 0;
+ String ColumnName = null;
+ String SQL = null;
+
+ int lineID = Env.getContextAsInt(Env.getCtx(), m_WindowNo, "M_InOutLine_ID");
+
+ if (lineID != 0)
+ {
+ log.fine("M_InOutLine_ID=" + lineID);
+
+ if (Env.getContext(Env.getCtx(), m_WindowNo, "MovementType").startsWith("C"))
+ AD_Window_ID = 169; // Customer
+ else
+ AD_Window_ID = 184; // Vendor
+ ColumnName = "M_InOut_ID";
+ SQL = "SELECT M_InOut_ID FROM M_InOutLine WHERE M_InOutLine_ID=?";
+ }
+ else
+ {
+ lineID = Env.getContextAsInt(Env.getCtx(), m_WindowNo, "M_InventoryLine_ID");
+
+ if (lineID != 0)
+ {
+ log.fine("M_InventoryLine_ID=" + lineID);
+ AD_Window_ID = 168;
+ ColumnName = "M_Inventory_ID";
+ SQL = "SELECT M_Inventory_ID FROM M_InventoryLine WHERE M_InventoryLine_ID=?";
+ }
+ else
+ {
+ lineID = Env.getContextAsInt(Env.getCtx(), m_WindowNo, "M_MovementLine_ID");
+
+ if (lineID != 0)
+ {
+ log.fine("M_MovementLine_ID=" + lineID);
+ AD_Window_ID = 170;
+ ColumnName = "M_Movement_ID";
+ SQL = "SELECT M_Movement_ID FROM M_MovementLine WHERE M_MovementLine_ID=?";
+ }
+ else
+ {
+ lineID = Env.getContextAsInt(Env.getCtx(), m_WindowNo, "M_ProductionLine_ID");
+
+ if (lineID != 0)
+ {
+ log.fine("M_ProductionLine_ID=" + lineID);
+ AD_Window_ID = 191;
+ ColumnName = "M_Production_ID";
+ SQL = "SELECT M_Production_ID FROM M_ProductionLine WHERE M_ProductionLine_ID=?";
+ }
+ else
+ log.fine("Not found WindowNo=" + m_WindowNo);
+ }
+ }
+ }
+
+ if (AD_Window_ID == 0)
+ return;
+
+ // Get Parent ID
+ int parentID = 0;
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(SQL, null);
+ pstmt.setInt(1, lineID);
+ ResultSet rs = pstmt.executeQuery();
+
+ if (rs.next())
+ parentID = rs.getInt(1);
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, SQL, e);
+ }
+
+ MQuery query = MQuery.getEqualQuery(ColumnName, parentID);
+ log.config("AD_Window_ID=" + AD_Window_ID + " - " + query);
+
+ if (parentID == 0)
+ log.log(Level.SEVERE, "No ParentValue - " + SQL + " - " + lineID);
+
+ // Zoom
+ AEnv.zoom(AD_Window_ID, query);
+/* ADWindow frame = new ADWindow(Env.getCtx(), AD_Window_ID);
+
+ if (frame == null)
+ return;
+
+ SessionManager.getAppDesktop().showWindow(frame);
+ frame = null;
+*/ } // zoom
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/AutoComplete.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/AutoComplete.java
new file mode 100644
index 0000000000..ebd8816df7
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/AutoComplete.java
@@ -0,0 +1,166 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import java.util.Arrays;
+
+import org.zkoss.zk.ui.event.InputEvent;
+import org.zkoss.zul.Comboitem;
+
+/**
+ * Auto-complete with combobox.
+ * Based on ZK's Auto-complete
+ *
+ * @author Niraj Sohun
+ * Aug 20, 2007
+ */
+
+public class AutoComplete extends Combobox
+{
+ private static final long serialVersionUID = 1L;
+
+ /** comboItems All menu labels */
+ private static String[] comboItems;
+
+ /** strDescription Description of menu items */
+ private static String[] strDescription;
+
+ /**
+ * Set menu labels
+ *
+ * @param vals Menu labels
+ */
+
+ public void setDict(String[] vals)
+ {
+ comboItems = vals;
+
+ if (comboItems != null)
+ {
+ Arrays.sort(comboItems);
+ }
+ }
+
+ /**
+ * Set description of menu items
+ *
+ * @param vals Description of menu items
+ */
+
+ public void setDescription(String[] vals)
+ {
+ strDescription = vals;
+ }
+
+ /**
+ * Constructor
+ */
+
+ public AutoComplete()
+ {
+ if (comboItems != null)
+ refresh("");
+ }
+
+ public AutoComplete(String value)
+ {
+ super.setValue(value);
+ }
+
+ public void setValue(String value)
+ {
+ super.setValue(value);
+ refresh(value);
+ }
+
+ /**
+ * Event handler responsible to reducing number of items
+ * Method is invoked each time something is typed in the combobox
+ *
+ * @param evt The event
+ */
+
+ public void onChanging(InputEvent evt)
+ {
+ if (!evt.isChangingBySelectBack())
+ refresh(evt.getValue());
+ }
+
+ /**
+ * Refresh comboitem based on the specified value.
+ */
+
+ private void refresh(String val)
+ {
+ val = val.toLowerCase();
+
+/* int j = Arrays.binarySearch(comboItemsL, val);
+
+ if (j < 0)
+ j = -j-1;
+
+ Iterator it = getItems().iterator();
+
+ for (; j < comboItems.length; ++j)
+ {
+ if (!comboItemsL[j].contains(val))
+ break;
+
+ if (it != null && it.hasNext())
+ {
+ ((Comboitem)it.next()).setLabel(comboItems[j]);
+
+ //if (strDescription[j] != null)
+ // comboitem.setDescription(strDescription[j]);
+ }
+ else
+ {
+ it = null;
+
+ Comboitem comboitem = new Comboitem(comboItems[j]);
+
+ if (strDescription[j] != null)
+ comboitem.setDescription(strDescription[j]);
+
+ comboitem.setParent(this);
+ }
+ }
+
+ while (it != null && it.hasNext())
+ {
+ it.next();
+ it.remove();
+ }*/
+
+ super.getChildren().clear();
+
+ if ((val == null) || (val.trim() == null))
+ return;
+
+ for (int i = 0; i < comboItems.length; i++)
+ {
+ if (comboItems[i].toLowerCase().contains(val))
+ {
+ Comboitem comboitem = new Comboitem();
+ comboitem.setLabel(comboItems[i]);
+ comboitem.setDescription(strDescription[i]);
+ super.appendChild(comboitem);
+ }
+ }
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/BackgroundColours.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/BackgroundColours.java
new file mode 100644
index 0000000000..ecb2edb2f1
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/BackgroundColours.java
@@ -0,0 +1,27 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+public final class BackgroundColours
+{
+ public final static String MANDATORY = "background-color:#fbb5b5";
+
+ public final static String ERROR = "background-color:#ffffff";
+
+ public final static String CORRECT = "background-color:#d18ae3";
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Bandbox.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Bandbox.java
new file mode 100644
index 0000000000..525208f93e
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Bandbox.java
@@ -0,0 +1,34 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 11, 2007
+ * @version $Revision: 0.10 $
+ */
+public class Bandbox extends org.zkoss.zul.Bandbox
+{
+ private static final long serialVersionUID = 1L;
+
+ public void setEnabled(boolean enabled)
+ {
+ this.setDisabled(!enabled);
+ }
+}
\ No newline at end of file
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Button.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Button.java
new file mode 100644
index 0000000000..19113fd92b
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Button.java
@@ -0,0 +1,61 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 12, 2007
+ * @version $Revision: 0.10 $
+ */
+public class Button extends org.zkoss.zul.Button
+{
+ private static final long serialVersionUID = 1L;
+
+ private String name;
+
+ public Button()
+ {
+ super();
+ }
+
+ public Button(String label)
+ {
+ super(label);
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public String getName()
+ {
+ return this.name;
+ }
+
+ public void setEnabled(boolean enabled)
+ {
+ super.setDisabled(!enabled);
+ }
+
+ public boolean isEnabled()
+ {
+ return !super.isDisabled();
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/CWindowToolbar.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/CWindowToolbar.java
new file mode 100644
index 0000000000..381d116721
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/CWindowToolbar.java
@@ -0,0 +1,427 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.logging.Level;
+
+import org.adempiere.webui.constants.EventConstants;
+import org.adempiere.webui.event.ToolbarListener;
+import org.compiere.util.CLogger;
+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.Label;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class CWindowToolbar extends FToolbar implements EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private static final String BUTTON_WIDTH = "32px";
+
+ private static CLogger log = CLogger.getCLogger(CWindowToolbar.class);
+
+ private Button btnIgnore;
+
+ private Button btnHelp, btnNew, btnDelete, btnSave;
+
+ private Button btnRefresh, btnFind, btnAttachment;
+
+ private Button btnGridToggle;
+
+ private Button btnHistoryRecords, btnMenu, btnParentRecord, btnDetailRecord;
+
+ private Button btnFirst, btnPrevious, btnNext, btnLast;
+
+ private Button btnReport, btnArchive, btnPrint;
+
+ private Button btnZoomAcross, btnActiveWorkflows, btnRequests, btnProductInfo;
+
+ private Button btnExit;
+
+ private ArrayList listeners = new ArrayList();
+
+ public CWindowToolbar()
+ {
+ init();
+ }
+
+ private void init()
+ {
+ btnIgnore = new Button("");
+ btnIgnore.setName("btnIgnore");
+ btnIgnore.setImage("/images/Ignore16.gif");
+ btnIgnore.setTooltiptext("Ignore Changes");
+ // --
+ btnHelp = new Button("");
+ btnHelp.setName("btnHelp");
+ btnHelp.setImage("/images/Help24.gif");
+ btnHelp.setTooltiptext("Help");
+
+ btnNew = new Button("");
+ btnNew.setName("btnNew");
+ btnNew.setImage("/images/New24.gif");
+ btnNew.setTooltiptext("New Record");
+
+ btnDelete = new Button("");
+ btnDelete.setName("btnDelete");
+ btnDelete.setImage("/images/Delete24.gif");
+ btnDelete.setTooltiptext("Delete current record");
+
+ btnSave = new Button("");
+ btnSave.setName("btnSave");
+ btnSave.setImage("/images/Save24.gif");
+ btnSave.setTooltiptext("Save changes");
+ // --
+ btnRefresh = new Button("");
+ btnRefresh.setName("btnRefresh");
+ btnRefresh.setImage("/images/Refresh24.gif");
+ btnRefresh.setTooltiptext("Refresh Data");
+
+ btnFind = new Button("");
+ btnFind.setName("btnFind");
+ btnFind.setImage("/images/Find24.gif");
+ btnFind.setTooltiptext("Find Records");
+
+ btnAttachment = new Button("");
+ btnAttachment.setName("btnAttachment");
+ btnAttachment.setImage("/images/Attachment24.gif");
+ btnAttachment.setTooltiptext("Attachments");
+ // --
+
+ btnGridToggle = new Button("");
+ btnGridToggle.setName("btnGridToggle");
+ btnGridToggle.setImage("/images/ZoomAcross24.gif");
+ btnGridToggle.setTooltiptext("Grid Toggle");
+
+ btnHistoryRecords = new Button("");
+ btnHistoryRecords.setName("btnHistoryRecords");
+ btnHistoryRecords.setImage("/images/HistoryX24.gif");
+ btnHistoryRecords.setTooltiptext("History Records");
+
+ btnMenu = new Button("");
+ btnMenu.setName("btnHome");
+ btnMenu.setImage("/images/Home24.gif");
+ btnMenu.setTooltiptext("Home");
+
+ btnParentRecord = new Button("");
+ btnParentRecord.setName("btnParentRecord");
+ btnParentRecord.setImage("/images/Parent24.gif");
+
+ btnDetailRecord = new Button("");
+ btnDetailRecord.setName("btnDetailRecord");
+ btnDetailRecord.setImage("/images/Detail24.gif");
+ // --
+ btnFirst = new Button("");
+ btnFirst.setName("btnFirst");
+ btnFirst.setImage("/images/First24.gif");
+
+ btnPrevious = new Button("");
+ btnPrevious.setName("btnPrevious");
+ btnPrevious.setImage("/images/Previous24.gif");
+
+ btnNext = new Button("");
+ btnNext.setName("btnNext");
+ btnNext.setImage("/images/Next24.gif");
+
+ btnLast = new Button("");
+ btnLast.setName("btnLast");
+ btnLast.setImage("/images/Last24.gif");
+ // --
+ btnReport = new Button("");
+ btnReport.setName("btnReport");
+ btnReport.setImage("/images/Report24.gif");
+
+ btnArchive = new Button("");
+ btnArchive.setName("btnArchive");
+ btnArchive.setImage("/images/Archive24.gif");
+
+ btnPrint = new Button("");
+ btnPrint.setName("btnPrint");
+ btnPrint.setImage("/images/Print24.gif");
+ // --
+ btnZoomAcross = new Button("");
+ btnZoomAcross.setName("btnZoomAcross");
+ btnZoomAcross.setImage("/images/ZoomAcross24.gif");
+
+ btnActiveWorkflows = new Button("");
+ btnActiveWorkflows.setName("btnActiveWorkflows");
+ btnActiveWorkflows.setImage("/images/WorkFlow24.gif");
+
+ btnRequests = new Button("");
+ btnRequests.setName("btnRequests");
+ btnRequests.setImage("/images/Request24.gif");
+
+ btnProductInfo = new Button("");
+ btnProductInfo.setName("btnProductInfo");
+ btnProductInfo.setImage("/images/Product24.gif");
+
+ btnExit = new Button("");
+ btnExit.setName("btnExit");
+ btnExit.setImage("/images/End24.gif");
+
+ this.appendChild(btnIgnore);
+ addSeparator();
+ this.appendChild(btnHelp);
+ this.appendChild(btnNew);
+// this.appendChild(btnEdit);
+ this.appendChild(btnDelete);
+ this.appendChild(btnSave);
+ addSeparator();
+ this.appendChild(btnRefresh);
+ this.appendChild(btnFind);
+ this.appendChild(btnAttachment);
+ this.appendChild(btnGridToggle);
+ addSeparator();
+ this.appendChild(btnHistoryRecords);
+ this.appendChild(btnMenu);
+ this.appendChild(btnParentRecord);
+ this.appendChild(btnDetailRecord);
+ addSeparator();
+ this.appendChild(btnFirst);
+ this.appendChild(btnPrevious);
+ this.appendChild(btnNext);
+ this.appendChild(btnLast);
+ addSeparator();
+ this.appendChild(btnReport);
+ this.appendChild(btnArchive);
+ this.appendChild(btnPrint);
+ addSeparator();
+ //this.appendChild(btnZoomAcross);
+ this.appendChild(btnActiveWorkflows);
+ this.appendChild(btnRequests);
+ this.appendChild(btnProductInfo);
+ addSeparator();
+ this.appendChild(btnExit);
+
+ for (Object obj : this.getChildren())
+ {
+ if (obj instanceof Button)
+ {
+ ((Button)obj).setWidth(BUTTON_WIDTH);
+ ((Button)obj).addEventListener(Events.ON_CLICK, this);
+ ((Button)obj).setEnabled(false);
+ }
+ }
+
+ // Help and Exit should always be enabled
+ btnHelp.setEnabled(true);
+ btnExit.setEnabled(true);
+
+ // Testing Purposes
+
+ btnGridToggle.setEnabled(true);
+ }
+
+ protected void addSeparator()
+ {
+ Label lblSeparator = new Label();
+ lblSeparator.setWidth("3px");
+ lblSeparator.setHeight("16px");
+ lblSeparator.setValue(" ");
+ this.appendChild(lblSeparator);
+ }
+
+ public void addListener(ToolbarListener toolbarListener)
+ {
+ listeners.add(toolbarListener);
+ }
+
+ public void removeListener(ToolbarListener toolbarListener)
+ {
+ listeners.remove(toolbarListener);
+ }
+
+ public void onEvent(Event event)
+ {
+ String eventName = event.getName();
+ Component eventComp = event.getTarget();
+
+ Iterator listenerIter = listeners.iterator();
+ if(eventName.equals(EventConstants.ONCLICK))
+ {
+ if(eventComp instanceof Button)
+ {
+ Button cComponent = (Button) eventComp;
+ String compName = cComponent.getName();
+ String methodName = "on" + compName.substring(3);
+ while(listenerIter.hasNext())
+ {
+ try
+ {
+ ToolbarListener tListener = listenerIter.next();
+ Method method = tListener.getClass().getMethod(methodName, (Class[]) null);
+ method.invoke(tListener, (Object[]) null);
+ }
+ catch(SecurityException e)
+ {
+ log.log(Level.SEVERE, "Could not invoke Toolbar listener method: " + methodName + "()", e);
+ }
+ catch(NoSuchMethodException e)
+ {
+ log.log(Level.SEVERE, "Could not invoke Toolbar listener method: " + methodName + "()", e);
+ }
+ catch(IllegalArgumentException e)
+ {
+ log.log(Level.SEVERE, "Could not invoke Toolbar listener method: " + methodName + "()", e);
+ }
+ catch(IllegalAccessException e)
+ {
+ log.log(Level.SEVERE, "Could not invoke Toolbar listener method: " + methodName + "()", e);
+ }
+ catch(InvocationTargetException e)
+ {
+ log.log(Level.SEVERE, "Could not invoke Toolbar listener method: " + methodName + "()", e);
+ }
+ }
+ }
+ }
+ }
+
+ public void enableHistoryRecords(boolean enabled)
+ {
+ this.btnHistoryRecords.setEnabled(enabled);
+ }
+
+ public void enableNavigation(boolean enabledd)
+ {
+ this.btnFirst.setEnabled(enabledd);
+ this.btnPrevious.setEnabled(enabledd);
+ this.btnNext.setEnabled(enabledd);
+ this.btnLast.setEnabled(enabledd);
+ }
+
+ public void enableTabNavigation(boolean enabled)
+ {
+ enableTabNavigation(enabled, enabled);
+ }
+
+ public void enableTabNavigation(boolean enableParent, boolean enableDetail)
+ {
+ this.btnParentRecord.setEnabled(enableParent);
+ this.btnDetailRecord.setEnabled(enableDetail);
+ }
+
+ public void enableFirstNavigation(boolean enabled)
+ {
+ this.btnFirst.setEnabled(enabled);
+ this.btnPrevious.setEnabled(enabled);
+ }
+
+ public void enableLastNavigation(boolean enabled)
+ {
+ this.btnLast.setEnabled(enabled);
+ this.btnNext.setEnabled(enabled);
+ }
+
+ public void enabledNew(boolean enabled)
+ {
+ this.btnNew.setEnabled(enabled);
+ }
+
+ /* public void enableEdit(boolean enabled)
+ {
+ this.btnEdit.setEnabled(enabled);
+ }*/
+
+ public void enableRefresh(boolean enabled)
+ {
+ this.btnRefresh.setEnabled(enabled);
+ }
+
+ public void enableSave(boolean enabled)
+ {
+ this.btnSave.setEnabled(enabled);
+ }
+
+ public void enableExit(boolean enabled)
+ {
+ this.btnExit.setEnabled(enabled);
+ }
+
+ public void enableDelete(boolean enabled)
+ {
+ this.btnDelete.setEnabled(enabled);
+ }
+
+ public void enableDeleteSelection(boolean enabled)
+ {
+ // TODO add delete selection button
+ }
+
+ public void enableChanges(boolean enabled)
+ {
+ this.btnNew.setEnabled(enabled);
+ this.btnIgnore.setEnabled(enabled);
+ }
+
+ public void enableIgnore(boolean enabled)
+ {
+ this.btnIgnore.setEnabled(enabled);
+ }
+
+ public void enableNew(boolean enabled)
+ {
+ this.btnNew.setEnabled(enabled);
+ }
+
+ public void enableAttachment(boolean enabled)
+ {
+ this.btnAttachment.setEnabled(enabled);
+ }
+
+ public void enablePrint(boolean enabled)
+ {
+ this.btnPrint.setEnabled(enabled);
+ }
+
+ public void enableReport(boolean enabled)
+ {
+ this.btnReport.setEnabled(enabled);
+ }
+
+ public void enableCopy(boolean enabled)
+ {
+ }
+
+ public void enableFind(boolean enabled)
+ {
+ this.btnFind.setEnabled(enabled);
+
+ }
+
+ public void enableGridToggle(boolean enabled)
+ {
+ btnGridToggle.setEnabled(enabled);
+ }
+
+ public boolean isAsap()
+ {
+ return true;
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Checkbox.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Checkbox.java
new file mode 100644
index 0000000000..10f3eea4f1
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Checkbox.java
@@ -0,0 +1,34 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class Checkbox extends org.zkoss.zul.Checkbox
+{
+ private static final long serialVersionUID = 1L;
+
+ public void setEnabled(boolean enabled)
+ {
+ this.setDisabled(!enabled);
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Column.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Column.java
new file mode 100644
index 0000000000..f73fb530cf
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Column.java
@@ -0,0 +1,35 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+
+public class Column extends org.zkoss.zul.Column
+{
+ private static final long serialVersionUID = 1L;
+
+ public Column()
+ {
+ this(null);
+ }
+
+ public Column(String str)
+ {
+ this.setLabel(str);
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Columns.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Columns.java
new file mode 100644
index 0000000000..d0837914ad
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Columns.java
@@ -0,0 +1,24 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+
+public class Columns extends org.zkoss.zul.Columns
+{
+ private static final long serialVersionUID = 1L;
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ComboItem.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ComboItem.java
new file mode 100644
index 0000000000..24dbf9efa9
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ComboItem.java
@@ -0,0 +1,47 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+/**
+ * Bad stuff, cannot overide method equals in AbstractComponent.
+ * @author Ashley G Ramdass
+ * @date Mar 10, 2007
+ * @version $Revision: 0.10 $
+ */
+public class ComboItem extends org.zkoss.zul.Comboitem
+{
+ private static final long serialVersionUID = 1L;
+
+ private Object obj;
+
+ public ComboItem(String label)
+ {
+ super(label);
+ }
+
+ public ComboItem(String label, String object)
+ {
+ super(label);
+ this.obj = object;
+ }
+
+ public Object getObject()
+ {
+ return obj;
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Combobox.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Combobox.java
new file mode 100644
index 0000000000..a7effc6bfc
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Combobox.java
@@ -0,0 +1,43 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import org.zkoss.zul.Comboitem;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class Combobox extends org.zkoss.zul.Combobox
+{
+ private static final long serialVersionUID = 1L;
+
+ public void setEnabled(boolean enabled)
+ {
+ this.setDisabled(!enabled);
+ }
+
+ public Comboitem appendItem(String label)
+ {
+ ComboItem item = new ComboItem(label);
+ item.setParent(this);
+ return item;
+ }
+}
\ No newline at end of file
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ConfirmPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ConfirmPanel.java
new file mode 100644
index 0000000000..3f40a4dca1
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ConfirmPanel.java
@@ -0,0 +1,350 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zul.Hbox;
+import org.zkoss.zul.Messagebox;
+/**
+ * Application Confirm Panel
+ * Web UI port of the rich client's ConfirmPanel by Jorg Janke
+ * @author Sendy Yagambrum
+ * @date July 25, 2007
+ **/
+public final class ConfirmPanel extends Hbox
+{
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Creates a button of the specified id
+ *
+ * @param id button id
+ * @return button
+ *
+ * The string can be any of the following and the corresponding button will be created:
+ *
+ * Ok Ok button
+ * Cancel Cancel button
+ * Refresh Refresh button
+ * Reset Reset button
+ * History History button
+ * Process Process button
+ * New New button
+ * Customize Customize button
+ * Delete Delete button
+ * Save Save button
+ * Zoom Zoom button
+ * Help Help button
+ *
+ *
+ */
+ public Button createButton(String name)
+ {
+ Button button = new Button();
+ button.setName("btn"+name);
+ button.setId(name);
+ button.setSrc("images/"+name+"24.gif");
+ return button;
+ }
+
+ /**
+ * create confirm panel with multiple options
+ * @param withCancelButton with cancel
+ * @param withRefreshButton with refresh
+ * @param withResetButton with reset
+ * @param withCustomizeButton with customize
+ * @param withHistoryButton with history
+ * @param withZoomButton with zoom
+ */
+ public ConfirmPanel(boolean withCancelButton,
+ boolean withRefreshButton,
+ boolean withResetButton,
+ boolean withCustomizeButton,
+ boolean withHistoryButton,
+ boolean withZoomButton)
+ {
+ init();
+
+ setVisible("Cancel", withCancelButton);
+ addComponentsRight(createButton("Ok"));
+ addComponentsRight(createButton("Cancel"));
+
+ if (withRefreshButton)
+ {
+ addComponentsLeft(createButton("Refresh"));
+ }
+ if (withResetButton)
+ {
+ addComponentsLeft(createButton("Reset"));
+ }
+ if (withCustomizeButton)
+ {
+ addComponentsLeft(createButton("Customize"));
+ }
+ if (withHistoryButton)
+ {
+ addComponentsLeft(createButton("History"));
+ }
+ if (withZoomButton)
+ {
+ addComponentsLeft(createButton("Zoom"));
+ }
+ }
+
+ /**
+ * Create confirm panel with Ok button only
+ */
+ public ConfirmPanel()
+ {
+ this(false,false,false,false,false,false);
+ }
+
+ /**
+ * Create confirm panel with Ok and Cancel button
+ * @param withCancel with cancel
+ *
+ */
+ public ConfirmPanel(boolean withCancel)
+ {
+ this(true,false,false,false,false,false);
+ }
+ //
+ private Hbox hboxBtnLeft;
+ private Hbox hboxBtnRight;
+ //
+ private Panel pnlBtnRight;
+ private Panel pnlBtnLeft;
+
+ /**
+ * initialise components
+ */
+ private void init()
+ {
+ pnlBtnLeft = new Panel();
+ pnlBtnLeft.setAlign("left");
+
+ pnlBtnRight = new Panel();
+ pnlBtnRight.setAlign("right");
+
+ hboxBtnRight = new Hbox();
+ hboxBtnRight.appendChild(pnlBtnRight);
+ hboxBtnRight.setWidth("100%");
+ hboxBtnRight.setStyle("text-align:right");
+
+ hboxBtnLeft = new Hbox();
+ hboxBtnLeft.appendChild(pnlBtnLeft);
+ hboxBtnLeft.setWidth("100%");
+ hboxBtnLeft.setStyle("text-align:left");
+
+ this.appendChild(hboxBtnLeft);
+ this.appendChild(hboxBtnRight);
+ this.setWidth("100%");
+ }
+
+ /**
+ * add button to the left side of the confirm panel
+ * @param button button
+ */
+ public void addComponentsLeft(Button button)
+ {
+ pnlBtnLeft.appendChild(button);
+ }
+
+ /**
+ * add button to the right side of the confirm panel
+ * @param button button
+ */
+ public void addComponentsRight(Button button)
+ {
+ pnlBtnRight.appendChild(button);
+ }
+
+ /**
+ * return button of the specified id
+ * @param id button id
+ * @return button or null if no button is found
+ * The button id can be any of the following
+ *
+ * Ok Ok button
+ * Cancel Cancel button
+ * Refresh Refresh button
+ * Reset Reset button
+ * History History button
+ * Process Process button
+ * New New button
+ * Customize Customize button
+ * Delete Delete button
+ * Save Save button
+ * Zoom Zoom button
+ * Help Help button
+ *
+ */
+ public Button getButton(String id)
+ {
+ return (Button)this.getFellowIfAny(id);
+ }
+
+ /**
+ * sets the visibility of the specified button
+ * @param btnName button name
+ * @param visible visibility
+ * The button name can be any of the following
+ *
+ * Ok Ok button
+ * Cancel Cancel button
+ * Refresh Refresh button
+ * Reset Reset button
+ * History History button
+ * Process Process button
+ * New New button
+ * Customize Customize button
+ * Delete Delete button
+ * Save Save button
+ * Zoom Zoom button
+ * Help Help button
+ *
+ */
+ public void setVisible(String id, boolean visible)
+ {
+ Button btn = getButton(id);
+ if (btn != null)
+ {
+ btn.setVisible(visible);
+ }
+ }
+ /**
+ * returns whether the specified button is visible or not
+ * @param btnName
+ * @return visibility of the button
+ * The button name can be any of the following
+ *
+ * Ok Ok button
+ * Cancel Cancel button
+ * Refresh Refresh button
+ * Reset Reset button
+ * History History button
+ * Process Process button
+ * New New button
+ * Customize Customize button
+ * Delete Delete button
+ * Save Save button
+ * Zoom Zoom button
+ * Help Help button
+ *
+ */
+ public boolean isVisible(String btnName)
+ {
+ Button btn = getButton(btnName);
+ if (btn != null)
+ {
+ return btn.isVisible();
+ }
+ else
+ {
+ try
+ {
+ Messagebox.show("No "+btnName+" button available");
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ return false;
+ }
+ }
+ /**
+ * enable specific button
+ * @param id button id
+ * @param enabled enabled
+ *
+ * The button id can be any of the following
+ *
+ * Ok Ok button
+ * Cancel Cancel button
+ * Refresh Refresh button
+ * Reset Reset button
+ * History History button
+ * Process Process button
+ * New New button
+ * Customize Customize button
+ * Delete Delete button
+ * Save Save button
+ * Zoom Zoom button
+ * Help Help button
+ *
+ */
+ public void setEnabled(String id, boolean enabled)
+ {
+ Button button = getButton(id);
+ if (button != null)
+ {
+ button.setEnabled(enabled);
+ }
+ }
+
+ /**
+ * enable all components
+ * @param enabled enabled
+ */
+ public void setEnabledAll(boolean enabled)
+ {
+ List list1 = pnlBtnLeft.getChildren();
+ List list2 = pnlBtnRight.getChildren();
+ Iterator iter1 = list1.iterator();
+ Iterator iter2 = list2.iterator();
+
+ while (iter1.hasNext())
+ {
+ Button button = (Button)iter1.next();
+ button.setEnabled(enabled);
+ }
+ while (iter2.hasNext())
+ {
+ Button button = (Button)iter2.next();
+ button.setEnabled(enabled);
+ }
+ }
+ /**
+ * add action listener on the existing buttons
+ * @param event event
+ * @param listener listener
+ */
+ public void addActionListener(String event, EventListener listener)
+ {
+ List list1 = pnlBtnLeft.getChildren();
+ List list2 = pnlBtnRight.getChildren();
+ Iterator iter1 = list1.iterator();
+ Iterator iter2 = list2.iterator();
+
+ while (iter1.hasNext())
+ {
+ Button button = (Button)iter1.next();
+ button.addEventListener(event, listener);
+ }
+ while (iter2.hasNext())
+ {
+ Button button = (Button)iter2.next();
+ button.addEventListener(event, listener);
+ }
+ }
+
+} // ConfirmPanel
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Datebox.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Datebox.java
new file mode 100644
index 0000000000..0f5d9f86f1
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Datebox.java
@@ -0,0 +1,34 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class Datebox extends org.zkoss.zul.Datebox
+{
+ private static final long serialVersionUID = 1L;
+
+ public void setEnabled(boolean enabled)
+ {
+ this.setDisabled(!enabled);
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/EditorBox.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/EditorBox.java
new file mode 100644
index 0000000000..1809a161cc
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/EditorBox.java
@@ -0,0 +1,102 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+
+import org.zkoss.zk.ui.event.EventListener;
+
+/**
+ * Editor Box consists of a text box and a button.
+ * May be used instaed of SearchBox, LocationBox....
+ *
+ * @author Niraj Sohun
+ * @date Jul 24, 2007
+ */
+
+public class EditorBox extends Panel
+{
+
+ private static final long serialVersionUID = 1L;
+
+ private PropertyChangeSupport m_propertyChangeListeners = new PropertyChangeSupport(this);
+ private Textbox txt;
+ private Button btn;
+
+ public EditorBox()
+ {
+ initComponents();
+ }
+
+ public EditorBox(String text)
+ {
+ initComponents();
+ setText(text);
+ }
+
+ public void setButtonImage(String imageSrc)
+ {
+ btn.setImage(imageSrc);
+ }
+
+ private void initComponents()
+ {
+ txt = new Textbox();
+ btn = new Button();
+
+ this.appendChild(txt);
+ this.appendChild(btn);
+ }
+
+ public Textbox getTextBox()
+ {
+ return txt;
+ }
+
+ public void setText(String value)
+ {
+ txt.setText(value);
+ }
+
+ public String getText()
+ {
+ return txt.getText();
+ }
+
+ public void setEnabled(boolean enabled)
+ {
+ txt.setReadonly(enabled);
+ btn.setEnabled(enabled);
+ }
+
+ public boolean isEnabled()
+ {
+ return txt.isReadonly();
+ }
+
+ public boolean addEventListener(String evtnm, EventListener listener)
+ {
+ return btn.addEventListener(evtnm, listener);
+ }
+
+ public synchronized void addPropertyChangeListener(PropertyChangeListener l)
+ {
+ m_propertyChangeListeners.addPropertyChangeListener(l);
+ }
+}
\ No newline at end of file
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/FTabbox.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/FTabbox.java
new file mode 100644
index 0000000000..607c6ee990
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/FTabbox.java
@@ -0,0 +1,257 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import java.util.ArrayList;
+
+import org.adempiere.webui.panel.ADTabpanel;
+import org.compiere.grid.VTabbedPane;
+import org.compiere.model.DataStatusEvent;
+import org.compiere.model.GridTab;
+import org.compiere.util.CLogger;
+import org.compiere.util.Evaluator;
+import org.zkoss.zul.Tab;
+import org.zkoss.zul.Tabpanels;
+import org.zkoss.zul.Tabs;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class FTabbox extends Tabbox
+{
+ private static final long serialVersionUID = 1L;
+
+ /** Logger */
+ private static CLogger log = CLogger.getCLogger (VTabbedPane.class);
+ /** List of dependent Variables */
+ private ArrayList m_dependents = new ArrayList();
+ /** Tab Panels for this tab box */
+ private FTabpanels tabpanels;
+ /** Tabs associated to this tab box */
+ private Tabs tabs;
+
+ public FTabbox()
+ {
+ super();
+ init();
+ }
+
+ private void init()
+ {
+ tabpanels = new FTabpanels();
+ tabs = new Tabs();
+ //this.setSclass("lite");
+ this.appendChild(tabs);
+ this.appendChild(tabpanels);
+ this.setOrient("vertical");
+ }// init
+
+ /**
+ * Add Tab
+ * @param tabName name
+ * @param gTab grid tab model
+ * @param tabElement GridController or VSortTab
+ */
+ public void addTab(GridTab gTab, Tabpanel tabPanel)
+ {
+ Tab tab = new Tab(gTab.getName());
+ tabPanel.setEnabled(gTab.isDisplayed());
+ tabs.appendChild(tab);
+ tabpanels.appendChild(tabPanel);
+ ArrayList dependents = gTab.getDependentOn();
+ for (int i = 0; i < dependents.size(); i++)
+ {
+ String name = dependents.get(i);
+ if (!m_dependents.contains(name))
+ {
+ m_dependents.add(name);
+ }
+ }
+ }// addTab
+
+ /**
+ * @param index of tab panel
+ * @return
+ */
+ public boolean isEnabledAt(int index)
+ {
+ Tabpanel tabpanel = tabpanels.getTabpanel(index);
+ if (tabpanel == null)
+ {
+ return false;
+ }
+ return tabpanel.isEnabled();
+ }// isEnabledAt
+
+ private boolean isDisplay(ADTabpanel tabpanel)
+ {
+ String logic = tabpanel.getDisplayLogic();
+ if (logic != null && logic.length() > 0)
+ {
+ boolean display = Evaluator.evaluateLogic(tabpanel, logic);
+ if (!display)
+ {
+ log.info("Not displayed - " + logic);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ *
+ * @param oldIndex
+ * @param newIndex
+ * @return
+ */
+ public boolean updateSelectedIndex(int oldIndex, int newIndex)
+ {
+ Tabpanel tabpanel = tabpanels.getTabpanel(newIndex);
+
+ ADTabpanel newTab = (ADTabpanel)tabpanel;
+
+ if (tabpanel == null || !isDisplay(newTab))
+ {
+ super.setSelectedIndex(oldIndex);
+ return false;
+ }
+
+ boolean canJump = true;
+
+ if (newIndex != oldIndex)
+ {
+ ADTabpanel oldTabpanel = tabpanels.getTabpanel(oldIndex);
+ if (oldTabpanel != null)
+ {
+ ADTabpanel oldTab = oldTabpanel;
+ if (newTab.getTabLevel() > oldTab.getTabLevel())
+ {
+ int currentLevel = newTab.getTabLevel();
+ for (int i = newIndex - 1; i >= 0; i--)
+ {
+ ADTabpanel tabPanel = tabpanels.getTabpanel(i);
+ if (tabPanel.getTabLevel() < currentLevel)
+ {
+ if (!tabPanel.isCurrent())
+ {
+ canJump = false;
+ break;
+ }
+ currentLevel = tabPanel.getTabLevel();
+ }
+ }
+ }
+ }
+ else
+ {
+ canJump = false;
+ }
+ }
+ if (canJump)
+ {
+ super.setSelectedIndex(newIndex);
+ }
+ else
+ {
+ super.setSelectedIndex (oldIndex);
+ }
+ return canJump;
+ }
+
+ /**
+ * Evaluate Tab Logic
+ * @param e event
+ */
+ public void evaluate (DataStatusEvent e)
+ {
+ boolean process = e == null;
+ String columnName = null;
+ if (!process)
+ {
+ columnName = e.getColumnName();
+ if (columnName != null)
+ process = m_dependents.contains(columnName);
+ else
+ process = true;
+ }
+
+ if (process)
+ {
+ log.config(columnName == null ? "" : columnName);
+ for (int i = 0; i < this.getTabCount(); i++)
+ {
+ ADTabpanel tabPanel = tabpanels.getTabpanel(i);
+ String logic = tabPanel.getDisplayLogic();
+ boolean display = true;
+ if (logic != null && logic.length() > 0)
+ {
+ display = Evaluator.evaluateLogic(tabPanel, logic);
+ }
+ tabPanel.setEnabled(display);
+
+ }
+ }
+
+ } // evaluate
+
+ /**
+ * @return the number of tab panels present
+ */
+ public int getTabCount()
+ {
+ return tabpanels.getChildren().size();
+ }
+
+ public ADTabpanel getTabpanel(int index)
+ {
+ try
+ {
+ Tabpanels tabpanels = this.getTabpanels();
+ ADTabpanel tabPanel = (ADTabpanel)tabpanels.getChildren().get(index);
+ return tabPanel;
+ }
+ catch (Exception ex)
+ {
+ throw new IndexOutOfBoundsException(ex.getMessage());
+ }
+ }
+
+ /**
+ * Return the selected Tab Panel
+ */
+ public ADTabpanel getSelectedTabpanel()
+ {
+ return getTabpanel(this.getSelectedIndex());
+ }
+
+ /**
+ * @return whether all events should be reported as they occur.
+ */
+ public boolean isAsap()
+ {
+ return true;
+ }
+
+ public boolean containsTab(Tab tab)
+ {
+ return tabs.getChildren().contains(tab);
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/FTabpanels.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/FTabpanels.java
new file mode 100644
index 0000000000..3b87a100b1
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/FTabpanels.java
@@ -0,0 +1,49 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import org.adempiere.webui.panel.ADTabpanel;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class FTabpanels extends Tabpanels
+{
+ private static final long serialVersionUID = 1L;
+
+ public boolean appendChild(Tabpanel tabPanel)
+ {
+ return super.appendChild(tabPanel);
+ }
+
+ public ADTabpanel getTabpanel(int index)
+ {
+ try
+ {
+ ADTabpanel tabPanel = (ADTabpanel)this.getChildren().get(index);
+ return tabPanel;
+ }
+ catch (Exception ex)
+ {
+ return null;
+ }
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/FToolbar.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/FToolbar.java
new file mode 100644
index 0000000000..089094ef2f
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/FToolbar.java
@@ -0,0 +1,36 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import org.zkoss.zul.Toolbar;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class FToolbar extends Toolbar
+{
+ private static final long serialVersionUID = 1L;
+
+ public String getName()
+ {
+ return getId();
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/FWindow.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/FWindow.java
new file mode 100644
index 0000000000..33fecb6e32
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/FWindow.java
@@ -0,0 +1,35 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class FWindow extends Window
+{
+ private static final long serialVersionUID = 1L;
+
+ public FWindow()
+ {
+ super();
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Grid.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Grid.java
new file mode 100644
index 0000000000..2092c19517
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Grid.java
@@ -0,0 +1,29 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class Grid extends org.zkoss.zul.Grid
+{
+ private static final long serialVersionUID = 1L;
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/GridPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/GridPanel.java
new file mode 100644
index 0000000000..e8a2dd7fd9
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/GridPanel.java
@@ -0,0 +1,271 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
+
+import javax.swing.table.AbstractTableModel;
+
+import org.adempiere.webui.panel.ADWindowPanel;
+import org.compiere.model.GridField;
+import org.compiere.model.GridTab;
+import org.compiere.model.GridTable;
+import org.compiere.model.MLookup;
+import org.compiere.model.MLookupFactory;
+import org.compiere.util.DisplayType;
+import org.compiere.util.Env;
+import org.compiere.util.NamePair;
+import org.zkforge.yuiext.grid.Column;
+import org.zkforge.yuiext.grid.Columns;
+import org.zkforge.yuiext.grid.Grid;
+import org.zkforge.yuiext.grid.Label;
+import org.zkforge.yuiext.grid.Row;
+import org.zkforge.yuiext.grid.Rows;
+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.Hbox;
+import org.zkoss.zul.Separator;
+
+public class GridPanel extends Panel implements EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private Grid grid = new Grid();
+ private Rows rows = new Rows();
+ private Row row = new Row();
+ private Columns columns = new Columns();
+ private Column column = new Column();
+ private Label label = new Label();
+
+ private int pageSize = 10;
+ private long numPages;
+
+ private GridField[] gridField;
+ private AbstractTableModel tableModel;
+
+ private int numColumns = 5;
+ private int numRows;
+
+ private Button[] buttons;
+ private Hbox boxButtons = new Hbox();
+
+ private ADWindowPanel windowPanel;
+ private int windowNo;
+
+ private GridTab gridTab;
+
+ private int pageId = 0;
+
+ public GridPanel()
+ {
+ super();
+ }
+
+ public GridPanel(int windowNo, ADWindowPanel windowPanel)
+ {
+ this.windowNo = windowNo;
+ this.windowPanel = windowPanel;
+ }
+
+ public void init(GridTab gridTab)
+ {
+ this.gridTab = gridTab;
+ tableModel = gridTab.getTableModel();
+
+ numColumns = tableModel.getColumnCount();
+ numRows = tableModel.getRowCount();
+
+ gridField = ((GridTable)tableModel).getFields();
+
+ loadButtons();
+ loadGridHeader();
+ loadRecords(0, pageSize);
+ loadDisplay();
+ }
+
+ public void setPageSize(int pageSize)
+ {
+ this.pageSize = pageSize;
+ }
+
+ public void clear()
+ {
+ this.getChildren().clear();
+ }
+
+ public void showGrid(boolean bool)
+ {
+ if (bool)
+ this.setVisible(true);
+ else
+ this.setVisible(false);
+ }
+
+ private void loadGridHeader()
+ {
+ if (grid.getColumns() != null)
+ return;
+
+ columns = new Columns();
+
+ for (int i = 0; i < numColumns; i++)
+ {
+ if (gridField[i].isDisplayed())
+ {
+ column = new Column(gridField[i].getHeader());
+ columns.appendChild(column);
+ }
+ }
+
+ grid.appendChild(columns);
+ }
+
+ private void loadButtons()
+ {
+ double pages = (double)numRows / (double)pageSize;
+ pages = Math.ceil(pages);
+ numPages = Math.round(pages);
+
+ if (numPages == 1)
+ return;
+
+ buttons = new Button[(int)numPages];
+
+ if (boxButtons.getChildren() != null)
+ boxButtons.getChildren().clear();
+
+ for (int i = 0; i < buttons.length; i++)
+ {
+ Integer count = i;
+ buttons[i] = new Button();
+ buttons[i].setId(count.toString());
+ buttons[i].addEventListener(Events.ON_CLICK, this);
+ buttons[i].setLabel(count.toString());
+ boxButtons.appendChild(buttons[i]);
+ }
+ }
+
+ private String getCell(Object obj, int columnIndex)
+ {
+ if (obj == null)
+ return "";
+
+ if (tableModel.getColumnClass(columnIndex).equals(Integer.class))
+ {
+ if (gridField[columnIndex].isLookup())
+ {
+ MLookup lookup = MLookupFactory.get(
+ Env.getCtx(), windowNo, 0, gridField[columnIndex].getAD_Column_ID(),
+ gridField[columnIndex].getDisplayType());
+
+ NamePair namepair = lookup.get(obj);
+
+ if (namepair != null)
+ return namepair.getName();
+ else
+ return "";
+ }
+ else
+ return "Lookup";
+ }
+ else if (tableModel.getColumnClass(columnIndex).equals(Timestamp.class))
+ {
+ SimpleDateFormat dateFormat = DisplayType.getDateFormat(DisplayType.Date);
+ return dateFormat.format((Timestamp)obj);
+ }
+ else
+ return obj.toString();
+ }
+
+ private void loadRecords(int start, int end)
+ {
+ if (grid.getRows() != null)
+ grid.getRows().getChildren().clear();
+
+ if (rows.getChildren() != null)
+ rows.getChildren().clear();
+
+ if (end > numRows)
+ end = numRows;
+
+ for (int i = start; i < end; i++)
+ {
+ row = new Row();
+
+ for (int j = 0; j < numColumns; j++)
+ {
+ if (!gridField[j].isDisplayed())
+ break;
+
+ label = new Label(getCell(tableModel.getValueAt(i, j), j));
+ row.appendChild(label);
+ }
+
+ rows.appendChild(row);
+ }
+
+ if (grid.getRows() == null)
+ grid.appendChild(rows);
+ }
+
+ private void loadDisplay()
+ {
+ this.setWidth("800px");
+ //this.setHeight("1000px");
+
+ grid.setWidth("100%");
+ grid.setHeight("800px");
+ grid.addEventListener(Events.ON_SELECT, this);
+
+ boxButtons.setWidth("60%");
+
+ this.appendChild(grid);
+ this.appendChild(new Separator());
+ this.appendChild(boxButtons);
+ }
+
+ public void onEvent(Event event) throws Exception
+ {
+ if (event == null)
+ return;
+
+ if (event.getTarget() instanceof Button)
+ {
+ Button btn = (Button)event.getTarget();
+
+ pageId = new Integer(btn.getId());
+
+ int start = pageId * pageSize;
+
+ int end = start + pageSize;
+
+ loadRecords(start, end);
+ }
+ else if (event.getTarget() == grid)
+ {
+ int keyRecordId = grid.getSelectedIndex() + (pageId * pageSize);
+
+ gridTab.navigate(keyRecordId);
+
+ this.setVisible(false);
+ windowPanel.showTabbox(true);
+ }
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Label.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Label.java
new file mode 100644
index 0000000000..836fdf2e3b
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Label.java
@@ -0,0 +1,39 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class Label extends org.zkoss.zul.Label
+{
+ private static final long serialVersionUID = 1L;
+
+ public Label()
+ {
+ super();
+ }
+
+ public Label(String value)
+ {
+ super(value);
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ListCell.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ListCell.java
new file mode 100644
index 0000000000..52426c470c
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ListCell.java
@@ -0,0 +1,32 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+public class ListCell extends org.zkoss.zul.Listcell
+{
+ private static final long serialVersionUID = 1L;
+
+ public ListCell(String str)
+ {
+ super(str);
+ }
+ public ListCell()
+ {
+ super();
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ListHead.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ListHead.java
new file mode 100644
index 0000000000..cca6e1043f
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ListHead.java
@@ -0,0 +1,23 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+public class ListHead extends org.zkoss.zul.Listhead
+{
+ private static final long serialVersionUID = 1L;
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ListHeader.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ListHeader.java
new file mode 100644
index 0000000000..53505f8267
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ListHeader.java
@@ -0,0 +1,33 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+public class ListHeader extends org.zkoss.zul.Listheader
+{
+ private static final long serialVersionUID = 1L;
+
+ public ListHeader(String str)
+ {
+ super(str);
+ }
+ public ListHeader()
+ {
+
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ListItem.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ListItem.java
new file mode 100644
index 0000000000..325a7e5e9a
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ListItem.java
@@ -0,0 +1,47 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class ListItem extends org.zkoss.zul.Listitem
+{
+ private static final long serialVersionUID = 1L;
+ private PropertyChangeSupport m_propertyChangeListeners = new PropertyChangeSupport(this);
+
+ public ListItem(String label, Object value)
+ {
+ super(label, value);
+ }
+
+ public ListItem()
+ {
+ super();
+ }
+
+ public synchronized void addPropertyChangeListener(PropertyChangeListener l)
+ {
+ m_propertyChangeListeners.addPropertyChangeListener(l);
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ListModelTable.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ListModelTable.java
new file mode 100644
index 0000000000..4492cac8f5
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ListModelTable.java
@@ -0,0 +1,306 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.Vector;
+
+import org.adempiere.webui.event.WTableModelEvent;
+import org.adempiere.webui.event.WTableModelListener;
+import org.zkoss.zul.ListModelExt;
+import org.zkoss.zul.ListModelList;
+
+/**
+ * This is a ListModel to be used with Listbox.
+ * The model allows for a table structure to be created, with columns
+ * in addition to the rows provided by {@link org.zkoss.zul.ListModelList}.
+ *
+ * @author Andrew Kimball
+ *
+ */
+public class ListModelTable extends ListModelList implements ListModelExt
+{
+
+ /**
+ * The Uniqe Identifier of the class
+ */
+ private static final long serialVersionUID = 1L;
+
+ /** Array of listeners to changes in the table model. */
+ protected ArrayList m_listeners = new ArrayList();
+ /** The number of columns in the table. */
+ private int m_noColumns;
+
+ /**
+ * Default constructor.
+ *
+ */
+ public ListModelTable()
+ {
+ super();
+ }
+
+ /**
+ * Construct the ListModel with a collection of objects.
+ * A copy is made of the collection.
+ * The objects should be vectors of objects
+ *
+ * @param collection The collection of objects with which to initialise the list
+ */
+ public ListModelTable(Collection collection)
+ {
+ super(collection);
+
+ m_noColumns = 0;
+
+ for (Object row : getInnerList())
+ {
+ if (row instanceof Vector)
+ {
+ m_noColumns = Math.max(m_noColumns, ((Vector)row).size());
+ }
+ else
+ {
+ throw new IllegalArgumentException("The collection must contain vectors of objects");
+ }
+ }
+ }
+
+ /**
+ * Query thenumber of columns in the table.
+ *
+ * @return the number of columns in the table. 0 if uninitialised.
+ */
+ public int getNoColumns()
+ {
+ return m_noColumns;
+ }
+
+ /**
+ * Add a column to the model.
+ *
+ */
+ public void addColumn()
+ {
+ m_noColumns++;
+
+ ensureRowSize();
+
+ return;
+ }
+
+ /**
+ * Ensure that each of the rows contains the correct number of elements.
+ * Please note that the table cannot be shrunk.
+ */
+ private void ensureRowSize()
+ {
+ Iterator> rowIterator = this.getInnerList().iterator();
+
+ while (rowIterator.hasNext())
+ {
+ rowIterator.next().setSize(m_noColumns);
+ }
+
+ return;
+ }
+
+ /**
+ * Set the number of columns that the table is to contain.
+ * @param columns The number of columns.
+ */
+ public void setNoColumns(int columns)
+ {
+ m_noColumns = columns;
+
+ ensureRowSize();
+ }
+
+ /**
+ * Query the number of rows in the table.
+ * @return the number of rows in the table
+ */
+ public int getNoRows()
+ {
+ return this.getSize();
+ }
+
+ /**
+ * Returns the cell value at rowIndex
and columnIndex
.
+ *
+ * @param rowIndex the index of the row whose value is to be queried
+ * @param columnIndex the index of the column whose value is to be queried
+ * @return The object stored at the specified position
+ */
+ public Object getDataAt(int rowIndex, int columnIndex)
+ {
+ Vector modelRow;
+ Object dataObject;
+
+ try
+ {
+ modelRow = (Vector)getElementAt(rowIndex);
+
+ dataObject = modelRow.get(columnIndex);
+ }
+ catch (Exception exception)
+ {
+ throw new IllegalArgumentException("Attempted to access "
+ + "nonexistent ListModelTable field at "
+ + rowIndex + ", " + columnIndex);
+ }
+
+ return dataObject;
+ }
+
+ /**
+ * Set the cell value at row
and column
.
+ *
+ * @param aValue The value to set
+ * @param row the index of the row whose value is to be set
+ * @param col the index of the column whose value is to be set
+ */
+ public void setDataAt(Object aValue, int row, int col)
+ {
+ Vector vector;
+ WTableModelEvent tcEvent;
+
+ try
+ {
+ if (getElementAt(row) instanceof Vector)
+ {
+ vector = (Vector)getElementAt(row);
+
+ try
+ {
+ vector.set(col, aValue);
+
+ // create a new event and fire the event
+ tcEvent = new WTableModelEvent(this, row, col);
+ fireTableChange(tcEvent);
+ }
+ catch (ArrayIndexOutOfBoundsException exception)
+ {
+ throw new IllegalArgumentException("Attempted to access "
+ + "nonexistent ListModelTable column at index "
+ + col);
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException("The ListModelTable cannot contain "
+ + "anything other than object vectors as its row elements");
+ }
+ }
+ catch (IndexOutOfBoundsException exception)
+ {
+ throw new IllegalArgumentException("Attempted to access "
+ + "nonexistent ListModelTable row at index " + row);
+ }
+
+ return;
+ }
+
+ /**
+ * Set the number of rows in the table and initialise new rows.
+ * For each new row, an empty collection of the size specified by
+ * {@link #setNoColumns(int)} is created.
+ * Please note that the number of rows in a table cannot be decreased.
+ * @param rowCount The number of rows to be contained in the table
+ */
+ public void setNoRows(int rowCount)
+ {
+ Vector newRow = null;
+
+ if (rowCount >= getSize())
+ {
+ while (getSize() < rowCount)
+ {
+ newRow = new Vector(getNoColumns());
+ newRow.setSize(getNoColumns());
+ add(newRow);
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException("The ListModelTable cannot be shrunk");
+ }
+ }
+
+ /**
+ * Add a listener for events from the data model.
+ *
+ * The listener will only be added if it doesn't already exist.
+ *
+ * @param listener A listener for changes in the table mode
+ */
+ public void addTableModelListener(WTableModelListener listener)
+ {
+ if (listener == null)
+ {
+ return;
+ }
+
+ if (!m_listeners.contains(listener))
+ {
+ m_listeners.add(listener);
+ }
+
+ return;
+ }
+
+ public void removeTableModelListener(WTableModelListener listener)
+ {
+ m_listeners.remove(listener);
+ }
+ /**
+ * Send the specified event
to all listeners.
+ *
+ * @param event The event tofire
+ */
+ private void fireTableChange(WTableModelEvent event)
+ {
+ for (WTableModelListener listener : m_listeners)
+ {
+ listener.tableChanged(event);
+ }
+
+ return;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.zkoss.zul.ListModelList#sort(java.util.Comparator, boolean)
+ */
+ public void sort(Comparator cmpr, boolean ascending)
+ {
+ Collections.sort(this.getInnerList(), cmpr);
+
+ WTableModelEvent event = new WTableModelEvent(this,
+ WTableModelEvent.ALL_ROWS,
+ WTableModelEvent.ALL_COLUMNS);
+
+ fireTableChange(event);
+
+ return;
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Listbox.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Listbox.java
new file mode 100644
index 0000000000..4df97c0fac
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Listbox.java
@@ -0,0 +1,111 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.List;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class Listbox extends org.zkoss.zul.Listbox
+{
+ private static final long serialVersionUID = 1L;
+ private PropertyChangeSupport m_propertyChangeListeners = new PropertyChangeSupport(this);
+
+ public void setEnabled(boolean enabled)
+ {
+ this.setDisabled(!enabled);
+ }
+
+ public boolean isEnabled()
+ {
+ return !this.isDisabled();
+ }
+
+ public ListItem appendItem(String label, Object value)
+ {
+ ListItem item = new ListItem(label, value);
+ super.appendChild(item);
+ return item;
+ }
+
+ public ListItem appendItem(String label, String value)
+ {
+ ListItem item = new ListItem(label, value);
+ super.appendChild(item);
+ return item;
+ }
+
+ public ListItem getItemAtIndex(int index)
+ {
+ return (ListItem)super.getItemAtIndex(index);
+ }
+
+ public ListItem getSelectedItem()
+ {
+ return (ListItem)super.getSelectedItem();
+ }
+
+ @SuppressWarnings("unchecked")
+ public List getItems()
+ {
+ return (List)super.getItems();
+ }
+
+ public synchronized void addPropertyChangeListener(PropertyChangeListener l)
+ {
+ m_propertyChangeListeners.addPropertyChangeListener(l);
+ }
+
+ /**
+ * Set selected item for the list box based on the value of list item
+ * set selected to none if no item found matching the value given or
+ * value is null
+ * @param value Value of ListItem to set as selected
+ */
+ public void setValue(Object value)
+ {
+ setSelectedItem(null);
+
+ if (value == null)
+ {
+ return ;
+ }
+
+ List items = getItems();
+ for (ListItem item : items)
+ {
+ if (value.equals(item.getValue()))
+ {
+ setSelectedItem(item);
+ break;
+ }
+ }
+ }
+
+ public ListHead getListHead()
+ {
+ return (ListHead)super.getListhead();
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Locationbox.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Locationbox.java
new file mode 100644
index 0000000000..967bf5fa2d
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Locationbox.java
@@ -0,0 +1,95 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+
+import org.zkoss.zk.ui.event.EventListener;
+
+/** Location Editor component
+ * @author Sendy Yagambrum
+ * @date July 16, 2007
+ **/
+public class Locationbox extends Panel
+{
+ private static final long serialVersionUID = 1L;
+ private PropertyChangeSupport m_propertyChangeListeners = new PropertyChangeSupport(this);
+ private Textbox txt;
+ private Button btn;
+
+ public Locationbox()
+ {
+ initComponents();
+ }
+
+ public Locationbox(String text)
+ {
+ initComponents();
+ setText(text);
+ }
+
+ public void setButtonImage(String imageSrc)
+ {
+ btn.setImage(imageSrc);
+ }
+
+ private void initComponents()
+ {
+ txt = new Textbox();
+ btn = new Button();
+ this.appendChild(txt);
+ this.appendChild(btn);
+ }
+
+ public Textbox getTextBox()
+ {
+ return txt;
+ }
+
+ public void setText(String value)
+ {
+ txt.setText(value);
+ }
+
+ public String getText()
+ {
+ return txt.getText();
+ }
+
+ public void setEnabled(boolean enabled)
+ {
+ txt.setReadonly(enabled);
+ btn.setEnabled(enabled);
+ }
+
+ public boolean isEnabled()
+ {
+ return !txt.isReadonly();
+ }
+
+ public boolean addEventListener(String evtnm, EventListener listener)
+ {
+ return btn.addEventListener(evtnm, listener);
+ }
+
+ public synchronized void addPropertyChangeListener(PropertyChangeListener l)
+ {
+ m_propertyChangeListeners.addPropertyChangeListener(l);
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Messagebox.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Messagebox.java
new file mode 100644
index 0000000000..04a635c490
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Messagebox.java
@@ -0,0 +1,272 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import org.adempiere.webui.apps.AEnv;
+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.Hbox;
+import org.zkoss.zul.Image;
+import org.zkoss.zul.Separator;
+
+/**
+* Messagebox : Replaces ZK's Messagebox
+*
+* @author Niraj Sohun
+* @date Jul 31, 2007
+*/
+
+public class Messagebox extends Window implements EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private String msg = new String("");
+ private String imgSrc = new String("");
+
+ private Label lblMsg = new Label();
+
+ private Button btnOk = new Button();
+ private Button btnCancel = new Button();
+ private Button btnYes = new Button();
+ private Button btnNo = new Button();
+ private Button btnAbort = new Button();
+ private Button btnRetry = new Button();
+ private Button btnIgnore = new Button();
+
+ private Image img = new Image();
+
+ private int returnValue;
+
+ /** A OK button. */
+ public static final int OK = 0x0001;
+
+ /** A Cancel button. */
+ public static final int CANCEL = 0x0002;
+
+ /** A Yes button. */
+ public static final int YES = 0x0010;
+
+ /** A No button. */
+ public static final int NO = 0x0020;
+
+ /** A Abort button. */
+ public static final int ABORT = 0x0100;
+
+ /** A Retry button. */
+ public static final int RETRY = 0x0200;
+
+ /** A IGNORE button. */
+ public static final int IGNORE = 0x0400;
+
+ /** A symbol consisting of a question mark in a circle. */
+ public static final String QUESTION = "~./zul/img/question.gif";
+
+ /** A symbol consisting of an exclamation point in a triangle with a yellow background. */
+ public static final String EXCLAMATION = "~./zul/img/exclamation.gif";
+
+ /** A symbol of a lowercase letter i in a circle. */
+ public static final String INFORMATION = "~./zul/img/information.gif";
+
+ /** A symbol consisting of a white X in a circle with a red background. */
+ public static final String ERROR = "~./zul/img/error.gif";
+
+ /** Contains no symbols. */
+ public static final String NONE = null;
+
+ public Messagebox()
+ {
+ super();
+ }
+
+ private void init()
+ {
+ lblMsg.setValue(msg);
+
+ btnOk.setLabel("OK");
+ btnOk.setImage("/images/Ok24.gif");
+ btnOk.addEventListener(Events.ON_CLICK, this);
+
+ btnCancel.setLabel("Cancel");
+ btnCancel.setImage("/images/Cancel24.gif");
+ btnCancel.addEventListener(Events.ON_CLICK, this);
+
+ btnYes.setLabel("Yes");
+ btnYes.setImage("/images/Ok24.gif");
+ btnYes.addEventListener(Events.ON_CLICK, this);
+
+ btnNo.setLabel("No");
+ btnNo.setImage("/images/Cancel24.gif");
+ btnNo.addEventListener(Events.ON_CLICK, this);
+
+ btnAbort.setLabel("Abort");
+ //btnAbort.setImage("/images/");
+ btnAbort.addEventListener(Events.ON_CLICK, this);
+
+ btnRetry.setLabel("Retry");
+ //btnRetry.setImage("/images/");
+ btnRetry.addEventListener(Events.ON_CLICK, this);
+
+ btnIgnore.setLabel("Ignore");
+ btnIgnore.setImage("/images/Ignore24.gif");
+ btnIgnore.addEventListener(Events.ON_CLICK, this);
+
+ Panel pnlMessage = new Panel();
+ pnlMessage.setWidth("100%");
+ pnlMessage.setStyle("text-align:left");
+ pnlMessage.appendChild(lblMsg);
+
+ Panel pnlImage = new Panel();
+
+ img.setSrc(imgSrc);
+
+ pnlImage.setWidth("100%");
+ pnlImage.setStyle("text-align:center");
+ pnlImage.appendChild(img);
+
+ Hbox hbox = new Hbox();
+ hbox.setWidth("100%");
+ hbox.setWidths("10%, 90%");
+
+ hbox.appendChild(pnlImage);
+ hbox.appendChild(pnlMessage);
+
+ Hbox pnlButtons = new Hbox();
+ pnlButtons.setWidth("100%");
+ pnlButtons.setStyle("text-align:center");
+ pnlButtons.appendChild(btnOk);
+ pnlButtons.appendChild(btnCancel);
+ pnlButtons.appendChild(btnYes);
+ pnlButtons.appendChild(btnNo);
+ pnlButtons.appendChild(btnAbort);
+ pnlButtons.appendChild(btnRetry);
+ pnlButtons.appendChild(btnIgnore);
+
+ this.setWidth("100%");
+ this.setBorder("normal");
+ this.setContentStyle("background-color:#c0d1d2");
+ this.setPosition("left, top");
+
+ Separator blank = new Separator();
+ blank.setOrient("vertical");
+ blank.setHeight("5px");
+
+ hbox.appendChild(blank);
+ hbox.appendChild(pnlButtons);
+
+ this.appendChild(hbox);
+ }
+
+ public int show(String message, String title, int buttons, String icon)
+ throws InterruptedException
+ {
+ this.msg = message;
+ this.imgSrc = icon;
+
+ btnOk.setVisible(false);
+ btnCancel.setVisible(false);
+ btnYes.setVisible(false);
+ btnNo.setVisible(false);
+ btnRetry.setVisible(false);
+ btnAbort.setVisible(false);
+ btnIgnore.setVisible(false);
+
+ if ((buttons & OK) != 0)
+ btnOk.setVisible(true);
+
+ if ((buttons & CANCEL) != 0)
+ btnCancel.setVisible(true);
+
+ if ((buttons & YES) != 0)
+ btnYes.setVisible(true);
+
+ if ((buttons & NO) != 0)
+ btnNo.setVisible(true);
+
+ if ((buttons & RETRY) != 0)
+ btnRetry.setVisible(true);
+
+ if ((buttons & ABORT) != 0)
+ btnAbort.setVisible(true);
+
+ if ((buttons & IGNORE) != 0)
+ btnIgnore.setVisible(true);
+
+ init();
+
+ if (icon == QUESTION)
+ {
+ this.setTitle(title);
+ this.setWidth("500px");
+ this.setPosition("center");
+ this.setClosable(true);
+ this.setAttribute("mode", "modal");
+ }
+ else
+ this.setAttribute("mode", "overlapped");
+
+ this.setVisible(true);
+ AEnv.showWindow(this);
+
+ return returnValue;
+ }
+
+ public static int showDialog(String message, String title, int buttons, String icon) throws InterruptedException
+ {
+ Messagebox msg = new Messagebox();
+
+ return msg.show(message, title, buttons, icon);
+ }
+
+ public void onEvent(Event event) throws Exception
+ {
+ if (event == null)
+ return;
+
+ if (event.getTarget() == btnOk)
+ {
+ returnValue = OK;
+ }
+ else if (event.getTarget() == btnCancel)
+ {
+ returnValue = CANCEL;
+ }
+ else if (event.getTarget() == btnYes)
+ {
+ returnValue = YES;
+ }
+ else if (event.getTarget() == btnNo)
+ {
+ returnValue = NO;
+ }
+ else if (event.getTarget() == btnAbort)
+ {
+ returnValue = ABORT;
+ }
+ else if (event.getTarget() == btnRetry)
+ {
+ returnValue = RETRY;
+ }
+ else if (event.getTarget() == btnIgnore)
+ {
+ returnValue = IGNORE;
+ }
+
+ this.detach();
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/NumberBox.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/NumberBox.java
new file mode 100644
index 0000000000..9e5e39b739
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/NumberBox.java
@@ -0,0 +1,276 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import java.text.NumberFormat;
+import java.text.ParseException;
+
+import org.zkoss.zul.Bandpopup;
+import org.zkoss.zul.Button;
+import org.zkoss.zul.Hbox;
+import org.zkoss.zul.Vbox;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 11, 2007
+ * @version $Revision: 0.10 $
+ */
+public class NumberBox extends Bandbox
+{
+ private static final long serialVersionUID = 1L;
+
+ private Textbox txtCalc = new Textbox();
+
+ boolean integral = false;
+
+ NumberFormat format = null;
+
+ public NumberBox(boolean integral)
+ {
+ super();
+ this.integral = integral;
+ init();
+ }
+
+ private void init()
+ {
+ this.setImage("/images/Calculator16.gif");
+ this.setAction("onKeyPress : return calc.validate('" +
+ this.getId() + "'," + integral + ", event);");
+ this.appendChild(getBandPopup());
+ }
+
+ public void setFormat(NumberFormat format)
+ {
+ this.format = format;
+ }
+
+ public void setValue(Number value)
+ {
+ if (format != null)
+ {
+ super.setValue(format.format(value));
+ }
+ else
+ {
+ super.setValue(value.toString());
+ }
+ }
+
+ public void setRawValue(Object value)
+ {
+ super.setRawValue(value);
+ }
+
+ public String getText()
+ {
+ return super.getText();
+ }
+
+ public void setValue(String value)
+ {
+ String formattedValue = "";
+ Number numberValue = null;
+
+ if (format != null)
+ {
+ try
+ {
+ numberValue = format.parse(value);
+ formattedValue = format.format(numberValue);
+ }
+ catch (ParseException e)
+ {
+ formattedValue = value;
+ }
+ }
+ else
+ {
+ formattedValue = value;
+ }
+
+ super.setValue(formattedValue);
+ }
+
+ public void setReadonly(boolean readonly)
+ {
+ // Due to bug in bandbox - once set readonly, setting to not readonly
+ // does not work
+ super.setDisabled(readonly);
+ }
+
+ private Bandpopup getBandPopup()
+ {
+ Bandpopup bandPopup = new Bandpopup();
+
+ Vbox vbox = new Vbox();
+
+ txtCalc = new Textbox();
+ txtCalc.setAction("onKeyPress : return calc.validate('" +
+ this.getId() + "!real','" + txtCalc.getId()
+ + "'," + integral + ", event);");
+ txtCalc.setMaxlength(250);
+ txtCalc.setCols(30);
+
+ String txtCalcId = txtCalc.getId();
+
+ vbox.appendChild(txtCalc);
+ Hbox row1 = new Hbox();
+
+ Button btnAC = new Button();
+ btnAC.setWidth("40px");
+ btnAC.setLabel("AC");
+ btnAC.setAction("onClick : calc.clearAll('" + txtCalcId + "')");
+
+ Button btn7 = new Button();
+ btn7.setWidth("30px");
+ btn7.setLabel("7");
+ btn7.setAction("onClick : calc.append('" + txtCalcId + "', '7')");
+
+ Button btn8 = new Button();
+ btn8.setWidth("30px");
+ btn8.setLabel("8");
+ btn8.setAction("onClick : calc.append('" + txtCalcId + "', '8')");
+
+ Button btn9 = new Button();
+ btn9.setWidth("30px");
+ btn9.setLabel("9");
+ btn9.setAction("onClick : calc.append('" + txtCalcId + "', '9')");
+
+ Button btnMultiply = new Button();
+ btnMultiply.setWidth("30px");
+ btnMultiply.setLabel("*");
+ btnMultiply.setAction("onClick : calc.append('" + txtCalcId + "', ' * ')");
+
+ row1.appendChild(btnAC);
+ row1.appendChild(btn7);
+ row1.appendChild(btn8);
+ row1.appendChild(btn9);
+ row1.appendChild(btnMultiply);
+
+ Hbox row2 = new Hbox();
+
+ Button btnC = new Button();
+ btnC.setWidth("40px");
+ btnC.setLabel("C");
+ btnC.setAction("onClick : calc.clear('" + txtCalcId + "')");
+
+ Button btn4 = new Button();
+ btn4.setWidth("30px");
+ btn4.setLabel("4");
+ btn4.setAction("onClick : calc.append('" + txtCalcId + "', '4')");
+
+ Button btn5 = new Button();
+ btn5.setWidth("30px");
+ btn5.setLabel("5");
+ btn5.setAction("onClick : calc.append('" + txtCalcId + "', '5')");
+
+ Button btn6 = new Button();
+ btn6.setWidth("30px");
+ btn6.setLabel("6");
+ btn6.setAction("onClick : calc.append('" + txtCalcId + "', '6')");
+
+ Button btnDivide = new Button();
+ btnDivide.setWidth("30px");
+ btnDivide.setLabel("/");
+ btnDivide.setAction("onClick : calc.append('" + txtCalcId + "', ' / ')");
+
+ row2.appendChild(btnC);
+ row2.appendChild(btn4);
+ row2.appendChild(btn5);
+ row2.appendChild(btn6);
+ row2.appendChild(btnDivide);
+
+ Hbox row3 = new Hbox();
+
+ Button btnModulo = new Button();
+ btnModulo.setWidth("40px");
+ btnModulo.setLabel("%");
+ btnModulo.setAction("onClick : calc.append('" + txtCalcId + "', ' % ')");
+
+ Button btn1 = new Button();
+ btn1.setWidth("30px");
+ btn1.setLabel("1");
+ btn1.setAction("onClick : calc.append('" + txtCalcId + "', '1')");
+
+ Button btn2 = new Button();
+ btn2.setWidth("30px");
+ btn2.setLabel("2");
+ btn2.setAction("onClick : calc.append('" + txtCalcId + "', '2')");
+
+ Button btn3 = new Button();
+ btn3.setWidth("30px");
+ btn3.setLabel("3");
+ btn3.setAction("onClick : calc.append('" + txtCalcId + "', '3')");
+
+ Button btnSubstract = new Button();
+ btnSubstract.setWidth("30px");
+ btnSubstract.setLabel("-");
+ btnSubstract.setAction("onClick : calc.append('" + txtCalcId + "', ' - ')");
+
+ row3.appendChild(btnModulo);
+ row3.appendChild(btn1);
+ row3.appendChild(btn2);
+ row3.appendChild(btn3);
+ row3.appendChild(btnSubstract);
+
+ Hbox row4 = new Hbox();
+
+ Button btnCurrency = new Button();
+ btnCurrency.setWidth("40px");
+ btnCurrency.setLabel("$");
+ btnCurrency.setDisabled(true);
+
+ Button btn0 = new Button();
+ btn0.setWidth("30px");
+ btn0.setLabel("0");
+ btn0.setAction("onClick : calc.append('" + txtCalcId + "', '0')");
+
+ Button btnDot = new Button();
+ btnDot.setWidth("30px");
+ btnDot.setLabel(".");
+ btnDot.setDisabled(integral);
+ btnDot.setAction("onClick : calc.append('" + txtCalcId + "', '.')");
+
+ Button btnEqual = new Button();
+ btnEqual.setWidth("30px");
+ btnEqual.setLabel("=");
+ btnEqual.setAction("onClick : calc.evaluate('" + this.getId() + "!real','"
+ + txtCalcId + "')");
+
+ Button btnAdd = new Button();
+ btnAdd.setWidth("30px");
+ btnAdd.setLabel("+");
+ btnAdd.setAction("onClick : calc.append('" + txtCalcId + "', ' + ')");
+
+ row4.appendChild(btnCurrency);
+ row4.appendChild(btnDot);
+ row4.appendChild(btn0);
+ row4.appendChild(btnEqual);
+ row4.appendChild(btnAdd);
+
+ vbox.appendChild(row1);
+ vbox.appendChild(row2);
+ vbox.appendChild(row3);
+ vbox.appendChild(row4);
+
+ bandPopup.appendChild(vbox);
+ return bandPopup;
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Panel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Panel.java
new file mode 100644
index 0000000000..78713b6bbe
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Panel.java
@@ -0,0 +1,40 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import org.zkoss.zul.Div;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class Panel extends Div
+{
+ private static final long serialVersionUID = 1L;
+
+ public static final String HORIZONTAL = "horizontal";
+
+ public static final String VERTICAL = "vertical";
+
+ public Panel()
+ {
+ super();
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Row.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Row.java
new file mode 100644
index 0000000000..5e3024c128
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Row.java
@@ -0,0 +1,30 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class Row extends org.zkoss.zul.Row
+{
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Rows.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Rows.java
new file mode 100644
index 0000000000..3485ee59e6
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Rows.java
@@ -0,0 +1,30 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class Rows extends org.zkoss.zul.Rows
+{
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Searchbox.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Searchbox.java
new file mode 100644
index 0000000000..4500481b12
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Searchbox.java
@@ -0,0 +1,107 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+
+import org.zkoss.zk.ui.event.EventListener;
+
+public class Searchbox extends Panel
+{
+ private static final long serialVersionUID = 1L;
+ private PropertyChangeSupport m_propertyChangeListeners = new PropertyChangeSupport(this);
+ private Textbox txt;
+ private Button btn;
+
+ public Searchbox()
+ {
+ initComponents();
+ }
+
+ public Searchbox(String text)
+ {
+ initComponents();
+ setText(text);
+ }
+
+ public void setButtonImage(String imageSrc)
+ {
+ btn.setImage(imageSrc);
+ }
+
+ private void initComponents()
+ {
+ txt = new Textbox();
+ btn = new Button();
+ appendChild(txt);
+ appendChild(btn);
+ }
+
+ public Textbox getTextBox()
+ {
+ return txt;
+ }
+
+ public void setText(String value)
+ {
+ txt.setText(value);
+ }
+
+ public String getText()
+ {
+ return txt.getText();
+ }
+
+ public void setEnabled(boolean enabled)
+ {
+ txt.setEnabled(enabled);
+ btn.setEnabled(enabled);
+ }
+
+ public boolean isEnabled()
+ {
+ return txt.isReadonly();
+ }
+
+ public boolean addEventListener(String evtnm, EventListener listener)
+ {
+ if("onClick".equals(evtnm))
+ {
+ return btn.addEventListener(evtnm, listener);
+ }
+ else
+ {
+ return txt.addEventListener(evtnm, listener);
+ }
+ }
+ public synchronized void addPropertyChangeListener(PropertyChangeListener l)
+ {
+ m_propertyChangeListeners.addPropertyChangeListener(l);
+ }
+
+ /**
+ * Set whether the SearchBox represents a mandatory field.
+ *
+ * @param mandatory whether the search box must be filled
+ */
+ public void setMandatory(boolean mandatory)
+ {
+ txt.setMandatory(mandatory);
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Tab.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Tab.java
new file mode 100644
index 0000000000..5bf22781c7
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Tab.java
@@ -0,0 +1,40 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class Tab extends org.zkoss.zul.Tab
+{
+ private static final long serialVersionUID = 1L;
+
+ public Tab(String str)
+ {
+ this.setLabel(str);
+ }
+
+ public Tab()
+ {
+
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Tabbox.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Tabbox.java
new file mode 100644
index 0000000000..5cb8fd54e1
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Tabbox.java
@@ -0,0 +1,50 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import org.zkoss.zul.Tabpanels;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class Tabbox extends org.zkoss.zul.Tabbox
+{
+ private static final long serialVersionUID = 1L;
+
+ public Tabpanel getTabpanel(int index)
+ {
+ try
+ {
+ Tabpanels tabpanels = this.getTabpanels();
+ Tabpanel tabPanel = (Tabpanel)tabpanels.getChildren().get(index);
+ return tabPanel;
+ }
+ catch (Exception ex)
+ {
+ throw new IndexOutOfBoundsException(ex.getMessage());
+ }
+ }
+
+ public Tabpanel getSelectedTabpanel()
+ {
+ return getTabpanel(this.getSelectedIndex());
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Tabpanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Tabpanel.java
new file mode 100644
index 0000000000..254d4e434e
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Tabpanel.java
@@ -0,0 +1,41 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class Tabpanel extends org.zkoss.zul.Tabpanel
+{
+ private static final long serialVersionUID = 1L;
+
+ private boolean enabled;
+
+ public boolean isEnabled()
+ {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled)
+ {
+ this.enabled = enabled;
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Tabpanels.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Tabpanels.java
new file mode 100644
index 0000000000..c908d49e76
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Tabpanels.java
@@ -0,0 +1,34 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class Tabpanels extends org.zkoss.zul.Tabpanels
+{
+ private static final long serialVersionUID = 1L;
+
+ public Tabpanels()
+ {
+ super();
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Tabs.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Tabs.java
new file mode 100644
index 0000000000..864a641739
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Tabs.java
@@ -0,0 +1,34 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 2, 2007
+ * @version $Revision: 0.10 $
+ */
+public class Tabs extends org.zkoss.zul.Tabs
+{
+ private static final long serialVersionUID = 1L;
+
+ public Tabs()
+ {
+ super();
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Textbox.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Textbox.java
new file mode 100644
index 0000000000..f3c08c471e
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Textbox.java
@@ -0,0 +1,62 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import org.zkoss.zk.ui.WrongValueException;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class Textbox extends org.zkoss.zul.Textbox
+{
+ private static final long serialVersionUID = 1L;
+
+
+ public Textbox()
+ {
+ super();
+ }
+
+ public Textbox(String value) throws WrongValueException
+ {
+ super(value);
+ }
+
+ public void setEnabled(boolean enabled)
+ {
+ this.setDisabled(!enabled);
+ }
+
+ /**
+ * Set whether the textbox represents a mandatory field.
+ *
+ * @param mandatory whether the texbox must be filled
+ */
+ public void setMandatory(boolean mandatory)
+ {
+/* if (mandatory)
+ {
+ ZkCssHelper.setStyleBackgroundColor(this, AdempierePLAF.getFieldBackground_Mandatory());
+ }
+*/
+ this.setStyle("background-color:#e1d6d6");
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ToolBar.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ToolBar.java
new file mode 100644
index 0000000000..7821acdc9b
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ToolBar.java
@@ -0,0 +1,29 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+/**
+ * @author Sendy Yagambrum
+ * @date July, 10 2007
+ */
+public class ToolBar extends org.zkoss.zul.Toolbar
+{
+
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ToolBarButton.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ToolBarButton.java
new file mode 100644
index 0000000000..3965d57cee
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ToolBarButton.java
@@ -0,0 +1,29 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+/**
+ * @author Sendy Yagambrum
+ * @date July, 10 2007
+ */
+public class ToolBarButton extends org.zkoss.zul.Toolbarbutton
+{
+
+ private static final long serialVersionUID = 0L;
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Urlbox.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Urlbox.java
new file mode 100644
index 0000000000..be575fded3
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Urlbox.java
@@ -0,0 +1,86 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import org.zkoss.zk.ui.event.EventListener;
+
+/**
+ * URL Box
+ */
+public class Urlbox extends Panel
+{
+
+ private static final long serialVersionUID = 1L;
+
+ private Textbox txtUrl;
+
+ private Button btnUrl;
+
+ public Urlbox()
+ {
+ initComponents();
+ }
+
+ public Urlbox(String url)
+ {
+ initComponents();
+ setText(url);
+ }
+
+ public void setButtonImage(String imageSrc)
+ {
+ btnUrl.setImage(imageSrc);
+ }
+
+ private void initComponents()
+ {
+ txtUrl = new Textbox();
+ btnUrl = new Button();
+ appendChild(txtUrl);
+ appendChild(btnUrl);
+ }
+
+ public void setText(String value)
+ {
+ txtUrl.setText(value);
+ }
+
+ public String getText()
+ {
+ return txtUrl.getText();
+ }
+
+ public void setEnabled(boolean enabled)
+ {
+ txtUrl.setEnabled(enabled);
+ btnUrl.setEnabled(enabled);
+ }
+
+ public void setButtonEnabled(boolean enabled)
+ {
+ btnUrl.setEnabled(enabled);
+ }
+
+ public boolean addEventListener(String evtnm, EventListener listener)
+ {
+ if ("onClick".equals(evtnm))
+ return btnUrl.addEventListener(evtnm, listener);
+ else
+ return txtUrl.addEventListener(evtnm, listener);
+ }
+}
\ No newline at end of file
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/VerticalBox.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/VerticalBox.java
new file mode 100644
index 0000000000..309be841ee
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/VerticalBox.java
@@ -0,0 +1,30 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class VerticalBox extends org.zkoss.zul.Vbox
+{
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/WAppsAction.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/WAppsAction.java
new file mode 100644
index 0000000000..ddecd93d6b
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/WAppsAction.java
@@ -0,0 +1,211 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import java.awt.Dimension;
+import java.io.IOException;
+import java.net.URI;
+
+import org.adempiere.webui.apps.AEnv;
+import org.compiere.util.Env;
+import org.compiere.util.Msg;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zk.ui.event.Events;
+
+
+
+/**
+ * Application Action.
+ * Creates Action with MenuItem and Button, delegate execution of action to an attached ActionListener instance
+ * The ActionCommand is translated for display
+ * If translated text contains &, the next character is the Mnemonic
+ *
+ * @author Andrew Kimball
+ */
+public class WAppsAction implements EventListener
+{
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Application Action
+ *
+ * @param action base action command - used as AD_Message for Text and Icon name
+ * @param accelerator optional keystroke for accelerator
+ * @param toggle is toggle action (maintains state)
+ */
+ public WAppsAction (String action, String accelerator) throws IOException
+ {
+ this (action, accelerator, null);
+ }
+
+ /**
+ * Application Action.
+ *
+ * @param action base action command - used as AD_Message for Text and Icon name
+ * @param accelerator optional keystroke for accelerator
+ * @param toolTipText text, if null defered from action
+ * @param toggle is toggle action (maintains state)
+ */
+ public WAppsAction (String action, String accelerator, String toolTipText) throws IOException
+ {
+ super();
+ String newToolTipText = toolTipText;
+ m_action = action;
+ if (m_accelerator == null)
+ {
+ m_accelerator = "";
+ }
+ else
+ {
+ m_accelerator = accelerator;
+ }
+
+
+ // Data
+ if (newToolTipText == null)
+ {
+ newToolTipText = Msg.getMsg(Env.getCtx(), action);
+ }
+ int pos = newToolTipText.indexOf('&');
+ if (pos != -1 && newToolTipText.length() > pos) // We have a nemonic - creates ALT-_
+ {
+ // TODO create mnemonic
+ Character ch = new Character(newToolTipText.toLowerCase().charAt(pos + 1));
+ if (ch != ' ')
+ {
+ // remove ampersand
+ newToolTipText = newToolTipText.substring(0, pos)
+ + newToolTipText.substring(pos + 1);
+ // append ALT-mnemonic to accelerator
+ m_accelerator += "@" + ch;
+ }
+ }
+ //
+ //Image small = getImage(action, true);
+ URI large = getImage(action, false);
+ //Image largePressed = null;
+
+ // Attributes
+
+ m_button = new Button();
+
+ m_button.setTooltiptext(newToolTipText); // Display
+
+ // Create Button
+
+ m_button.setName(action);
+ // Correcting Action items
+ if (large != null)
+ {
+ m_button.setImage(large.getPath());
+ //m_button.setImage("/images/Cancel16.gif");
+ m_button.setLabel(null);
+ }
+ m_button.setWidth(Integer.toString(Double.valueOf(BUTTON_SIZE.getWidth()).intValue()));
+ m_button.setHeight(Integer.toString(Double.valueOf(BUTTON_SIZE.getHeight()).intValue()));
+ } // Action
+
+ /** Button Size */
+ public static final Dimension BUTTON_SIZE = new Dimension(28,28);
+ /** CButton or CToggelButton */
+ private Button m_button;
+
+ private String m_action = null;
+ private String m_accelerator = null;
+ private EventListener m_delegate = null;
+
+ /**
+ * Get Icon with name action
+ * @param name name
+ * @param small small
+ * @return Icon
+ */
+ private URI getImage(String name, boolean small) throws IOException
+ {
+ String fullName = name + (small ? "16" : "24");
+ URI uri = AEnv.getImage2(fullName);
+ return uri;
+ } // getIcon
+
+ /**
+ * Get Name/ActionCommand
+ * @return ActionName
+ */
+ public String getName()
+ {
+ return m_action;
+ } // getName
+
+ /**
+ * Return Button
+ * @return Button
+ */
+ public Button getButton()
+ {
+ return m_button;
+ } // getButton
+
+
+ /**
+ * Set Delegate to receive the actionPerformed calls
+ * @param listener listener
+ * @throws IllegalArgumentException if the listener is not a window. This
+ * exception can be ignored as events will still be fired for button presses.
+ */
+ public void setDelegate(EventListener listener) throws IllegalArgumentException
+ {
+ m_button.addEventListener(Events.ON_CLICK, this);
+ m_delegate = listener;
+
+ if (listener instanceof Window)
+ {
+ ((Window) listener).setCtrlKeys(this.m_accelerator);
+ ((Window) listener).addEventListener(Events.ON_CTRL_KEY, this);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Functionality has been restricted. "
+ + " as a result of the listener not being a Window. "
+ + "Consequently, it is unable to respond to keystrokes");
+ }
+
+ return;
+ } // setDelegate
+
+ /* (non-Javadoc)
+ * @see org.zkoss.zk.ui.event.EventListener#onEvent(org.zkoss.zk.ui.event.Event)
+ */
+ public void onEvent(Event event) throws Exception
+ {
+ // TODO Auto-generated method stub
+ Event newEvent = new Event(this.m_action, event.getTarget());
+ m_delegate.onEvent(newEvent);
+
+ return;
+ }
+
+ public String getCtrlKeys()
+ {
+ return this.m_accelerator;
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/WConfirmPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/WConfirmPanel.java
new file mode 100644
index 0000000000..7ea2961623
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/WConfirmPanel.java
@@ -0,0 +1,652 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import java.io.IOException;
+import java.util.logging.Level;
+
+import org.compiere.util.CLogger;
+import org.compiere.util.Env;
+import org.compiere.util.Msg;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zk.ui.event.Events;
+
+/**
+ * @author Andrew Kimball
+ *
+ */
+public class WConfirmPanel extends Panel implements EventListener
+{
+ /** Action String OK. */
+ public static final String A_OK = "Ok";
+ /** Action String Cancel. */
+ public static final String A_CANCEL = "Cancel";
+ /** Action String Refresh. */
+ public static final String A_REFRESH = "Refresh";
+ /** Action String Reset. */
+ public static final String A_RESET = "Reset";
+ /** Action String Customize. */
+ public static final String A_CUSTOMIZE = "Customize";
+ /** Action String History. */
+ public static final String A_HISTORY = "History";
+ /** Action String Zoom. */
+ public static final String A_ZOOM = "Zoom";
+
+ /** Action String Process. */
+ public static final String A_PROCESS = "Process";
+ /** Action String Print. */
+ public static final String A_PRINT = "Print";
+ /** Action String Export. */
+ public static final String A_EXPORT = "Export";
+ /** Action String Help. */
+ public static final String A_HELP = "Help";
+ /** Action String Delete. */
+ public static final String A_DELETE = "Delete";
+ /** Action String PAttribute. */
+ public static final String A_PATTRIBUTE = "PAttribute";
+ /** Action String New. */
+ public static final String A_NEW = "New";
+
+ /** Logger. */
+ private static CLogger log = CLogger.getCLogger(WConfirmPanel.class);
+
+
+ /** Cancel action. */
+ private WAppsAction m_actionCancel;
+ private WAppsAction m_actionOk;
+
+ private WAppsAction m_actionRefresh;
+ private WAppsAction m_actionReset;
+ private WAppsAction m_actionCustomize;
+ private WAppsAction m_actionHistory;
+ private WAppsAction m_actionZoom;
+
+ /**
+ * Create Confirmation Panel with OK Button.
+ */
+ public WConfirmPanel()
+ {
+ this (false, false, false, false, false, false, true);
+ } // ConfirmPanel
+
+
+ /**
+ * Create Confirmation Panel with OK and Cancel Button.
+ * @param withCancelButton with cancel
+ */
+ public WConfirmPanel(boolean withCancelButton)
+ {
+ this(withCancelButton, false, false, false, false, false, true);
+ }
+
+ /**
+ * Create Confirmation Panel with different buttons.
+ * @param withCancelButton with cancel
+ * @param withRefreshButton with refresh
+ * @param withResetButton with reset
+ * @param withCustomizeButton with customize
+ * @param withHistoryButton with history
+ * @param withZoomButton with zoom
+ * @param withText with tool tip text
+ */
+ public WConfirmPanel(boolean withCancelButton,
+ boolean withRefreshButton,
+ boolean withResetButton,
+ boolean withCustomizeButton,
+ boolean withHistoryButton,
+ boolean withZoomButton,
+ boolean withText)
+ {
+ Panel pnlOkCancel = new Panel();
+ Button button;
+
+ try
+ {
+
+ this.setAlign("right");
+
+ // Cancel
+ m_actionCancel = createCancelButton(withText);
+ Button btnCancel = m_actionCancel.getButton();
+ setCancelVisible(btnCancel, withCancelButton);
+ pnlOkCancel.appendChild(btnCancel);
+
+ // OK
+ m_actionOk = createOKButton(withText);
+ Button btnOk = m_actionOk.getButton();
+ pnlOkCancel.appendChild(btnOk);
+
+ this.appendChild(pnlOkCancel);
+
+ //
+ if (withRefreshButton)
+ {
+ m_actionRefresh = createRefreshButton(withText);
+ Button btnRefresh = m_actionRefresh.getButton();
+ this.appendChild(btnRefresh);
+ }
+ if (withResetButton)
+ {
+ m_actionReset = createResetButton(withText);
+ Button btnReset = m_actionReset.getButton();
+ this.appendChild(btnReset);
+ }
+ if (withCustomizeButton)
+ {
+ m_actionCustomize = createCustomizeButton(withText);
+ Button btnCustomize = m_actionCustomize.getButton();
+ this.appendChild(btnCustomize);
+ }
+ if (withHistoryButton)
+ {
+ m_actionHistory = createHistoryButton(withText);
+ Button btnHistory = m_actionHistory.getButton();
+ this.appendChild(btnHistory);
+ }
+ if (withZoomButton)
+ {
+ m_actionZoom = createZoomButton(withText);
+ Button btnZoom = m_actionZoom.getButton();
+ this.appendChild(btnZoom);
+ }
+ }
+ catch(Exception exception)
+ {
+ log.log(Level.WARNING, "Failed to correctly create Confirmation Panel:"
+ + exception.getMessage());
+ }
+ } // ConfirmPanel
+
+ /**
+ * Create OK Button with Standard text.
+ * @param withText with text
+ * @return OK Button
+ */
+ public static final WAppsAction createOKButton (boolean withText) throws IOException
+ {
+ if (withText)
+ {
+ return createOKButton(Msg.getMsg(Env.getCtx(), A_OK));
+ }
+ return createOKButton("");
+ } // createOKButton
+
+ /**
+ * Create OK Button with label text and F4 Shortcut.
+ * @param text text
+ * @return OK Button
+ */
+ public static final WAppsAction createOKButton (String text) throws IOException
+ {
+ final String specialKey = "#f2";
+ WAppsAction aa = new WAppsAction(A_OK, specialKey, text);
+ return aa;
+ } // createOKButton
+
+ /**
+ * Create Cancel Button wlth label text and register ESC as KeyStroke.
+ * @param text text
+ * @return Cancel Button
+ */
+ public static final WAppsAction createCancelButton(String text) throws IOException
+ {
+ WAppsAction aa = new WAppsAction(A_CANCEL, null, text);
+ return aa;
+ } // createCancelButton
+
+ /**
+ * Create Cancel Button wlth Standard text.
+ * @param withText with text
+ * @return Button
+ */
+ public static final WAppsAction createCancelButton(boolean withText) throws IOException
+ {
+ if (withText)
+ {
+ return createCancelButton(Msg.getMsg(Env.getCtx(), A_CANCEL));
+ }
+ return createCancelButton("");
+ } // createCancelButton
+
+
+
+ /**
+ * Create Refresh Button wlth label text and F5.
+ * @param text text
+ * @return button
+ */
+ public static final WAppsAction createRefreshButton (String text) throws IOException
+ {
+ final String specialKey = "#f5";
+
+ WAppsAction aa = new WAppsAction(A_REFRESH, specialKey, text);
+
+ return aa;
+ } // createRefreshButton
+
+ /**
+ * Create Refresh Button wlth Standard text.
+ * @param withText with text
+ * @return Button
+ */
+ public static final WAppsAction createRefreshButton (boolean withText) throws IOException
+ {
+ if (withText)
+ {
+ return createRefreshButton(Msg.getMsg(Env.getCtx(), A_REFRESH));
+ }
+ return createRefreshButton("");
+ } // createRefreshButton
+
+
+ /**
+ * Create Reset Button wlth label text.
+ * @param text text
+ * @return button
+ */
+ public static final WAppsAction createResetButton (String text) throws IOException
+ {
+ WAppsAction aa = new WAppsAction(A_RESET, null, text);
+
+ return aa;
+ } // createResetButton
+
+ /**
+ * Create Reset Button wlth Standard text.
+ * @param withText with text
+ * @return Button
+ */
+ public static final WAppsAction createResetButton (boolean withText) throws IOException
+ {
+ if (withText)
+ {
+ return createResetButton(Msg.getMsg(Env.getCtx(), A_RESET));
+ }
+ return createResetButton(null);
+ } // createRefreshButton
+
+ /**
+ * Create Customize Button wlth label text.
+ * @param text text
+ * @return button
+ */
+ public static final WAppsAction createCustomizeButton (String text) throws IOException
+ {
+ WAppsAction aa = new WAppsAction(A_CUSTOMIZE, null, text);
+
+ return aa;
+ // Env.getImageIcon("Preference24.gif"));
+ } // createCustomizeButton
+
+ /**
+ * Create Customize Button wlth Standard text.
+ * @param withText with text
+ * @return aa
+ */
+ public static final WAppsAction createCustomizeButton (boolean withText) throws IOException
+ {
+ if (withText)
+ {
+ return createCustomizeButton(Msg.getMsg(Env.getCtx(), A_CUSTOMIZE));
+ }
+ return createCustomizeButton(null);
+ } // createCustomizeButton
+
+
+ /**
+ * Create History Button wlth label text.
+ * @param text text
+ * @return aa
+ */
+ public static final WAppsAction createHistoryButton (String text) throws IOException
+ {
+ final String specialKey = "#f9";
+ WAppsAction aa = new WAppsAction(A_HISTORY, specialKey, text);
+
+ return aa;
+ } // createHistoryButton
+
+ /**
+ * Create History Button wlth Standard text.
+ * @param withText with text
+ * @return aa
+ */
+ public static final WAppsAction createHistoryButton (boolean withText) throws IOException
+ {
+ if (withText)
+ {
+ return createHistoryButton(Msg.getMsg(Env.getCtx(), A_HISTORY));
+ }
+ return createHistoryButton(null);
+ } // createHistoryButton
+
+
+ /**
+ * Create Zoom Button wlth label text.
+ * @param text text
+ * @return aa
+ */
+ public static final WAppsAction createZoomButton (String text) throws IOException
+ {
+ WAppsAction aa = new WAppsAction(A_ZOOM, null, text);
+
+ return aa;
+ } // createZoomButton
+
+ /**
+ * Create Zoom Button wlth Standard text.
+ * @param withText with text
+ * @return aa
+ */
+ public static final WAppsAction createZoomButton (boolean withText) throws IOException
+ {
+ if (withText)
+ {
+ return createZoomButton(Msg.getMsg(Env.getCtx(), A_ZOOM));
+ }
+ return createZoomButton(null);
+ } // createZoomButton
+
+
+ /**
+ * Create Process Button wlth label text Shift-F4.
+ * @param text text
+ * @return aa
+ */
+ public static final WAppsAction createProcessButton (String text) throws IOException
+ {
+ // Shift-F4
+ final String specialKey = "$#f4";
+ WAppsAction aa = new WAppsAction(A_PROCESS, specialKey, text);
+
+ return aa;
+ } // createProcessButton
+
+ /**
+ * Create Process Button wlth Standard text.
+ * @param withText with text
+ * @return aa
+ */
+ public static final WAppsAction createProcessButton (boolean withText) throws IOException
+ {
+ if (withText)
+ {
+ return createProcessButton(Msg.getMsg(Env.getCtx(), A_PROCESS));
+ }
+ return createProcessButton(null);
+ } // createProcessButton
+
+
+ /**
+ * Create Print Button wlth label text.
+ * @param text text
+ * @return aa
+ */
+ public static final WAppsAction createPrintButton (String text) throws IOException
+ {
+ final String specialKey = "#f12";
+ WAppsAction aa = new WAppsAction(A_PRINT, specialKey, text);
+
+ return aa;
+ } // createPrintButton
+
+ /**
+ * Create Print Button wlth Standard text.
+ * @param withText with text
+ * @return aa
+ */
+ public static final WAppsAction createPrintButton (boolean withText) throws IOException
+ {
+ if (withText)
+ {
+ return createPrintButton(Msg.getMsg(Env.getCtx(), A_PRINT));
+ }
+ return createPrintButton(null);
+ } // createPrintButton
+
+
+ /**
+ * Create Help Button wlth label text.
+ * @param text text
+ * @return aa
+ */
+ public static final WAppsAction createHelpButton (String text) throws IOException
+ {
+ final String specialKey = "#f1";
+ WAppsAction aa = new WAppsAction(A_HELP, specialKey, text);
+
+ return aa;
+ } // createHelpButton
+
+ /**
+ * Create Help Button wlth Standard text.
+ * @param withText with text
+ * @return aa
+ */
+ public static final WAppsAction createHelpButton (boolean withText) throws IOException
+ {
+ if (withText)
+ {
+ return createHelpButton(Msg.getMsg(Env.getCtx(), A_HELP));
+ }
+ return createHelpButton(null);
+ } // createHelpButton
+
+
+ /**
+ * Create Export Button wlth label text.
+ * @param text text
+ * @return aa
+ */
+ public static final WAppsAction createExportButton (String text) throws IOException
+ {
+ WAppsAction aa = new WAppsAction(A_EXPORT, null, text);
+
+ return aa;
+ } // createExportButton
+
+ /**
+ * Create Export Button wlth Standard text.
+ * @param withText with text
+ * @return aa
+ */
+ public static final WAppsAction createExportButton (boolean withText) throws IOException
+ {
+ if (withText)
+ {
+ return createExportButton(Msg.getMsg(Env.getCtx(), A_EXPORT));
+ }
+ return createExportButton(null);
+ } // createExportButton
+
+
+ /************************
+ * Create Delete Button with label text - F3.
+ * @param text text
+ * @return Delete Button
+ */
+ public static final WAppsAction createDeleteButton (String text) throws IOException
+ {
+ final String specialKey = "#f3";
+ WAppsAction aa = new WAppsAction(A_DELETE, specialKey, text);
+
+ return aa;
+ } // createDeleteButton
+
+ /**
+ * Create Delete Button with Standard text.
+ * @param withText with text
+ * @return Delete Button
+ */
+ public static final WAppsAction createDeleteButton (boolean withText) throws IOException
+ {
+ if (withText)
+ {
+ return createDeleteButton(Msg.getMsg(Env.getCtx(), A_DELETE));
+ }
+ return createDeleteButton(null);
+ } // createDeleteButton
+
+
+ /************************
+ * Create Product Attribute Button with Standard text.
+ * @param withText with text
+ * @return Product Attribute Button
+ */
+ public static final WAppsAction createPAttributeButton (boolean withText) throws IOException
+ {
+ if (withText)
+ {
+ return createPAttributeButton(Msg.getMsg(Env.getCtx(), A_PATTRIBUTE));
+ }
+ return createPAttributeButton(null);
+ } // createPAttributeButton
+
+ /**
+ * Create Product Attribute Button with label text.
+ * @param text text
+ * @return Product Attribute Button
+ */
+ public static final WAppsAction createPAttributeButton (String text) throws IOException
+ {
+ WAppsAction aa = new WAppsAction(A_PATTRIBUTE, null, text);
+
+ return aa;
+ } // createPAttributeButton
+
+
+ /**
+ * Create New Button with Standard text.
+ * @param withText with text
+ * @return New Button
+ */
+ public static final WAppsAction createNewButton (boolean withText) throws IOException
+ {
+ if (withText)
+ {
+ return createNewButton(Msg.getMsg(Env.getCtx(), A_NEW));
+ }
+ return createNewButton(null);
+ } // createNewButton
+
+ /**
+ * Create New Button with label text - F2.
+ * @param text text
+ * @return Product Attribute Button
+ */
+ public static final WAppsAction createNewButton (String text) throws IOException
+ {
+ final String specialKey = "#f2";
+ WAppsAction aa = new WAppsAction(A_NEW, specialKey, text);
+
+ return aa;
+ } // createNewButton
+
+ /**
+ * Show Cancel button.
+ * @param value trie for visible
+ */
+ public void setCancelVisible (Button button, boolean value)
+ {
+ button.setVisible(value);
+ button.setEnabled(value);
+ }
+
+ /**
+ * Add Event Listener.
+ *
+ * if (e.getActionCommand().equals(ConfirmPanel.A_OK))
+ *
+ * In order to respond to keystrokes, the EventListener
+ * should be a Window
. If the listener is not a window
+ * the panel will only respond to onClick
events.
+ *
+ * @param listener the event listener
+ */
+ public void addEventListener(EventListener listener)
+ {
+ String ctrlKeys = "";
+ try
+ {
+ m_actionOk.setDelegate(listener);
+ ctrlKeys += m_actionOk.getCtrlKeys();
+ m_actionCancel.setDelegate(listener);
+ ctrlKeys += m_actionCancel.getCtrlKeys();
+ //
+ if (m_actionRefresh != null)
+ {
+ m_actionRefresh.setDelegate(listener);
+ ctrlKeys += m_actionRefresh.getCtrlKeys();
+ }
+ if (m_actionReset != null)
+ {
+ m_actionReset.setDelegate(listener);
+ ctrlKeys += m_actionReset.getCtrlKeys();
+ }
+ if (m_actionCustomize != null)
+ {
+ m_actionCustomize.setDelegate(listener);
+ ctrlKeys += m_actionCustomize.getCtrlKeys();
+ }
+ if (m_actionHistory != null)
+ {
+ m_actionHistory.setDelegate(listener);
+ ctrlKeys += m_actionHistory.getCtrlKeys();
+ }
+ if (m_actionZoom != null)
+ {
+ m_actionZoom.setDelegate(listener);
+ ctrlKeys += m_actionZoom.getCtrlKeys();
+ }
+ }
+ catch (IllegalArgumentException exception)
+ {
+ log.warning(exception.getMessage());
+ }
+
+ // Set OK as default Button
+ // and Cancel as cancel button
+ if (listener instanceof Window)
+ {
+ ((Window) listener).addEventListener(Events.ON_CANCEL, m_actionCancel);
+ ((Window) listener).addEventListener(Events.ON_OK, m_actionOk);
+ // TODO enable Ctrl Keys
+ //((Window) listener).setCtrlKeys(ctrlKeys);
+ //((Window) listener).addEventListener(Events.ON_CTRL_KEY, this);
+ }
+ else
+ {
+ log.warning("Functionality of the Confirmation Panel has been restricted. "
+ + " as a result of the specified listener not being a Window. "
+ + "Consequently, it is unable to respond to keystrokes");
+ }
+ } // addActionListener
+
+ /* (non-Javadoc)
+ * @see org.zkoss.zk.ui.event.EventListener#onEvent(org.zkoss.zk.ui.event.Event)
+ */
+ public void onEvent(Event event) throws Exception
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/WListItemRenderer.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/WListItemRenderer.java
new file mode 100644
index 0000000000..980248f0b4
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/WListItemRenderer.java
@@ -0,0 +1,684 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import java.awt.Color;
+import java.math.BigDecimal;
+import java.sql.Timestamp;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Vector;
+
+import org.adempiere.webui.event.TableValueChangeEvent;
+import org.adempiere.webui.event.TableValueChangeListener;
+import org.compiere.minigrid.IDColumn;
+import org.compiere.util.DisplayType;
+import org.compiere.util.MSort;
+import org.compiere.util.Util;
+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.zk.ui.event.SelectEvent;
+import org.zkoss.zul.Listbox;
+import org.zkoss.zul.Listcell;
+import org.zkoss.zul.Listitem;
+import org.zkoss.zul.ListitemRenderer;
+import org.zkoss.zul.ListitemRendererExt;
+
+/**
+ * Renderer for {@link org.adempiere.webui.component.ListItems}
+ * for the {@link org.adempiere.webui.component.Listbox}.
+ *
+ * @author Andrew Kimball
+ *
+ */
+public class WListItemRenderer implements ListitemRenderer, EventListener, ListitemRendererExt
+{
+ /** Array of listeners for changes in the table components. */
+ protected ArrayList m_listeners =
+ new ArrayList();
+
+ /** A list containing the indices of the currently selected ListItems. */
+ private Set m_selectedItems = new HashSet();
+ /** Array of table details. */
+ private ArrayList m_tableColumns = new ArrayList();
+ /** Array of {@link ListHeader}s for the list head. */
+ private ArrayList m_headers = new ArrayList();
+
+ /**
+ * Default constructor.
+ *
+ */
+ public WListItemRenderer()
+ {
+ super();
+ }
+
+ /**
+ * Constructor specifying the column headers.
+ *
+ * @param columnNames vector of column titles.
+ */
+ public WListItemRenderer(Vector< ? extends String> columnNames)
+ {
+ super();
+ WTableColumn tableColumn;
+
+ for (String columnName : columnNames)
+ {
+ tableColumn = new WTableColumn();
+ tableColumn.setHeaderValue(Util.cleanAmp(columnName));
+ m_tableColumns.add(tableColumn);
+ }
+ }
+
+ /**
+ * Get the column details of the specified column
.
+ *
+ * @param columnIndex The index of the column for which details are to be retrieved.
+ * @return The details of the column at the specified index.
+ */
+ private WTableColumn getColumn(int columnIndex)
+ {
+ try
+ {
+ return m_tableColumns.get(columnIndex);
+ }
+ catch (IndexOutOfBoundsException exception)
+ {
+ throw new IllegalArgumentException("There is no WTableColumn at column "
+ + columnIndex);
+ }
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.zkoss.zul.ListitemRenderer#render(org.zkoss.zul.Listitem, java.lang.Object)
+ */
+ public void render(Listitem item, Object data) throws Exception
+ {
+ render((ListItem)item, data);
+ }
+
+ /**
+ * Renders the data
to the specified Listitem
.
+ *
+ * @param item the listitem to render the result.
+ * Note: when this method is called, the listitem has no child
+ * at all.
+ * @param data that is returned from {@link ListModel#getElementAt}
+ * @throws Exception
+ * @see {@link #render(Listitem, Object)}
+ */
+ private void render(ListItem item, Object data)
+ {
+ Listcell listcell = null;
+ int colIndex = 0;
+ int rowIndex = item.getIndex();
+ WListbox table = null;
+
+ if (item.getListbox() instanceof WListbox)
+ {
+ table = (WListbox)item.getListbox();
+ }
+
+ if (!(data instanceof Vector))
+ {
+ throw new IllegalArgumentException("A model element was not a vector");
+ }
+
+ for (Object field : (Vector)data)
+ {
+ listcell = getCellComponent(table, field, rowIndex, colIndex);
+ listcell.setParent(item);
+ colIndex++;
+ }
+
+ return;
+ }
+
+ /**
+ * Obtain the foreground colour to be used for the specified field.
+ *
+ * @param table The table containing the affected field.
+ * @param row The row of the field for which the colour is wanted.
+ * @return The Color
to be used.
+ */
+/* private Color getForegroundColour(WListbox table, int row)
+ {
+ Color fg = AdempierePLAF.getTextColor_Normal();
+
+ int colourCode = table.getColorCode(row);
+ //
+ if (colourCode == 0)
+ {
+ // Black
+ }
+ else if (colourCode < 0)
+ {
+ fg = AdempierePLAF.getTextColor_Issue(); // Red
+ }
+ else
+ {
+ fg = AdempierePLAF.getTextColor_OK(); // Blue
+ }
+
+ // Highlighted row
+ if (table.isSelected)
+ {
+ //fg = table.getSelectionForeground();
+ }
+
+ return fg;
+ }
+*/
+ /**
+ * Obtain the background colour to be used for the specified field.
+ *
+ * @param table The table containing the affected field.
+ * @param row The row of the field for which the colour is wanted.
+ * @param column The column of the field for which the colour is wanted.
+ * @return The Color
to be used.
+ */
+/* private Color getBackgroundColour(WListbox table, int row, int column)
+ {
+
+ Color bg = AdempierePLAF.getFieldBackground_Normal();
+
+ boolean isCellReadOnly = !table.isCellEditable(row, column);
+ if (isCellReadOnly)
+ {
+ bg = AdempierePLAF.getFieldBackground_Inactive();
+ if (isSelected && !hasFocus)
+ {
+ bg = bg.darker();
+ }
+ }
+
+ // Highlighted row
+ if (isSelected)
+ {
+ // Windows is white on blue
+ bg = table.getSelectionBackground();
+ if (hasFocus)
+ {
+ bg = GraphUtil.brighter(bg, .9);
+ }
+ }
+
+ return bg;
+ }
+*/
+ /**
+ * Generate the cell for the given field
.
+ *
+ * @param table The table into which the cell will be placed.
+ * @param field The data field for which the cell is to be created.
+ * @param rowIndex The row in which the cell is to be placed.
+ * @param columnIndex The column in which the cell is to be placed.
+ * @return The list cell component.
+ */
+ private Listcell getCellComponent(WListbox table, Object field,
+ int rowIndex, int columnIndex)
+ {
+ ListCell listcell = new ListCell();
+ boolean isCellEditable = table.isCellEditable(rowIndex, columnIndex);
+
+/* Color fgColor = getForegroundColour(table, rowIndex);
+ Color bgColor = getBackgroundColour(table, rowIndex, columnIndex);
+
+ ZkCssHelper.appendStyle(listcell, "color:#" + ZkCssHelper.createHexColorString(fgColor)
+ + "; bgcolor:#" + ZkCssHelper.createHexColorString(bgColor));
+*/
+ // TODO put this in factory method for generating cell renderers, which
+ // are assigned to Table Columns
+ if (field != null)
+ {
+ if (field instanceof Boolean)
+ {
+ listcell.setValue(Boolean.valueOf(field.toString()));
+
+ table.setCheckmark(false);
+ Checkbox checkbox = new Checkbox();
+ checkbox.setChecked(Boolean.valueOf(field.toString()));
+
+ if (isCellEditable)
+ {
+ checkbox.setEnabled(true);
+ checkbox.addEventListener(Events.ON_CHECK, this);
+ }
+ else
+ {
+ checkbox.setEnabled(false);
+ }
+
+ listcell.appendChild(checkbox);
+ ZkCssHelper.appendStyle(listcell, "text-align:center");
+ }
+ else if (field instanceof BigDecimal)
+ {
+ DecimalFormat format = DisplayType.getNumberFormat(DisplayType.Amount);
+ // set cell value to allow sorting
+ listcell.setValue(field.toString());
+
+ if (isCellEditable)
+ {
+ NumberBox numberbox = new NumberBox(false);
+ numberbox.setFormat(format);
+ numberbox.setValue((BigDecimal)field);
+ numberbox.setWidth("100px");
+ numberbox.setButtonVisible(true);
+ numberbox.setReadonly(false);
+ numberbox.setStyle("text-align:right; "
+ + listcell.getStyle());
+ numberbox.addEventListener(Events.ON_CHANGE, this);
+ listcell.appendChild(numberbox);
+ }
+ else
+ {
+ listcell.setLabel(format.format(((BigDecimal)field).doubleValue()));
+ ZkCssHelper.appendStyle(listcell, "text-align:right");
+ }
+ }
+ else if (field instanceof Timestamp)
+ {
+
+ SimpleDateFormat dateFormat = DisplayType.getDateFormat(DisplayType.Date);
+ listcell.setValue(dateFormat.format((Timestamp)field));
+ listcell.setLabel(dateFormat.format((Timestamp)field));
+ }
+ // if ID column make it invisible
+ else if (field instanceof IDColumn)
+ {
+ //listcell.setLabel(field.toString());
+ listcell.setValue(((IDColumn) field).getRecord_ID());
+ //listcell.setVisible(false);
+ table.setCheckmark(true);
+ table.addEventListener(Events.ON_SELECT, this);
+ }
+ else
+ {
+ listcell.setLabel(field.toString());
+ listcell.setValue(field.toString());
+ }
+ }
+ else
+ {
+ listcell.setLabel("");
+ listcell.setValue("");
+ }
+
+ return listcell;
+ }
+
+
+ /**
+ * Update Table Column.
+ *
+ * @param index The index of the column to update
+ * @param header The header text for the column
+ */
+ public void updateColumn(int index, String header)
+ {
+ WTableColumn tableColumn;
+
+ tableColumn = getColumn(index);
+ tableColumn.setHeaderValue(Util.cleanAmp(header));
+
+ return;
+ } // updateColumn
+
+ /**
+ * Add Table Column.
+ * after adding a column, you need to set the column classes again
+ * (DefaultTableModel fires TableStructureChanged, which calls
+ * JTable.tableChanged .. createDefaultColumnsFromModel
+ * @param header The header text for the column
+ */
+ public void addColumn(String header)
+ {
+ WTableColumn tableColumn;
+
+ tableColumn = new WTableColumn();
+ tableColumn.setHeaderValue(Util.cleanAmp(header));
+ m_tableColumns.add(tableColumn);
+
+ return;
+ } // addColumn
+
+ /**
+ * Get the number of columns.
+ * @return the number of columns
+ */
+ public int getNoColumns()
+ {
+ return m_tableColumns.size();
+ }
+
+ /**
+ * This is unused.
+ * The readonly proprty of a column should be set in
+ * the parent table.
+ *
+ * @param colIndex
+ * @param readOnly
+ * @deprecated
+ */
+ public void setRO(int colIndex, Boolean readOnly)
+ {
+ return;
+ }
+
+ /**
+ * Create a ListHeader using the given headerValue
to
+ * generate the header text.
+ * The toString
method of the headerValue
+ * is used to set the header text.
+ *
+ * @param headerValue The object to use for generating the header text.
+ * @param headerIndex The column index of the header
+ * @return The generated ListHeader
+ * @see #renderListHead(ListHead)
+ */
+ private Component getListHeaderComponent(Object headerValue, int headerIndex)
+ {
+ ListHeader header = null;
+
+ if (m_headers.size() <= headerIndex)
+ {
+ Comparator ascComparator = getColumnComparator(true, headerIndex);
+ Comparator dscComparator = getColumnComparator(false, headerIndex);
+
+ header = new ListHeader(headerValue.toString());
+
+ header.setSort("auto");
+ header.setSortAscending(ascComparator);
+ header.setSortDescending(dscComparator);
+
+ header.setWidth("auto");
+ m_headers.add(header);
+ }
+ else
+ {
+ header = m_headers.get(headerIndex);
+
+ if (!header.getLabel().equals(headerValue.toString()))
+ {
+ header.setLabel(headerValue.toString());
+ }
+ }
+
+ return header;
+ }
+
+ /**
+ * Obtain the comparator for a given column.
+ *
+ * @param ascending whether the comparator will sort ascending
+ * @param columnIndex the index of the column for which the comparator is required
+ * @return comparator for the given column for the given direction
+ */
+ protected Comparator getColumnComparator(boolean ascending, final int columnIndex)
+ {
+ Comparator comparator;
+ final MSort sort = new MSort(0, null);
+
+ sort.setSortAsc(ascending);
+
+ comparator = new Comparator()
+ {
+ public int compare(Object o1, Object o2)
+ {
+ Object item1 = ((Vector)o1).get(columnIndex);
+ Object item2 = ((Vector)o2).get(columnIndex);
+ return sort.compare(item1, item2);
+ }
+ };
+
+ return comparator;
+ }
+
+ /**
+ * Render the ListHead for the table with headers for the table columns.
+ *
+ * @param head The ListHead component to render.
+ * @see #addColumn(String)
+ * @see #WListItemRenderer(Vector)
+ */
+ public void renderListHead(ListHead head)
+ {
+ Component header;
+ WTableColumn column;
+
+ for (int columnIndex = 0; columnIndex < m_tableColumns.size(); columnIndex++)
+ {
+ column = m_tableColumns.get(columnIndex);
+ header = getListHeaderComponent(column.getHeaderValue(), columnIndex);
+ head.appendChild(header);
+ }
+ head.setSizable(true);
+ head.setWidth("auto");
+
+ return;
+ }
+
+ /* (non-Javadoc)
+ * @see org.zkoss.zk.ui.event.EventListener#onEvent(org.zkoss.zk.ui.event.Event)
+ */
+ public void onEvent(Event event) throws Exception
+ {
+ int col = -1;
+ int row = -1;
+ Object value = null;
+ TableValueChangeEvent vcEvent = null;
+ Set newlyUnselectedItems = new HashSet();
+ Set newlySelectedItems = new HashSet();
+ WTableColumn tableColumn;
+
+ Component source = event.getTarget();
+
+ if (source instanceof WListbox)
+ {
+ if (event instanceof SelectEvent)
+ {
+ col = 0;
+ tableColumn = m_tableColumns.get(col);
+
+ newlyUnselectedItems.addAll(m_selectedItems);
+ newlyUnselectedItems.removeAll(((SelectEvent)event).getSelectedItems());
+
+ newlySelectedItems.addAll(((SelectEvent)event).getSelectedItems());
+ newlySelectedItems.removeAll(m_selectedItems);
+
+ m_selectedItems.clear();
+ m_selectedItems.addAll(((SelectEvent)event).getSelectedItems());
+
+ for (Object item : newlySelectedItems)
+ {
+ row =((ListItem)item).getIndex();
+ value = Boolean.TRUE;
+ vcEvent = new TableValueChangeEvent(source,
+ tableColumn.getHeaderValue().toString(),
+ row, col,
+ value, value);
+ fireTableValueChange(vcEvent);
+ }
+
+
+ for (Object item : newlyUnselectedItems)
+ {
+ row =((ListItem)item).getIndex();
+ value = Boolean.FALSE;
+ vcEvent = new TableValueChangeEvent(source,
+ tableColumn.getHeaderValue().toString(),
+ row, col,
+ value, value);
+
+ fireTableValueChange(vcEvent);
+ }
+ }
+ }
+
+ else if (source.getParent() instanceof Listcell)
+ {
+ row = getRowPosition(source);
+ col = getColumnPosition(source);
+
+ tableColumn = m_tableColumns.get(col);
+
+ if (source instanceof Checkbox)
+ {
+ value = Boolean.valueOf(((Checkbox)source).isChecked());
+ }
+ else if (source instanceof NumberBox)
+ {
+ value = new BigDecimal(((NumberBox)source).getValue());
+ }
+
+ if(value != null)
+ {
+ vcEvent = new TableValueChangeEvent(source,
+ tableColumn.getHeaderValue().toString(),
+ row, col,
+ value, value);
+
+ fireTableValueChange(vcEvent);
+ }
+ }
+
+ return;
+ }
+
+ /**
+ * Get the row index of the given source
component.
+ *
+ * @param source The component for which the row index is to be found.
+ * @return The row index of the given component.
+ */
+ protected int getRowPosition(Component source)
+ {
+ Listcell cell;
+ ListItem item;
+ int row = -1;
+
+ cell = (Listcell)source.getParent();
+ item = (ListItem)cell.getParent();
+
+ row = item.getIndex();
+
+ return row;
+ }
+
+ /**
+ * Get the column index of the given source
component.
+ *
+ * @param source The component for which the column index is to be found.
+ * @return The column index of the given component.
+ */
+ protected int getColumnPosition(Component source)
+ {
+ Listcell cell;
+ int col = -1;
+
+ cell = (Listcell)source.getParent();
+ col = cell.getColumnIndex();
+
+ return col;
+ }
+
+
+ /**
+ * Reset the renderer.
+ * This should be called if the table using this renderer is cleared.
+ */
+ public void clearColumns()
+ {
+ m_tableColumns.clear();
+ }
+
+ /**
+ * Clear the renderer.
+ * This should be called if the table using this renderer is cleared.
+ */
+ public void clearSelection()
+ {
+ m_selectedItems.clear();
+ }
+
+ /**
+ * Add a listener for changes in the table's component values.
+ *
+ * @param listener The listener to add.
+ */
+ public void addTableValueChangeListener(TableValueChangeListener listener)
+ {
+ if (listener == null)
+ {
+ return;
+ }
+
+ m_listeners.add(listener);
+
+ return;
+ }
+
+ /**
+ * Fire the given table value change event
.
+ *
+ * @param event The event to pass to the listeners
+ */
+ private void fireTableValueChange(TableValueChangeEvent event)
+ {
+ for (TableValueChangeListener listener : m_listeners)
+ {
+ listener.tableValueChange(event);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.zkoss.zul.ListitemRendererExt#getControls()
+ */
+ public int getControls()
+ {
+ return DETACH_ON_RENDER;
+ }
+
+ /* (non-Javadoc)
+ * @see org.zkoss.zul.ListitemRendererExt#newListcell(org.zkoss.zul.Listitem)
+ */
+ public Listcell newListcell(Listitem item)
+ {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.zkoss.zul.ListitemRendererExt#newListitem(org.zkoss.zul.Listbox)
+ */
+ public Listitem newListitem(Listbox listbox)
+ {
+ return new ListItem();
+ }
+
+}
+
+
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/WListbox.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/WListbox.java
new file mode 100644
index 0000000000..2759ff4bca
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/WListbox.java
@@ -0,0 +1,1000 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import java.math.BigDecimal;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Vector;
+import java.util.logging.Level;
+
+import org.adempiere.webui.event.TableValueChangeEvent;
+import org.adempiere.webui.event.TableValueChangeListener;
+import org.adempiere.webui.event.WTableModelEvent;
+import org.adempiere.webui.event.WTableModelListener;
+import org.adempiere.webui.exception.ApplicationException;
+import org.compiere.minigrid.ColumnInfo;
+import org.compiere.minigrid.IDColumn;
+import org.compiere.minigrid.MiniTable;
+import org.compiere.model.MRole;
+import org.compiere.model.PO;
+import org.compiere.util.CLogger;
+import org.compiere.util.Env;
+import org.compiere.util.KeyNamePair;
+import org.compiere.util.Util;
+import org.zkoss.zul.ListModel;
+
+/**
+ * ZK Listbox extension for Adempiere Web UI.
+ * The listbox contains a model and a renderer.
+ * The model holds the underlying data objects, while the
+ * renderer deals with displaying the data objects.
+ * The renderer will render data objects using a variety of components.
+ * These components can then be edited if they are not readonly.
+ *
+ * @author Andrew Kimball
+ * @author Sendy Yagambrum
+ */
+public class WListbox extends Listbox implements TableValueChangeListener, WTableModelListener
+{
+
+ /** Logger. */
+ private static CLogger logger = CLogger.getCLogger(MiniTable.class);
+ /** Unique serial version identifier. */
+ private static final long serialVersionUID = 1L;
+
+ /** Model Index of Key Column. */
+ protected int m_keyColumnIndex = -1;
+
+ /** List of R/W columns. */
+ private ArrayList m_readWriteColumn = new ArrayList();
+ // TODO this duplicates other info held on columns. Needs rationalising.
+ /** Layout set in prepareTable and used in loadTable. */
+ private ColumnInfo[] m_layout = null;
+ /** column class types (e.g. Boolean) */
+ private ArrayList m_modelHeaderClass = new ArrayList();
+ /** Color Column Index of Model. */
+ private int m_colorColumnIndex = -1;
+ /** Color Column compare data. */
+ private Object m_colorDataCompare = Env.ZERO;
+
+ /**
+ * Default constructor.
+ *
+ * Sets a row renderer and an empty model
+ */
+ public WListbox()
+ {
+ super();
+ WListItemRenderer rowRenderer = new WListItemRenderer();
+ rowRenderer.addTableValueChangeListener(this);
+
+ setItemRenderer(rowRenderer);
+ setModel(new ListModelTable());
+ }
+
+ /**
+ * Set the data model and column header names for the Listbox.
+ *
+ * @param model The data model to assign to the table
+ * @param columnNames The names of the table columns
+ */
+ public void setData(ListModelTable model, Vector< ? extends String> columnNames)
+ {
+ // instantiate our custom row renderer
+ WListItemRenderer rowRenderer = new WListItemRenderer(columnNames);
+
+ // add listener for listening to component changes
+ rowRenderer.addTableValueChangeListener(this);
+
+ // assign the model and renderer
+ this.setModel(model);
+ getModel().setNoColumns(columnNames.size());
+ this.setItemRenderer(rowRenderer);
+
+ // re-render
+ this.repaint();
+
+ return;
+ }
+
+ public void setModel(ListModel model)
+ {
+ super.setModel(model);
+ if (model instanceof ListModelTable)
+ {
+ // TODO need to remove listener before adding, but how to do this without
+ // causing ConcurrentModificationException
+ //((ListModelTable)model).removeTableModelListener(this);
+ ((ListModelTable)model).addTableModelListener(this);
+ }
+ }
+
+ /**
+ * Create the listbox header by fetching it from the renderer and adding
+ * it to the Listbox.
+ *
+ */
+ private void initialiseHeader()
+ {
+ ListHead head = null;
+
+ head = super.getListHead();
+
+ //detach the old header
+ if (head != null)
+ {
+ head.detach();
+ }
+
+ head = new ListHead();
+
+ // recreate the list head
+ // TODO use reflection to check whether ItemRenderer is able to render ListHead
+ if (this.getItemRenderer() instanceof WListItemRenderer)
+ {
+ ((WListItemRenderer)this.getItemRenderer()).renderListHead(head);
+ }
+ else
+ {
+ throw new ApplicationException("Rendering of the ListHead is unsupported for "
+ + this.getItemRenderer().getClass().getSimpleName());
+ }
+
+ //reattach the listhead
+ head.setParent(this);
+
+ return;
+ }
+
+ /**
+ * Is the cell at the specified row and column editable?
+ *
+ * @param row row index of cell
+ * @param column column index of cell
+ * @return true if cell is editable, false otherwise
+ */
+ public boolean isCellEditable(int row, int column)
+ {
+ // if the first column holds a boolean and it is false, it is not editable
+ if (column != 0
+ && (getValueAt(row, 0) instanceof Boolean)
+ && !((Boolean)getValueAt(row, 0)).booleanValue())
+ {
+ return false;
+ }
+
+ // is the column read/write?
+ if (m_readWriteColumn.contains(new Integer(column)))
+ {
+ return true;
+ }
+
+ return false;
+ } // isCellEditable
+
+ /**
+ * Returns the cell value at row
and column
.
+ *
+ * Note : The column is specified in the table view's display
+ * order, and not in the TableModel
's column
+ * order. This is an important distinction because as the
+ * user rearranges the columns in the table,
+ * the column at a given index in the view will change.
+ * Meanwhile the user's actions never affect the model's
+ * column ordering.
+ *
+ * @param row the index of the row whose value is to be queried
+ * @param column the index of the column whose value is to be queried
+ * @return the Object at the specified cell
+ */
+ public Object getValueAt(int row, int column)
+ {
+ return getModel().getDataAt(row, convertColumnIndexToModel(column));
+ }
+
+ /**
+ * Return the ListModelTable
associated with this table.
+ *
+ * @return The ListModelTable
associated with this table.
+ */
+ public ListModelTable getModel()
+ {
+ if (super.getModel() instanceof ListModelTable)
+ {
+ return (ListModelTable)super.getModel();
+ }
+ else
+ {
+ throw new IllegalArgumentException("Model must be instance of " + ListModelTable.class.getName());
+ }
+ }
+
+ /**
+ * Set the cell value at row
and column
.
+ *
+ * @param value The value to set
+ * @param row the index of the row whose value is to be set
+ * @param column the index of the column whose value is to be set
+ */
+ public void setValueAt(Object value, int row, int column)
+ {
+ getModel().setDataAt(value, row, convertColumnIndexToModel(column));
+ }
+
+ /**
+ * Convert the index for a column from the display index to the
+ * corresponding index in the underlying model.
+ *
+ * This is unused for this implementation because the column ordering
+ * cannot be dynamically changed.
+ *
+ * @param viewColumnIndex the index of the column in the view
+ * @return the index of the corresponding column in the model
+ *
+ * @see #convertColumnIndexToVi
+ */
+ public int convertColumnIndexToModel(int viewColumnIndex)
+ {
+ return viewColumnIndex;
+ }
+
+ /**
+ * Set Column at the specified index
to read-only or read/write.
+ *
+ * @param index index of column to set as read-only (or not)
+ * @param readOnly Read only value. If true
column is read only,
+ * if false
column is read-write
+ */
+ public void setColumnReadOnly (int index, boolean readOnly)
+ {
+ Integer indexObject = new Integer(index);
+
+ // Column is ReadWrite
+ if (m_readWriteColumn.contains(indexObject))
+ {
+ // Remove from list
+ if (readOnly)
+ {
+ m_readWriteColumn.remove(indexObject);
+ } // ReadOnly
+ }
+ // current column is R/O - ReadWrite - add to list
+ else if (!readOnly)
+ {
+ m_readWriteColumn.add(indexObject);
+ }
+
+ return;
+ } // setColumnReadOnly
+
+ /**
+ * Prepare Table and return SQL required to get resultset to
+ * populate table.
+ *
+ * @param layout array of column info
+ * @param from SQL FROM content
+ * @param where SQL WHERE content
+ * @param multiSelection multiple selections
+ * @param tableName table name
+ * @return SQL statement to use to get resultset to populate table
+ */
+ public String prepareTable(ColumnInfo[] layout,
+ String from,
+ String where,
+ boolean multiSelection,
+ String tableName)
+ {
+ return prepareTable(layout, from, where, multiSelection, tableName, true);
+ } // prepareTable
+
+ /**
+ * Prepare Table and return SQL required to get resultset to
+ * populate table
+ *
+ * @param layout array of column info
+ * @param from SQL FROM content
+ * @param where SQL WHERE content
+ * @param multiSelection multiple selections
+ * @param tableName multiple selections
+ * @param addAccessSQL specifies whether to addAcessSQL
+ * @return SQL statement to use to get resultset to populate table
+ */
+ public String prepareTable(ColumnInfo[] layout,
+ String from,
+ String where,
+ boolean multiSelection,
+ String tableName,boolean addAccessSQL)
+ {
+ int columnIndex = 0;
+ StringBuffer sql = new StringBuffer ("SELECT ");
+ setLayout(layout);
+
+ clearColumns();
+
+ setMultiSelection(multiSelection);
+
+ // add columns & sql
+ for (columnIndex = 0; columnIndex < layout.length; columnIndex++)
+ {
+ // create sql
+ if (columnIndex > 0)
+ {
+ sql.append(", ");
+ }
+ sql.append(layout[columnIndex].getColSQL());
+
+ // adding ID column
+ if (layout[columnIndex].isKeyPairCol())
+ {
+ sql.append(",").append(layout[columnIndex].getKeyPairColSQL());
+ }
+
+ // add to model
+ addColumn(layout[columnIndex].getColHeader());
+
+ // set the colour column
+ if (layout[columnIndex].isColorColumn())
+ {
+ setColorColumn(columnIndex);
+ }
+ if (layout[columnIndex].getColClass() == IDColumn.class)
+ {
+ m_keyColumnIndex = columnIndex;
+ }
+ }
+
+ // set editors (two steps)
+ for (columnIndex = 0; columnIndex < layout.length; columnIndex++)
+ {
+ setColumnClass(columnIndex,
+ layout[columnIndex].getColClass(),
+ layout[columnIndex].isReadOnly(),
+ layout[columnIndex].getColHeader());
+ }
+
+ sql.append( " FROM ").append(from);
+ sql.append(" WHERE ").append(where);
+
+ // Table Selection
+ // TODO
+ //setRowSelectionAllowed(true);
+
+ // org.compiere.apps.form.VMatch.dynInit calls routine for initial init only
+ if (from.length() == 0)
+ {
+ return sql.toString();
+ }
+ //
+ if (addAccessSQL)
+ {
+ String finalSQL = MRole.getDefault().addAccessSQL(sql.toString(),
+ tableName,
+ MRole.SQL_FULLYQUALIFIED,
+ MRole.SQL_RO);
+
+ logger.finest(finalSQL);
+
+ return finalSQL;
+ }
+ else
+ {
+ return sql.toString();
+ }
+ } // prepareTable
+
+ /**
+ * Clear the table columns from both the model and renderer
+ */
+ private void clearColumns()
+ {
+ ((WListItemRenderer)getItemRenderer()).clearColumns();
+ getModel().setNoColumns(0);
+
+ return;
+ }
+
+
+ /**
+ * Add Table Column and specify the column header.
+ *
+ * @param header name of column header
+ */
+ public void addColumn (String header)
+ {
+ WListItemRenderer renderer = (WListItemRenderer)getItemRenderer();
+ renderer.addColumn(Util.cleanAmp(header));
+ getModel().addColumn();
+
+ return;
+ } // addColumn
+
+ /**
+ * Set the attributes of the column.
+ *
+ * @param index The index of the column to be modified
+ * @param classType The class of data that the column will contain
+ * @param readOnly Whether the data in the column is read only
+ * @param header The header text for the column
+ *
+ * @see #setColumnClass(int, Class, boolean)
+ */
+ public void setColumnClass (int index, Class classType, boolean readOnly, String header)
+ {
+ WListItemRenderer renderer = (WListItemRenderer)getItemRenderer();
+
+ setColumnReadOnly(index, readOnly);
+
+ // TODO transfer this to Renderer
+ m_modelHeaderClass.add(classType);
+
+ return;
+ }
+
+
+
+
+ /**
+ * Set the attributes of the column.
+ *
+ * @param index The index of the column to be modified
+ * @param classType The class of data that the column will contain
+ * @param readOnly Whether the data in the column is read only
+ *
+ * @see #setColumnClass(int, Class, boolean, String)
+ */
+ public void setColumnClass (int index, Class classType, boolean readOnly)
+ {
+ setColumnReadOnly(index, readOnly);
+
+ m_modelHeaderClass.add(classType);
+
+ return;
+ }
+
+ /**
+ * Set the attributes of the column.
+ *
+ * @param classType The class of data that the column will contain
+ * @param readOnly Whether the data in the column is read only
+ * @param header The header text for the column
+ *
+ * @see #setColumnClass(int, Class, boolean)
+ * @see #addColumn(String)
+ */
+ public void addColumn(Class classType, boolean readOnly, String header)
+ {
+ m_modelHeaderClass.add(classType);
+
+ setColumnReadOnly(m_modelHeaderClass.size() - 1, readOnly);
+
+ addColumn(header);
+
+ return;
+ }
+
+ /**
+ * Set the Column to determine the color of the row (based on model index).
+ * @param modelIndex the index of the column used to decide the colour
+ */
+ public void setColorColumn (int modelIndex)
+ {
+ m_colorColumnIndex = modelIndex;
+ } // setColorColumn
+
+ /**
+ * Load Table from ResultSet - The ResultSet is not closed.
+ *
+ * @param rs ResultSet containing data t enter int the table.
+ * The contents must conform to the column layout defined in
+ * {@link #prepareTable(ColumnInfo[], String, String, boolean, String)}
+ */
+ public void loadTable(ResultSet rs)
+ {
+ int row = 0; // model row
+ int col = 0; // model column
+ Object data = null;
+ int rsColIndex = 0; // index into result set
+ int rsColOffset = 1; // result set columns start with 1
+ Class columnClass; // class of the column
+
+ if (getLayout() == null)
+ {
+ throw new UnsupportedOperationException("Layout not defined");
+ }
+
+ clearTable();
+
+ try
+ {
+ while (rs.next())
+ {
+ row = getItemCount();
+ setRowCount(row + 1);
+ rsColOffset = 1;
+ for (col = 0; col < m_layout.length; col++)
+ {
+ columnClass = m_layout[col].getColClass();
+ rsColIndex = col + rsColOffset;
+
+ if (isColumnClassMismatch(col, columnClass))
+ {
+ throw new ApplicationException("Cannot enter a " + columnClass.getName()
+ + " in column " + col + ". " +
+ "An object of type " + m_modelHeaderClass.get(col).getSimpleName()
+ + " was expected.");
+ }
+
+ if (columnClass == IDColumn.class)
+ {
+ data = new IDColumn(rs.getInt(rsColIndex));
+ }
+ else if (columnClass == Boolean.class)
+ {
+ data = new Boolean(rs.getString(rsColIndex).equals("Y"));
+ }
+ else if (columnClass == Timestamp.class)
+ {
+ data = rs.getTimestamp(rsColIndex);
+ }
+ else if (columnClass == BigDecimal.class)
+ {
+ data = rs.getBigDecimal(rsColIndex);
+ }
+ else if (columnClass == Double.class)
+ {
+ data = new Double(rs.getDouble(rsColIndex));
+ }
+ else if (columnClass == Integer.class)
+ {
+ data = new Integer(rs.getInt(rsColIndex));
+ }
+ else if (columnClass == KeyNamePair.class)
+ {
+ // TODO factor out this generation
+ String display = rs.getString(rsColIndex);
+ int key = rs.getInt(rsColIndex + 1);
+ data = new KeyNamePair(key, display);
+ rsColOffset++;
+ }
+ else
+ {
+ // TODO factor out this cleanup
+ String s = rs.getString(rsColIndex);
+ if (s != null)
+ {
+ data = s.trim(); // problems with NCHAR
+ }
+ }
+ // store in underlying model
+ getModel().setDataAt(data, row, col);
+ }
+ }
+ }
+ catch (SQLException exception)
+ {
+ logger.log(Level.SEVERE, "", exception);
+ }
+ // TODO implement this
+ //autoSize();
+
+ // repaint the table
+ this.repaint();
+
+ logger.config("Row(rs)=" + getRowCount());
+
+ return;
+ } // loadTable
+
+ /**
+ * @param col
+ * @param columnClass
+ * @return
+ */
+ private boolean isColumnClassMismatch(int col, Class columnClass)
+ {
+ return !columnClass.equals(m_modelHeaderClass.get(col));
+ }
+
+ /**
+ * Load Table from Object Array.
+ * @param pos array of Persistent Objects
+ */
+ public void loadTable(PO[] pos)
+ {
+ int row = 0;
+ int col = 0;
+ int poIndex = 0; // index into the PO array
+ String columnName;
+ Object data;
+ Class columnClass;
+
+ if (m_layout == null)
+ {
+ throw new UnsupportedOperationException("Layout not defined");
+ }
+
+ // Clear Table
+ clearTable();
+
+ for (poIndex = 0; poIndex < pos.length; poIndex++)
+ {
+ PO myPO = pos[poIndex];
+ row = getRowCount();
+ setRowCount(row + 1);
+
+ for (col = 0; col < m_layout.length; col++)
+ {
+ columnName = m_layout[col].getColSQL();
+ data = myPO.get_Value(columnName);
+ if (data != null)
+ {
+ columnClass = m_layout[col].getColClass();
+
+ if (isColumnClassMismatch(col, columnClass))
+ {
+ throw new ApplicationException("Cannot enter a " + columnClass.getName()
+ + " in column " + col + ". " +
+ "An object of type " + m_modelHeaderClass.get(col).getSimpleName()
+ + " was expected.");
+ }
+
+ if (columnClass == IDColumn.class)
+ {
+ data = new IDColumn(((Integer)data).intValue());
+ }
+ else if (columnClass == Double.class)
+ {
+ data = new Double(((BigDecimal)data).doubleValue());
+ }
+ }
+ // store
+ getModel().setDataAt(data, row, col);
+ }
+ }
+ // TODO implement this
+ //autoSize();
+
+ // repaint the table
+ this.repaint();
+
+ logger.config("Row(array)=" + getRowCount());
+
+ return;
+ } // loadTable
+
+ /**
+ * Clear the table components.
+ */
+ public void clear()
+ {
+ this.getChildren().clear();
+ }
+ /**
+ * Get the key of currently selected row based on layout defined in
+ * {@link #prepareTable(ColumnInfo[], String, String, boolean, String)}.
+ *
+ * @return ID if key
+ */
+ public Integer getSelectedRowKey()
+ {
+ int row = 0;
+ final int noSelection = -1;
+ final int noIndex = -1;
+ Object data;
+
+ if (m_layout == null)
+ {
+ throw new UnsupportedOperationException("Layout not defined");
+ }
+
+ row = getSelectedRow();
+
+ // TODO factor out the two parts of this guard statement
+ if (row != noSelection && m_keyColumnIndex != noIndex)
+ {
+ data = getModel().getDataAt(row, m_keyColumnIndex);
+
+ if (data instanceof IDColumn)
+ {
+ data = ((IDColumn)data).getRecord_ID();
+ }
+ if (data instanceof Integer)
+ {
+ return (Integer)data;
+ }
+ }
+
+ return null;
+ } // getSelectedRowKey
+
+
+ /**
+ * Returns the index of the first selected row, -1 if no row is selected.
+ *
+ * @return the index of the first selected row
+ */
+ public int getSelectedRow()
+ {
+ return this.getSelectedIndex();
+ }
+
+ /**
+ * Set the size of the underlying data model.
+ *
+ * @param rowCount number of rows
+ */
+ public void setRowCount (int rowCount)
+ {
+ getModel().setNoRows(rowCount);
+
+ return;
+ } // setRowCount
+
+ /**
+ * Get Layout.
+ *
+ * @return Array of ColumnInfo
+ */
+ public ColumnInfo[] getLayoutInfo()
+ {
+ return getLayout();
+ } // getLayout
+
+ /**
+ * Removes all data stored in the underlying model.
+ *
+ */
+ public void clearTable()
+ {
+ WListItemRenderer renderer = null;
+
+ // First clear the model
+ getModel().clear();
+
+ // Then the renderer
+ if (getItemRenderer() instanceof WListItemRenderer)
+ {
+ renderer = (WListItemRenderer)getItemRenderer();
+ renderer.clearSelection();
+ }
+ else
+ {
+ throw new IllegalArgumentException("Renderer must be instance of WListItemRenderer");
+ }
+
+ return;
+ }
+
+
+ /**
+ * Get the number of rows in this table's model.
+ *
+ * @return the number of rows in this table's model
+ *
+ */
+ public int getRowCount()
+ {
+ return getModel().getSize();
+ }
+
+
+ /**
+ * Set whether or not multiple rows can be selected.
+ *
+ * @param multiSelection are multiple selections allowed
+ */
+ public void setMultiSelection(boolean multiSelection)
+ {
+ this.setMultiple(multiSelection);
+
+ return;
+ } // setMultiSelection
+
+
+ /**
+ * Query whether multiple rows can be selected in the table.
+ *
+ * @return true if multiple rows can be selected
+ */
+ public boolean isMultiSelection()
+ {
+ return this.isMultiple();
+ } // isMultiSelection
+
+ /**
+ * Set ColorColumn comparison criteria.
+ *
+ * @param dataCompare object encapsualating comparison criteria
+ */
+ public void setColorCompare (Object dataCompare)
+ {
+ m_colorDataCompare = dataCompare;
+
+ return;
+ } //
+
+ /**
+ * Get ColorCode for Row.
+ *
+ * If numerical value in compare column is
+ * negative = -1,
+ * positive = 1,
+ * otherwise = 0
+ * If Timestamp
+ *
+ * @param row row
+ * @return color code
+ */
+ public int getColorCode (int row)
+ {
+ // TODO expose these through interface
+ // (i.e. make public class member variables)
+ final int valPositive = 1;
+ final int valNegative = -1;
+ final int valOtherwise = 0;
+ Object data;
+ int cmp = valOtherwise;
+
+ if (m_colorColumnIndex == -1)
+ {
+ return valOtherwise;
+ }
+
+ data = getModel().getDataAt(row, m_colorColumnIndex);
+
+ // We need to have a Number
+ if (data == null)
+ {
+ return valOtherwise;
+ }
+
+ try
+ {
+ if (data instanceof Timestamp)
+ {
+ if ((m_colorDataCompare == null)
+ || !(m_colorDataCompare instanceof Timestamp))
+ {
+ m_colorDataCompare = new Timestamp(System.currentTimeMillis());
+ }
+ cmp = ((Timestamp)m_colorDataCompare).compareTo((Timestamp)data);
+ }
+ else
+ {
+ if ((m_colorDataCompare == null)
+ || !(m_colorDataCompare instanceof BigDecimal))
+ {
+ m_colorDataCompare = Env.ZERO;
+ }
+ if (!(data instanceof BigDecimal))
+ {
+ data = new BigDecimal(data.toString());
+ }
+ cmp = ((BigDecimal)m_colorDataCompare).compareTo((BigDecimal)data);
+ }
+ }
+ catch (Exception exception)
+ {
+ return valOtherwise;
+ }
+
+ if (cmp > 0)
+ {
+ return valNegative;
+ }
+ else if (cmp < 0)
+ {
+ return valPositive;
+ }
+
+ return valOtherwise;
+ } // getColorCode
+
+ /* (non-Javadoc)
+ * @see org.adempiere.webui.event.TableValueChangeListener#tableValueChange
+ * (org.adempiere.webui.event.TableValueChangeEvent)
+ */
+ public void tableValueChange(TableValueChangeEvent event)
+ {
+ int col = event.getColumn(); // column of table field which caused the event
+ int row = event.getRow(); // row of table field which caused the event
+ boolean newBoolean;
+ IDColumn idColumn;
+
+ // if the event was caused by an ID Column and the value is a boolean
+ // then set the IDColumn's select field
+ if (this.getValueAt(row, col) instanceof IDColumn
+ && event.getNewValue() instanceof Boolean)
+ {
+ newBoolean = ((Boolean)event.getNewValue()).booleanValue();
+ idColumn = (IDColumn)this.getValueAt(row, col);
+ idColumn.setSelected(newBoolean);
+ this.setValueAt(idColumn, row, col);
+ }
+ // othewise just set the value in the model to the new value
+ else
+ {
+ this.setValueAt(event.getNewValue(), row, col);
+ }
+
+ return;
+ }
+
+
+ /**
+ * Repaint the Table.
+ */
+ public void repaint()
+ {
+ // create the head
+ initialiseHeader();
+
+ // this causes re-rendering of the Listbox
+ this.setModel(this.getModel());
+
+ return;
+ }
+
+ /**
+ * Get the table layout.
+ *
+ * @return the layout of the table
+ * @see #setLayout(ColumnInfo[])
+ */
+ public ColumnInfo[] getLayout()
+ {
+ return m_layout;
+ }
+
+ /**
+ * Set the column information for the table.
+ *
+ * @param layout The new layout to set for the table
+ * @see #getLayout()
+ */
+ private void setLayout(ColumnInfo[] layout)
+ {
+ this.m_layout = layout;
+ getModel().setNoColumns(m_layout.length);
+
+ return;
+ }
+
+ /**
+ * Respond to a change in the table's model.
+ *
+ * If the event indicates that the entire table has changed, the table is repainted.
+ *
+ * @param event The event fired to indicate a change in the table's model
+ */
+ public void tableChanged(WTableModelEvent event)
+ {
+ if ((event.getType() == WTableModelEvent.CONTENTS_CHANGED)
+ && (event.getColumn() == WTableModelEvent.ALL_COLUMNS)
+ && (event.getFirstRow() == WTableModelEvent.ALL_ROWS))
+ {
+ this.repaint();
+ }
+
+ return;
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/WStatusBar.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/WStatusBar.java
new file mode 100644
index 0000000000..acb340f936
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/WStatusBar.java
@@ -0,0 +1,241 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import java.awt.Color;
+
+import org.adempiere.webui.component.Label;
+import org.compiere.model.DataStatusEvent;
+
+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;
+
+/**
+ * Web UI status bar. Based upon the rich client's
+ * {@link org.compiere.apps.StatusBar}. The basic status bar contains one or
+ * both of (a) a general status description and (b) a database status
+ * description. In addition, components can be added to the status bar to extend
+ * its functionaility
+ *
+ * @author Andrew Kimball
+ */
+public class WStatusBar extends Grid implements EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ /** label */
+ private Label statusLine = new Label();
+
+ private Label statusDB = new Label();
+
+ private Row statusBar = new Row();
+
+ private String m_text;
+
+ private DataStatusEvent m_dse = null;
+
+ private boolean mt_error;
+
+ private String mt_text;
+
+ /**
+ * Constructor for a Standard Status Bar.
+ */
+ public WStatusBar()
+ {
+ super();
+
+ Rows rows = new Rows();
+ try
+ {
+ initialise();
+ // this.setBorder("normal");
+ rows.appendChild(statusBar);
+ this.appendChild(rows);
+ this.setWidth("98%");
+ }
+ catch (Exception e)
+ {
+
+ }
+ // this.setName("statusBar");
+ } // StatusBar
+
+ /**
+ * Static Initialisation.
+ *
+ * @throws Exception
+ */
+ private void initialise() throws Exception
+ {
+ statusLine.setValue("statusLine");
+ statusBar.appendChild(statusLine);
+
+ statusDB.setValue("#");
+ statusDB.setStyle("text-align:right; " + "color:"
+ + ZkCssHelper.createHexColorString(Color.blue));
+ statusDB.addEventListener(Events.ON_CLICK, this);
+
+ statusBar.appendChild(statusDB);
+ } // jbInit
+
+ /**
+ * Get Status Line text.
+ *
+ * @return StatusLine text
+ */
+ public final String getStatusLine()
+ {
+ return statusLine.getValue().trim();
+ } // getStatusLine
+
+ /**
+ * Set Status Line
+ *
+ * @param text
+ * text
+ * @param error
+ * error
+ */
+ public final void setStatusLine(final String text, final boolean error)
+ {
+ mt_error = error;
+ mt_text = text;
+ if (mt_error)
+ {
+/* ZkCssHelper.appendStyle(statusLine, ZkCssHelper
+ .createHexColorString(AdempierePLAF.getTextColor_Issue()));
+*/ }
+ else
+ {
+/* ZkCssHelper.appendStyle(statusLine, ZkCssHelper
+ .createHexColorString(AdempierePLAF.getTextColor_OK()));
+*/ }
+ statusLine.setValue(mt_text);
+ //
+ Thread.yield();
+ } // setStatusLine
+
+ /**
+ * Set ToolTip of StatusLine
+ *
+ * @param tip
+ * tooltip text
+ */
+ public final void setStatusToolTip(final String tip)
+ {
+ statusLine.setTooltiptext(tip);
+ } // setStatusToolTip
+
+ /**
+ * Set Standard Status Line (non error)
+ *
+ * @param text
+ * text to display on the status line
+ */
+ public final void setStatusLine(final String text)
+ {
+ if (text == null)
+ {
+ setStatusLine("", false);
+ }
+ else
+ {
+ setStatusLine(text, false);
+ }
+ } // setStatusLine
+
+ /**
+ * Set Status DB Info
+ *
+ * @param text
+ * description of database status
+ * @param dse
+ * data status event
+ */
+ public final void setStatusDB(final String text, final DataStatusEvent dse)
+ {
+ if (text == null || text.length() == 0)
+ {
+ statusDB.setValue("");
+ statusDB.setVisible(false);
+ statusDB.detach();
+ }
+ else
+ {
+ StringBuffer sb = new StringBuffer(" ");
+ sb.append(text).append(" ");
+ statusDB.setValue(sb.toString());
+ if (!statusDB.isVisible())
+ {
+ statusDB.setVisible(true);
+ }
+ statusDB.setParent(statusBar);
+ }
+
+ // Save
+ m_text = text;
+ m_dse = dse;
+ } // setStatusDB
+
+ /**
+ * Set Status DB Info
+ *
+ * @param text
+ * description of database status
+ */
+ public final void setStatusDB(final String text)
+ {
+ setStatusDB(text, null);
+ } // setStatusDB
+
+ /**
+ * Set Status DB Info
+ *
+ * @param no
+ * Database status identifier
+ */
+ public final void setStatusDB(final int no)
+ {
+ setStatusDB(String.valueOf(no), null);
+ } // setStatusDB
+
+ /**
+ * Add Component to East of StatusBar
+ *
+ * @param component
+ * component
+ */
+ public final void addStatusComponent(final Component component)
+ {
+ this.appendChild(component);
+ } // addStatusComponent
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.zkoss.zk.ui.event.EventListener#onEvent(org.zkoss.zk.ui.event.Event)
+ */
+ public void onEvent(final Event evt) throws Exception
+ {
+ // TODO Auto-generated method stub
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/WTableColumn.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/WTableColumn.java
new file mode 100644
index 0000000000..6d6e48f85e
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/WTableColumn.java
@@ -0,0 +1,255 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+/**
+ * @author Andrew Kimball
+ *
+ */
+public class WTableColumn
+{
+ /** The width of the column. */
+ protected int width;
+
+ /** The minimum width of the column. */
+ protected int minWidth;
+
+ /** The preferred width of the column. */
+ private int preferredWidth;
+
+ /** The maximum width of the column. */
+ protected int maxWidth;
+
+ /** If true, the user is allowed to resize the column; the default is true. */
+ protected boolean isResizable;
+
+ /** The header value of the column. */
+ protected Object headerValue;
+
+ /**
+ * Cover method, using a default width of 75
+ * @see #WTableColumn(int)
+ */
+ public WTableColumn() {
+ this(75);
+ }
+
+ public WTableColumn(int width)
+ {
+ this.width = width;
+ this.preferredWidth = width;
+
+ // Set other instance variables to default values.
+ minWidth = 15;
+ maxWidth = Integer.MAX_VALUE;
+ isResizable = true;
+ headerValue = null;
+ }
+
+
+ /**
+ * Sets the Object
whose string representation will be
+ * used as the value for the headerRenderer
. When the
+ * WTableColumn
is created, the default headerValue
+ * is null
.
+ *
+ * @param headerValue the new headerValue
+ * @see #getHeaderValue
+ */
+ public void setHeaderValue(Object headerValue)
+ {
+ this.headerValue = headerValue;
+
+ return;
+ }
+
+
+ /**
+ * Returns the Object
used as the value for the header
+ * renderer.
+ *
+ * @return the headerValue
property
+ * @see #setHeaderValue
+ */
+ public Object getHeaderValue()
+ {
+ return headerValue;
+ }
+
+
+ /**
+ * This method should not be used to set the widths of columns in the
+ * WListbox
, use setPreferredWidth
instead.
+ * This method sets this column's width to width
.
+ * If width
exceeds the minimum or maximum width,
+ * it is adjusted to the appropriate limiting value.
+ *
+ * @param width the new width
+ * @see #getWidth
+ * @see #setMinWidth
+ * @see #setMaxWidth
+ * @see #setPreferredWidth
+ */
+ public void setWidth(int width)
+ {
+ this.width = Math.min(Math.max(width, minWidth), maxWidth);
+
+ return;
+ }
+
+ /**
+ * Returns the width of the TableColumn
. The default width is
+ * 75.
+ *
+ * @return the width
property
+ * @see #setWidth
+ */
+ public int getWidth()
+ {
+ return width;
+ }
+
+ /**
+ * Sets this column's preferred width to preferredWidth
.
+ * If preferredWidth
exceeds the minimum or maximum width,
+ * it is adjusted to the appropriate limiting value.
+ *
+ * @param preferredWidth the new preferred width
+ * @see #getPreferredWidth
+ */
+ public void setPreferredWidth(int preferredWidth)
+ {
+ this.preferredWidth = Math.min(Math.max(preferredWidth, minWidth), maxWidth);;
+ }
+
+ /**
+ * Returns the preferred width of the WTableColumn
.
+ * The default preferred width is 75.
+ *
+ * @return the preferredWidth
property
+ * @see #setPreferredWidth
+ */
+ public int getPreferredWidth()
+ {
+ return preferredWidth;
+ }
+
+ /**
+ * Sets the WTableColumn
's minimum width to
+ * minWidth
; also adjusts the current width
+ * and preferred width if they are less than this value.
+ *
+ * @param minWidth the new minimum width
+ * @see #getMinWidth
+ * @see #setPreferredWidth
+ * @see #setMaxWidth
+ */
+ public void setMinWidth(int minWidth)
+ {
+ this.minWidth = Math.max(minWidth, 0);
+
+ if (width < minWidth)
+ {
+ setWidth(minWidth);
+ }
+
+ if (preferredWidth < minWidth)
+ {
+ setPreferredWidth(minWidth);
+ }
+
+ return;
+ }
+
+ /**
+ * Returns the minimum width for the WTableColumn
. The
+ * WTableColumn
's width can't be made less than this either
+ * by the user or programmatically. The default minWidth is 15.
+ *
+ * @return the minWidth
property
+ * @see #setMinWidth
+ */
+ public int getMinWidth()
+ {
+ return minWidth;
+ }
+
+ /**
+ * Sets the WTableColumn
's maximum width to
+ * maxWidth
; also adjusts the width and preferred
+ * width if they are greater than this value.
+ *
+ * @param maxWidth the new maximum width
+ * @see #getMaxWidth
+ * @see #setPreferredWidth
+ * @see #setMinWidth
+ */
+ public void setMaxWidth(int maxWidth)
+ {
+ this.maxWidth = Math.max(minWidth, maxWidth);
+ if (width > maxWidth)
+ {
+ setWidth(maxWidth);
+ }
+ if (preferredWidth > maxWidth)
+ {
+ setPreferredWidth(maxWidth);
+ }
+
+ return;
+ }
+
+ /**
+ * Returns the maximum width for the WTableColumn
. The
+ * WTableColumn
's width can't be made larger than this
+ * either by the user or programmatically. The default maxWidth
+ * is Integer.MAX_VALUE.
+ *
+ * @return the maxWidth
property
+ * @see #setMaxWidth
+ */
+ public int getMaxWidth()
+ {
+ return maxWidth;
+ }
+
+ /**
+ * Sets whether this column can be resized.
+ *
+ * @param isResizable if true, resizing is allowed; otherwise false
+ * @see #getResizable
+ */
+ public void setResizable(boolean isResizable)
+ {
+ this.isResizable = isResizable;
+ }
+
+ /**
+ * Returns true if the user is allowed to resize the
+ * WTableColumn
's
+ * width, false otherwise. You can change the width programmatically
+ * regardless of this setting. The default is true.
+ *
+ * @return the isResizable
property
+ * @see #setResizable
+ */
+ public boolean getResizable()
+ {
+ return isResizable;
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Window.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Window.java
new file mode 100644
index 0000000000..1b1933bfbe
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/Window.java
@@ -0,0 +1,42 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class Window extends org.zkoss.zul.Window
+{
+ private static final long serialVersionUID = 1L;
+
+ public static final String MODE_MODAL = "modal";
+
+ public static final String MODE_POPUP = "popup";
+
+ public static final String MODE_OVERLAPPED = "overlapped";
+
+ public static final String MODE_EMBEDDED = "embedded";
+
+ public Window()
+ {
+ super();
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ZkCssHelper.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ZkCssHelper.java
new file mode 100644
index 0000000000..295c1e1d00
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/ZkCssHelper.java
@@ -0,0 +1,177 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component;
+
+import java.awt.Color;
+
+import org.zkoss.zk.ui.HtmlBasedComponent;
+
+/**
+ * Utility function to support ZK functions.
+ *
+ * Provides functionsfor manipulating the CSS style for
+ * ZK components.
+ *
+ * @author Andrew Kimball
+ *
+ */
+public final class ZkCssHelper
+{
+
+ /** Left text alignment CSS style property and value. */
+ public static final String STYLE_TEXT_ALIGN_LEFT = "text-align:left";
+ /** Right text alignment CSS style property and value. */
+ public static final String STYLE_TEXT_ALIGN_RIGHT = "text-align:right";
+ /** Centre text alignment CSS style property and value. */
+ public static final String STYLE_TEXT_ALIGN_CENTER = "text-align:center";
+ /** CSS style property for color. */
+ public static final String STYLE_COLOR = "color:#";
+ /** CSS style property for background color. */
+ public static final String STYLE_BACKGROUND_COLOR = "background-color:#";
+
+ /**
+ * Private default constructor.
+ * This exists purely for conformance and should not be used.
+ */
+ private ZkCssHelper()
+ {
+
+ }
+
+ /**
+ * Obtains the string description of the RGB components of a color
.
+ * The returned string is suitable for using in CSS styles.
+ * The red, green and blue components are formatted as hexadecimal characters.
+ * Each component is in the range 00 to FF.
+ * The entire string is therefore
+ * a 6 character string ranging from "000000" to "FFFFFF".
+ *
+ * @param color The color for which the string is to be created
+ * @return The string representation of the colour's RGB components.
+ */
+ public static String createHexColorString(Color color)
+ {
+ String colorString = String.format("%02X%02X%02X",
+ color.getRed(),
+ color.getGreen(),
+ color.getBlue());
+
+ return colorString;
+ }
+
+
+ /**
+ * Adds a new CSS style to component
.
+ * The ";" prefix is not required.
+ *
+ * @param component the HTML based ZK component whose CSS style is to be modified
+ * @param style CSS style string to append to current style
+ *
+ * @see #setStyle(String)
+ */
+ public static void appendStyle(HtmlBasedComponent component, String style)
+ {
+ String oldStyle = "";
+
+ if (component.getStyle() != null)
+ {
+ oldStyle = component.getStyle();
+ }
+ component.setStyle(oldStyle
+ + "; " + style);
+
+ return;
+ }
+
+ /**
+ * Adds a CSS color style to component
.
+ *
+ * The current style of the component is retained.
+ *
+ * @param component the HTML based ZK component whose CSS style is to be modified
+ * @param color the color to be set
+ * @see #appendStyleBackgroundColor(HtmlBasedComponent, Color)
+ * @see #setStyleColor(HtmlBasedComponent, Color)
+ */
+ public static void appendStyleColor(HtmlBasedComponent component, Color color)
+ {
+ String colorString = createHexColorString(color);
+ String colorStyleString = STYLE_COLOR + colorString;
+ appendStyle(component, colorStyleString);
+
+ return;
+ }
+
+
+ /**
+ * Sets CSS color style for component
.
+ *
+ * Previous styles are removed.
+ *
+ * @param component the HTML based ZK component whose CSS style is to be modified
+ * @param color the color to be set
+ * @see #setStyleBackgroundColor(HtmlBasedComponent, Color)
+ * @see #appendStyleColor(HtmlBasedComponent, Color)
+ */
+ public static void setStyleColor(HtmlBasedComponent component, Color color)
+ {
+ String colorString = createHexColorString(color);
+ String colorStyleString = STYLE_COLOR + colorString;
+ component.setStyle(colorStyleString);
+
+ return;
+ }
+
+ /**
+ * Adds a CSS background color style to component
.
+ *
+ * The current style of the component is retained.
+ *
+ * @param component the HTML based ZK component whose CSS style is to be modified
+ * @param color the color to be set
+ * @see #appendStyleBackColor(HtmlBasedComponent, Color)
+ * @see #setStyleBackgroundColor(HtmlBasedComponent, Color)
+ */
+ public static void appendStyleBackgroundColor(HtmlBasedComponent component, Color color)
+ {
+ String colorString = createHexColorString(color);
+ String colorStyleString = STYLE_BACKGROUND_COLOR + colorString;
+ appendStyle(component, colorStyleString);
+
+ return;
+ }
+
+ /**
+ * Sets CSS background color style for component
.
+ *
+ * Previous styles are removed.
+ *
+ * @param component the HTML based ZK component whose CSS style is to be modified
+ * @param color the color to be set
+ * @see #appendStyleBackgroundColor(HtmlBasedComponent, Color)
+ * @see #setStyleColor(HtmlBasedComponent, Color)
+ */
+ public static void setStyleBackgroundColor(HtmlBasedComponent component, Color color)
+ {
+ String colorString = createHexColorString(color);
+ String colorStyleString = STYLE_BACKGROUND_COLOR + colorString;
+ component.setStyle(colorStyleString);
+
+ return;
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/test/ComponentTests.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/test/ComponentTests.java
new file mode 100644
index 0000000000..4333e269e7
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/test/ComponentTests.java
@@ -0,0 +1,38 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component.test;
+
+
+import org.adempiere.webui.component.test.ListModelTableTest;
+import org.adempiere.webui.component.test.WListItemRendererTest;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+/**
+ * Test Suite for running all of the tests in
+ * {@link org.adempiere.webui.component.test}.
+ *
+ * @author Andrew Kimball
+ *
+ */
+@RunWith(value=Suite.class)
+@SuiteClasses({ListModelTableTest.class, WListItemRendererTest.class})
+public class ComponentTests
+{
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/test/ListModelTableTest.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/test/ListModelTableTest.java
new file mode 100644
index 0000000000..40a99e9cfa
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/test/ListModelTableTest.java
@@ -0,0 +1,231 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component.test;
+
+import java.util.Vector;
+
+import org.adempiere.webui.component.ListModelTable;
+import org.adempiere.webui.event.WTableModelEvent;
+import org.adempiere.webui.event.WTableModelListener;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+import static org.junit.Assert.*;
+
+/**
+ * Test class for {@link org.adempiere.webui.component.ListModelTable}.
+ *
+ * @author Andrew Kimball
+ *
+ */
+public class ListModelTableTest implements WTableModelListener
+{
+ /** First data object. */
+ private static final Integer ms_number0 = Integer.valueOf(0);
+ /** Second data object. */
+ private static final Integer ms_number1 = Integer.valueOf(1);
+ /** Third data object. */
+ private static final Integer ms_number2 = Integer.valueOf(2);
+ /** Third data object. */
+ private static final Integer ms_number3 = Integer.valueOf(3);
+ /** Fourth data object. */
+ private static final Integer ms_number4 = Integer.valueOf(4);
+ /** Fifth data object. */
+ private static final Integer ms_number5 = Integer.valueOf(5);
+ /** Sixth data object. */
+ private static final Integer ms_number6 = Integer.valueOf(6);
+
+ /** The table instance on which tests are to be run. */
+ private ListModelTable m_table;
+ /** A flag to indicate whether the listener has been called and has succeeded. */
+ private boolean m_isListenerCalled = false;
+
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Before
+ public void setUp() throws Exception
+ {
+ Vector row0 = new Vector();
+ Vector row1 = new Vector();
+ Vector data = new Vector();
+
+ // create two rows of data
+ row0.add(ms_number0);
+ row0.add(ms_number1);
+ row1.add(ms_number2);
+ row1.add(ms_number3);
+
+ // create the data
+ data.add(row0);
+ data.add(row1);
+
+ // instantiate the model
+ m_table = new ListModelTable(data);
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @After
+ public void tearDown() throws Exception
+ {
+ }
+
+ /**
+ * Test method for {@link org.adempiere.webui.component.ListModelTable#ListModelTable()}.
+ */
+ @Test
+ public final void testListModelTable()
+ {
+ ListModelTable table = new ListModelTable();
+ boolean isException = false;
+ Object data;
+
+ assertEquals(0, table.getNoColumns());
+ assertEquals(0, table.getSize());
+ // try to get data from an invalid field
+ try
+ {
+ data = table.getDataAt(0, 0);
+ // never reach here, but removes warnings
+ assertNull(data);
+ }
+ catch (IllegalArgumentException exception)
+ {
+ isException = true;
+ }
+ assertTrue(isException);
+ }
+
+ /**
+ * Test method for {@link org.adempiere.webui.component.ListModelTable#ListModelTable(java.util.Collection)}.
+ */
+ @Test (expected= IllegalArgumentException.class)
+ public final void testListModelTableCollection()
+ {
+ final int invalidRow = 2;
+ final int noColumns = 2;
+ Object data;
+
+ assertEquals(noColumns, m_table.getNoColumns());
+ assertEquals(noColumns, m_table.getSize());
+ assertEquals(Integer.valueOf(0), m_table.getDataAt(0, 0));
+
+ //try to get data from an invalid field
+ data = m_table.getDataAt(invalidRow, 0);
+ }
+
+
+ /**
+ * Test method for {@link org.adempiere.webui.component.ListModelTable#addColumn()}.
+ */
+ @Test
+ public final void testAddColumn()
+ {
+ final int noColumns = 3;
+ m_table.addColumn();
+
+ assertEquals(noColumns, m_table.getNoColumns());
+ assertNull(m_table.getDataAt(0, noColumns - 1));
+ }
+
+ /**
+ * Test method for {@link org.adempiere.webui.component.ListModelTable#setNoColumns(int)}.
+ */
+ @Test
+ public final void testSetNoColumns()
+ {
+ final int noColumns = 3;
+
+ m_table.setNoColumns(noColumns);
+
+ assertEquals(noColumns, m_table.getNoColumns());
+ assertNull(m_table.getDataAt(0, noColumns - 1));
+ }
+
+ /**
+ * Test method for {@link org.adempiere.webui.component.ListModelTable#getDataAt(int, int)}.
+ */
+ @Test
+ public final void testGetDataAt()
+ {
+ assertEquals(ms_number0, m_table.getDataAt(0, 0));
+ assertEquals(ms_number3, m_table.getDataAt(1, 1));
+ }
+
+ /**
+ * Test method for {@link org.adempiere.webui.component.ListModelTable#setDataAt(java.lang.Object, int, int)}.
+ */
+ @Test (expected= IllegalArgumentException.class)
+ public final void testSetDataAt()
+ {
+ final int invalidRow = 2;
+
+ m_table.setDataAt(ms_number4, 0, 0);
+ m_table.setDataAt(ms_number5, 1, 1);
+
+ assertEquals(ms_number4, m_table.getDataAt(0, 0));
+ assertEquals(ms_number5, m_table.getDataAt(1, 1));
+
+ // expect this to throw an exception
+ m_table.setDataAt(ms_number6, invalidRow, 0);
+ }
+
+ /**
+ * Test method for {@link org.adempiere.webui.component.ListModelTable#setNoRows(int)}.
+ */
+ @Test
+ public final void testSetNoRows()
+ {
+ final int noRows = 3;
+ m_table.setNoRows(m_table.getSize() + 1);
+
+ assertEquals(noRows, m_table.getSize());
+ assertEquals(ms_number3, m_table.getDataAt(1, 1));
+ assertNull(m_table.getDataAt(2, 1));
+ }
+
+ /**
+ * Test method for
+ * {@link org.adempiere.webui.component.ListModelTable#addTableModelListener(org.adempiere.webui.event.WTableModelListener)}.
+ */
+ @Test
+ public final void testAddTableModelListener()
+ {
+ m_table.addTableModelListener(this);
+ m_table.setDataAt(ms_number4, 0, 0);
+
+ assertTrue(m_isListenerCalled);
+ }
+
+ /* (non-Javadoc)
+ * @see org.adempiere.webui.event.WTableModelListener#tableChanged(org.adempiere.webui.event.WTableModelEvent)
+ */
+ public void tableChanged(WTableModelEvent event)
+ {
+ assertEquals(ms_number4, m_table.getDataAt(0, 0));
+ m_isListenerCalled = true;
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/test/WListItemRendererTest.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/test/WListItemRendererTest.java
new file mode 100644
index 0000000000..cecfff64b6
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/component/test/WListItemRendererTest.java
@@ -0,0 +1,222 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.component.test;
+
+import static org.junit.Assert.*;
+
+import java.util.Vector;
+
+import org.adempiere.webui.component.ListHead;
+import org.adempiere.webui.component.ListHeader;
+import org.adempiere.webui.component.ListItem;
+import org.adempiere.webui.component.ListModelTable;
+import org.adempiere.webui.component.WListItemRenderer;
+import org.adempiere.webui.component.WListbox;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.zkoss.zul.Listitem;
+
+/**
+ * @author Andrew Kimball
+ *
+ */
+public class WListItemRendererTest
+{
+
+ WListItemRenderer m_renderer;
+ Vector m_dataValid = new Vector();
+ Vector m_dataInvalid = new Vector();
+
+ Vector m_columnNames = new Vector();
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Before
+ public void setUp() throws Exception
+ {
+ Vector dataRowValid = new Vector();
+ Vector dataRowInvalid = new Vector();
+
+ m_columnNames.add("Name");
+ m_columnNames.add("Age");
+
+ m_renderer = new WListItemRenderer(m_columnNames);
+
+ dataRowValid.add("River Phoenix");
+ dataRowValid.add(Integer.valueOf(23));
+ m_dataValid.add(dataRowValid);
+
+ dataRowInvalid.add("Elvis Presley");
+ dataRowInvalid.add(Integer.valueOf(42));
+ dataRowInvalid.add("Graceland");
+ m_dataInvalid.add(dataRowInvalid);
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @After
+ public void tearDown() throws Exception
+ {
+ }
+
+ /**
+ * Test method for {@link org.adempiere.webui.component.WListItemRenderer#WListItemRenderer()}.
+ */
+ @Test
+ public final void testWListItemRenderer()
+ {
+ WListItemRenderer renderer = new WListItemRenderer();
+ assertEquals(0, renderer.getNoColumns());
+ }
+
+ /**
+ * Test method for {@link org.adempiere.webui.component.WListItemRenderer#WListItemRenderer(java.util.Vector)}.
+ */
+ @Test
+ public final void testWListItemRendererVectorOfQextendsString()
+ {
+ assertEquals(2, m_renderer.getNoColumns());
+ }
+
+ /**
+ * Test method for {@link org.adempiere.webui.component.WListItemRenderer#render(org.zkoss.zul.Listitem, java.lang.Object)}.
+ */
+ @Ignore("Not running because instantiating a ZX listbox causes a NullPointerException as it" +
+ " attempts to post events")
+ @Test
+ public final void testRender() throws Exception
+ {
+ /*ListModelTable model = new ListModelTable(m_dataValid);
+ WListbox table = new WListbox();
+ table.setData(model, m_columnNames);
+
+ Listitem item = m_renderer.newListitem(table);
+ m_renderer.render(item, table.getModel().get(0));
+ */
+
+ fail("Not yet implemented");
+ }
+
+ /**
+ * Test method for {@link org.adempiere.webui.component.WListItemRenderer#updateColumn(int, java.lang.String)}.
+ */
+ @Test
+ public final void testUpdateColumn()
+ {
+ ListHead head = new ListHead();
+ ListHeader header;
+
+ m_renderer.updateColumn(1, "Address");
+ assertEquals(2, m_renderer.getNoColumns());
+
+ m_renderer.renderListHead(head);
+
+ header = (ListHeader)head.getChildren().get(1);
+ assertEquals("Address", header.getLabel());
+ }
+
+ /**
+ * Test method for {@link org.adempiere.webui.component.WListItemRenderer#addColumn(java.lang.String)}.
+ */
+ @Test
+ public final void testAddColumn()
+ {
+ m_renderer.addColumn("Address");
+ assertEquals(3, m_renderer.getNoColumns());
+ }
+
+ /**
+ * Test method for {@link org.adempiere.webui.component.WListItemRenderer#renderListHead(org.adempiere.webui.component.ListHead)}.
+ */
+ @Test
+ public final void testRenderListHead()
+ {
+ ListHead head = new ListHead();
+ Object header;
+
+ m_renderer.renderListHead(head);
+
+ assertEquals(2, head.getChildren().size());
+
+ header = head.getChildren().get(1);
+
+ assertTrue(header instanceof ListHeader);
+ assertEquals("Age", ((ListHeader)header).getLabel());
+ }
+
+ /**
+ * Test method for {@link org.adempiere.webui.component.WListItemRenderer#getRowPosition(org.zkoss.zk.ui.Component)}.
+ */
+ @Ignore("Not running because the ZX listbox cannot be instantiated in JUnit")
+ @Test
+ public final void testGetRowPosition()
+ {
+ fail("Not yet implemented");
+ }
+
+ /**
+ * Test method for {@link org.adempiere.webui.component.WListItemRenderer#getColumnPosition(org.zkoss.zk.ui.Component)}.
+ */
+ @Ignore("Not running because the ZX listbox cannot be instantiated in JUnit")
+ @Test
+ public final void testGetColumnPosition()
+ {
+ fail("Not yet implemented");
+ }
+
+ /**
+ * Test method for {@link org.adempiere.webui.component.WListItemRenderer#clearColumns()}.
+ */
+ @Test
+ public final void testClearColumns()
+ {
+ ListHead head = new ListHead();
+
+ m_renderer.clearColumns();
+ assertEquals(0, m_renderer.getNoColumns());
+
+ m_renderer.renderListHead(head);
+
+ assertEquals(0, head.getChildren().size());
+ }
+
+ /**
+ * Test method for {@link org.adempiere.webui.component.WListItemRenderer#clearSelection()}.
+ */
+ @Ignore("Not running because the ZX listbox cannot be instantiated in JUnit")
+ @Test
+ public final void testClearSelection()
+ {
+ fail("Not yet implemented");
+ }
+
+ /**
+ * Test method for {@link org.adempiere.webui.component.WListItemRenderer#addTableValueChangeListener(org.adempiere.webui.event.TableValueChangeListener)}.
+ */
+ @Ignore("Not running because the ZX listbox cannot be instantiated in JUnit")
+ @Test
+ public final void testAddTableValueChangeListener()
+ {
+ fail("Not yet implemented");
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/constants/Constraints.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/constants/Constraints.java
new file mode 100644
index 0000000000..7a1121ec8d
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/constants/Constraints.java
@@ -0,0 +1,40 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.constants;
+
+import org.zkoss.zul.Constraint;
+import org.zkoss.zul.SimpleConstraint;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 18, 2007
+ * @version $Revision: 0.10 $
+ */
+public class Constraints
+{
+ public static final Constraint MANDATORY;
+
+ public static final Constraint NO_CONSTRAINT;
+
+ static
+ {
+ MANDATORY = new SimpleConstraint(SimpleConstraint.NO_EMPTY);
+ NO_CONSTRAINT = (Constraint)null;
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/constants/EventConstants.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/constants/EventConstants.java
new file mode 100644
index 0000000000..ed726b32f4
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/constants/EventConstants.java
@@ -0,0 +1,34 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.constants;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 18, 2007
+ * @version $Revision: 0.10 $
+ */
+public class EventConstants
+{
+ public static final String ONCLICK = "onClick";
+
+ public static final String ONCHANGE = "onChange";
+
+ public static final String ONSELECT = "onSelect";
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WButtonEditor.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WButtonEditor.java
new file mode 100644
index 0000000000..ca7754365a
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WButtonEditor.java
@@ -0,0 +1,267 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.editor;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.logging.Level;
+
+import org.adempiere.webui.component.Button;
+import org.adempiere.webui.event.ActionEvent;
+import org.adempiere.webui.event.ActionListener;
+import org.compiere.model.GridField;
+import org.compiere.model.MLookup;
+import org.compiere.model.MLookupFactory;
+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.NamePair;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.Events;
+
+/**
+ * This class is based on org.compiere.grid.ed.VButton written by Jorg Janke.
+ * @author Jorg Janke
+ *
+ * Modifications - UI Compatibility
+ * @author ashley
+ */
+public class WButtonEditor extends WEditor
+{
+ private static final String[] LISTENER_EVENTS = {};
+
+ private static final CLogger logger;
+
+ static
+ {
+ logger = CLogger.getCLogger(WButtonEditor.class);
+ }
+
+ private Button button;
+
+ private String m_text;
+ private boolean m_mandatory;
+ private Object m_value;
+ /** List of Key/Name */
+ private HashMap m_values = null;
+
+ /** Description as ToolTip */
+
+ private MLookup m_lookup;
+
+ private int AD_Process_ID;
+ private GridField gridfield = null;
+
+ private ArrayList actionListeners = new ArrayList();
+
+ public WButtonEditor(GridField gridField)
+ {
+ super(new Button(), gridField);
+ button = (Button)super.component;
+ m_text = gridField.getHeader();
+ AD_Process_ID = gridField.getAD_Process_ID();
+ gridfield = gridField;
+ init();
+ }
+
+ /**
+ * Get AD_Process_ID
+ * @return AD_Process_ID or 0
+ */
+ public int getProcess_ID()
+ {
+ return AD_Process_ID;
+ } // getProcess_ID
+
+ public GridField getGridField()
+ {
+ return gridfield;
+ }
+
+ private void init()
+ {
+ label.setValue(" ");
+ button.setLabel(gridField.getHeader());
+ button.setTooltiptext(gridField.getDescription());
+ button.addEventListener(Events.ON_CLICK, this);
+
+ String columnName = super.getColumnName();
+ if (columnName.equals("PaymentRule"))
+ {
+ readReference(195);
+// this.setForeground(Color.blue);
+ button.setImage("/images/Payment16.gif"); // 29*14
+ }
+ else if (columnName.equals("DocAction"))
+ {
+ readReference(135);
+// this.setForeground(Color.blue);
+ button.setImage("/images/Process16.gif"); // 16*16
+ }
+ else if (columnName.equals("CreateFrom"))
+ {
+ button.setImage("/images/Copy16.gif"); // 16*16
+ }
+ else if (columnName.equals("Record_ID"))
+ {
+ button.setImage("/images/Zoom16.gif"); // 16*16
+ button.setLabel(Msg.getMsg(Env.getCtx(), "ZoomDocument"));
+ }
+ else if (columnName.equals("Posted"))
+ {
+ readReference(234);
+// this.setForeground(Color.magenta);
+ button.setImage("/images/InfoAccount16.gif"); // 16*16
+ }
+
+ if (gridField.getColumnName().endsWith("_ID") && !gridField.getColumnName().equals("Record_ID"))
+ {
+ m_lookup = MLookupFactory.get(Env.getCtx(), gridField.getWindowNo(), 0,
+ gridField.getAD_Column_ID(), DisplayType.Search);
+ }
+ else if (gridField.getAD_Reference_Value_ID() != 0)
+ {
+ // Assuming List
+ m_lookup = MLookupFactory.get(Env.getCtx(), gridField.getWindowNo(), 0,
+ gridField.getAD_Column_ID(), DisplayType.List);
+ }
+ }
+
+ @Override
+ public String getDisplay()
+ {
+ return m_value.toString();
+ }
+
+ @Override
+ public Object getValue()
+ {
+ return m_values;
+ }
+
+ @Override
+ public boolean isMandatory()
+ {
+ return m_mandatory;
+ }
+
+
+ @Override
+ public void setMandatory(boolean mandatory)
+ {
+ m_mandatory = mandatory;
+ }
+
+ @Override
+ public void setValue(Object value)
+ {
+ m_value = value;
+ String text = m_text;
+
+ // Nothing to show or Record_ID
+ if (value == null || super.getColumnName().equals("Record_ID"))
+ {
+ ;
+ }
+ else if (m_values != null)
+ {
+ text = (String)m_values.get(value);
+ }
+ else if (m_lookup != null)
+ {
+ NamePair pp = m_lookup.get(value);
+ if (pp != null)
+ text = pp.getName();
+ }
+ button.setLabel(text != null ? text : "");
+ }
+
+ public HashMap getValues()
+ {
+ return m_values;
+ } // getValues
+
+ /**
+ * Fill m_Values with Ref_List values
+ * @param AD_Reference_ID reference
+ */
+ private void readReference(int AD_Reference_ID)
+ {
+ m_values = new HashMap();
+
+ String SQL;
+ if (Env.isBaseLanguage(Env.getCtx(), "AD_Ref_List"))
+ SQL = "SELECT Value, Name FROM AD_Ref_List WHERE AD_Reference_ID=?";
+ else
+ SQL = "SELECT l.Value, t.Name FROM AD_Ref_List l, AD_Ref_List_Trl t "
+ + "WHERE l.AD_Ref_List_ID=t.AD_Ref_List_ID"
+ + " AND t.AD_Language='" + Env.getAD_Language(Env.getCtx()) + "'"
+ + " AND l.AD_Reference_ID=?";
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(SQL, null);
+ pstmt.setInt(1, AD_Reference_ID);
+ ResultSet rs = pstmt.executeQuery();
+
+ while (rs.next())
+ {
+ String value = rs.getString(1);
+ String name = rs.getString(2);
+ m_values.put(value,name);
+ }
+
+
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ logger.log(Level.SEVERE, SQL, e);
+ }
+
+ } // readReference
+
+ public void addActionListener(ActionListener actionListener)
+ {
+ actionListeners.add(actionListener);
+ }
+
+ @Override
+ public String[] getEvents()
+ {
+ return LISTENER_EVENTS;
+ }
+
+ public void onEvent(Event event) throws Exception
+ {
+ if (Events.ON_CLICK.equals(event.getName()))
+ {
+ ActionEvent actionEvent = new ActionEvent(this, getColumnName(), Events.ON_CLICK);
+ for (ActionListener evtListener : actionListeners)
+ {
+ evtListener.actionPerformed(actionEvent);
+ }
+ }
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WDateEditor.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WDateEditor.java
new file mode 100644
index 0000000000..1b9419ef94
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WDateEditor.java
@@ -0,0 +1,146 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.editor;
+
+import java.sql.Timestamp;
+import java.util.Date;
+import java.util.logging.Level;
+
+import org.adempiere.webui.component.Datebox;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.compiere.model.GridField;
+import org.compiere.util.CLogger;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.Events;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 12, 2007
+ * @version $Revision: 0.10 $
+ */
+public class WDateEditor extends WEditor
+{
+ private static final String[] LISTENER_EVENTS = {Events.ON_CHANGE};
+ private static final CLogger logger;
+
+ static
+ {
+ logger = CLogger.getCLogger(WDateEditor.class);
+ }
+
+ private Timestamp oldValue = new Timestamp(0);
+
+ private Datebox datebox;
+
+ public WDateEditor(GridField gridField)
+ {
+ super(new Datebox(), gridField);
+ datebox = (Datebox)super.component;
+ }
+
+
+ /**
+ * Constructor for use if a grid field is unavailable
+ *
+ * @param label
+ * column name (not displayed)
+ * @param description
+ * description of component
+ * @param mandatory
+ * whether a selection must be made
+ * @param readonly
+ * whether or not the editor is read only
+ * @param updateable
+ * whether the editor contents can be changed
+ */
+ public WDateEditor (String label, String description, boolean mandatory, boolean readonly, boolean updateable)
+ {
+ super(new Datebox(), label, description, mandatory, readonly, updateable);
+
+ this.datebox = (Datebox)super.component;
+ setColumnName("Date");
+ }
+
+ public WDateEditor()
+ {
+ this("Date", "Date", false, false, true);
+ } // VDate
+
+ public void onEvent(Event event)
+ {
+ Date date = datebox.getValue();
+ Timestamp newValue = null;
+
+ if (date != null)
+ {
+ newValue = new Timestamp(date.getTime());
+ }
+
+ ValueChangeEvent changeEvent = new ValueChangeEvent(this, this.getColumnName(), oldValue, newValue);
+ super.fireValueChange(changeEvent);
+ oldValue = newValue;
+ }
+
+ @Override
+ public String getDisplay()
+ {
+ return null;
+ }
+
+ @Override
+ public Object getValue()
+ {
+ return null;
+ }
+
+ @Override
+ public boolean isMandatory()
+ {
+ return false;
+ }
+
+ @Override
+ public void setMandatory(boolean mandatory)
+ {
+ }
+
+ @Override
+ public void setValue(Object value)
+ {
+ if (value == null)
+ {
+ oldValue = null;
+ }
+ else if (value instanceof Timestamp)
+ {
+ datebox.setValue((Timestamp)value);
+ oldValue = (Timestamp)value;
+ }
+ else
+ {
+ logger.log(Level.SEVERE, "New field value is not of type timestamp");
+ }
+ }
+
+ public String[] getEvents()
+ {
+ return LISTENER_EVENTS;
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WEditor.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WEditor.java
new file mode 100644
index 0000000000..81c33c8829
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WEditor.java
@@ -0,0 +1,393 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.editor;
+
+import java.awt.Color;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
+
+import org.adempiere.webui.component.Button;
+import org.adempiere.webui.component.Checkbox;
+import org.adempiere.webui.component.Datebox;
+import org.adempiere.webui.component.EditorBox;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.Listbox;
+import org.adempiere.webui.component.Locationbox;
+import org.adempiere.webui.component.Searchbox;
+import org.adempiere.webui.component.Urlbox;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.event.ValueChangeListener;
+import org.compiere.model.GridField;
+import org.compiere.model.GridTab;
+import org.zkoss.zk.ui.Component;
+import org.zkoss.zk.ui.HtmlBasedComponent;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zul.impl.InputElement;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 11, 2007
+ * @version $Revision: 0.10 $
+ */
+public abstract class WEditor implements EventListener, PropertyChangeListener
+{
+ private static final String[] lISTENER_EVENTS = {};
+
+ public static final int MAX_DISPLAY_LENGTH = 35;
+
+ protected GridField gridField;
+
+ protected GridTab gridTab;
+
+ protected Label label;
+
+ protected Component component;
+
+ protected boolean mandatory;
+
+ protected ArrayList listeners = new ArrayList();
+
+ private String strLabel;
+
+ private String description;
+
+ private boolean readOnly;
+
+ private boolean updateable;
+
+ private String columnName;
+
+ public WEditor(Component comp, GridField gridField)
+ {
+ if (comp == null)
+ {
+ throw new IllegalArgumentException("Component cannot be null");
+ }
+
+ if (gridField == null)
+ {
+ throw new IllegalArgumentException("Grid field cannot be null");
+ }
+
+ this.setComponent(comp);
+ this.gridField = gridField;
+ this.setMandatory(gridField.isMandatory(false));
+ this.readOnly = gridField.isReadOnly();
+ this.description = gridField.getDescription();
+ this.updateable = gridField.isUpdateable();
+ this.columnName = gridField.getColumnName();
+ this.strLabel = gridField.getHeader();
+ init();
+ }
+
+ /**
+ * Method is used to distinguish between 2 similar WSearchEditors
+ *
+ */
+ public String getDescription()
+ {
+ return description;
+
+ }
+
+ /**
+ * Constructor for use if a grid field is unavailable
+ *
+ * @param comp The editor's component
+ * @param label column name (not displayed)
+ * @param description description of component
+ * @param mandatory whether a selection must be made
+ * @param readonly whether or not the editor is read only
+ * @param updateable whether the editor contents can be changed
+ */
+ public WEditor(Component comp, String label, String description, boolean mandatory, boolean readonly, boolean updateable)
+ {
+ if (comp == null)
+ {
+ throw new IllegalArgumentException("Component cannot be null");
+ }
+
+ this.setComponent(comp);
+ this.setMandatory(mandatory);
+ this.readOnly = readonly;
+ this.description = description;
+ this.updateable = updateable;
+ this.strLabel = label;
+ init();
+ }
+
+ /**
+ * Set the editor component.
+ * @param comp the editor component
+ */
+ protected void setComponent(Component comp)
+ {
+ this.component = comp;
+ }
+
+ private void init()
+ {
+ label = new Label("");
+ label.setValue(strLabel);
+ label.setTooltiptext(description);
+
+
+ this.setMandatory (mandatory);
+
+ if (readOnly || !updateable)
+ {
+ this.setReadWrite(false);
+ }
+ else
+ {
+ this.setReadWrite(true);
+ }
+
+ ((HtmlBasedComponent)component).setTooltiptext(description);
+ label.setTooltiptext(description);
+ }
+
+ public GridField getGridField()
+ {
+ return gridField;
+ }
+
+ public String getColumnName()
+ {
+ return columnName;
+ }
+
+ /**
+ * Remove the table qualifier from the supplied column name.
+ *
+ * The column name may be prefixed with the table name
+ * i.e. [table name].[column name]
.
+ * The function returns
+ *
+ * @param originalColumnName The column name to clean
+ * @return the column name with any table qualifier removed
+ * i.e. [column name]
+ */
+ protected String cleanColumnName(String originalColumnName)
+ {
+ String cleanColumnName;
+ /*
+ * The regular expression to use to find the table qualifier.
+ * Matches "."
+ */
+ final String regexTablePrefix = ".*\\.";
+
+ cleanColumnName = originalColumnName.replaceAll(regexTablePrefix, "");
+
+ return cleanColumnName;
+ }
+
+ protected void setColumnName(String columnName)
+ {
+ String cleanColumnName = cleanColumnName(columnName);
+ this.columnName = cleanColumnName;
+ }
+
+ public Component getComponent()
+ {
+ return component;
+ }
+
+ public void setGridTab(GridTab gridTab)
+ {
+ this.gridTab = gridTab;
+ }
+
+ public WEditorPopupMenu getPopupMenu()
+ {
+ return null;
+ }
+
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ if (evt.getPropertyName().equals(org.compiere.model.GridField.PROPERTY))
+ {
+ setValue((evt.getNewValue()));
+ }
+ }
+
+ public void addValueChangeListner(ValueChangeListener listener)
+ {
+ if (listener == null)
+ {
+ return;
+ }
+
+ if (listeners.size() == 0)
+ {
+ for (String event : this.getEvents())
+ {
+ component.addEventListener(event, this);
+ }
+ }
+ listeners.add(listener);
+ }
+
+ protected void fireValueChange(ValueChangeEvent event)
+ {
+ for (ValueChangeListener listener : listeners)
+ {
+ listener.valueChange(event);
+ }
+ }
+
+ public Label getLabel()
+ {
+ return label;
+ }
+
+ public void setReadWrite(boolean readWrite)
+ {
+ if (component instanceof Checkbox)
+ {
+ ((Checkbox)component).setEnabled(readWrite);
+ }
+ else if (component instanceof Button)
+ {
+ ((Button)component).setEnabled(readWrite);
+ }
+ else if (component instanceof Listbox)
+ {
+ ((Listbox)component).setEnabled(readWrite);
+ }
+ else if (component instanceof Datebox)
+ {
+ ((Datebox)component).setEnabled(readWrite);
+ }
+ else if (component instanceof Urlbox)
+ {
+ ((Urlbox)component).setEnabled(readWrite);
+ }
+ else if (component instanceof Searchbox)
+ {
+ ((Searchbox)component).setEnabled(readWrite);
+ }
+ else if (component instanceof Locationbox)
+ {
+ ((Locationbox)component).setEnabled(readWrite);
+ }
+ else if (component instanceof EditorBox)
+ {
+ ((EditorBox)component).setEnabled(readWrite);
+ }
+ else
+ {
+ ((InputElement)component).setReadonly(!readWrite);
+ }
+ }
+
+ public boolean isReadWrite()
+ {
+ if (component instanceof Checkbox)
+ {
+ return ((Checkbox)component).isDisabled();
+ }
+ else if (component instanceof Button)
+ {
+ return ((Button)component).isEnabled();
+ }
+ else if (component instanceof Listbox)
+ {
+ return ((Listbox)component).isEnabled();
+ }
+ else if (component instanceof Searchbox)
+ {
+ return ((Searchbox)component).isEnabled();
+ }
+ else if (component instanceof Locationbox)
+ {
+ return ((Locationbox)component).isEnabled();
+ }
+ else if (component instanceof EditorBox)
+ {
+ return ((EditorBox)component).isEnabled();
+ }
+ else
+ {
+ return ((InputElement)component).isReadonly();
+ }
+ }
+
+ public void setVisible(boolean visible)
+ {
+ label.setVisible(visible);
+ component.setVisible(visible);
+ }
+
+ public boolean isVisible()
+ {
+ return component.isVisible();
+ }
+
+ public void setBackground(boolean error)
+ {
+
+ }
+
+ public void setBackground(Color color)
+ {
+
+ }
+
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer(30);
+ sb.append(this.getClass().getName());
+ sb.append("[").append(this.getColumnName());
+ sb.append("=");
+ sb.append(this.getValue()).append("]");
+ return sb.toString();
+ }
+
+ abstract public void setValue(Object value);
+
+ abstract public Object getValue();
+
+ abstract public String getDisplay();
+
+ public String[] getEvents()
+ {
+ return WEditor.lISTENER_EVENTS;
+ }
+
+ /**
+ * Set whether the editor represents a mandatory field.
+ * @param mandatory whether the field is mandatory
+ */
+ public void setMandatory (boolean mandatory)
+ {
+ this.mandatory = mandatory;
+ }
+
+ public boolean isMandatory()
+ {
+ return this.mandatory;
+ }
+
+ public boolean isAsap()
+ {
+ return true;
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WEditorPopupMenu.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WEditorPopupMenu.java
new file mode 100644
index 0000000000..0aaff34cf7
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WEditorPopupMenu.java
@@ -0,0 +1,147 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.editor;
+
+import java.util.ArrayList;
+
+import org.adempiere.webui.event.ContextMenuEvent;
+import org.adempiere.webui.event.ContextMenuListener;
+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;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class WEditorPopupMenu extends Menupopup implements EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private static final String EVENT_ATTRIBUTE = "EVENT";
+ public static final String ZOOM_EVENT = "ZOOM";
+ public static final String REQUERY_EVENT = "REQUERY";
+ public static final String PREFERENCE_EVENT = "VALUE_PREFERENCE";
+ public static final String NEW_EVENT = "NEW_RECORD";
+
+ private boolean newEnabled = true;
+ private boolean zoomEnabled = true;
+ private boolean requeryEnabled = true;
+ private boolean preferencesEnabled = true;
+
+ private Menuitem zoomItem;
+ private Menuitem requeryItem;
+ private Menuitem prefItem;
+ private Menuitem newItem;
+
+
+ private ArrayList menuListeners = new ArrayList();
+
+ public WEditorPopupMenu(boolean zoom, boolean requery, boolean preferences)
+ {
+ super();
+ this.zoomEnabled = zoom;
+ this.requeryEnabled = requery;
+ this.preferencesEnabled = preferences;
+ init();
+ }
+
+ public WEditorPopupMenu(boolean zoom, boolean requery, boolean preferences, boolean newRecord)
+ {
+ super();
+ this.zoomEnabled = zoom;
+ this.requeryEnabled = requery;
+ this.preferencesEnabled = preferences;
+ this.newEnabled = newRecord;
+ init();
+ }
+
+
+ private void init()
+ {
+ if (zoomEnabled)
+ {
+ zoomItem = new Menuitem();
+ zoomItem.setAttribute(EVENT_ATTRIBUTE, ZOOM_EVENT);
+ zoomItem.setLabel("Zoom");
+ zoomItem.setImage("/images/Zoom16.gif");
+ zoomItem.addEventListener(Events.ON_CLICK, this);
+
+ this.appendChild(zoomItem);
+ }
+
+ if (requeryEnabled)
+ {
+ requeryItem = new Menuitem();
+ requeryItem.setAttribute(EVENT_ATTRIBUTE, REQUERY_EVENT);
+ requeryItem.setLabel("ReQuery");
+ requeryItem.setImage("/images/Refresh16.gif");
+ requeryItem.addEventListener(Events.ON_CLICK, this);
+ this.appendChild(requeryItem);
+ }
+
+ if (preferencesEnabled)
+ {
+ prefItem = new Menuitem();
+ prefItem.setAttribute(EVENT_ATTRIBUTE, PREFERENCE_EVENT);
+ prefItem.setLabel("Value Preference");
+ prefItem.setImage("/images/VPreference16.gif");
+ prefItem.addEventListener(Events.ON_CLICK, this);
+ this.appendChild(prefItem);
+ }
+
+ if (newEnabled)
+ {
+ newItem = new Menuitem();
+ newItem.setAttribute(EVENT_ATTRIBUTE, NEW_EVENT);
+ newItem.setLabel("New Record");
+ newItem.setImage("/images/New16.gif");
+ newItem.addEventListener(Events.ON_CLICK, this);
+ this.appendChild(newItem);
+ }
+ }
+
+ public void addMenuListener(ContextMenuListener listener)
+ {
+ menuListeners.add(listener);
+ }
+
+ public boolean isAsap()
+ {
+ return true;
+ }
+
+ public void onEvent(Event event)
+ {
+ String evt = (String)event.getTarget().getAttribute(EVENT_ATTRIBUTE);
+
+ if (evt != null)
+ {
+ ContextMenuEvent menuEvent = new ContextMenuEvent(evt);
+
+ for (ContextMenuListener listener : menuListeners)
+ {
+ listener.onMenu(menuEvent);
+ }
+ }
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WLocationEditor.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WLocationEditor.java
new file mode 100644
index 0000000000..0fe9978401
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WLocationEditor.java
@@ -0,0 +1,163 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.editor;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import org.adempiere.webui.apps.AEnv;
+import org.adempiere.webui.component.Locationbox;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.window.WLocationDialog;
+import org.compiere.model.MLocation;
+import org.compiere.model.MLocationLookup;
+import org.compiere.util.CLogger;
+import org.compiere.util.Env;
+import org.compiere.util.Msg;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zk.ui.event.Events;
+
+/**
+ * @author Sendy Yagambrum
+ * @date July 16, 2007
+ *
+ * This class is based on VLocation written by Jorg Janke
+ **/
+public class WLocationEditor extends WEditor implements EventListener, PropertyChangeListener
+{
+ private static final String[] LISTENER_EVENTS = {Events.ON_CLICK};
+
+ private static CLogger log = CLogger.getCLogger(WLocationEditor.class);
+ private static final long serialVersionUID = 1L;
+ private Locationbox locationbox;
+ private String m_columnName;
+ private MLocationLookup m_Location;
+ private MLocation m_value;
+
+ /**
+ * Constructor without GridField
+ * @param columnName column name
+ * @param mandatory mandatory
+ * @param isReadOnly read only
+ * @param isUpdateable updateable
+ * @param mLocation location model
+ **/
+ public WLocationEditor(String columnName, boolean mandatory, boolean isReadOnly, boolean isUpdateable,
+ MLocationLookup mLocation)
+ {
+ super(new Locationbox(), "Address","",mandatory,isReadOnly,isUpdateable);
+
+ m_columnName = columnName;
+ m_Location = mLocation;
+ locationbox = (Locationbox)super.component;
+ locationbox.setButtonImage("/images/Location10.gif");
+ }
+
+ @Override
+ public String getDisplay()
+ {
+ return locationbox.getText();
+ }
+
+ @Override
+ public Object getValue()
+ {
+ if (m_value == null)
+ return null;
+ return new Integer(m_value.getC_Location_ID());
+ }
+
+ @Override
+ public void setValue(Object value)
+ {
+ if (value == null)
+ {
+ m_value = null;
+ locationbox.setText(null);
+ }
+ else
+ {
+ m_value = m_Location.getLocation(value, null);
+ if (m_value == null)
+ locationbox.setText("<" + value + ">");
+ else
+ locationbox.setText(m_value.toString());
+ }
+ }
+
+ /**
+ * Return Editor value
+ * @return value
+ */
+ public int getC_Location_ID()
+ {
+ if (m_value == null)
+ return 0;
+ return m_value.getC_Location_ID();
+ }
+
+ /**
+ * Property Change Listener
+ * @param evt PropertyChangeEvent
+ */
+ public void propertyChange (PropertyChangeEvent evt)
+ {
+ if (evt.getPropertyName().equals(org.compiere.model.GridField.PROPERTY))
+ setValue(evt.getNewValue());
+ }
+
+ public void onEvent(Event event) throws Exception
+ {
+ //
+ if ("onClick".equals(event.getName()))
+ {
+ log.config( "actionPerformed - " + m_value);
+ WLocationDialog ld = new WLocationDialog(Msg.getMsg(Env.getCtx(), "Location"), m_value);
+ ld.setVisible(true);
+ AEnv.showWindow(ld);
+ m_value = ld.getValue();
+ //
+ if (!ld.isChanged())
+ return;
+
+ // Data Binding
+ int C_Location_ID = 0;
+ if (m_value != null)
+ C_Location_ID = m_value.getC_Location_ID();
+ Integer ii = new Integer(C_Location_ID);
+ // force Change - user does not realize that embedded object is already saved.
+ ValueChangeEvent valuechange = new ValueChangeEvent(this,m_columnName,null,null);
+ fireValueChange(valuechange); // resets m_mLocation
+ if (C_Location_ID != 0)
+ {
+ ValueChangeEvent vc = new ValueChangeEvent(this,m_columnName,null,ii);
+ fireValueChange(vc);
+ }
+ setValue(ii);
+ }
+ }
+
+ /**
+ * return listener events to be associated with editor component
+ */
+ public String[] getEvents()
+ {
+ return LISTENER_EVENTS;
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WLocatorEditor.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WLocatorEditor.java
new file mode 100644
index 0000000000..1726c4f4ec
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WLocatorEditor.java
@@ -0,0 +1,417 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.editor;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.logging.Level;
+
+import org.adempiere.webui.apps.AEnv;
+import org.adempiere.webui.component.EditorBox;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.window.WLocatorDialog;
+import org.compiere.model.MLocator;
+import org.compiere.model.MLocatorLookup;
+import org.compiere.model.MRole;
+import org.compiere.model.MWarehouse;
+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.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zk.ui.event.Events;
+
+/**
+ * Locator Editor : Based on VLocator
+ *
+ * @author Niraj Sohun
+ * @date Jul 23, 2007
+ */
+
+public class WLocatorEditor extends WEditor implements EventListener, PropertyChangeListener
+{
+ private static final String[] LISTENER_EVENTS = {Events.ON_CLICK};
+
+ private String m_columnName;
+ private MLocatorLookup m_mLocator;
+ private EditorBox editorbox;
+ private MLocator m_value;
+ private int m_WindowNo;
+
+ private static CLogger log = CLogger.getCLogger(WLocatorEditor.class);
+ /**
+ * IDE Constructor
+ */
+
+ public WLocatorEditor()
+ {
+ this("M_Locator_ID", false, false, true, null);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param columnName ColumnName
+ * @param mandatory mandatory
+ * @param isReadOnly read only
+ * @param isUpdateable updateable
+ * @param mLocator locator (lookup) model
+ * @param WindowNo window no
+ */
+
+ public WLocatorEditor( String columnName, boolean mandatory, boolean isReadOnly,
+ boolean isUpdateable, MLocatorLookup mLocator)
+ {
+ super(new EditorBox(), "Locator", "", mandatory, isReadOnly, isUpdateable);
+
+ m_columnName = columnName;
+ m_mLocator = mLocator;
+ editorbox = (EditorBox)super.component;
+ editorbox.setButtonImage("/images/Locator10.gif");
+
+ setDefault_Locator_ID(); // set default locator, teo_sarca [ 1661546 ]
+ }
+
+ public void setValue(Object value)
+ {
+ setValue (value, false);
+ }
+
+ /**
+ * Set Value
+ * @param value value
+ * @param fire data binding
+ */
+
+ private void setValue (Object value, boolean fire)
+ {
+ if (value != null)
+ {
+ m_mLocator.setOnly_Warehouse_ID (getOnly_Warehouse_ID ());
+ m_mLocator.setOnly_Product_ID(getOnly_Product_ID());
+
+ if (!m_mLocator.isValid(value))
+ value = null;
+ }
+
+ m_value = m_mLocator.getMLocator(value, null);
+ editorbox.setText(m_mLocator.getDisplay(value)); // loads value
+
+ // Data Binding
+
+ ValueChangeEvent val = new ValueChangeEvent(this, m_columnName, null, value);
+ fireValueChange(val);
+ }
+
+ /**
+ * Return Editor value
+ * @return value
+ */
+
+ public Object getValue()
+ {
+ if (getM_Locator_ID() == 0)
+ return null;
+
+ return m_value;
+ } // getValue
+
+ /**
+ * Get M_Locator_ID
+ * @return id
+ */
+
+ public int getM_Locator_ID()
+ {
+ if (m_value != null/* && m_value instanceof Integer*/)
+ return m_value.getM_Locator_ID();
+
+ return 0;
+ } // getM_Locator_ID
+
+ /**
+ * Return Display Value
+ * @return display value
+ */
+
+ public String getDisplay()
+ {
+ return editorbox.getText();
+ } // getDisplay
+
+ public void onEvent(Event event) throws Exception
+ {
+ // Warehouse/Product
+
+ int only_Warehouse_ID = getOnly_Warehouse_ID();
+ int only_Product_ID = getOnly_Product_ID();
+
+ log.config("Only Warehouse_ID=" + only_Warehouse_ID + ", Product_ID=" + only_Product_ID);
+
+ // Text Entry ok
+
+ if (event.getTarget() == editorbox && actionText(only_Warehouse_ID, only_Product_ID))
+ return;
+
+ // Button - Start Dialog
+
+ int M_Locator_ID = 0;
+
+ //if (m_value instanceof Integer)
+ if (m_value != null)
+ M_Locator_ID = m_value.getM_Locator_ID();
+
+ m_mLocator.setOnly_Warehouse_ID(only_Warehouse_ID);
+ m_mLocator.setOnly_Product_ID(getOnly_Product_ID());
+
+ WLocatorDialog ld = new WLocatorDialog(Msg.translate(Env.getCtx(), m_columnName),
+ m_mLocator, M_Locator_ID, isMandatory(), only_Warehouse_ID, this.m_WindowNo);
+
+ // display
+ ld.setVisible(true);
+ AEnv.showWindow(ld);
+
+ m_mLocator.setOnly_Warehouse_ID(0);
+
+ // redisplay
+
+ if (!ld.isChanged())
+ return;
+ setValue (ld.getValue(), true);
+ }
+
+ /**
+ * Hit Enter in Text Field
+ * @param only_Warehouse_ID if not 0 restrict warehouse
+ * @param only_Product_ID of not 0 restricted product
+ * @return true if found
+ */
+
+ private boolean actionText(int only_Warehouse_ID, int only_Product_ID)
+ {
+ String text = editorbox.getText();
+ log.fine(text);
+
+ // Null
+
+ if (text == null || text.length() == 0)
+ {
+ if (isMandatory())
+ return false;
+ else
+ {
+ setValue (null, true);
+ return true;
+ }
+ }
+
+ if (text.endsWith("%"))
+ text = text.toUpperCase();
+ else
+ text = text.toUpperCase() + "%";
+
+ // Look up - see MLocatorLookup.run
+
+ StringBuffer sql = new StringBuffer("SELECT M_Locator_ID FROM M_Locator ")
+ .append(" WHERE IsActive='Y' AND UPPER(Value) LIKE ")
+ .append(DB.TO_STRING(text));
+
+ if (getOnly_Warehouse_ID() != 0)
+ sql.append(" AND M_Warehouse_ID=?");
+
+ if (getOnly_Product_ID() != 0)
+ sql.append(" AND (IsDefault='Y' ") // Default Locator
+ .append("OR EXISTS (SELECT * FROM M_Product p ") // Product Locator
+ .append("WHERE p.M_Locator_ID=M_Locator.M_Locator_ID AND p.M_Product_ID=?)")
+ .append("OR EXISTS (SELECT * FROM M_Storage s ") // Storage Locator
+ .append("WHERE s.M_Locator_ID=M_Locator.M_Locator_ID AND s.M_Product_ID=?))");
+
+ String finalSql = MRole.getDefault(Env.getCtx(), false).addAccessSQL(
+ sql.toString(), "M_Locator", MRole.SQL_NOTQUALIFIED, MRole.SQL_RO);
+
+ int M_Locator_ID = 0;
+ PreparedStatement pstmt = null;
+
+ try
+ {
+ pstmt = DB.prepareStatement(finalSql, null);
+ int index = 1;
+
+ if (only_Warehouse_ID != 0)
+ pstmt.setInt(index++, only_Warehouse_ID);
+
+ if (only_Product_ID != 0)
+ {
+ pstmt.setInt(index++, only_Product_ID);
+ pstmt.setInt(index++, only_Product_ID);
+ }
+
+ ResultSet rs = pstmt.executeQuery();
+
+ if (rs.next())
+ {
+ M_Locator_ID = rs.getInt(1);
+
+ if (rs.next())
+ M_Locator_ID = 0; // more than one
+ }
+ rs.close();
+ pstmt.close();
+ pstmt = null;
+ }
+ catch (SQLException ex)
+ {
+ log.log(Level.SEVERE, finalSql, ex);
+ }
+
+ try
+ {
+ if (pstmt != null)
+ pstmt.close();
+ }
+ catch (SQLException ex1)
+ {
+ }
+
+ pstmt = null;
+
+ if (M_Locator_ID == 0)
+ return false;
+
+ setValue (new Integer(M_Locator_ID), true);
+ return true;
+ } // actionText
+
+ /**
+ * Set Field/WindowNo for ValuePreference (NOP)
+ * @param mField Model Field
+ */
+
+ public void setField (org.compiere.model.GridField mField)
+ {
+ } // setField
+
+ /**
+ * Get Warehouse restriction if any.
+ * @return M_Warehouse_ID or 0
+ */
+
+ private int getOnly_Warehouse_ID()
+ {
+ String only_Warehouse = Env.getContext(Env.getCtx(), m_WindowNo, "M_Warehouse_ID", true);
+ int only_Warehouse_ID = 0;
+
+ try
+ {
+ if (only_Warehouse != null && only_Warehouse.length () > 0)
+ only_Warehouse_ID = Integer.parseInt (only_Warehouse);
+ }
+ catch (Exception ex)
+ {
+ }
+
+ return only_Warehouse_ID;
+ } // getOnly_Warehouse_ID
+
+ /**
+ * Get Product restriction if any.
+ * @return M_Product_ID or 0
+ */
+
+ private int getOnly_Product_ID()
+ {
+ if (!Env.isSOTrx(Env.getCtx(), m_WindowNo))
+ return 0; // No product restrictions for PO
+
+ String only_Product = Env.getContext(Env.getCtx(), m_WindowNo, "M_Product_ID", true);
+ int only_Product_ID = 0;
+
+ try
+ {
+ if (only_Product != null && only_Product.length () > 0)
+ only_Product_ID = Integer.parseInt (only_Product);
+ }
+ catch (Exception ex)
+ {
+ }
+ return only_Product_ID;
+ } // getOnly_Product_ID
+
+ /**
+ * Set the default locator if this field is mandatory
+ * and we have a warehouse restriction.
+ *
+ * @since 3.1.4
+ */
+
+ private void setDefault_Locator_ID()
+ {
+ // teo_sarca, FR [ 1661546 ] Mandatory locator fields should use defaults
+
+ if (!isMandatory() || m_mLocator == null)
+ {
+ return;
+ }
+
+ int M_Warehouse_ID = getOnly_Warehouse_ID();
+
+ if (M_Warehouse_ID <= 0)
+ {
+ return;
+ }
+
+ MWarehouse wh = MWarehouse.get(Env.getCtx(), M_Warehouse_ID);
+
+ if (wh == null || wh.get_ID() <= 0)
+ {
+ return;
+ }
+
+ MLocator loc = wh.getDefaultLocator();
+
+ if (loc == null || loc.get_ID() <= 0)
+ {
+ return;
+ }
+
+ setValue(Integer.valueOf(loc.get_ID()));
+ }
+
+ /**
+ * Property Change Listener
+ * @param evt PropertyChangeEvent
+ */
+
+ public void propertyChange (PropertyChangeEvent evt)
+ {
+ if (evt.getPropertyName().equals(org.compiere.model.GridField.PROPERTY))
+ setValue(evt.getNewValue());
+ }
+
+ /**
+ * return listener events to be associated with editor component
+ */
+ public String[] getEvents()
+ {
+ return LISTENER_EVENTS;
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WNumberEditor.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WNumberEditor.java
new file mode 100644
index 0000000000..157f00c99d
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WNumberEditor.java
@@ -0,0 +1,129 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.editor;
+
+import org.adempiere.webui.component.NumberBox;
+import org.adempiere.webui.event.ContextMenuEvent;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.compiere.model.GridField;
+import org.compiere.util.DisplayType;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.Events;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 11, 2007
+ * @version $Revision: 0.10 $
+ */
+public class WNumberEditor extends WEditor
+{
+ public final String[] LISTENER_EVENTS = {Events.ON_CHANGE};
+
+ public static final int MAX_DISPLAY_LENGTH = 20;
+
+ private NumberBox comp;
+
+ private String oldValue;
+
+ private boolean mandatory = false;
+
+ public WNumberEditor(GridField gridField)
+ {
+ super(new NumberBox(gridField.getDisplayType() == DisplayType.Integer),
+ gridField);
+ comp = (NumberBox)super.component;
+ init();
+ }
+
+ public WNumberEditor(GridField gridField, boolean integral)
+ {
+ super(new NumberBox(integral), gridField);
+ comp = (NumberBox)super.component;
+ init();
+ }
+
+ private void init()
+ {
+ comp.setMaxlength(gridField.getFieldLength());
+ comp.setCols(MAX_DISPLAY_LENGTH);
+ comp.setTooltiptext(gridField.getDescription());
+ }
+
+ public void onEvent(Event event)
+ {
+ String newValue = comp.getValue();
+ ValueChangeEvent changeEvent = new ValueChangeEvent(this, this.getColumnName(), oldValue, newValue);
+ super.fireValueChange(changeEvent);
+ oldValue = newValue;
+ }
+
+ @Override
+ public String getDisplay()
+ {
+ return comp.getValue();
+ }
+
+ @Override
+ public Object getValue()
+ {
+ return comp.getValue();
+ }
+
+ @Override
+ public boolean isMandatory()
+ {
+ return mandatory;
+ }
+
+ @Override
+ public void setMandatory(boolean mandatory)
+ {
+ this.mandatory = mandatory;
+ }
+
+ @Override
+ public void setValue(Object value)
+ {
+ if (value != null)
+ {
+ comp.setValue(value.toString());
+ }
+ else
+ {
+ comp.setValue("0");
+ }
+ }
+
+ public String[] getEvents()
+ {
+ return LISTENER_EVENTS;
+ }
+
+ public void onMenu(ContextMenuEvent evt)
+ {
+ /* Wrong implementation for Value Preference - Swing is being called
+ if (WEditorPopupMenu.PREFERENCE_EVENT.equals(evt.getContextEvent()))
+ {
+ if (MRole.getDefault().isShowPreference())
+ ValuePreference.start (this.getGridField(), getValue());
+ return;
+ }
+ */
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WPasswordEditor.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WPasswordEditor.java
new file mode 100644
index 0000000000..6ce808a67c
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WPasswordEditor.java
@@ -0,0 +1,37 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.editor;
+
+import org.compiere.model.GridField;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 12, 2007
+ * @version $Revision: 0.10 $
+ */
+public class WPasswordEditor extends WStringEditor
+{
+
+ public WPasswordEditor(GridField gridField)
+ {
+ super(gridField);
+ super.setTypePassword(true);
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WSearchEditor.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WSearchEditor.java
new file mode 100644
index 0000000000..01f4438225
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WSearchEditor.java
@@ -0,0 +1,846 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.editor;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.logging.Level;
+
+import org.adempiere.webui.apps.AEnv;
+import org.adempiere.webui.component.Searchbox;
+import org.adempiere.webui.event.ContextMenuEvent;
+import org.adempiere.webui.event.ContextMenuListener;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.event.ValueChangeListener;
+import org.adempiere.webui.grid.WBPartner;
+import org.adempiere.webui.panel.InfoBPartnerPanel;
+import org.adempiere.webui.panel.InfoPanel;
+import org.adempiere.webui.panel.InfoProductPanel;
+import org.compiere.grid.ed.ValuePreference;
+import org.compiere.model.GridField;
+import org.compiere.model.Lookup;
+import org.compiere.model.MLookup;
+import org.compiere.model.MRole;
+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.Events;
+
+/**
+ * Search Editor for web UI.
+ * Web UI port of search type VLookup
+ *
+ * @author Ashley G Ramdass
+ *
+ */
+public class WSearchEditor extends WEditor implements ContextMenuListener, PropertyChangeListener, ValueChangeListener
+{
+ private static final String[] LISTENER_EVENTS = {Events.ON_CLICK, Events.ON_CHANGE};
+ private Searchbox searchbox;
+ private Lookup lookup;
+ private String m_tableName = null;
+ private String m_keyColumnName = null;
+ private String columnName;
+ private WEditorPopupMenu popupMenu;
+ private Object value;
+
+ private static CLogger log = CLogger.getCLogger(WSearchEditor.class);
+
+ public WSearchEditor (GridField gridField)
+ {
+ super(new Searchbox(), gridField);
+
+ lookup = gridField.getLookup();
+
+ if (lookup != null)
+ columnName = lookup.getColumnName();
+
+ init();
+ }
+
+ /**
+ * Set the underlying component.
+ *
+ * @param comp the component to use
+ */
+ protected void setComponent(Component comp)
+ {
+ // TODO remove this duplication of components.
+ // Only need component from WEditor (superclass)
+ // and can then override get component and cast it to Searchbox
+ if (!(comp instanceof Searchbox))
+ {
+ throw new IllegalArgumentException("A search editor must contain a Searchbox");
+ }
+ super.setComponent(comp);
+ this.searchbox = (Searchbox)super.component;
+ }
+
+ /**
+ * Constructor for use if a grid field is unavailable
+ *
+ * @param lookup Store of selectable data
+ * @param label column name (not displayed)
+ * @param description description of component
+ * @param mandatory whether a selection must be made
+ * @param readonly whether or not the editor is read only
+ * @param updateable whether the editor contents can be changed
+ */
+ public WSearchEditor (Lookup lookup, String label, String description, boolean mandatory, boolean readonly, boolean updateable)
+ {
+ super(new Searchbox(), label, description, mandatory, readonly, updateable);
+
+ if (lookup == null)
+ {
+ throw new IllegalArgumentException("Lookup cannot be null");
+ }
+
+ this.lookup = lookup;
+ columnName = lookup.getColumnName();
+ super.setColumnName(columnName);
+ init();
+ }
+
+ /**
+ * initialise editor
+ * @param columnName columnName
+ */
+ private void init()
+ {
+
+ columnName = this.getColumnName();
+ popupMenu = new WEditorPopupMenu(true, true, true, true);
+
+ (searchbox.getTextBox()).setContext(popupMenu.getId());
+
+ if (columnName.equals("C_BPartner_ID"))
+ {
+ searchbox.setButtonImage("/images/BPartner10.gif");
+ }
+ else if (columnName.equals("M_Product_ID"))
+ {
+ searchbox.setButtonImage("/images/Product10.gif");
+ }
+ else
+ {
+ searchbox.setButtonImage("/images/PickOpen10.gif");
+ }
+
+ return;
+ }
+
+ public WEditorPopupMenu getPopupMenu()
+ {
+ return popupMenu;
+ }
+
+ @Override
+ public void setValue(Object value)
+ {
+ this.value = value;
+ if (value != null && !"".equals(String.valueOf(value)))
+ {
+ String text = lookup.getDisplay(value);
+
+ if (text.startsWith("_"))
+ {
+ text = text.substring(1);
+ }
+
+ searchbox.setText(text);
+ }
+ else
+ {
+ searchbox.setText("");
+ }
+ }
+
+ /**
+ * Set whether the editor represents a mandatory field.
+ *
+ * @param mandatory whether the editor must be filled
+ */
+ public void setMandatory(boolean mandatory)
+ {
+ searchbox.setMandatory(mandatory);
+ super.setMandatory(mandatory);
+ }
+
+ @Override
+ public Object getValue()
+ {
+ return value;
+ }
+
+ @Override
+ public String getDisplay()
+ {
+ return searchbox.getText();
+ }
+
+ public void onEvent(Event e)
+ {
+ if ("onChange".equals(e.getName()))
+ {
+ actionText(searchbox.getText());
+
+ }
+ else if ("onClick".equals(e.getName()))
+ {
+ actionButton("");
+ }
+
+ }
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ if ("FieldValue".equals(evt.getPropertyName()))
+ {
+ if ( evt.getNewValue()== null)
+ {
+ actionRefresh("");
+ }
+ else
+ {
+ actionRefresh(evt.getNewValue());
+
+ }
+ }
+ }
+
+ private void actionRefresh(Object value)
+ {
+ boolean mandatory = isMandatory();
+ AEnv.actionRefresh(lookup, value, mandatory);
+ setValue(value);
+ }
+
+ private void actionZoom()
+ {
+ AEnv.actionZoom(lookup, getValue());
+ }
+ private void actionZoom(Object value)
+ {
+ AEnv.actionZoom(lookup, value);
+ }
+
+ public void onMenu(ContextMenuEvent evt)
+ {
+ if (WEditorPopupMenu.REQUERY_EVENT.equals(evt.getContextEvent()))
+ {
+ actionRefresh(getValue());
+ }
+ else if (WEditorPopupMenu.ZOOM_EVENT.equals(evt.getContextEvent()))
+ {
+ actionZoom();
+ }
+ else if (WEditorPopupMenu.PREFERENCE_EVENT.equals(evt.getContextEvent()))
+ {
+ if (MRole.getDefault().isShowPreference())
+ ValuePreference.start (this.getGridField(), getValue());
+ return;
+ }
+ else if (WEditorPopupMenu.NEW_EVENT.equals(evt.getContextEvent()))
+ {
+ actionBPartner(true);
+ }
+ }
+
+ private void actionText(String text)
+ {
+ // Nothing entered
+ if (text == null || text.length() == 0 || text.equals("%"))
+ {
+ actionButton(text);
+ return;
+ }
+ text = text.toUpperCase();
+ log.config(getColumnName() + " - " + text);
+
+ // Exact first
+ PreparedStatement pstmt = null;
+ String finalSQL = Msg.parseTranslation(Env.getCtx(), getDirectAccessSQL(text));
+ int id = -3;
+
+ try
+ {
+ pstmt = DB.prepareStatement(finalSQL, null);
+ ResultSet rs = pstmt.executeQuery();
+ if (rs.next())
+ {
+ id = rs.getInt(1); // first
+ if (rs.next())
+ id = -1; // only if unique
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (Exception e)
+ {
+ log.log(Level.SEVERE, finalSQL, e);
+ id = -2;
+ }
+
+ // Try like
+ if (id == -3 && !text.endsWith("%"))
+ {
+ text += "%";
+ finalSQL = Msg.parseTranslation(Env.getCtx(), getDirectAccessSQL(text));
+
+ try
+ {
+ pstmt = DB.prepareStatement(finalSQL, null);
+ ResultSet rs = pstmt.executeQuery();
+ if (rs.next())
+ {
+ id = rs.getInt(1); // first
+ if (rs.next())
+ id = -1; // only if unique
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (Exception e)
+ {
+ log.log(Level.SEVERE, finalSQL, e);
+ id = -2;
+ }
+ }
+
+ try
+ {
+ if (pstmt != null)
+ pstmt.close();
+ }
+ catch (Exception e)
+ {
+ }
+
+ // No (unique) result
+ if (id <= 0)
+ {
+ if (id == -3)
+ log.fine(getColumnName() + " - Not Found - " + finalSQL);
+ else
+ log.fine(getColumnName() + " - Not Unique - " + finalSQL);
+
+ //m_value = null; // force re-display
+ actionButton(searchbox.getText());
+ return;
+ }
+ log.fine(getColumnName() + " - Unique ID=" + id);
+
+ actionCombo(new Integer(id)); // data binding
+ //m_text.requestFocus();
+ } // actionText
+
+
+ private void actionCombo (Object value)
+ {
+ log.fine("Value=" + value);
+
+ ValueChangeEvent evt = new ValueChangeEvent(this, this.getColumnName(), value, value);
+ // -> ADTabpanel - valuechange
+ fireValueChange(evt);
+ /*
+ // is the value updated ?
+ boolean updated = false;
+ if (value == null && getValue() == null)
+ updated = true;
+ else if (value != null && value.equals(getValue()))
+ updated = true;
+ if (!updated)
+ {
+ // happens if VLookup is used outside of APanel/GridController (no property listener)
+ log.fine(getColumnName() + " - Value explicitly set - new=" + value + ", old=" + getValue());
+ if (getListeners(PropertyChangeListener.class).length <= 0)
+ setValue(value);
+ }
+ */
+ } // actionCombo
+
+ /**
+ * Action - Special BPartner Screen
+ * @param newRecord true if new record should be created
+ */
+
+ private void actionBPartner (boolean newRecord)
+ {
+ WBPartner vbp = new WBPartner (lookup.getWindowNo());
+ int BPartner_ID = 0;
+
+ // if update, get current value
+ if (!newRecord)
+ {
+ if (value instanceof Integer)
+ BPartner_ID = ((Integer)value).intValue();
+ else if (value != null)
+ BPartner_ID = Integer.parseInt(value.toString());
+ }
+
+ vbp.loadBPartner (BPartner_ID);
+
+
+ vbp.setVisible(true);
+ AEnv.showWindow(vbp);
+
+ // get result
+ int result = vbp.getC_BPartner_ID();
+
+ if (result == 0 // 0 = not saved
+ && result == BPartner_ID) // the same
+ return;
+
+ // Maybe new BPartner - put in cache
+ lookup.getDirect(new Integer(result), false, true);
+ setValue(new Integer(result));
+ actionCombo (new Integer(result)); // data binding
+
+ //setValue(getValue());
+ } // actionBPartner
+
+ private void actionButton(String queryValue)
+ {
+ // m_button.setEnabled(false); // disable double click
+
+ if (lookup == null)
+ return; // leave button disabled
+
+ //m_text.requestFocus(); // closes other editors
+
+ /**
+ * Three return options:
+ * - Value Selected & OK pressed => store result => result has value
+ * - Cancel pressed => store null => result == null && cancelled
+ * - Window closed -> ignore => result == null && !cancalled
+ */
+
+ //Object result = null; // Not Being Used
+ //boolean cancelled = false; // Not Being Used
+
+ String col = lookup.getColumnName(); // fully qualified name
+
+ if (col.indexOf('.') != -1)
+ col = col.substring(col.indexOf('.')+1);
+
+ // Zoom / Validation
+ String whereClause = getWhereClause();
+
+ log.fine(col + ", Zoom=" + lookup.getZoom() + " (" + whereClause + ")");
+
+ // boolean resetValue = false; // Reset value so that is always treated as new entry
+
+ if (col.equals("M_Product_ID"))
+ {
+ // Reset
+ Env.setContext(Env.getCtx(), Env.WINDOW_INFO, Env.TAB_INFO, "M_Product_ID", "0");
+ Env.setContext(Env.getCtx(), Env.WINDOW_INFO, Env.TAB_INFO, "M_AttributeSetInstance_ID", "0");
+ Env.setContext(Env.getCtx(), Env.WINDOW_INFO, Env.TAB_INFO, "M_Lookup_ID", "0");
+
+ // Replace Value with name if no value exists
+ if (queryValue.length() == 0 && searchbox.getText().length() > 0)
+ queryValue = "@" + searchbox.getText() + "@"; // Name indicator - otherwise Value
+
+ int M_Warehouse_ID = Env.getContextAsInt(Env.getCtx(), lookup.getWindowNo(), "M_Warehouse_ID");
+ int M_PriceList_ID = Env.getContextAsInt(Env.getCtx(), lookup.getWindowNo(), "M_PriceList_ID");
+
+ // Show Info
+ InfoProductPanel ip = new InfoProductPanel (lookup.getWindowNo(),
+ M_Warehouse_ID, M_PriceList_ID, false,queryValue, whereClause);
+
+ ip.setVisible(true);
+ ip.setTitle("Product Info");
+ ip.setStyle("border: 2px");
+ ip.setClosable(true);
+ ip.setAttribute("mode", "modal");
+ ip.addValueChangeListener(this);
+ AEnv.showWindow(ip);
+ }
+ else if (col.equals("C_BPartner_ID"))
+ {
+ // Replace Value with name if no value exists
+ if (queryValue.length() == 0 && searchbox.getText().length() > 0)
+ queryValue = searchbox.getText();
+
+ boolean isSOTrx = true; // default
+
+ if (Env.getContext(Env.getCtx(), lookup.getWindowNo(), "IsSOTrx").equals("N"))
+ isSOTrx = false;
+
+ InfoBPartnerPanel ip = new InfoBPartnerPanel(queryValue, lookup.getWindowNo(), isSOTrx,false, whereClause);
+
+ ip.setVisible(true);
+ ip.setTitle("Business Partner Info");
+ ip.setStyle("border: 2px");
+ ip.setClosable(true);
+ ip.setAttribute("mode", "modal");
+ ip.addValueChangeListener(this);
+ AEnv.showWindow(ip);
+
+ /*
+ cancelled = ip.isCancelled();
+ result = ip.getSelectedKey();
+ */
+ }
+ else // General Info
+ {
+ if (m_tableName == null) // sets table name & key column
+ getDirectAccessSQL("*");
+
+ if (queryValue.length() == 0 && searchbox.getText().length() > 0)
+ queryValue = searchbox.getText();
+
+ boolean isSOTrx = true; // default
+
+ if (Env.getContext(Env.getCtx(), lookup.getWindowNo(), "IsSOTrx").equals("N"))
+ isSOTrx = false;
+
+ InfoPanel ig = InfoPanel.create(lookup.getWindowNo(), m_tableName,m_keyColumnName,queryValue, false, whereClause);
+ ig.setVisible(true);
+ ig.setStyle("border: 2px");
+ ig.setClosable(true);
+ ig.setAttribute("mode", "modal");
+ ig.addValueChangeListener(this);
+ AEnv.showWindow(ig);
+
+
+ }
+
+ /*
+ // Result
+ if (result != null)
+ {
+ log.config(m_columnName + " - Result = " + result.toString() + " (" + result.getClass().getName() + ")");
+ // make sure that value is in cache
+ m_lookup.getDirect(result, false, true);
+ if (resetValue)
+ actionCombo (null);
+ actionCombo (result); // data binding
+ }
+ else if (cancelled)
+ {
+ log.config(m_columnName + " - Result = null (cancelled)");
+ actionCombo(null);
+ }
+ else
+ {
+ log.config(m_columnName + " - Result = null (not cancelled)");
+ setValue(m_value); // to re-display value
+ }
+ //
+ m_button.setEnabled(true);
+ m_text.requestFocus();
+ */
+ }
+
+ /**
+ * Generate Access SQL for Search.
+ * The SQL returns the ID of the value entered
+ * Also sets m_tableName and m_keyColumnName
+ * @param text uppercase text for LIKE comparison
+ * @return sql or ""
+ * Example
+ * SELECT C_Payment_ID FROM C_Payment WHERE UPPER(DocumentNo) LIKE x OR ...
+ */
+ private String getDirectAccessSQL (String text)
+ {
+ String m_columnName = getColumnName();
+
+ StringBuffer sql = new StringBuffer();
+ m_tableName = m_columnName.substring(0, m_columnName.length()-3);
+ m_keyColumnName = m_columnName;
+
+ if (m_columnName.equals("M_Product_ID"))
+ {
+ // Reset
+ Env.setContext(Env.getCtx(), Env.WINDOW_INFO, Env.TAB_INFO, "M_Product_ID", "0");
+ Env.setContext(Env.getCtx(), Env.WINDOW_INFO, Env.TAB_INFO, "M_AttributeSetInstance_ID", "0");
+ Env.setContext(Env.getCtx(), Env.WINDOW_INFO, Env.TAB_INFO, "M_Locator_ID", "0");
+
+ sql.append("SELECT M_Product_ID FROM M_Product WHERE (UPPER(Value) LIKE ")
+ .append(DB.TO_STRING(text))
+ .append(" OR UPPER(Name) LIKE ").append(DB.TO_STRING(text))
+ .append(" OR UPC LIKE ").append(DB.TO_STRING(text)).append(")");
+ }
+ else if (m_columnName.equals("C_BPartner_ID"))
+ {
+ sql.append("SELECT C_BPartner_ID FROM C_BPartner WHERE (UPPER(Value) LIKE ")
+ .append(DB.TO_STRING(text))
+ .append(" OR UPPER(Name) LIKE ").append(DB.TO_STRING(text)).append(")");
+ }
+ else if (m_columnName.equals("C_Order_ID"))
+ {
+ sql.append("SELECT C_Order_ID FROM C_Order WHERE UPPER(DocumentNo) LIKE ")
+ .append(DB.TO_STRING(text));
+ }
+ else if (m_columnName.equals("C_Invoice_ID"))
+ {
+ sql.append("SELECT C_Invoice_ID FROM C_Invoice WHERE UPPER(DocumentNo) LIKE ")
+ .append(DB.TO_STRING(text));
+ }
+ else if (m_columnName.equals("M_InOut_ID"))
+ {
+ sql.append("SELECT M_InOut_ID FROM M_InOut WHERE UPPER(DocumentNo) LIKE ")
+ .append(DB.TO_STRING(text));
+ }
+ else if (m_columnName.equals("C_Payment_ID"))
+ {
+ sql.append("SELECT C_Payment_ID FROM C_Payment WHERE UPPER(DocumentNo) LIKE ")
+ .append(DB.TO_STRING(text));
+ }
+ else if (m_columnName.equals("GL_JournalBatch_ID"))
+ {
+ sql.append("SELECT GL_JournalBatch_ID FROM GL_JournalBatch WHERE UPPER(DocumentNo) LIKE ")
+ .append(DB.TO_STRING(text));
+ }
+ else if (m_columnName.equals("SalesRep_ID"))
+ {
+ sql.append("SELECT AD_User_ID FROM AD_User WHERE UPPER(Name) LIKE ")
+ .append(DB.TO_STRING(text));
+
+ m_tableName = "AD_User";
+ m_keyColumnName = "AD_User_ID";
+ }
+
+ // Predefined
+
+ if (sql.length() > 0)
+ {
+ String wc = getWhereClause();
+
+ if (wc != null && wc.length() > 0)
+ sql.append(" AND ").append(wc);
+
+ sql.append(" AND IsActive='Y'");
+ // ***
+
+ log.finest(m_columnName + " (predefined) " + sql.toString());
+
+ return MRole.getDefault().addAccessSQL(sql.toString(),
+ m_tableName, MRole.SQL_NOTQUALIFIED, MRole.SQL_RO);
+ }
+
+ // Check if it is a Table Reference
+
+ if (lookup != null && lookup instanceof MLookup)
+ {
+ int AD_Reference_ID = ((MLookup)lookup).getAD_Reference_Value_ID();
+
+ if (AD_Reference_ID != 0)
+ {
+ String query = "SELECT kc.ColumnName, dc.ColumnName, t.TableName "
+ + "FROM AD_Ref_Table rt"
+ + " INNER JOIN AD_Column kc ON (rt.AD_Key=kc.AD_Column_ID)"
+ + " INNER JOIN AD_Column dc ON (rt.AD_Display=dc.AD_Column_ID)"
+ + " INNER JOIN AD_Table t ON (rt.AD_Table_ID=t.AD_Table_ID) "
+ + "WHERE rt.AD_Reference_ID=?";
+
+ String displayColumnName = null;
+ PreparedStatement pstmt = null;
+
+ try
+ {
+ pstmt = DB.prepareStatement(query, null);
+ pstmt.setInt(1, AD_Reference_ID);
+ ResultSet rs = pstmt.executeQuery();
+
+ if (rs.next())
+ {
+ m_keyColumnName = rs.getString(1);
+ displayColumnName = rs.getString(2);
+ m_tableName = rs.getString(3);
+ }
+ rs.close();
+ pstmt.close();
+ pstmt = null;
+ }
+ catch (Exception e)
+ {
+ log.log(Level.SEVERE, query, e);
+ }
+
+ try
+ {
+ if (pstmt != null)
+ pstmt.close();
+
+ pstmt = null;
+ }
+ catch (Exception e)
+ {
+ pstmt = null;
+ }
+
+ if (displayColumnName != null)
+ {
+ sql = new StringBuffer();
+ sql.append("SELECT ").append(m_keyColumnName)
+ .append(" FROM ").append(m_tableName)
+ .append(" WHERE UPPER(").append(displayColumnName)
+ .append(") LIKE ").append(DB.TO_STRING(text))
+ .append(" AND IsActive='Y'");
+
+ String wc = getWhereClause();
+
+ if (wc != null && wc.length() > 0)
+ sql.append(" AND ").append(wc);
+
+ // ***
+
+ log.finest(m_columnName + " (Table) " + sql.toString());
+
+ return MRole.getDefault().addAccessSQL(sql.toString(),
+ m_tableName, MRole.SQL_NOTQUALIFIED, MRole.SQL_RO);
+ }
+ } // Table Reference
+ } // MLookup
+
+ /** Check Well Known Columns of Table - assumes TableDir **/
+
+ String query = "SELECT t.TableName, c.ColumnName "
+ + "FROM AD_Column c "
+ + " INNER JOIN AD_Table t ON (c.AD_Table_ID=t.AD_Table_ID AND t.IsView='N') "
+ + "WHERE (c.ColumnName IN ('DocumentNo', 'Value', 'Name') OR c.IsIdentifier='Y')"
+ + " AND c.AD_Reference_ID IN (10,14)"
+ + " AND EXISTS (SELECT * FROM AD_Column cc WHERE cc.AD_Table_ID=t.AD_Table_ID"
+ + " AND cc.IsKey='Y' AND cc.ColumnName=?)";
+
+ m_keyColumnName = m_columnName;
+ sql = new StringBuffer();
+ PreparedStatement pstmt = null;
+
+ try
+ {
+ pstmt = DB.prepareStatement(query, null);
+ pstmt.setString(1, m_keyColumnName);
+ ResultSet rs = pstmt.executeQuery();
+
+ while (rs.next())
+ {
+ if (sql.length() != 0)
+ sql.append(" OR ");
+
+ m_tableName = rs.getString(1);
+ sql.append("UPPER(").append(rs.getString(2)).append(") LIKE ").append(DB.TO_STRING(text));
+ }
+
+ rs.close();
+ pstmt.close();
+ pstmt = null;
+ }
+ catch (SQLException ex)
+ {
+ log.log(Level.SEVERE, query, ex);
+ }
+
+ try
+ {
+ if (pstmt != null)
+ pstmt.close();
+ }
+ catch (SQLException ex1)
+ {
+ }
+ pstmt = null;
+ //
+ if (sql.length() == 0)
+ {
+ log.log(Level.SEVERE, m_columnName + " (TableDir) - no standard/identifier columns");
+ return "";
+ }
+ //
+ StringBuffer retValue = new StringBuffer ("SELECT ")
+ .append(m_columnName).append(" FROM ").append(m_tableName)
+ .append(" WHERE ").append(sql)
+ .append(" AND IsActive='Y'");
+
+ String wc = getWhereClause();
+
+ if (wc != null && wc.length() > 0)
+ retValue.append(" AND ").append(wc);
+ // ***
+ log.finest(m_columnName + " (TableDir) " + sql.toString());
+ return MRole.getDefault().addAccessSQL(retValue.toString(),
+ m_tableName, MRole.SQL_NOTQUALIFIED, MRole.SQL_RO);
+ }
+
+ private String getWhereClause()
+ {
+ String whereClause = "";
+
+ if (lookup == null)
+ return "";
+
+ if (lookup.getZoomQuery() != null)
+ whereClause = lookup.getZoomQuery().getWhereClause();
+
+ String validation = lookup.getValidation();
+
+ if (validation == null)
+ validation = "";
+
+ if (whereClause.length() == 0)
+ whereClause = validation;
+ else if (validation.length() > 0)
+ whereClause += " AND " + validation;
+
+ // log.finest("ZoomQuery=" + (lookup.getZoomQuery()==null ? "" : lookup.getZoomQuery().getWhereClause())
+ // + ", Validation=" + lookup.getValidation());
+
+ if (whereClause.indexOf('@') != -1)
+ {
+ String validated = Env.parseContext(Env.getCtx(), lookup.getWindowNo(), whereClause, false);
+
+ if (validated.length() == 0)
+ log.severe(getColumnName() + " - Cannot Parse=" + whereClause);
+ else
+ {
+ log.fine(getColumnName() + " - Parsed: " + validated);
+ return validated;
+ }
+ }
+ return whereClause;
+ } // getWhereClause
+
+
+ public String[] getEvents()
+ {
+ return LISTENER_EVENTS;
+ }
+
+ public void valueChange(ValueChangeEvent evt)
+ {
+ if (getColumnName().equals(evt.getPropertyName()))
+ {
+ if (evt.getNewValue() != null)
+ {
+ actionCombo(evt.getNewValue());
+ }
+ }
+ else if ("zoom".equals(evt.getPropertyName()))
+ {
+ actionZoom(evt.getNewValue());
+ }
+
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WStringEditor.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WStringEditor.java
new file mode 100644
index 0000000000..5f39d9525e
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WStringEditor.java
@@ -0,0 +1,141 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.editor;
+
+import org.adempiere.webui.component.Textbox;
+import org.adempiere.webui.event.ContextMenuEvent;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.compiere.grid.ed.ValuePreference;
+import org.compiere.model.GridField;
+import org.compiere.model.MRole;
+import org.compiere.util.DisplayType;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.Events;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 11, 2007
+ * @version $Revision: 0.10 $
+ */
+public class WStringEditor extends WEditor
+{
+ private static final String[] LISTENER_EVENTS = {Events.ON_CHANGE};
+
+ protected Textbox textbox;
+
+ private String oldText;
+
+
+ public WStringEditor(GridField gridField)
+ {
+ super(new Textbox(), gridField);
+ textbox = (Textbox)super.component;
+
+ init();
+ }
+
+ private void init()
+ {
+ textbox.setMaxlength(gridField.getFieldLength());
+ int displayLength = gridField.getDisplayLength();
+ if (displayLength <= 0 || displayLength > MAX_DISPLAY_LENGTH)
+ {
+ displayLength = MAX_DISPLAY_LENGTH;
+ }
+ textbox.setCols(displayLength);
+
+ if (gridField.getDisplayType() == DisplayType.Text)
+ {
+ textbox.setMultiline(true);
+ textbox.setRows(3);
+ }
+ else if (gridField.getDisplayType() == DisplayType.TextLong)
+ {
+ textbox.setMultiline(true);
+ textbox.setRows(5);
+ }
+ else if (gridField.getDisplayType() == DisplayType.Memo)
+ {
+ textbox.setMultiline(true);
+ textbox.setRows(8);
+ }
+ }
+
+ public void onEvent(Event event)
+ {
+ String newText = textbox.getValue();
+ ValueChangeEvent changeEvent = new ValueChangeEvent(this, this.getColumnName(), oldText, newText);
+ super.fireValueChange(changeEvent);
+ oldText = newText;
+ }
+
+ @Override
+ public String getDisplay()
+ {
+ return textbox.getValue();
+ }
+
+ @Override
+ public Object getValue()
+ {
+ return textbox.getValue();
+ }
+
+ @Override
+ public void setValue(Object value)
+ {
+ if (value != null)
+ {
+ textbox.setValue(value.toString());
+ }
+ else
+ {
+ textbox.setValue("");
+ }
+ oldText = textbox.getValue();
+ }
+
+ protected void setTypePassword(boolean password)
+ {
+ if (password)
+ {
+ textbox.setType("password");
+ }
+ else
+ {
+ textbox.setType("text");
+ }
+ }
+
+ @Override
+ public String[] getEvents()
+ {
+ return LISTENER_EVENTS;
+ }
+
+ public void onMenu(ContextMenuEvent evt)
+ {
+ if (WEditorPopupMenu.PREFERENCE_EVENT.equals(evt.getContextEvent()))
+ {
+ if (MRole.getDefault().isShowPreference())
+ ValuePreference.start (this.getGridField(), getValue());
+ return;
+ }
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WTableDirEditor.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WTableDirEditor.java
new file mode 100644
index 0000000000..a5750d640b
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WTableDirEditor.java
@@ -0,0 +1,269 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.editor;
+
+import java.beans.PropertyChangeEvent;
+
+import javax.swing.event.ListDataEvent;
+import javax.swing.event.ListDataListener;
+
+import org.adempiere.webui.apps.AEnv;
+import org.adempiere.webui.component.ListItem;
+import org.adempiere.webui.component.Listbox;
+import org.adempiere.webui.event.ContextMenuEvent;
+import org.adempiere.webui.event.ContextMenuListener;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.compiere.grid.ed.ValuePreference;
+import org.compiere.model.GridField;
+import org.compiere.model.Lookup;
+import org.compiere.model.MRole;
+import org.compiere.util.CLogger;
+import org.compiere.util.DisplayType;
+import org.compiere.util.Env;
+import org.compiere.util.KeyNamePair;
+import org.compiere.util.ValueNamePair;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.Events;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 12, 2007
+ * @version $Revision: 0.10 $
+ */
+public class WTableDirEditor extends WEditor implements ListDataListener,
+ContextMenuListener
+{
+ public final String[] LISTENER_EVENTS = {Events.ON_SELECT};
+
+ private static final CLogger logger;
+
+ static
+ {
+ logger = CLogger.getCLogger(WTableDirEditor.class);
+ }
+
+ private Lookup lookup;
+ private Listbox listbox;
+ private Object oldValue;
+ private WEditorPopupMenu popupMenu;
+
+ public WTableDirEditor(GridField gridField)
+ {
+ super(new Listbox(), gridField);
+ listbox = (Listbox)super.component;
+ lookup = gridField.getLookup();
+ init();
+ }
+
+ /**
+ * Constructor for use if a grid field is unavailable
+ *
+ * @param lookup Store of selectable data
+ * @param label column name (not displayed)
+ * @param description description of component
+ * @param mandatory whether a selection must be made
+ * @param readonly whether or not the editor is read only
+ * @param updateable whether the editor contents can be changed
+ */
+ public WTableDirEditor(Lookup lookup, String label, String description, boolean mandatory, boolean readonly, boolean updateable)
+ {
+ super(new Listbox(), label, description, mandatory, readonly, updateable);
+
+ if (lookup == null)
+ {
+ throw new IllegalArgumentException("Lookup cannot be null");
+ }
+
+ this.listbox = (Listbox)super.component;
+ this.lookup = lookup;
+ super.setColumnName(lookup.getColumnName());
+ init();
+ }
+
+ private void init()
+ {
+ listbox.setRows(0);
+ listbox.setMultiple(false);
+ listbox.setMold("select");
+ listbox.setWidth("200px");
+ listbox.addPropertyChangeListener(this);
+
+ boolean zoom= false;
+ if (lookup != null)
+ {
+ lookup.addListDataListener(this);
+
+ if ((lookup.getDisplayType() == DisplayType.List && Env.getContextAsInt(Env.getCtx(), "#AD_Role_ID") == 0)
+ || lookup.getDisplayType() != DisplayType.List)
+ {
+ zoom= true;
+ }
+ lookup.refresh();
+ refreshList();
+ }
+
+ popupMenu = new WEditorPopupMenu(zoom, true, true);
+ listbox.setContext(popupMenu.getId());
+ }
+
+ @Override
+ public String getDisplay()
+ {
+
+ String display = null;
+ ListItem selItem = listbox.getSelectedItem();
+ if (selItem != null)
+ {
+ display = selItem.getLabel();
+ }
+ return display;
+ }
+
+ @Override
+ public Object getValue()
+ {
+ Object retVal = null;
+ ListItem selItem = listbox.getSelectedItem();
+ if (selItem != null)
+ {
+ retVal = selItem.getValue();
+ }
+ return retVal;
+ }
+
+ public void setValue(Object value)
+ {
+ if (value != null && (value instanceof Integer || value instanceof String))
+ {
+ listbox.setValue(value);
+
+ if (listbox.getSelectedIndex() == -1 && lookup != null)
+ {
+ lookup.refresh();
+ oldValue = value;
+ refreshList();
+ }
+ }
+ else
+ {
+ listbox.setValue(null);
+ }
+
+ oldValue = value;
+ }
+
+ private void refreshList()
+ {
+ if (listbox.getItemCount() > 0)
+ listbox.getItems().clear();
+
+ if (lookup != null)
+ {
+ int size = lookup.getSize();
+
+ for (int i = 0; i < size; i++)
+ {
+ Object obj = lookup.getElementAt(i);
+ if (obj instanceof KeyNamePair)
+ {
+ KeyNamePair lookupKNPair = (KeyNamePair) obj;
+ listbox.appendItem(lookupKNPair.getName(), lookupKNPair.getKey());
+ }
+ else if (obj instanceof ValueNamePair)
+ {
+ ValueNamePair lookupKNPair = (ValueNamePair) obj;
+ listbox.appendItem(lookupKNPair.getName(), lookupKNPair.getValue());
+ }
+ }
+ }
+
+ listbox.setValue(oldValue);
+ }
+
+ public void onEvent(Event event)
+ {
+ Object newValue = getValue();
+ ValueChangeEvent changeEvent = new ValueChangeEvent(this, this.getColumnName(), oldValue, newValue);
+ super.fireValueChange(changeEvent);
+ oldValue = newValue;
+ }
+
+ public String[] getEvents()
+ {
+ return LISTENER_EVENTS;
+ }
+
+ public void contentsChanged(ListDataEvent e)
+ {
+ refreshList();
+ }
+
+ public void intervalAdded(ListDataEvent e)
+ {}
+
+ public void intervalRemoved(ListDataEvent e)
+ {}
+
+ public WEditorPopupMenu getPopupMenu()
+ {
+ return popupMenu;
+ }
+
+ private void actionRefresh()
+ {
+ Object curValue = getValue();
+ if (lookup != null)
+ {
+ lookup.refresh();
+ refreshList();
+ setValue(curValue);
+ }
+ }
+
+ private void actionZoom()
+ {
+ AEnv.actionZoom(lookup, getValue());
+ }
+
+ public void onMenu(ContextMenuEvent evt)
+ {
+ if (WEditorPopupMenu.REQUERY_EVENT.equals(evt.getContextEvent()))
+ {
+ actionRefresh();
+ }
+ else if (WEditorPopupMenu.ZOOM_EVENT.equals(evt.getContextEvent()))
+ {
+ actionZoom();
+ }
+ else if (WEditorPopupMenu.PREFERENCE_EVENT.equals(evt.getContextEvent()))
+ {
+ if (MRole.getDefault().isShowPreference())
+ ValuePreference.start (this.getGridField(), getValue());
+ return;
+ }
+ }
+
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ if ("FieldValue".equals(evt.getPropertyName()))
+ {
+ setValue(evt.getNewValue());
+ }
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WUnknownEditor.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WUnknownEditor.java
new file mode 100644
index 0000000000..5d9c3ea2f9
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WUnknownEditor.java
@@ -0,0 +1,40 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.editor;
+
+import org.compiere.model.GridField;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 12, 2007
+ * @version $Revision: 0.10 $
+ */
+public class WUnknownEditor extends WStringEditor
+{
+ public WUnknownEditor(GridField gridField)
+ {
+ super(gridField);
+ init();
+ }
+
+ private void init()
+ {
+ super.textbox.setEnabled(false);
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WUrlEditor.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WUrlEditor.java
new file mode 100644
index 0000000000..0cdd1ca1fc
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WUrlEditor.java
@@ -0,0 +1,104 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.editor;
+
+import java.net.URL;
+
+import org.adempiere.webui.component.Urlbox;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.window.FDialog;
+import org.compiere.model.GridField;
+import org.compiere.util.Env;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.Events;
+
+public class WUrlEditor extends WEditor
+{
+ private static final String[] LISTENER_EVENTS = {Events.ON_CLICK, Events.ON_CHANGE};
+
+ private Urlbox urlbox;
+
+ public WUrlEditor(GridField gridField)
+ {
+ super(new Urlbox(), gridField);
+ this.urlbox = (Urlbox)super.component;
+ urlbox.setButtonImage("/images/Online16.gif");
+ }
+
+
+ @Override
+ public void setValue(Object value)
+ {
+ if (value == null)
+ {
+ urlbox.setText("");
+ }
+ else
+ {
+ urlbox.setText(String.valueOf(value));
+ }
+ }
+
+ @Override
+ public Object getValue()
+ {
+ return urlbox.getText();
+ }
+
+ @Override
+ public String getDisplay()
+ {
+ return urlbox.getText();
+ }
+
+ public void onEvent(Event event)
+ {
+ if (Events.ON_CHANGE.equals(event.getName()))
+ {
+ ValueChangeEvent changeEvent = new ValueChangeEvent(this, this.getColumnName(), urlbox.getText(), urlbox.getText());
+ fireValueChange(changeEvent);
+ }
+ else if (Events.ON_CLICK.equals(event.getName()))
+ {
+ String urlString =urlbox.getText();
+ String message = null;
+ if (urlString != null && urlString.length() > 0)
+ {
+ try
+ {
+ URL url = new URL(urlString);
+ Env.startBrowser(urlString);
+ return;
+ }
+ catch(Exception e)
+ {
+ message = e.getMessage();
+ }
+ }
+ FDialog.warn(0, this.getComponent(), "URLnotValid", message);
+
+ }
+ }
+
+ public String[] getEvents()
+ {
+ return LISTENER_EVENTS;
+ }
+
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WYesNoEditor.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WYesNoEditor.java
new file mode 100644
index 0000000000..e3aa462e04
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WYesNoEditor.java
@@ -0,0 +1,125 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.editor;
+
+import java.beans.PropertyChangeEvent;
+import java.util.logging.Level;
+
+import org.adempiere.webui.component.Checkbox;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.compiere.model.GridField;
+import org.compiere.util.CLogger;
+import org.compiere.util.Env;
+import org.compiere.util.Msg;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.Events;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 11, 2007
+ * @version $Revision: 0.10 $
+ */
+public class WYesNoEditor extends WEditor
+{
+ public final String[] LISTENER_EVENTS = {Events.ON_CHECK};
+ private static final CLogger logger;
+
+ static
+ {
+ logger = CLogger.getCLogger(WYesNoEditor.class);
+ }
+
+ private Checkbox checkbox;
+ private boolean oldValue = false;
+
+ public WYesNoEditor(GridField gridField)
+ {
+ super(new Checkbox(), gridField);
+ checkbox = (Checkbox)super.component;
+ init();
+ }
+
+ private void init()
+ {
+ super.label.setValue("");
+ super.label.setTooltiptext("");
+ checkbox.setLabel(gridField.getHeader());
+ }
+
+ public void onEvent(Event event)
+ {
+ Boolean newValue = (Boolean)getValue();
+ ValueChangeEvent changeEvent = new ValueChangeEvent(this, this.getColumnName(), oldValue, newValue);
+ super.fireValueChange(changeEvent);
+ oldValue = newValue;
+ }
+
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ if (evt.getPropertyName().equals(org.compiere.model.GridField.PROPERTY))
+ {
+ setValue(evt.getNewValue());
+ }
+ }
+
+ @Override
+ public String getDisplay()
+ {
+ String display = checkbox.isChecked() ? "Y" : "N";
+ return Msg.translate(Env.getCtx(), display);
+ }
+
+ @Override
+ public Object getValue()
+ {
+ return new Boolean(checkbox.isChecked());
+ }
+
+ @Override
+ public void setValue(Object value)
+ {
+ if (value == null || value instanceof Boolean)
+ {
+ Boolean val = ((value == null) ? false
+ : (Boolean) value);
+ checkbox.setChecked(val);
+ oldValue = val;
+ }
+ else if (value instanceof String)
+ {
+ Boolean val = value.equals("Y");
+ checkbox.setChecked(val);
+ oldValue = val;
+ }
+ else
+ {
+ logger.log(Level.SEVERE,
+ "New field value of unknown type, Type: "
+ + value.getClass()
+ + ", Value: " + value);
+ checkbox.setChecked(false);
+ }
+ }
+
+ public String[] getEvents()
+ {
+ return LISTENER_EVENTS;
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WebEditorFactory.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WebEditorFactory.java
new file mode 100644
index 0000000000..91dc93ac71
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/editor/WebEditorFactory.java
@@ -0,0 +1,142 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.editor;
+
+import org.compiere.model.GridField;
+import org.compiere.model.MLocationLookup;
+import org.compiere.model.MLocatorLookup;
+import org.compiere.util.CLogger;
+import org.compiere.util.DisplayType;
+import org.compiere.util.Env;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 12, 2007
+ * @version $Revision: 0.10 $
+ */
+public class WebEditorFactory
+{
+
+ private final static CLogger logger;
+
+ static
+ {
+ logger = CLogger.getCLogger(WebEditorFactory.class);
+ }
+
+ public static WEditor getEditor(GridField gridField, boolean tableEditor)
+ {
+ if (gridField == null)
+ {
+ return null;
+ }
+
+ WEditor editor = null;
+ int displayType = gridField.getDisplayType();
+ int WindowNo = gridField.getWindowNo();
+
+ /** Not a Field */
+ if (gridField.isHeading())
+ {
+ return null;
+ }
+
+ /** String (clear/password) */
+ if (displayType == DisplayType.String
+ || displayType == DisplayType.PrinterName
+ || (tableEditor && (displayType == DisplayType.Text || displayType == DisplayType.TextLong)) )
+ {
+ if (gridField.isEncryptedField())
+ {
+ editor = new WPasswordEditor(gridField);
+ }
+ else
+ {
+ editor = new WStringEditor(gridField);
+ }
+ }
+ /** Number */
+ else if (DisplayType.isNumeric(displayType))
+ {
+ editor = new WNumberEditor(gridField);
+ }
+
+ /** YesNo */
+ else if (displayType == DisplayType.YesNo)
+ {
+ editor = new WYesNoEditor(gridField);
+ }
+
+ /** Text */
+ else if (displayType == DisplayType.Text || displayType == DisplayType.Memo || displayType == DisplayType.TextLong)
+ {
+ editor = new WStringEditor(gridField);
+ }
+
+ /** Date */
+ else if (DisplayType.isDate(displayType))
+ {
+ editor = new WDateEditor(gridField);
+ }
+
+ /** Button */
+ else if (displayType == DisplayType.Button)
+ {
+ editor = new WButtonEditor(gridField);
+ }
+
+ /** Table Direct */
+ else if (displayType == DisplayType.TableDir ||
+ displayType == DisplayType.Table || displayType == DisplayType.List
+ || displayType == DisplayType.ID )
+ {
+ boolean integralValue = (displayType == DisplayType.TableDir || displayType == DisplayType.ID);
+ editor = new WTableDirEditor(gridField);
+
+ }
+
+ else if (displayType == DisplayType.URL)
+ {
+ editor = new WUrlEditor(gridField);
+ }
+
+ else if (displayType == DisplayType.Search)
+ {
+ editor = new WSearchEditor(gridField);
+ }
+
+ else if (displayType == DisplayType.Location)
+ {
+ editor = new WLocationEditor(gridField.getColumnName(),gridField.isMandatory(false),gridField.isReadOnly(),gridField.isUpdateable(),
+ (MLocationLookup)gridField.getLookup());
+ }
+ else if (displayType == DisplayType.Locator)
+ {
+ editor = new WLocatorEditor(gridField.getColumnName(), gridField.isMandatory(false),
+ gridField.isReadOnly(), gridField.isUpdateable(),
+ (MLocatorLookup)gridField.getLookup());
+ }
+ else
+ {
+ editor = new WUnknownEditor(gridField);
+ }
+
+ return editor;
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/ActionEvent.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/ActionEvent.java
new file mode 100644
index 0000000000..96b28e6329
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/ActionEvent.java
@@ -0,0 +1,80 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.event;
+
+/**
+ * ActionEvent represents events associated with no data change.
+ *
+ * @author Niraj Sohun
+ * @date Jul 25, 2007
+ */
+
+public class ActionEvent
+{
+ /**
+ * The object on which the Event initially occurred.
+ */
+ protected Object source;
+
+ /**
+ * Name of the property that changed. May be null, if not known.
+ */
+ private String propertyName;
+
+ /**
+ * Name of event (ON_CLICK, ...)
+ */
+ private String eventName;
+
+ /**
+ * Constructor
+ * @param source - event source
+ * @param propertyName - name of property that changed
+ * @param eventName - name of event
+ */
+ public ActionEvent(Object source, String propertyName, String eventName)
+ {
+ this.source = source;
+ this.propertyName = propertyName;
+ this.eventName = eventName;
+ }
+
+ /**
+ * returns name of property that changed
+ */
+ public String getPropertyName()
+ {
+ return propertyName;
+ }
+
+ /**
+ * returns source of event
+ */
+ public Object getSource()
+ {
+ return source;
+ }
+
+ /**
+ * returns name of event
+ */
+ public String getEventName()
+ {
+ return eventName;
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/ActionListener.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/ActionListener.java
new file mode 100644
index 0000000000..26c017c11f
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/ActionListener.java
@@ -0,0 +1,30 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.event;
+
+/**
+ * ActionListener handles events associated with no data change.
+ *
+ * @author Niraj Sohun
+ * @date Jul 25, 2007
+ */
+
+public interface ActionListener
+{
+ void actionPerformed(ActionEvent event);
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/ContextMenuEvent.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/ContextMenuEvent.java
new file mode 100644
index 0000000000..5845ba1f9b
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/ContextMenuEvent.java
@@ -0,0 +1,39 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.event;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 10, 2007
+ * @version $Revision: 0.10 $
+ */
+public class ContextMenuEvent
+{
+ private String contextEvent;
+
+ public ContextMenuEvent(String event)
+ {
+ this.contextEvent = event;
+ }
+
+ public String getContextEvent()
+ {
+ return contextEvent;
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/ContextMenuListener.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/ContextMenuListener.java
new file mode 100644
index 0000000000..1be5771b01
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/ContextMenuListener.java
@@ -0,0 +1,29 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.event;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 10, 2007
+ * @version $Revision: 0.10 $
+ */
+public interface ContextMenuListener
+{
+ public void onMenu(ContextMenuEvent evt);
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/MenuListener.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/MenuListener.java
new file mode 100644
index 0000000000..d15b2f6488
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/MenuListener.java
@@ -0,0 +1,29 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.event;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public interface MenuListener
+{
+ public void onMenuSelected(int menuId);
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/TableValueChangeEvent.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/TableValueChangeEvent.java
new file mode 100644
index 0000000000..05d594647b
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/TableValueChangeEvent.java
@@ -0,0 +1,73 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.event;
+
+/**
+ * An event encapsulating a change in a Table.
+ * The event details the object that changed, it's position in the table
+ * and the changed value.
+ *
+ * @author Andrew Kimball
+ */
+public class TableValueChangeEvent extends ValueChangeEvent
+{
+ /** the row on which the event occurred */
+ private int m_row;
+ /** the column on which the event occurred */
+ private int m_column;
+
+ /**
+ * Constructor for the event.
+ *
+ * @param source The object that changed
+ * @param propertyName The column name of the changed object
+ * @param row The row of the changed object
+ * @param column The column of the changed object
+ * @param oldValue The new value of the object
+ * @param newValue The old value of the object (often just a copy of the new value)
+ */
+ public TableValueChangeEvent(Object source, String propertyName,
+ int row, int column,
+ Object oldValue, Object newValue)
+ {
+ super(source, propertyName, oldValue, newValue);
+ this.m_row = row;
+ this.m_column = column;
+ }
+
+ /**
+ * Get the column index for the changed value
+ *
+ * @return the index of the column at which the change occurred
+ */
+ public int getColumn()
+ {
+ return m_column;
+ }
+
+ /**
+ * Get the row index for the changed value
+ *
+ * @return the index of the row at which the change occurred
+ */
+ public int getRow()
+ {
+ return m_row;
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/TableValueChangeListener.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/TableValueChangeListener.java
new file mode 100644
index 0000000000..3ad954455e
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/TableValueChangeListener.java
@@ -0,0 +1,37 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.event;
+
+/**
+ * Interface specifying the functions
+ * that must be implemented to listen for a TableValueChangeEvent event
+ *
+ * @author Andrew Kimball
+ */
+public interface TableValueChangeListener
+{
+ /**
+ * Respond to a TableValueChangeEvent event
+ * Notifies this listener that an event has occurred.
+ * To get the event, you have to register it first by use of
+ * {@link org.adempiere.webui.component.WListItemRenderer#addTableValueChangeListener(TableValueChangeListener)}
+ *
+ * @param event The event that has occurred
+ */
+ public void tableValueChange(TableValueChangeEvent event);
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/ToolbarListener.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/ToolbarListener.java
new file mode 100644
index 0000000000..92d2082a21
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/ToolbarListener.java
@@ -0,0 +1,53 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.event;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public interface ToolbarListener
+{
+ public void onIgnore();
+
+ public void onNew();
+
+ public void onEdit();
+
+ public void onFirst();
+
+ public void onLast();
+
+ public void onNext();
+
+ public void onPrevious();
+
+ public void onParentRecord();
+
+ public void onDetailRecord();
+
+ public void onRefresh();
+
+ public void onExit();
+
+ public void onPrint();
+
+ public void onReport();
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/ValueChangeEvent.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/ValueChangeEvent.java
new file mode 100644
index 0000000000..8aeac44ca8
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/ValueChangeEvent.java
@@ -0,0 +1,77 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.event;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 10, 2007
+ * @version $Revision: 0.10 $
+ */
+public class ValueChangeEvent
+{
+
+ /**
+ * The object on which the Event initially occurred.
+ */
+ protected Object source;
+
+ /**
+ * name of the property that changed. May be null, if not known.
+ */
+ private String propertyName;
+
+ /**
+ * New value for property. May be null if not known.
+ */
+ private Object newValue;
+
+ /**
+ * Previous value for property. May be null if not known.
+ */
+ private Object oldValue;
+
+ public ValueChangeEvent(Object source, String propertyName,
+ Object oldValue, Object newValue)
+ {
+ this.source = source;
+ this.propertyName = propertyName;
+ this.newValue = newValue;
+ this.oldValue = oldValue;
+ }
+
+ public Object getNewValue()
+ {
+ return newValue;
+ }
+
+ public Object getOldValue()
+ {
+ return oldValue;
+ }
+
+ public String getPropertyName()
+ {
+ return propertyName;
+ }
+
+ public Object getSource()
+ {
+ return source;
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/ValueChangeListener.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/ValueChangeListener.java
new file mode 100644
index 0000000000..2f0f1e494c
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/ValueChangeListener.java
@@ -0,0 +1,29 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.event;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 10, 2007
+ * @version $Revision: 0.10 $
+ */
+public interface ValueChangeListener
+{
+ public void valueChange(ValueChangeEvent evt);
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/WTableModelEvent.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/WTableModelEvent.java
new file mode 100644
index 0000000000..ab7c45c454
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/WTableModelEvent.java
@@ -0,0 +1,137 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.event;
+
+import org.zkoss.zul.ListModel;
+import org.zkoss.zul.event.ListDataEvent;
+
+/**
+ * @author andy
+ *
+ */
+public class WTableModelEvent extends ListDataEvent
+{
+
+ /** Specifies all rows. */
+ public static final int ALL_ROWS = -1;
+ /** Specifies all columns in a row or rows. */
+ public static final int ALL_COLUMNS = -1;
+ /** Identifies the header row. */
+ public static final int HEADER_ROW = -1;
+
+ //
+ // Instance Variables
+ //
+ protected int m_column;
+
+ /**
+ * All row data in the table has changed, listeners should discard any state
+ * that was based on the rows and requery the TableModel
to
+ * get the new row count and all the appropriate values. The
+ * WListbox
will repaint the entire visible region on receiving
+ * this event, querying the model for the cell values that are visible. The
+ * structure of the table ie, the column names, types and order have not
+ * changed.
+ *
+ * @param source The list model that has changed
+ */
+ public WTableModelEvent(ListModel source)
+ {
+ // Use Integer.MAX_VALUE instead of getRowCount() in case rows were
+ // deleted.
+ this(source, 0, Integer.MAX_VALUE, ALL_COLUMNS, CONTENTS_CHANGED);
+ }
+
+ /**
+ * This row of data has been updated. To denote the arrival of a completely
+ * new table with a different structure use HEADER_ROW
as the
+ * value for the row
.
+ *
+ * @param source The list model that has changed
+ * @param row Index of the affected row
+ */
+ public WTableModelEvent(ListModel source, int row)
+ {
+ this(source, row, row, ALL_COLUMNS, CONTENTS_CHANGED);
+ }
+
+ /**
+ * The cell in [row ,column ] has been updated.
+ *
+ * @param source The list model that has changed
+ * @param row Index of the affected row
+ * @param column Index of the affected column
+ */
+ public WTableModelEvent(ListModel source, int row, int column)
+ {
+ this(source, row, row, column, CONTENTS_CHANGED);
+ }
+
+ /**
+ * The cells from (firstRow, column) to (lastRow, column) have been changed.
+ * The column refers to the column index of the cell in the model's
+ * co-ordinate system. When column is ALL_COLUMNS, all cells in the
+ * specified range of rows are considered changed.
+ *
+ * The type should be one of: CONTENTS_CHANGED, INTERVAL_ADDED, INTERVAL_REMOVED.
+ *
+ * @param source The list model that has changed
+ * @param firstRow Index of the first affected row
+ * @param lastRow Index of the last affected row
+ * @param column Index of the affected column
+ * @param type the type of change
+ */
+ public WTableModelEvent(ListModel source, int firstRow, int lastRow,
+ int column, int type)
+ {
+ super(source, type, firstRow, lastRow);
+
+ m_column = column;
+ }
+
+ /**
+ * Returns the column for the event. If the return value is ALL_COLUMNS
it
+ * means every column in the specified row has been affected.
+ *
+ * @return the affected column, or {@link #ALL_COLUMNS}
+ */
+ public int getColumn()
+ {
+ return m_column;
+ };
+
+ /**
+ * Obtain the index of the first affected row
+ *
+ * @return the index of the first affected row
+ */
+ public int getFirstRow()
+ {
+ return getIndex0();
+ }
+
+ /**
+ * Obtain the index of the last affected row
+ *
+ * @return the index of the last affected row
+ */
+ public int getLastRow()
+ {
+ return getIndex1();
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/WTableModelListener.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/WTableModelListener.java
new file mode 100644
index 0000000000..f43dec6e47
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/event/WTableModelListener.java
@@ -0,0 +1,37 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.event;
+
+/**
+ * WTableModelListener defines the interface for an object that listens
+ * to changes in a WTableModel.
+ *
+ * @author Andrew Kimball
+ *
+ * @see WTableModelEvent
+ */
+public interface WTableModelListener
+{
+ /**
+ * This fine grain notification tells listeners the exact range
+ * of cells, rows, or columns that changed.
+ *
+ * @param event table model event
+ */
+ public void tableChanged(WTableModelEvent event);
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/exception/ApplicationException.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/exception/ApplicationException.java
new file mode 100644
index 0000000000..052ea5e872
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/exception/ApplicationException.java
@@ -0,0 +1,39 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.exception;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class ApplicationException extends RuntimeException
+{
+ private static final long serialVersionUID = 1L;
+
+ public ApplicationException(String msg)
+ {
+ super(msg);
+ }
+
+ public ApplicationException(String msg, Exception ex)
+ {
+ super(msg, ex);
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/grid/WBPartner.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/grid/WBPartner.java
new file mode 100644
index 0000000000..63237aedbe
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/grid/WBPartner.java
@@ -0,0 +1,534 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.grid;
+
+import java.util.logging.Level;
+
+import org.adempiere.webui.component.BackgroundColours;
+import org.adempiere.webui.component.ConfirmPanel;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.ListItem;
+import org.adempiere.webui.component.Listbox;
+import org.adempiere.webui.component.Textbox;
+import org.adempiere.webui.component.VerticalBox;
+import org.adempiere.webui.component.Window;
+import org.adempiere.webui.editor.WLocationEditor;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.event.ValueChangeListener;
+import org.adempiere.webui.window.FDialog;
+import org.compiere.model.MBPartner;
+import org.compiere.model.MBPartnerLocation;
+import org.compiere.model.MLocation;
+import org.compiere.model.MLocationLookup;
+import org.compiere.model.MRole;
+import org.compiere.model.MUser;
+import org.compiere.util.CLogger;
+import org.compiere.util.DB;
+import org.compiere.util.Env;
+import org.compiere.util.KeyNamePair;
+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.Hbox;
+import org.zkoss.zul.Separator;
+
+/**
+ * Business Partner : Based on VBPartner
+ *
+ * @author Niraj Sohun
+ * Aug 15, 2007
+ *
+ */
+
+public class WBPartner extends Window implements EventListener, ValueChangeListener
+{
+ private static final long serialVersionUID = 1L;
+ private static CLogger log = CLogger.getCLogger(WBPartner.class);
+
+ private int m_WindowNo;
+
+ /** The Partner */
+ private MBPartner m_partner = null;
+
+ /** The Location */
+ private MBPartnerLocation m_pLocation = null;
+
+ /** The User */
+ private MUser m_user = null;
+
+ /** Read Only */
+ private boolean m_readOnly = false;
+
+ private Object[] m_greeting;
+
+ private Textbox fValue = new Textbox();
+ private Listbox fGreetingBP = new Listbox();
+ private Textbox fName = new Textbox();
+ private Textbox fName2 = new Textbox();
+ private Textbox fContact = new Textbox();
+ private Listbox fGreetingC = new Listbox();
+ private Textbox fTitle = new Textbox();
+ private Textbox fEMail = new Textbox();
+ private Textbox fPhone = new Textbox();
+ private Textbox fPhone2 = new Textbox();
+ private Textbox fFax = new Textbox();
+
+ private WLocationEditor fAddress;/* = new WLocationDialog();*/
+
+ private VerticalBox centerPanel = new VerticalBox();
+
+ private ConfirmPanel confirmPanel = new ConfirmPanel(true, false, false, false, false, false);
+
+ /**
+ * Constructor.
+ * Requires call loadBPartner
+ * @param frame parent
+ * @param WindowNo Window No
+ */
+
+ public WBPartner(int WindowNo)
+ {
+ super();
+
+ m_WindowNo = WindowNo;
+ m_readOnly = !MRole.getDefault().canUpdate(
+ Env.getAD_Client_ID(Env.getCtx()), Env.getAD_Org_ID(Env.getCtx()),
+ MBPartner.Table_ID, 0, false);
+ log.info("R/O=" + m_readOnly);
+
+ try
+ {
+ jbInit();
+ }
+ catch(Exception ex)
+ {
+ log.log(Level.SEVERE, ex.getMessage());
+ }
+
+ initBPartner();
+
+ } // WBPartner
+
+ /**
+ * Static Init
+ * @throws Exception
+ */
+
+ void jbInit() throws Exception
+ {
+ this.setWidth("350px");
+ this.setBorder("normal");
+ this.setClosable(true);
+ this.setTitle("Business Partner");
+ this.setAttribute("mode", "modal");
+ this.appendChild(centerPanel);
+ this.appendChild(confirmPanel);
+
+ confirmPanel.addActionListener(Events.ON_CLICK, this);
+ }
+
+ /**
+ * Dynamic Init
+ */
+ private void initBPartner()
+ {
+ // Get Data
+ m_greeting = fillGreeting();
+
+ // Value
+ fValue.addEventListener(Events.ON_CHANGE , this);
+ createLine (fValue, "Value", true);
+
+ // Greeting Business Partner
+ fGreetingBP.setMold("select");
+ fGreetingBP.setRows(0);
+
+ for (int i = 0; i < m_greeting.length; i++)
+ fGreetingBP.appendItem(m_greeting[i].toString(), m_greeting[i]);
+ createLine (fGreetingBP, "Greeting", false);
+
+ // Name
+ fName.addEventListener(Events.ON_CLICK, this);
+ createLine (fName, "Name", false)/*.setFontBold(true)*/;
+
+ // Name2
+ createLine (fName2, "Name2", false);
+
+ // Contact
+ createLine (fContact, "Contact", true)/*.setFontBold(true)*/;
+
+ // Greeting Contact
+ fGreetingC.setMold("select");
+ fGreetingC.setRows(0);
+
+ for (int i = 0; i < m_greeting.length; i++)
+ fGreetingC.appendItem(m_greeting[i].toString(), m_greeting[i]);
+
+ createLine (fGreetingC, "Greeting", false);
+
+ // Title
+ createLine(fTitle, "Title", false);
+
+ // Email
+ createLine (fEMail, "EMail", false);
+
+ // Location
+ boolean ro = m_readOnly;
+
+ if (!ro)
+ ro = !MRole.getDefault().canUpdate(
+ Env.getAD_Client_ID(Env.getCtx()), Env.getAD_Org_ID(Env.getCtx()),
+ MBPartnerLocation.Table_ID, 0, false);
+
+ if (!ro)
+ ro = !MRole.getDefault().canUpdate(
+ Env.getAD_Client_ID(Env.getCtx()), Env.getAD_Org_ID(Env.getCtx()),
+ MLocation.Table_ID, 0, false);
+
+ fAddress = new WLocationEditor("C_Location_ID", false, ro, true,
+ new MLocationLookup (Env.getCtx(), m_WindowNo));
+ fAddress.addValueChangeListner(this);
+ fAddress.setValue (null);
+ createLine (fAddress.getComponent(), "C_Location_ID", true)/*.setFontBold(true)*/;
+
+ // Phone
+ createLine (fPhone, "Phone", true);
+
+ // Phone2
+ createLine (fPhone2, "Phone2", false);
+
+ // Fax
+ createLine (fFax, "Fax", false);
+ } // initBPartner
+
+ /**
+ * Create Line
+ * @param field field
+ * @param title label value
+ * @param addSpace add more space
+ * @return label
+ */
+
+ private Label createLine (Component field, String title, boolean addSpace)
+ {
+ Hbox hbox = new Hbox();
+
+ hbox.setWidth("100%");
+ hbox.setWidths("30%, 70%");
+
+ Label label = new Label(Msg.translate(Env.getCtx(), title));
+ hbox.appendChild(label);
+
+ hbox.appendChild(field);
+
+ centerPanel.appendChild(hbox);
+ centerPanel.appendChild(new Separator());
+
+ return label;
+ } // createLine
+
+ /**
+ * Fill Greeting
+ * @return KeyNamePair Array of Greetings
+ */
+
+ private Object[] fillGreeting()
+ {
+ String sql = "SELECT C_Greeting_ID, Name FROM C_Greeting WHERE IsActive='Y' ORDER BY 2";
+ sql = MRole.getDefault().addAccessSQL(sql, "C_Greeting", MRole.SQL_NOTQUALIFIED, MRole.SQL_RO);
+
+ return DB.getKeyNamePairs(sql, true);
+ } // fillGreeting
+
+ /**
+ * Search m_greeting for key
+ * @param key C_Greeting_ID
+ * @return Greeting
+ */
+
+ private KeyNamePair getGreeting (int key)
+ {
+ for (int i = 0; i < m_greeting.length; i++)
+ {
+ KeyNamePair p = (KeyNamePair)m_greeting[i];
+ if (p.getKey() == key)
+ return p;
+ }
+
+ return new KeyNamePair(-1, " ");
+ } // getGreeting
+
+ /**
+ * Load BPartner
+ * @param C_BPartner_ID - existing BPartner or 0 for new
+ * @return true if loaded
+ */
+
+ public boolean loadBPartner (int C_BPartner_ID)
+ {
+ log.config("C_BPartner_ID=" + C_BPartner_ID);
+
+ // New bpartner
+ if (C_BPartner_ID == 0)
+ {
+ m_partner = null;
+ m_pLocation = null;
+ m_user = null;
+ return true;
+ }
+
+ m_partner = new MBPartner (Env.getCtx(), C_BPartner_ID, null);
+
+ if (m_partner.get_ID() == 0)
+ {
+ FDialog.error(m_WindowNo, this, "BPartnerNotFound");
+ return false;
+ }
+
+ // BPartner - Load values
+ fValue.setText(m_partner.getValue());
+
+ KeyNamePair keynamepair = getGreeting(m_partner.getC_Greeting_ID());
+
+ for (int i = 0; i < fGreetingBP.getItemCount(); i++)
+ {
+ ListItem listitem = fGreetingBP.getItemAtIndex(i);
+ KeyNamePair compare = (KeyNamePair)listitem.getValue();
+
+ if (compare == keynamepair)
+ {
+ fGreetingBP.setSelectedIndex(i);
+ break;
+ }
+ }
+
+ fName.setText(m_partner.getName());
+ fName2.setText(m_partner.getName2());
+
+ // Contact - Load values
+ m_pLocation = m_partner.getLocation(
+ Env.getContextAsInt(Env.getCtx(), m_WindowNo, "C_BPartner_Location_ID"));
+
+ if (m_pLocation != null)
+ {
+ int location = m_pLocation.getC_Location_ID();
+ fAddress.setValue (new Integer(location));
+
+ fPhone.setText(m_pLocation.getPhone());
+ fPhone2.setText(m_pLocation.getPhone2());
+ fFax.setText(m_pLocation.getFax());
+ }
+ // User - Load values
+ m_user = m_partner.getContact(
+ Env.getContextAsInt(Env.getCtx(), m_WindowNo, "AD_User_ID"));
+
+ if (m_user != null)
+ {
+ keynamepair = getGreeting(m_user.getC_Greeting_ID());
+
+ for (int i = 0; i < fGreetingC.getItemCount(); i++)
+ {
+ ListItem listitem = fGreetingC.getItemAtIndex(i);
+ KeyNamePair compare = (KeyNamePair)listitem.getValue();
+
+ if (compare == keynamepair)
+ {
+ fGreetingC.setSelectedIndex(i);
+ break;
+ }
+ }
+
+ fContact.setText(m_user.getName());
+ fTitle.setText(m_user.getTitle());
+ fEMail.setText(m_user.getEMail());
+
+ fPhone.setText(m_user.getPhone());
+ fPhone2.setText(m_user.getPhone2());
+ fFax.setText(m_user.getFax());
+ }
+ return true;
+ } // loadBPartner
+
+ /**
+ * Save.
+ * Checks mandatory fields and saves Partner, Contact and Location
+ * @return true if saved
+ */
+
+ private boolean actionSave()
+ {
+ log.config("");
+
+ // Check Mandatory fields
+ if (fName.getText().equals(""))
+ {
+ fName.setStyle(BackgroundColours.ERROR);
+ return false;
+ }
+ else
+ fName.setStyle(BackgroundColours.MANDATORY);
+
+ if (fAddress.getC_Location_ID() == 0)
+ {
+ //fAddress.setBackground(Color)(BackgroundColours.ERROR);
+ return false;
+ }
+ //else
+ //fAddress.setBackground(AdempierePLAF.getFieldBackground_Mandatory());
+
+ // ***** Business Partner *****
+
+ if (m_partner == null)
+ {
+ int AD_Client_ID = Env.getAD_Client_ID(Env.getCtx());
+ m_partner = MBPartner.getTemplate(Env.getCtx(), AD_Client_ID);
+ boolean isSOTrx = !"N".equals(Env.getContext(Env.getCtx(), m_WindowNo, "IsSOTrx"));
+ m_partner.setIsCustomer (isSOTrx);
+ m_partner.setIsVendor (!isSOTrx);
+ }
+
+ // Check Value
+
+ String value = fValue.getText();
+
+ if (value == null || value.length() == 0)
+ {
+ // get Table Document No
+ value = DB.getDocumentNo (Env.getAD_Client_ID(Env.getCtx()), "C_BPartner", null);
+ fValue.setText(value);
+ }
+
+ m_partner.setValue(fValue.getText());
+
+ m_partner.setName(fName.getText());
+ m_partner.setName2(fName2.getText());
+
+ ListItem listitem = fGreetingBP.getSelectedItem();
+ KeyNamePair p = (KeyNamePair)listitem.getValue();
+
+ if (p != null && p.getKey() > 0)
+ m_partner.setC_Greeting_ID(p.getKey());
+ else
+ m_partner.setC_Greeting_ID(0);
+
+ if (m_partner.save())
+ log.fine("C_BPartner_ID=" + m_partner.getC_BPartner_ID());
+ else
+ FDialog.error(m_WindowNo, this, "BPartnerNotSaved");
+
+ // ***** Business Partner - Location *****
+
+ if (m_pLocation == null)
+ m_pLocation = new MBPartnerLocation(m_partner);
+
+ m_pLocation.setC_Location_ID(fAddress.getC_Location_ID());
+
+ m_pLocation.setPhone(fPhone.getText());
+ m_pLocation.setPhone2(fPhone2.getText());
+ m_pLocation.setFax(fFax.getText());
+
+ if (m_pLocation.save())
+ log.fine("C_BPartner_Location_ID=" + m_pLocation.getC_BPartner_Location_ID());
+ else
+ FDialog.error(m_WindowNo, this, "BPartnerNotSaved", Msg.translate(Env.getCtx(), "C_BPartner_Location_ID"));
+
+ // ***** Business Partner - User *****
+
+ String contact = fContact.getText();
+ String email = fEMail.getText();
+
+ if (m_user == null && (contact.length() > 0 || email.length() > 0))
+ m_user = new MUser (m_partner);
+
+ if (m_user != null)
+ {
+ if (contact.length() == 0)
+ contact = fName.getText();
+
+ m_user.setName(contact);
+ m_user.setEMail(email);
+ m_user.setTitle(fTitle.getText());
+
+ listitem = fGreetingC.getSelectedItem();
+ p = (KeyNamePair)listitem.getValue();
+
+ if (p != null && p.getKey() > 0)
+ m_user.setC_Greeting_ID(p.getKey());
+ else
+ m_user.setC_Greeting_ID(0);
+
+ m_user.setPhone(fPhone.getText());
+ m_user.setPhone2(fPhone2.getText());
+ m_user.setFax(fFax.getText());
+
+ if (m_user.save())
+ log.fine("AD_User_ID=" + m_user.getAD_User_ID());
+ else
+ FDialog.error(m_WindowNo, this, "BPartnerNotSaved", Msg.translate(Env.getCtx(), "AD_User_ID"));
+ }
+ return true;
+ } // actionSave
+
+ /**
+ * Returns BPartner ID
+ * @return C_BPartner_ID (0 = not saved)
+ */
+
+ public int getC_BPartner_ID()
+ {
+ if (m_partner == null)
+ return 0;
+
+ return m_partner.getC_BPartner_ID();
+ } // getBPartner_ID
+
+ public void onEvent(Event e) throws Exception
+ {
+ if (m_readOnly)
+ this.detach();
+
+ // copy value
+
+ else if (e.getTarget() == fValue)
+ {
+ if (fName.getText() == null || fName.getText().length() == 0)
+ fName.setText(fValue.getText());
+ }
+ else if (e.getTarget() == fName)
+ {
+ if (fContact.getText() == null || fContact.getText().length() == 0)
+ fContact.setText(fName.getText());
+ }
+
+ // OK pressed
+ else if ((e.getTarget() == confirmPanel.getButton("Ok")) && actionSave())
+ this.detach();
+
+ // Cancel pressed
+ else if (e.getTarget() == confirmPanel.getButton("Cancel"))
+ this.detach();
+
+ }
+
+ public void valueChange(ValueChangeEvent evt)
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/ADForm.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/ADForm.java
new file mode 100755
index 0000000000..bdfbfddff8
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/ADForm.java
@@ -0,0 +1,247 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import java.util.logging.Level;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.adempiere.webui.component.Window;
+import org.adempiere.webui.exception.ApplicationException;
+import org.adempiere.webui.session.SessionManager;
+import org.compiere.model.MForm;
+import org.compiere.util.CLogger;
+import org.compiere.util.Env;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
+
+/**
+ * Adempeire Web UI custom form.
+ * The form is abstract, so specific types of custom form must be implemented
+ *
+ * @author Andrew Kimball
+ */
+public abstract class ADForm extends Window implements EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+
+ /** The class' logging enabler */
+ protected static final CLogger logger;
+
+ static
+ {
+ logger = CLogger.getCLogger(ADForm.class);
+ }
+
+ /** The form's title (for display purposes) */
+ private String m_title;
+ /** The unique identifier of the form type */
+ private int m_adFormId;
+ /** The identifying number of the window in which the form is housed */
+ protected int m_windowNo;
+
+ /**
+ * Constructor
+ *
+ * @param ctx the context into which the form is being placed
+ * @param adFormId the Adempiere form identifier
+ */
+ protected ADForm()
+ {
+ m_windowNo = SessionManager.getAppDesktop().registerWindow(this);
+ }
+
+ protected int getWindowNo()
+ {
+ return m_windowNo;
+ }
+
+ protected int getAdFormId()
+ {
+ return m_adFormId;
+ }
+
+ /**
+ * Initialise the form
+ *
+ * @param adFormId the Adempiere form identifier
+ * @param name the name of the Adempiere form
+ */
+
+ protected void init(int adFormId, String name)
+ {
+ if(adFormId <= 0)
+ {
+ throw new IllegalArgumentException("Form Id is invalid");
+ }
+
+ m_adFormId = adFormId;
+ m_title = name;
+
+ return;
+ }
+
+ /**
+ * Accessor for the form's title
+ *
+ * @return the title of the form
+ */
+ public String getTitle()
+ {
+ return m_title;
+ }
+
+
+ /**
+ * Convert the rich client class name for a form to its web UI equivalent
+ *
+ * @param originalName The full class path to convert
+ * @return the converted class name
+ */
+ private static String translateFormClassName(String originalName)
+ {
+ String modifiedName;
+ /* match any field containing the string ".compiere."
+ * Usually of the form "org.compiere.apps.form.".
+ * Although there are special cases which also need handling
+ */
+ final String regex = "(.*)\\.compiere\\.(.*\\.)V(\\w*)$";
+ //final String regex = "(.*)\\.compiere\\.(.*\\.)V(\\w*)$";
+ /*
+ * replacement string to translate class paths to the form
+ * "org.adempiere.webui.apps.form."
+ */
+ final String replacementPackage = ".adempiere.webui.";
+ /*
+ * replacement string to translate custom form class name from
+ * "V" to "W"
+ */
+ final String replacementPrefix = "W";
+ Pattern pattern = Pattern.compile(regex);
+ Matcher matcher = pattern.matcher(originalName);
+ int group = 1;
+
+ /*
+ * If no match is found throw an exception stating that the form
+ * has not been implemented in the webUI
+ */
+ if (matcher.find()== false)
+ {
+ // What to do with those that do not have .compiere. in it
+ throw new ApplicationException("The selected custom form '" +
+ originalName +
+ "' is not part of the core distribution and " +
+ "has not been implemented for the web based user interface");
+ }
+
+ /*
+ * reconstruct the name using the captured groups and the replacement strings
+ */
+ modifiedName = matcher.group(group++)
+ + replacementPackage
+ + matcher.group(group++)
+ + replacementPrefix
+ + matcher.group(group++);
+
+ return modifiedName;
+ }
+
+ /**
+ * Create a new form corresponding to the specified identifier
+ *
+ * @param adFormID The unique identifier for the form type
+ * @return The created form
+ */
+ public static ADForm openForm (int adFormID)
+ {
+ Object obj;
+ ADForm form;
+ String webClassName = "";
+ MForm mform = new MForm(Env.getCtx(), adFormID, null);
+ String richClassName = mform.getClassname();
+ String name = mform.getName();
+
+ if (mform.get_ID() == 0 || richClassName == null)
+ {
+ throw new ApplicationException("There is no form associated with the specified selection");
+ }
+ else
+ {
+
+ logger.info("AD_Form_ID=" + adFormID + " - Class=" + richClassName);
+
+ if ("org.compiere.apps.form.ArchiveViewer".equals(richClassName))
+ webClassName = "org.adempiere.webui.apps.form.WArchiveViewer"; // TEMP
+ else
+ webClassName = translateFormClassName(richClassName);
+
+ try
+ {
+ // Create instance w/o parameters
+ obj = Class.forName(webClassName).newInstance();
+ }
+ catch (Exception e)
+ {
+ throw new ApplicationException("The selected web user interface custom form '" +
+ webClassName +
+ "' is not accessible.");
+ }
+
+ try
+ {
+ if (obj instanceof ADForm)
+ {
+ form = (ADForm)obj;
+ form.init(adFormID, name);
+ return form;
+ }
+ else
+ {
+ throw new ApplicationException("The web user interface custom form '" +
+ webClassName +
+ "' cannot be displayed in the web user interface.");
+ }
+ }
+ catch (Exception ex)
+ {
+ logger.log(Level.SEVERE, "Class=" + webClassName + ", AD_Form_ID=" + adFormID, ex);
+ throw new ApplicationException("The web user interface custom form '" +
+ webClassName +
+ "' failed to initialise:" + ex);
+ }
+ }
+ } // openForm
+
+ /**
+ *
+ * @return false
+ */
+ public boolean isAsap()
+ {
+ return false;
+ }
+
+ /**
+ *
+ */
+ public void onEvent(Event arg0) throws Exception
+ {
+
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/ADTabpanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/ADTabpanel.java
new file mode 100644
index 0000000000..6484e5c207
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/ADTabpanel.java
@@ -0,0 +1,436 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import java.util.ArrayList;
+
+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.Tabpanel;
+import org.adempiere.webui.editor.WButtonEditor;
+import org.adempiere.webui.editor.WEditor;
+import org.adempiere.webui.editor.WEditorPopupMenu;
+import org.adempiere.webui.editor.WebEditorFactory;
+import org.adempiere.webui.event.ContextMenuListener;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.event.ValueChangeListener;
+import org.adempiere.webui.window.FDialog;
+import org.compiere.model.DataStatusEvent;
+import org.compiere.model.DataStatusListener;
+import org.compiere.model.GridField;
+import org.compiere.model.GridTab;
+import org.compiere.model.GridTable;
+import org.compiere.model.GridWindow;
+import org.compiere.util.CLogger;
+import org.compiere.util.Env;
+import org.compiere.util.Evaluatee;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zul.Image;
+
+/**
+ *
+ * This class is based on org.compiere.grid.GridController written by Jorg Janke.
+ * Changes have been brought for UI compatibility.
+ *
+ * @author Jorg Janke
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ *
+ */
+public class ADTabpanel extends Tabpanel implements Evaluatee, EventListener,
+DataStatusListener, ValueChangeListener
+{
+
+ private static final CLogger logger;
+
+ static
+ {
+ logger = CLogger.getCLogger(ADTabpanel.class);
+ }
+
+ private Image panelImage;
+
+ private GridTab gridTab;
+
+ private GridWindow gridWindow;
+
+ private ADWindowPanel windowPanel;
+
+ private int windowNo;
+
+ private Grid grid;
+
+ private ArrayList editors = new ArrayList();
+
+ private boolean editing;
+
+ public ADTabpanel()
+ {
+ init();
+ }
+
+ private void init()
+ {
+ initComponents();
+// this.appendChild(panelImage);
+// this.appendChild(grid);
+ }
+
+ private void initComponents()
+ {
+ grid = new Grid();
+ grid.setWidth("750px");
+
+ panelImage = new Image();
+// panelImage.setSrc("/images/loading.png");
+
+ }
+
+ public void init(ADWindowPanel winPanel, int windowNo, GridTab gridTab,
+ GridWindow gridWindow)
+ {
+ this.windowNo = windowNo;
+ this.gridWindow = gridWindow;
+ this.gridTab = gridTab;
+ this.windowPanel = winPanel;
+ gridTab.addDataStatusListener(this);
+ initGrid();
+ }
+
+ private void initGrid()
+ {
+ Rows rows = new Rows();
+ GridField fields[] = gridTab.getFields();
+ Row row = new Row();
+ for (int i = 0; i < fields.length; i++)
+ {
+ GridField field = fields[i];
+ if (field.isDisplayed())
+ {
+ if (!field.isSameLine())
+ {
+ if (row.getChildren().size() == 2)
+ {
+ row.appendChild(new Label(" "));
+ row.appendChild(new Label(" "));
+ }
+ rows.appendChild(row);
+ row = new Row();
+ }
+
+ WEditor comp = WebEditorFactory.getEditor(field, false);
+
+ if (comp != null) // Not heading
+ {
+ comp.setGridTab(this.getGridTab());
+ field.addPropertyChangeListener(comp);
+ editors.add(comp);
+ row.appendChild(comp.getLabel());
+ row.appendChild(comp.getComponent());
+
+ if (comp instanceof WButtonEditor)
+ {
+ ((WButtonEditor)comp).addActionListener(windowPanel);
+ }
+ else
+ {
+ comp.addValueChangeListner(this);
+ }
+
+ WEditorPopupMenu popupMenu = comp.getPopupMenu();
+
+ if (popupMenu != null)
+ {
+ popupMenu.addMenuListener((ContextMenuListener)comp);
+ this.appendChild(popupMenu);
+ }
+ }
+ }
+ }
+ if (row.getChildren().size() > 0)
+ {
+ if (row.getChildren().size() == 2)
+ {
+ row.appendChild(new Label(" "));
+ row.appendChild(new Label(" "));
+ }
+ rows.appendChild(row);
+ }
+ grid.appendChild(rows);
+
+ }
+
+ public void dynamicDisplay (int col)
+ {
+ if (!gridTab.isOpen())
+ {
+ return;
+ }
+
+ // Selective
+ if (col > 0)
+ {
+ GridField changedField = gridTab.getField(col);
+ String columnName = changedField.getColumnName();
+ ArrayList dependants = gridTab.getDependantFields(columnName);
+ logger.config("(" + gridTab.toString() + ") "
+ + columnName + " - Dependents=" + dependants.size());
+ if (dependants.size() == 0 && changedField.getCallout().length() > 0)
+ {
+ for (WEditor comp : editors)
+ {
+ if (columnName.equals(comp.getColumnName()))
+ {
+ boolean manMissing = false;
+ boolean noValue = changedField.getValue() == null || changedField.getValue().toString().length() == 0;
+ if (noValue && changedField.isEditable(true) && changedField.isMandatory(true))
+ {
+ manMissing = true;
+ }
+ comp.setBackground(manMissing || changedField.isError());
+ break;
+ }
+ }
+ return;
+ }
+ }
+
+ boolean noData = gridTab.getRowCount() == 0;
+ logger.config(gridTab.toString() + " - Rows=" + gridTab.getRowCount());
+ for (WEditor comp : editors)
+ {
+ GridField mField = comp.getGridField();
+ if (mField != null)
+ {
+ if (mField.isDisplayed(true)) // check context
+ {
+ if (!comp.isVisible())
+ {
+ comp.setVisible(true); // visibility
+ }
+ if (noData)
+ {
+ comp.setReadWrite(false);
+ }
+ else
+ {
+ boolean rw = mField.isEditable(true); // r/w - check Context
+ comp.setReadWrite(rw);
+ boolean manMissing = false;
+ if (rw && mField.getValue() == null && mField.isMandatory(true)) // check context
+ {
+ manMissing = true;
+ }
+ comp.setBackground(manMissing || mField.isError());
+ }
+ }
+ else if (comp.isVisible())
+ {
+ comp.setVisible(false);
+ }
+ }
+ } // all components
+
+ logger.config(gridTab.toString() + " - fini - " + (col<=0 ? "complete" : "seletive"));
+ } // dynamicDisplay
+
+ public String getDisplayLogic()
+ {
+ return gridTab.getDisplayLogic();
+ }
+
+ public String getTitle()
+ {
+ return gridTab.getName();
+ } // getTitle
+
+ /**
+ * @param variableName
+ */
+ public String get_ValueAsString(String variableName)
+ {
+ return Env.getContext(Env.getCtx(), windowNo, variableName);
+ } // get_ValueAsString
+
+ /**
+ * @return The tab level of this Tabpanel
+ */
+ public int getTabLevel()
+ {
+ return gridTab.getTabLevel();
+ }
+
+ public boolean isCurrent()
+ {
+ return gridTab != null ? gridTab.isCurrent() : false;
+ }
+
+ public int getWindowNo()
+ {
+ return windowNo;
+ }
+
+ public void query()
+ {
+ gridTab.query(false);
+ }
+
+ public void query (boolean onlyCurrentRows, int onlyCurrentDays, int maxRows)
+ {
+// gridTab.query(onlyCurrentRows, onlyCurrentDays, maxRows);
+ gridTab.query(false);
+ }
+
+ public GridTab getGridTab()
+ {
+ return gridTab;
+ }
+
+ public void refresh()
+ {
+ gridTab.dataRefresh();
+ }
+
+ public void activate(boolean activate)
+ {
+ if (!this.getChildren().contains(grid))
+ {
+ this.appendChild(grid);
+ }
+
+ grid.setVisible(activate);
+ }
+
+ public boolean isEditing()
+ {
+ return this.editing;
+ }
+
+ public void editRecord(boolean edit)
+ {
+ /* this.editing = edit;
+ for (Editor editor : editors)
+ {
+ editor.setEditing(edit);
+ }*/
+ }
+
+ public boolean isAsap()
+ {
+ return false;
+ }
+
+ public void onEvent(Event event)
+ {
+/* if (event == null)
+ return;
+
+ if (event.getTarget() == listView)
+ {
+ keyRecordId = listView.getSelectedIndex();
+
+ //Object value = gridTab.getValue(keyRecordId, keyColumnName);
+
+ //MQuery mquery = MQuery.getEqualQuery(keyColumnName, value);
+ }
+ else if (confirmPanel.getButton("Ok").equals(event.getTarget()))
+ {
+ gridTab.navigate(keyRecordId);
+ gridView.setVisible(false);
+ }
+ else if (confirmPanel.getButton("Cancel").equals(event.getTarget()))
+ {
+ gridView.setVisible(false);
+ windowPanel.showTabbox(true);
+ }*/
+ }
+
+ public void dataStatusChanged(DataStatusEvent e)
+ {
+ int col = e.getChangedColumn();
+ logger.config("(" + gridTab + ") Col=" + col + ": " + e.toString());
+
+ // Process Callout
+ GridField mField = gridTab.getField(col);
+ if (mField != null
+ && (mField.getCallout().length() > 0 || gridTab.hasDependants(mField.getColumnName())))
+ {
+ String msg = gridTab.processFieldChange(mField); // Dependencies & Callout
+ if (msg.length() > 0)
+ {
+ FDialog.error(windowNo, this, msg);
+ }
+ }
+ //if (col >= 0)
+ dynamicDisplay(col);
+ }
+
+ public void valueChange(ValueChangeEvent e)
+ {
+ if (gridTab.isProcessed()) // only active records
+ {
+ Object source = e.getSource();
+ if (source instanceof WEditor)
+ {
+ if (!((WEditor)source).isReadWrite())
+ {
+ logger.config("(" + gridTab.toString() + ") " + e.getPropertyName());
+ return;
+ }
+ }
+ else
+ {
+ logger.config("(" + gridTab.toString() + ") " + e.getPropertyName());
+ return;
+ }
+ } // processed
+ logger.config("(" + gridTab.toString() + ") "
+ + e.getPropertyName() + "=" + e.getNewValue() + " (" + e.getOldValue() + ") "
+ + (e.getOldValue() == null ? "" : e.getOldValue().getClass().getName()));
+
+
+ // Get Row/Col Info
+ GridTable mTable = gridTab.getTableModel();
+ int row = gridTab.getCurrentRow();
+ int col = mTable.findColumn(e.getPropertyName());
+ //
+ if (e.getNewValue() == null && e.getOldValue() != null
+ && e.getOldValue().toString().length() > 0) // some editors return "" instead of null
+ mTable.setChanged (true);
+ else
+ {
+ // mTable.setValueAt (e.getNewValue(), row, col, true);
+ mTable.setValueAt (e.getNewValue(), row, col); // -> dataStatusChanged -> dynamicDisplay
+ // Force Callout
+ if ( e.getPropertyName().equals("S_ResourceAssignment_ID") )
+ {
+ GridField mField = gridTab.getField(col);
+ if (mField != null && mField.getCallout().length() > 0)
+ {
+ gridTab.processFieldChange(mField); // Dependencies & Callout
+ }
+ }
+ }
+
+ } // ValueChange
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/ADWindowPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/ADWindowPanel.java
new file mode 100644
index 0000000000..6d8785f3ff
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/ADWindowPanel.java
@@ -0,0 +1,1129 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import java.util.Properties;
+
+import org.adempiere.webui.apps.AEnv;
+import org.adempiere.webui.apps.ProcessModalDialog;
+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.FTabbox;
+import org.adempiere.webui.component.GridPanel;
+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.session.SessionManager;
+import org.adempiere.webui.window.FDialog;
+import org.adempiere.webui.window.FindWindow;
+import org.compiere.model.DataStatusEvent;
+import org.compiere.model.DataStatusListener;
+import org.compiere.model.GridField;
+import org.compiere.model.GridTab;
+import org.compiere.model.GridWindow;
+import org.compiere.model.GridWindowVO;
+import org.compiere.model.GridWorkbench;
+import org.compiere.model.MQuery;
+import org.compiere.model.MRole;
+import org.compiere.process.DocAction;
+import org.compiere.util.CLogger;
+import org.compiere.util.DB;
+import org.compiere.util.Env;
+import org.compiere.util.Msg;
+import org.compiere.util.WebDoc;
+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.Tab;
+import org.zkoss.zul.Vbox;
+
+/**
+ *
+ * This class is based on org.compiere.apps.APanel written by Jorg Janke.
+ * @author Jorg Janke
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class ADWindowPanel extends Vbox implements ToolbarListener,
+ EventListener, DataStatusListener, ActionListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private static final CLogger logger;
+
+ static
+ {
+ logger = CLogger.getCLogger(ADWindowPanel.class);
+ }
+
+ private Properties ctx;
+
+ private GridWindow gridWindow;
+
+ private StatusBarPanel statusBar;
+
+ private FTabbox tabbox;
+
+ private GridWorkbench workbench;
+
+ private int curWindowNo;
+
+ private GridTab curTab;
+
+ private boolean m_onlyCurrentRows;
+
+ private ADTabpanel curTabpanel;
+
+ private CWindowToolbar toolbar;
+
+ private int curTabIndex;
+
+ private String title;
+
+ private boolean newRecord;
+
+ private boolean boolChanges = false;
+
+ private GridPanel gridPanel;
+
+ private boolean viewed = false;
+
+ private boolean changesOccured = false;
+
+ private int m_onlyCurrentDays = 0;
+
+ public ADWindowPanel()
+ {
+
+ }
+
+ public ADWindowPanel(Properties ctx, int windowNo)
+ {
+ this.ctx = ctx;
+ this.curWindowNo = windowNo;
+
+ init();
+ }
+
+ public void showTabbox(boolean visible)
+ {
+ if (visible)
+ tabbox.setVisible(true);
+ else
+ tabbox.setVisible(false);
+ }
+
+ private void init()
+ {
+ initComponents();
+
+ Vbox vbox = new Vbox();
+ vbox.appendChild(toolbar);
+ vbox.appendChild(tabbox);
+ vbox.appendChild(statusBar);
+ vbox.appendChild(gridPanel);
+ this.appendChild(vbox);
+ tabbox.addEventListener(Events.ON_SELECT, this);
+ }
+
+ public StatusBarPanel getStatusBar()
+ {
+ return statusBar;
+ }
+
+ private void initComponents()
+ {
+ /** Initalise toolbar */
+ toolbar = new CWindowToolbar();
+ toolbar.addListener(this);
+
+ statusBar = new StatusBarPanel();
+
+ tabbox = new FTabbox();
+
+ gridPanel = new GridPanel(curWindowNo, this);
+ gridPanel.showGrid(false);
+ }
+
+ public boolean initPanel(int adWindowId, MQuery query)
+ {
+ // Set AutoCommit for this Window
+ Env.setAutoCommit(ctx, curWindowNo, Env.isAutoCommit(ctx));
+ boolean autoNew = Env.isAutoNew(ctx);
+ Env.setAutoNew(ctx, curWindowNo, autoNew);
+
+ GridWindowVO gWindowVO = AEnv.getMWindowVO(curWindowNo, adWindowId, 0);
+ if (gWindowVO == null)
+ {
+ throw new ApplicationException(Msg.getMsg(ctx,
+ "AccessTableNoView")
+ + "(No Window Model Info)");
+ }
+ gridWindow = new GridWindow(gWindowVO);
+ title = gridWindow.getName();
+ // Set SO/AutoNew for Window
+ Env.setContext(ctx, curWindowNo, "IsSOTrx", gridWindow.isSOTrx());
+ if (!autoNew && gridWindow.isTransaction())
+ {
+ Env.setAutoNew(ctx, curWindowNo, true);
+ }
+
+ /**
+ * Window Tabs
+ */
+ int tabSize = gridWindow.getTabCount();
+ for (int tab = 0; tab < tabSize; tab++)
+ {
+ gridWindow.initTab(tab);
+
+ GridTab gTab = gridWindow.getTab(tab);
+ Env.setContext(ctx, curWindowNo, tab, "TabLevel", Integer
+ .toString(gTab.getTabLevel()));
+
+ ADTabpanel fTabPanel = new ADTabpanel();
+ fTabPanel.init(this, curWindowNo, gTab, gridWindow);
+ gTab.addDataStatusListener(this);
+ tabbox.addTab(gTab, fTabPanel);
+
+ // Query first tab
+ if (tab == 0)
+ {
+ query = initialQuery(query, gTab);
+ if (query != null && query.getRecordCount() <= 1)
+ {
+ // goSingleRow = true;
+ }
+ // Set initial Query on first tab
+ if (query != null)
+ {
+ m_onlyCurrentRows = false;
+ gTab.setQuery(query);
+ }
+ curTab = gTab;
+ curTabpanel = fTabPanel;
+ curTabIndex = tab;
+ }
+ }
+
+ Env.setContext(ctx, curWindowNo, "WindowName", gridWindow.getName());
+ curTab.getTableModel().setChanged(false);
+ curTabIndex = 0;
+ curTabpanel.query();
+ curTabpanel.activate(true);
+
+ if (tabbox.getTabCount() > 0)
+ {
+ tabbox.setSelectedIndex(0);
+ }
+ toolbar.enableTabNavigation(tabbox.getTabCount() > 1);
+ toolbar.enableFind(true);
+ tabbox.evaluate(null);
+ this.appendChild(tabbox);
+
+ if (gridWindow.isTransaction())
+ {
+ toolbar.enableHistoryRecords(true);
+ history(1);
+ }
+
+ return true;
+ }
+
+ /**
+ * Initial Query
+ *
+ * @param query
+ * initial query
+ * @param mTab
+ * tab
+ * @return query or null
+ */
+ private MQuery initialQuery(MQuery query, GridTab mTab)
+ {
+ // We have a (Zoom) query
+ if (query != null && query.isActive() && query.getRecordCount() < 10)
+ return query;
+ //
+ StringBuffer where = new StringBuffer();
+ // Query automatically if high volume and no query
+ boolean require = mTab.isHighVolume();
+ if (!require && !m_onlyCurrentRows) // No Trx Window
+ {
+ String wh1 = mTab.getWhereExtended();
+ if (wh1 == null || wh1.length() == 0)
+ wh1 = mTab.getWhereClause();
+ if (wh1 != null && wh1.length() > 0)
+ where.append(wh1);
+ //
+ if (query != null)
+ {
+ String wh2 = query.getWhereClause();
+ if (wh2.length() > 0)
+ {
+ if (where.length() > 0)
+ where.append(" AND ");
+ where.append(wh2);
+ }
+ }
+ //
+ StringBuffer sql = new StringBuffer("SELECT COUNT(*) FROM ")
+ .append(mTab.getTableName());
+ if (where.length() > 0)
+ sql.append(" WHERE ").append(where);
+ // Does not consider security
+ int no = DB.getSQLValue(null, sql.toString());
+ //
+ require = MRole.getDefault().isQueryRequire(no);
+ }
+ // Show Query
+ if (require)
+ {
+ GridField[] findFields = mTab.getFields();
+ FindWindow find = new FindWindow(curWindowNo,
+ mTab.getName(), mTab.getAD_Table_ID(), mTab.getTableName(),
+ where.toString(), findFields, 10); // no query below 10
+ find.setVisible(true);
+ AEnv.showWindow(find);
+ query = find.getQuery();
+ find = null;
+ }
+ return query;
+ } // initialQuery
+
+ public String getTitle()
+ {
+ return title;
+ }
+
+ public void onDetailRecord()
+ {
+ int maxInd = tabbox.getTabs().getChildren().size() - 1;
+ int curInd = tabbox.getSelectedIndex();
+ if (curInd < maxInd)
+ {
+ tabbox.setSelectedIndex(curInd + 1);
+ }
+ }
+
+ public void onParentRecord()
+ {
+ int curInd = tabbox.getSelectedIndex();
+ if (curInd > 0)
+ {
+ tabbox.setSelectedIndex(curInd - 1);
+ }
+ }
+
+ public void onFirst()
+ {
+ curTab.navigate(0);
+ }
+
+ public void onLast()
+ {
+ curTab.navigate(curTab.getRowCount() - 1);
+ }
+
+ public void onNext()
+ {
+ curTab.navigateRelative(+1);
+ }
+
+ public void onPrevious()
+ {
+ curTab.navigateRelative(-1);
+ }
+
+ public void onHistoryRecords()
+ {
+ logger.info("");
+
+ if (gridWindow.isTransaction())
+ {
+ if (curTab.needSave(true, true)/* && !onSave(false)*/)
+ return;
+
+ WOnlyCurrentDays ocd = new WOnlyCurrentDays();
+ m_onlyCurrentDays = ocd.getCurrentDays();
+
+ history(m_onlyCurrentDays);
+ }
+ }
+
+ private void history(int onlyCurrentDays)
+ {
+ if (onlyCurrentDays == 1) // Day
+ {
+ m_onlyCurrentRows = true;
+ onlyCurrentDays = 0; // no Created restriction
+ }
+ else
+ m_onlyCurrentRows = false;
+
+ curTab.setQuery(null); // reset previous queries
+ MRole role = MRole.getDefault();
+ int maxRows = role.getMaxQueryRecords();
+
+ logger.config("OnlyCurrent=" + m_onlyCurrentRows
+ + ", Days=" + m_onlyCurrentDays
+ + ", MaxRows=" + maxRows);
+
+ curTab.query(m_onlyCurrentRows, onlyCurrentDays, maxRows);
+
+ }
+
+ public void onAttachment()
+ {
+/* int record_ID = curTab.getRecord_ID();
+ logger.info("Record_ID=" + record_ID);
+
+ if (record_ID == -1) // No Key
+ {
+ //aAttachment.setEnabled(false);
+ return;
+ }
+
+ // Attachment va =
+ new WAttachment ( curWindowNo, curTab.getAD_AttachmentID(),
+ curTab.getAD_Table_ID(), record_ID, null);
+
+ curTab.loadAttachments(); // reload
+ //aAttachment.setPressed(m_curTab.hasAttachment());
+*/ }
+
+ public void onGridToggle()
+ {
+ //curTabpanel.switchRowPresentation();
+
+ if (!viewed)
+ {
+ gridPanel.init(curTab);
+ viewed = true;
+ }
+
+ if (changesOccured)
+ {
+ changesOccured = false;
+ gridPanel.clear();
+ gridPanel.init(curTab);
+ }
+
+ if (tabbox.isVisible())
+ {
+ tabbox.setVisible(false);
+ gridPanel.showGrid(true);
+ }
+ else
+ {
+ tabbox.setVisible(true);
+ gridPanel.showGrid(false);
+ }
+
+ }
+
+ public void onExit()
+ {
+ String message = "Please save changes before closing";
+
+ if (!boolChanges)
+ {
+ SessionManager.getAppDesktop().removeWindow();
+ }
+ else
+ FDialog.info(this.curWindowNo, this, message);
+ }
+
+ public boolean isAsap()
+ {
+ return true;
+ }
+
+ private void find()
+ {
+ MQuery mquery = new MQuery(curTab.getAD_Table_ID());
+
+ }
+
+ public void onEvent(Event event)
+ {
+ if (event.getTarget() instanceof Tab && tabbox.containsTab((Tab)event.getTarget()))
+ {
+
+ boolean back = false;
+
+ int oldTabIndex = curTabIndex;
+ int newTabIndex = tabbox.getSelectedIndex();
+
+ if (oldTabIndex == newTabIndex)
+ {
+ return;
+ }
+
+ if (curTabpanel.isEditing())
+ {
+ FDialog.warn(curWindowNo, "Please save your changes before " +
+ "switching tabs!!!", title);
+ tabbox.setSelectedIndex(curTabIndex);
+ return;
+ }
+
+ if (!tabbox.updateSelectedIndex(oldTabIndex, newTabIndex))
+ {
+ FDialog.warn(curWindowNo, "TabSwitchJumpGo", title);
+ return;
+ }
+
+ back = (newTabIndex < oldTabIndex);
+
+ ADTabpanel oldTabpanel = curTabpanel;
+ ADTabpanel newTabpanel = tabbox.getSelectedTabpanel();
+ curTab = newTabpanel.getGridTab();
+
+ if (!back)
+ {
+ newTabpanel.query();
+ }
+ else
+ {
+ newTabpanel.refresh();
+ }
+
+ oldTabpanel.activate(false);
+ newTabpanel.activate(true);
+ curTabIndex = newTabIndex;
+ curTabpanel = newTabpanel;
+
+ toolbar.enableChanges(curTab.isReadOnly());
+ toolbar.enabledNew(curTab.isInsertRecord());
+
+ toolbar.enableTabNavigation(curTabIndex > 0,
+ curTabIndex < (tabbox.getTabCount() - 1));
+ }
+ }
+
+ public void dataStatusChanged(DataStatusEvent e)
+ {
+ /* // update Navigation
+ boolean firstRow = e.isFirstRow();
+ boolean lastRow = e.isLastRow();
+ toolbar.enableFirstNavigation(!firstRow);
+ toolbar.enableLastNavigation(!lastRow);
+
+ // update Change
+ boolean changed = e.isChanged() || e.isInserting();
+ boolean readOnly = curTab.isReadOnly();
+ boolean insertRecord = !readOnly;
+ if (insertRecord)
+ {
+ insertRecord = curTab.isInsertRecord();
+ }
+
+ toolbar.enabledNew(!changed && insertRecord);
+ toolbar.enableRefresh(!changed);
+ toolbar.enableDelete(!changed && !readOnly);
+
+ if (readOnly && curTab.isAlwaysUpdateField())
+ {
+ readOnly = false;
+ }
+
+ lblRecords.setValue(e.getMessage());
+ tabbox.evaluate(e);*/
+
+ logger.info(e.getMessage());
+ String dbInfo = e.getMessage();
+ if (curTab != null && curTab.isQueryActive())
+ dbInfo = "[ " + dbInfo + " ]";
+ statusBar.setStatusDB(dbInfo, e);
+
+ // Set Message / Info
+ if (e.getAD_Message() != null || e.getInfo() != null)
+ {
+ StringBuffer sb = new StringBuffer();
+ String msg = e.getMessage();
+ if (msg != null && msg.length() > 0)
+ {
+ sb.append(Msg.getMsg(Env.getCtx(), e.getAD_Message()));
+ }
+ String info = e.getInfo();
+ if (info != null && info.length() > 0)
+ {
+ if (sb.length() > 0 && !sb.toString().trim().endsWith(":"))
+ sb.append(": ");
+ sb.append(info);
+ }
+ if (sb.length() > 0)
+ {
+ int pos = sb.indexOf("\n");
+ if (pos != -1) // replace CR/NL
+ sb.replace(pos, pos+1, " - ");
+ statusBar.setStatusLine (sb.toString (), e.isError ());
+ }
+ }
+
+ // Confirm Error
+ if (e.isError() && !e.isConfirmed())
+ {
+ FDialog.error(curWindowNo, this, e.getAD_Message(), e.getInfo());
+ e.setConfirmed(true); // show just once - if MTable.setCurrentRow is involved the status event is re-issued
+ }
+ // Confirm Warning
+ else if (e.isWarning() && !e.isConfirmed())
+ {
+ FDialog.warn(curWindowNo, this, e.getAD_Message(), e.getInfo());
+ e.setConfirmed(true); // show just once - if MTable.setCurrentRow is involved the status event is re-issued
+ }
+
+ // update Navigation
+ boolean firstRow = e.isFirstRow();
+ boolean lastRow = e.isLastRow();
+ toolbar.enableFirstNavigation(!firstRow);
+ toolbar.enableLastNavigation(!lastRow);
+
+ // update Change
+ boolean changed = e.isChanged() || e.isInserting();
+ boolChanges = changed;
+ boolean readOnly = curTab.isReadOnly();
+ boolean insertRecord = !readOnly;
+
+ if (insertRecord)
+ {
+ insertRecord = curTab.isInsertRecord();
+ }
+ toolbar.enabledNew(!changed && insertRecord);
+ toolbar.enableCopy(!changed && insertRecord);
+ toolbar.enableRefresh(!changed);
+ toolbar.enableDelete(!changed && !readOnly);
+ //
+ if (readOnly && curTab.isAlwaysUpdateField())
+ {
+ readOnly = false;
+ }
+ toolbar.enableIgnore(changed && !readOnly);
+ toolbar.enableSave(changed && !readOnly);
+
+ //
+ // No Rows
+ if (e.getTotalRows() == 0 && insertRecord)
+ {
+ toolbar.enabledNew(true);
+ toolbar.enableDelete(false);
+ toolbar.enableDeleteSelection(false);
+ }
+ else
+ {
+ toolbar.enableDeleteSelection(true);
+ }
+
+ // Single-Multi
+// aMulti.setPressed(!m_curGC.isSingleRow());
+
+ // History (on first Tab only)
+ if (isFirstTab())
+ {
+// aHistory.setPressed(!curTab.isOnlyCurrentRows());
+ }
+
+ // Transaction info
+ String trxInfo = curTab.getTrxInfo();
+ if (trxInfo != null)
+ {
+// statusBar.setInfo(trxInfo);
+ }
+
+ // Check Attachment
+ boolean canHaveAttachment = curTab.canHaveAttachment(); // not single _ID column
+ //
+ if (canHaveAttachment && e.isLoading() &&
+ curTab.getCurrentRow() > e.getLoadedRows())
+ {
+ canHaveAttachment = false;
+ }
+ if (canHaveAttachment && curTab.getRecord_ID() == -1) // No Key
+ {
+ canHaveAttachment = false;
+ }
+ if (canHaveAttachment)
+ {
+ toolbar.enableAttachment(true);
+ /*aAttachment.setPressed(m_curTab.hasAttachment());
+ aChat.setEnabled(true);
+ aChat.setPressed(m_curTab.hasChat());*/
+ }
+ else
+ {
+ toolbar.enableAttachment(false);
+// aChat.setEnabled(false);
+ }
+ // Lock Indicator
+ /* if (m_isPersonalLock)
+ {
+ aLock.setPressed(m_curTab.isLocked());
+ }*/
+
+ tabbox.evaluate(e);
+
+
+ toolbar.enablePrint(true);
+ toolbar.enableReport(true);
+ }
+
+ public boolean isFirstTab()
+ {
+ int selTabIndex = tabbox.getSelectedIndex();
+ return (selTabIndex == 0);
+ }
+
+ public void onRefresh()
+ {
+ curTab.dataRefreshAll();
+ curTabpanel.dynamicDisplay(0);
+ }
+
+ public void onHelp()
+ {
+ WebDoc doc = gridWindow.getHelpDoc(true);
+ SessionManager.getAppDesktop().showURL(doc, "Help", true);
+ }
+
+ public void onNew()
+ {
+ if (!curTab.isInsertRecord())
+ {
+ logger.warning("Insert Record disabled for Tab");
+ return;
+ }
+
+ newRecord = curTab.dataNew (false);
+ if (newRecord)
+ {
+
+ curTabpanel.editRecord(true);
+ curTabpanel.dynamicDisplay(0);
+ toolbar.enableChanges(false);
+ toolbar.enableDelete(false);
+ toolbar.enableNavigation(false);
+ toolbar.enableTabNavigation(false);
+ toolbar.enableIgnore(true);
+ toolbar.enablePrint(true);
+ toolbar.enableReport(true);
+ }
+ else
+ {
+ logger.severe("Could not create new record");
+ }
+
+ }
+
+ public void onFind()
+ {
+ if (curTab == null)
+ return;
+
+ // Gets Fields from AD_Field_v
+ GridField[] findFields = GridField.createFields(ctx, curTab.getWindowNo(), 0,curTab.getAD_Tab_ID());
+ FindWindow find = new FindWindow (curTab.getWindowNo(), curTab.getName(),
+ curTab.getAD_Table_ID(), curTab.getTableName(),
+ curTab.getWhereExtended(), findFields, 1);
+ AEnv.showWindow(find);
+ MQuery query = find.getQuery();
+
+ find = null;
+
+ // Confirmed query
+ if (query != null)
+ {
+ m_onlyCurrentRows = false; // search history too
+ curTab.setQuery(query);
+ curTabpanel.query(m_onlyCurrentRows, m_onlyCurrentDays, 0); // autoSize
+ }
+ }
+
+ public void onIgnore()
+ {
+ curTab.dataIgnore();
+ curTab.dataRefresh();
+ curTabpanel.dynamicDisplay(0);
+ curTabpanel.editRecord(false);
+ toolbar.enableIgnore(false);
+ }
+
+ public void onEdit()
+ {
+ curTabpanel.editRecord(true);
+ toolbar.enableIgnore(true);
+ toolbar.enabledNew(false);
+ toolbar.enableDelete(false);
+ toolbar.enableNavigation(false);
+ toolbar.enableTabNavigation(false);
+ toolbar.enablePrint(true);
+ toolbar.enableReport(true);
+ }
+
+ public void onSave()
+ {
+ changesOccured = true;
+
+ boolean retValue = curTab.dataSave(true);
+
+ if (!retValue)
+ {
+ FDialog.error(curWindowNo, this, "SaveIgnored");
+ statusBar.setStatusLine(Msg.getMsg(Env.getCtx(), "SaveIgnored"), true);
+ }
+ curTabpanel.dynamicDisplay(0);
+ }
+
+ public void onDelete()
+ {
+ if (curTab.isReadOnly())
+ {
+ return;
+ }
+
+ if (FDialog.ask(curWindowNo, this, "DeleteRecord?"))
+ {
+ if (!curTab.dataDelete())
+ {
+ FDialog.error(curWindowNo, "Could not delete record", "Error");
+ }
+ }
+ curTabpanel.dynamicDisplay(0);
+ }
+
+ public void onPrint() {
+ //Get process defined for this tab
+ int AD_Process_ID = curTab.getAD_Process_ID();
+ //log.info("ID=" + AD_Process_ID);
+
+ // No report defined
+ if (AD_Process_ID == 0)
+ {
+ onReport();
+
+ return;
+ }
+
+ //TODO: cmd_save(false) -> onSave ?
+ //onSave();
+ //
+ int table_ID = curTab.getAD_Table_ID();
+ int record_ID = curTab.getRecord_ID();
+
+ ProcessModalDialog dialog = new ProcessModalDialog(null,this.getTitle(),null,0,
+ AD_Process_ID,table_ID, record_ID, true);
+ if (dialog.isValid()) {
+ dialog.setPosition("center");
+ try {
+ dialog.doModal();
+ }
+ catch (InterruptedException e) {
+
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public void onReport() {
+ if (!MRole.getDefault().isCanReport(curTab.getAD_Table_ID()))
+ {
+ FDialog.error(curWindowNo, this, "AccessCannotReport");
+ return;
+ }
+
+ //TODO: cmd_save(false); -> onSave ?
+
+ // Query
+ MQuery query = new MQuery(curTab.getTableName());
+ // Link for detail records
+ String queryColumn = curTab.getLinkColumnName();
+ // Current row otherwise
+ if (queryColumn.length() == 0)
+ queryColumn = curTab.getKeyColumnName();
+ // Find display
+ String infoName = null;
+ String infoDisplay = null;
+ for (int i = 0; i < curTab.getFieldCount(); i++)
+ {
+ GridField field = curTab.getField(i);
+ if (field.isKey())
+ infoName = field.getHeader();
+ if ((field.getColumnName().equals("Name") || field.getColumnName().equals("DocumentNo") )
+ && field.getValue() != null)
+ infoDisplay = field.getValue().toString();
+ if (infoName != null && infoDisplay != null)
+ break;
+ }
+ if (queryColumn.length() != 0)
+ {
+ if (queryColumn.endsWith("_ID"))
+ query.addRestriction(queryColumn, MQuery.EQUAL,
+ new Integer(Env.getContextAsInt(ctx, curWindowNo, queryColumn)),
+ infoName, infoDisplay);
+ else
+ query.addRestriction(queryColumn, MQuery.EQUAL,
+ Env.getContext(ctx, curWindowNo, queryColumn),
+ infoName, infoDisplay);
+ }
+
+ new WReport (curTab.getAD_Table_ID(), query, null, curWindowNo);
+
+ }
+
+ /**************************************************************************
+ * Start Button Process
+ * @param vButton button
+ */
+ private void actionButton (WButtonEditor wButton)
+ {
+ logger.info(wButton.toString());
+
+ boolean startWOasking = false;
+ boolean batch = false;
+ String col = wButton.getColumnName();
+
+ // 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
+
+ // save first ---------------
+
+ if (curTab.needSave(true, false))
+ onSave();
+
+ int table_ID = curTab.getAD_Table_ID();
+
+ // Record_ID
+
+ int record_ID = curTab.getRecord_ID();
+
+ // Record_ID - Language Handling
+
+ if (record_ID == -1 && curTab.getKeyColumnName().equals("AD_Language"))
+ record_ID = Env.getContextAsInt (ctx, curWindowNo, "AD_Language_ID");
+
+ // Record_ID - Change Log ID
+
+ if (record_ID == -1
+ && (wButton.getProcess_ID() == 306 || wButton.getProcess_ID() == 307))
+ {
+ Integer id = (Integer)curTab.getValue("AD_ChangeLog_ID");
+ record_ID = id.intValue();
+ }
+
+ // Ensure it's saved
+
+ if (record_ID == -1 && curTab.getKeyColumnName().endsWith("_ID"))
+ {
+ FDialog.error(curWindowNo, this, "SaveErrorRowNotFound");
+ return;
+ }
+
+ // Pop up Payment Rules
+
+ if (col.equals("PaymentRule"))
+ {
+ WPayment vp = new WPayment(curWindowNo, curTab, wButton);
+
+
+ if (vp.isInitOK()) // may not be allowed
+ {
+ vp.setVisible(true);
+ AEnv.showWindow(vp);
+ }
+ //vp.dispose();
+
+ if (vp.needSave())
+ {
+ onSave();
+ onRefresh();
+ }
+ } // PaymentRule
+
+ // Pop up Document Action (Workflow)
+
+ else if (col.equals("DocAction"))
+ {
+ WDocActionPanel win = new WDocActionPanel(curTab);
+ //if (win.getNumberOfOptions() == 0)
+ //{
+ // vda.dispose ();
+ // log.info("DocAction - No Options");
+ // return;
+ //}
+ //else
+ {
+ win.setVisible(true);
+ AEnv.showWindow(win);
+
+ if (!win.isStartProcess())
+ return;
+
+ //batch = win.isBatch();
+ startWOasking = true;
+ //vda.dispose();
+ } } // DocAction
+
+ // Pop up Create From
+
+ else if (col.equals("CreateFrom"))
+ {
+ // curWindowNo
+ WCreateFrom wcf = WCreateFrom.create(curTab);
+
+ if (wcf != null)
+ {
+ if (wcf.isInitOK())
+ {
+ wcf.setVisible(true);
+ curTab.dataRefresh();
+ }
+ return;
+ }
+ // else may start process
+ } // CreateFrom
+
+ // Posting -----
+
+ else if (col.equals("Posted") && MRole.getDefault().isShowAcct())
+ {
+ // Check Doc Status
+
+ String processed = Env.getContext(ctx, curWindowNo, "Processed");
+
+ if (!processed.equals("Y"))
+ {
+ String docStatus = Env.getContext(ctx, curWindowNo, "DocStatus");
+
+ if (DocAction.STATUS_Completed.equals(docStatus)
+ || DocAction.STATUS_Closed.equals(docStatus)
+ || DocAction.STATUS_Reversed.equals(docStatus)
+ || DocAction.STATUS_Voided.equals(docStatus))
+ ;
+ else
+ {
+ FDialog.error(curWindowNo, this, "PostDocNotComplete");
+ return;
+ }
+ }
+
+ // Check Post Status
+ Object ps = curTab.getValue("Posted");
+
+ if (ps != null && ps.equals("Y"))
+ {
+ new org.adempiere.webui.acct.WAcctViewer(Env.getContextAsInt (ctx, curWindowNo, "AD_Client_ID"),
+ curTab.getAD_Table_ID(), curTab.getRecord_ID());
+ }
+ else
+ {
+ if (FDialog.ask(curWindowNo, this, "PostImmediate?"))
+ {
+ boolean force = ps != null && !ps.equals ("N"); // force when problems
+
+ String error = AEnv.postImmediate (curWindowNo, Env.getAD_Client_ID(ctx),
+ curTab.getAD_Table_ID(), curTab.getRecord_ID(), force);
+
+ curTab.dataRefresh();
+
+ if (error != null)
+ FDialog.error(curWindowNo, this, "PostingError-N", error);
+ }
+ }
+ return;
+ } // Posted
+
+ /**
+ * Start Process ----
+ */
+
+ logger.config("Process_ID=" + wButton.getProcess_ID() + ", Record_ID=" + record_ID);
+
+ if (wButton.getProcess_ID() == 0)
+ return;
+
+ // Save item changed
+
+ if (curTab.needSave(true, false))
+ this.onSave();
+
+ // hengsin - [ 1639242 ] Inconsistent appearance of Process/Report Dialog
+ // globalqss - Add support for Don't ShowHelp option in Process
+ // this code must be changed if integrated the parameters and help in only one window
+ /*
+ MProcess pr = new MProcess(m_ctx, vButton.getProcess_ID(), null);
+ if (pr.getShowHelp() != null && pr.getShowHelp().equals("N")) {
+ startWOasking = true;
+ }
+ // end globalqss
+
+ // Ask user to start process, if Description and Help is not empty
+
+ if (!startWOasking && !(vButton.getDescription().equals("") && vButton.getHelp().equals("")))
+ if (!ADialog.ask(m_curWindowNo, this, "StartProcess?",
+ // "" + vButton.getText() + " " +
+ vButton.getDescription() + "\n" + vButton.getHelp()))
+ return;
+ //
+ String title = vButton.getDescription();
+ if (title == null || title.length() == 0)
+ title = vButton.getName();
+ ProcessInfo pi = new ProcessInfo (title, vButton.getProcess_ID(), table_ID, record_ID);
+ pi.setAD_User_ID (Env.getAD_User_ID(m_ctx));
+ pi.setAD_Client_ID (Env.getAD_Client_ID(m_ctx));
+ pi.setIsBatch(batch);
+
+ // Trx trx = Trx.get(Trx.createTrxName("AppsPanel"), true);
+ ProcessCtl.process(this, m_curWindowNo, pi, null); // calls lockUI, unlockUI
+ */
+
+ ProcessModalDialog dialog = new ProcessModalDialog(null,
+ Env.getHeader(ctx, curWindowNo), null, curWindowNo,
+ wButton.getProcess_ID(), table_ID, record_ID, startWOasking);
+
+ if (dialog.isValid())
+ {
+ dialog.setWidth("500px");
+ dialog.setVisible(true);
+ dialog.setPosition("center");
+ AEnv.showWindow(dialog);
+ }
+ curTab.dataRefresh();
+ curTabpanel.dynamicDisplay(0);
+ } // actionButton
+
+ public void actionPerformed(ActionEvent event)
+ {
+ if (event.getSource() instanceof WButtonEditor)
+ {
+ actionButton((WButtonEditor)event.getSource());
+ }
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/ChatPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/ChatPanel.java
new file mode 100644
index 0000000000..4596523513
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/ChatPanel.java
@@ -0,0 +1,36 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import org.adempiere.webui.component.Panel;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 2, 2007
+ * @version $Revision: 0.10 $
+ */
+public class ChatPanel extends Panel
+{
+ private static final long serialVersionUID = 1L;
+
+ public ChatPanel()
+ {
+ super();
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/ConfigurationPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/ConfigurationPanel.java
new file mode 100644
index 0000000000..2092667805
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/ConfigurationPanel.java
@@ -0,0 +1,36 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import org.adempiere.webui.component.Panel;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 2, 2007
+ * @version $Revision: 0.10 $
+ */
+public class ConfigurationPanel extends Panel
+{
+ private static final long serialVersionUID = 1L;
+
+ public ConfigurationPanel()
+ {
+ super();
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/FooterPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/FooterPanel.java
new file mode 100644
index 0000000000..f6ba45e714
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/FooterPanel.java
@@ -0,0 +1,57 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.Panel;
+import org.adempiere.webui.component.Window;
+import org.zkoss.zul.Separator;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 3, 2007
+ * @version $Revision: 0.10 $
+ */
+
+public class FooterPanel extends Window
+{
+ private static final long serialVersionUID = 1L;
+
+ private Panel panel = new Panel();
+ private Label label = new Label();
+
+ public FooterPanel()
+ {
+ super();
+ init();
+ }
+
+ private void init()
+ {
+ label.setValue("2007 Posterita Limited");
+
+ panel.setWidth("100%");
+ panel.setStyle("text-align:center");
+ panel.appendChild(label);
+
+ this.appendChild(new Separator());
+ this.appendChild(panel);
+ this.appendChild(new Separator());
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/HeaderPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/HeaderPanel.java
new file mode 100644
index 0000000000..b4e5bbe976
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/HeaderPanel.java
@@ -0,0 +1,91 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import org.adempiere.webui.component.Panel;
+import org.adempiere.webui.session.SessionManager;
+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.Hbox;
+import org.zkoss.zul.Image;
+import org.zkoss.zul.Label;
+import org.zkoss.zul.Separator;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 2, 2007
+ * @version $Revision: 0.10 $
+ */
+
+public class HeaderPanel extends Panel implements EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private Image image = new Image();
+ private SideUserPanel pnlSideUser;
+
+ public HeaderPanel()
+ {
+ super();
+ init();
+ }
+
+ private void init()
+ {
+ pnlSideUser = new SideUserPanel();
+
+ Hbox hbox = new Hbox();
+ hbox.setWidth("100%");
+ hbox.setWidths("300px, 550px, 350px");
+
+ Panel right = new Panel();
+ right.setWidth("100%");
+ right.setStyle("text-align:right");
+
+ Panel left = new Panel();
+ left.setWidth("100%");
+ left.setStyle("text-align:center");
+
+ right.appendChild(pnlSideUser);
+
+ image.setSrc("/images/PosteritaAjaxUILogo.jpg");
+ image.addEventListener(Events.ON_CLICK, this);
+ left.appendChild(image);
+
+ hbox.appendChild(left);
+ hbox.appendChild(new Label(""));
+ hbox.appendChild(right);
+
+ this.setWidth("100%");
+ this.appendChild(new Separator());
+ this.appendChild(hbox);
+ this.appendChild(new Separator());
+ }
+
+ public void onEvent(Event event) throws Exception {
+ if (event == null)
+ return;
+
+ if (event.getTarget() == image){
+ SessionManager.getAppDesktop().showURL("http://www.posterita.org/", true);
+ }
+
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoAssetPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoAssetPanel.java
new file mode 100644
index 0000000000..b0953e385f
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoAssetPanel.java
@@ -0,0 +1,422 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.Textbox;
+import org.adempiere.webui.component.VerticalBox;
+import org.adempiere.webui.editor.WEditor;
+import org.adempiere.webui.editor.WSearchEditor;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.event.ValueChangeListener;
+import org.adempiere.webui.event.WTableModelEvent;
+import org.compiere.minigrid.ColumnInfo;
+import org.compiere.minigrid.IDColumn;
+import org.compiere.model.MLookupFactory;
+import org.compiere.util.DisplayType;
+import org.compiere.util.Env;
+import org.compiere.util.Msg;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zk.ui.event.Events;
+import org.zkoss.zul.Hbox;
+import org.zkoss.zul.Separator;
+
+/**
+* Based on InfoPayment written by Jorg Janke
+*
+* @author Niraj Sohun
+* Aug, 02, 2007
+*/
+
+public class InfoAssetPanel extends InfoPanel implements ValueChangeListener, EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ /** From Clause */
+ private static String s_assetFROM = "A_ASSET a"
+ + " LEFT OUTER JOIN M_Product p ON (a.M_Product_ID=p.M_Product_ID)"
+ + " LEFT OUTER JOIN C_BPartner bp ON (a.C_BPartner_ID=bp.C_BPartner_ID)"
+ + " LEFT OUTER JOIN AD_User u ON (a.AD_User_ID=u.AD_User_ID)";
+
+ /** Array of Column Info */
+ private static final ColumnInfo[] s_assetLayout = {
+ new ColumnInfo(" ", "a.A_Asset_ID", IDColumn.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "Value"), "a.Value", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "Name"), "a.Name", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "M_Product_ID"), "p.Name", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "C_BPartner_ID"), "bp.Name", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "AD_User_ID"), "u.Name", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "AssetServiceDate"), "a.AssetServiceDate", Timestamp.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "GuaranteeDate"), "a.GuaranteeDate", Timestamp.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "VersionNo"), "a.VersionNo", String.class)
+ };
+
+ private Textbox fieldValue = new Textbox();
+ private Textbox fieldName = new Textbox();
+
+ private WEditor fBPartner_ID;
+ private WEditor fProduct_ID;
+
+ private Label labelValue = new Label();
+ private Label labelName = new Label();
+
+ /**
+ * Standard Constructor
+
+ * @param WindowNo window no
+ * @param A_Asset_ID asset
+ * @param value Query Value or Name if enclosed in @
+ * @param multiSelection multiple selections
+ * @param whereClause where clause
+ */
+
+ public InfoAssetPanel( int WindowNo, int A_Asset_ID, String value,
+ boolean multiSelection, String whereClause)
+ {
+ super (WindowNo, "a", "A_Asset_ID", multiSelection, whereClause);
+
+ log.info(value + ", ID=" + A_Asset_ID + ", WHERE=" + whereClause);
+ setTitle(Msg.getMsg(Env.getCtx(), "InfoAsset"));
+
+ statInit();
+ initInfo(value, A_Asset_ID, whereClause);
+
+ int no = contentPanel.getRowCount();
+ setStatusLine(Integer.toString(no) + " " + Msg.getMsg(Env.getCtx(), "SearchRows_EnterQuery"), false);
+ setStatusDB(Integer.toString(no));
+
+ // AutoQuery
+
+ if (value != null && value.length() > 0)
+ executeQuery();
+
+ p_loadedOK = true;
+
+ // Focus
+ // fieldValue.requestFocus();
+
+ //AEnv.positionCenterWindow(frame, this);
+ } // InfoProduct
+
+ /**
+ * Static Setup - add fields to parameterPanel
+ */
+
+ private void statInit()
+ {
+ Hbox boxValue = new Hbox();
+
+ labelValue.setValue(Msg.getMsg(Env.getCtx(), "Value"));
+ fieldValue.addEventListener(Events.ON_CHANGE, this);
+
+ boxValue.setWidth("100%");
+ boxValue.setWidths("40%, 60%");
+ boxValue.appendChild(labelValue);
+ boxValue.appendChild(fieldValue);
+
+ Hbox boxName = new Hbox();
+
+ labelName.setValue(Msg.getMsg(Env.getCtx(), "Name"));
+ fieldName.addEventListener(Events.ON_CANCEL, this);
+
+ boxName.setWidth("100%");
+ boxName.setWidths("40%, 60%");
+ boxName.appendChild(labelName);
+ boxName.appendChild(fieldName);
+
+ // From A_Asset.
+
+ Hbox boxBPartner = new Hbox();
+
+ fBPartner_ID = new WSearchEditor(
+ MLookupFactory.get (Env.getCtx(), p_WindowNo, 0, 8065, DisplayType.Search),
+ Msg.translate(Env.getCtx(), "C_BPartner_ID"), "", false, false, true);
+ fBPartner_ID.addValueChangeListner(this);
+
+ boxBPartner.setWidth("100%");
+ boxBPartner.setWidths("40%, ");
+
+ boxBPartner.appendChild(fBPartner_ID.getLabel());
+ boxBPartner.appendChild(fBPartner_ID.getComponent());
+
+
+ Hbox boxProduct = new Hbox();
+
+ fProduct_ID = new WSearchEditor(
+ MLookupFactory.get (Env.getCtx(), p_WindowNo, 0, 8047, DisplayType.Search),
+ Msg.translate(Env.getCtx(), "M_Product_ID"), "", false, false, true);
+ fProduct_ID.addValueChangeListner(this);
+
+ boxProduct.appendChild(fProduct_ID.getLabel());
+ boxProduct.appendChild(fProduct_ID.getComponent());
+
+ VerticalBox boxCol1 = new VerticalBox();
+ boxCol1.appendChild(boxValue);
+ boxCol1.appendChild(new Separator());
+ boxCol1.appendChild(boxName);
+
+ VerticalBox boxCol2 = new VerticalBox();
+ boxCol2.appendChild(boxBPartner);
+ boxCol2.appendChild(new Separator());
+ boxCol2.appendChild(boxProduct);
+
+ Hbox mainBox = new Hbox();
+ mainBox.setWidth("100%");
+ mainBox.setWidths("30%, 70%");
+ mainBox.appendChild(boxCol1);
+ mainBox.appendChild(boxCol2);
+
+ this.setWidth("850px");
+ this.setTitle("Info Asset");
+ this.setClosable(true);
+ this.setBorder("normal");
+ this.appendChild(mainBox);
+ this.appendChild(new Separator());
+ this.appendChild(contentPanel);
+ this.appendChild(new Separator());
+ this.appendChild(confirmPanel);
+ this.appendChild(new Separator());
+ this.appendChild(statusBar);
+ }
+
+ /**
+ * Dynamic Init
+ * @param value value
+ * @param whereClause where clause
+ */
+
+ private void initInfo (String value, int A_Asset_ID, String whereClause)
+ {
+ // Create Grid
+
+ StringBuffer where = new StringBuffer();
+ where.append("a.IsActive='Y'");
+
+ if (whereClause != null && whereClause.length() > 0)
+ where.append(" AND ").append(whereClause);
+
+ prepareTable(s_assetLayout, s_assetFROM, where.toString(), "a.Value");
+
+ // Set Value
+
+ if (value == null)
+ value = "%";
+
+ if (!value.endsWith("%"))
+ value += "%";
+ } // initInfo
+
+ /*************************************************************************/
+ /**
+ * Construct SQL Where Clause and define parameters.
+ * (setParameters needs to set parameters)
+ * Includes first AND
+ * @return WHERE clause
+ */
+
+ String getSQLWhere()
+ {
+ StringBuffer sql = new StringBuffer();
+
+ // => Value
+
+ String value = fieldValue.getText().toUpperCase();
+
+ if (!(value.equals("") || value.equals("%")))
+ sql.append(" AND UPPER(a.Value) LIKE ?");
+
+ // => Name
+
+ String name = fieldName.getText().toUpperCase();
+
+ if (!(name.equals("") || name.equals("%")))
+ sql.append (" AND UPPER(a.Name) LIKE ?");
+
+ // C_BPartner_ID
+
+ Integer C_BPartner_ID = null;
+
+ if (fBPartner_ID.getDisplay() != "")
+ C_BPartner_ID = (Integer)fBPartner_ID.getValue();
+
+ if (C_BPartner_ID != null)
+ sql.append (" AND a.C_BPartner_ID=").append(C_BPartner_ID);
+
+ // M_Product_ID
+
+ Integer M_Product_ID = null;
+
+ if (fProduct_ID.getDisplay() != "")
+ M_Product_ID = (Integer)fProduct_ID.getValue();
+
+ if (M_Product_ID != null)
+ sql.append (" AND a.M_Product_ID=").append(M_Product_ID);
+
+ return sql.toString();
+ } // getSQLWhere
+
+ /**
+ * Set Parameters for Query
+ * (as defined in getSQLWhere)
+ *
+ * @param pstmt pstmt
+ * @param forCount for counting records
+ * @throws SQLException
+ */
+
+ void setParameters(PreparedStatement pstmt, boolean forCount) throws SQLException
+ {
+ int index = 1;
+
+ // => Value
+
+ String value = fieldValue.getText().toUpperCase();
+
+ if (!(value.equals("") || value.equals("%")))
+ {
+ if (!value.endsWith("%"))
+ value += "%";
+
+ pstmt.setString(index++, value);
+ log.fine("Value: " + value);
+ }
+
+ // => Name
+
+ String name = fieldName.getText().toUpperCase();
+
+ if (!(name.equals("") || name.equals("%")))
+ {
+ if (!name.endsWith("%"))
+ name += "%";
+
+ pstmt.setString(index++, name);
+ log.fine("Name: " + name);
+ }
+ } // setParameters
+
+ /**
+ * Save Selection Details
+ * Get Location/Partner Info
+ */
+
+ public void saveSelectionDetail()
+ {
+ int row = contentPanel.getSelectedRow();
+
+ if (row == -1)
+ return;
+
+ // publish for Callout to read
+
+ Integer ID = getSelectedRowKey();
+ Env.setContext(Env.getCtx(), Env.WINDOW_INFO, Env.TAB_INFO, "A_Asset_ID", ID == null ? "0" : ID.toString());
+ } // saveSelectionDetail
+
+ /*************************************************************************/
+ /**
+ * Show History
+ */
+
+ void showHistory()
+ {
+ log.info( "InfoAsset.showHistory");
+ } // showHistory
+
+ /**
+ * Has History
+ * @return true
+ */
+
+ boolean hasHistory()
+ {
+ return false;
+ } // hasHistory
+
+ /**
+ * Zoom
+ */
+
+/* public void zoom()
+ {
+ log.info( "InfoAsset.zoom");
+ Integer A_Asset_ID = getSelectedRowKey();
+
+ if (A_Asset_ID == null)
+ return;
+
+ MQuery query = new MQuery("A_Asset");
+ query.addRestriction("A_Asset_ID", MQuery.EQUAL, A_Asset_ID);
+ query.setRecordCount(1);
+
+ int AD_WindowNo = getAD_Window_ID("A_Asset", true);
+ super.zoom (AD_WindowNo, query);
+ } // zoom
+*/
+ /**
+ * Has Zoom
+ * @return true
+ */
+
+ boolean hasZoom()
+ {
+ return true;
+ } // hasZoom
+
+ /**
+ * Customize
+ */
+
+ void customize()
+ {
+ log.info( "InfoAsset.customize");
+ } // customize
+
+ /**
+ * Has Customize
+ * @return false
+ */
+
+ boolean hasCustomize()
+ {
+ return false; // for now
+ } // hasCustomize
+
+ public void tableChanged(WTableModelEvent event)
+ {
+
+ }
+
+ public void valueChange(ValueChangeEvent evt)
+ {
+ if (fBPartner_ID.equals(evt.getSource()))
+ {
+ fBPartner_ID.setValue(evt.getNewValue());
+ }
+
+ if (fProduct_ID.equals(evt.getSource()))
+ {
+ fProduct_ID.setValue(evt.getNewValue());
+ }
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoAssignmentPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoAssignmentPanel.java
new file mode 100644
index 0000000000..d808805ac0
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoAssignmentPanel.java
@@ -0,0 +1,377 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.Date;
+import java.util.logging.Level;
+
+import org.adempiere.webui.component.Button;
+import org.adempiere.webui.component.Datebox;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.VerticalBox;
+import org.adempiere.webui.editor.WEditor;
+import org.adempiere.webui.editor.WSearchEditor;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.event.ValueChangeListener;
+import org.adempiere.webui.event.WTableModelEvent;
+import org.compiere.minigrid.ColumnInfo;
+import org.compiere.minigrid.IDColumn;
+import org.compiere.model.MLookupFactory;
+import org.compiere.util.DB;
+import org.compiere.util.DisplayType;
+import org.compiere.util.Env;
+import org.compiere.util.Msg;
+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.Hbox;
+import org.zkoss.zul.Separator;
+
+/**
+* Based on InfoAssignment written by Jorg Janke
+*
+* @author Niraj Sohun
+* Aug 06, 2007
+*/
+
+public class InfoAssignmentPanel extends InfoPanel implements EventListener, ValueChangeListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private WEditor fieldResourceType;
+ private WEditor fieldResource;
+
+ private Button bNew = new Button();
+
+ private Datebox fieldFrom = new Datebox();
+ private Datebox fieldTo = new Datebox();
+
+ private Label labelFrom = new Label(Msg.translate(Env.getCtx(), "DateFrom"));
+ private Label labelTo = new Label(Msg.translate(Env.getCtx(), "DateTo"));
+
+ /** From Clause */
+ private static String s_assignmentFROM =
+ "S_ResourceAssignment ra, S_ResourceType rt, S_Resource r, C_UOM uom";
+
+ private static String s_assignmentWHERE =
+ "ra.IsActive='Y' AND ra.S_Resource_ID=r.S_Resource_ID "
+ + "AND r.S_ResourceType_ID=rt.S_ResourceType_ID AND rt.C_UOM_ID=uom.C_UOM_ID";
+
+ /** Array of Column Info */
+ private static ColumnInfo[] s_assignmentLayout = {
+ new ColumnInfo(" ", "ra.S_ResourceAssignment_ID", IDColumn.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "S_ResourceType_ID"), "rt.Name", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "S_Resource_ID"), "r.Name", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "AssignDateFrom"), "ra.AssignDateFrom", Timestamp.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "Qty"), "ra.Qty", Double.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "C_UOM_ID"), "uom.UOMSymbol", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "AssignDateTo"), "ra.AssignDateTo", Timestamp.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "IsConfirmed"), "ra.IsConfirmed", Boolean.class)
+ };
+
+ /**
+ * Constructor
+ *
+ * @param WindowNo WindowNo
+ * @param value Query value Name or Value if contains numbers
+ * @param multiSelection multiple selection
+ * @param whereClause where clause
+ */
+
+ public InfoAssignmentPanel (int WindowNo,
+ String value, boolean multiSelection, String whereClause)
+ {
+ super (WindowNo, "ra", "S_ResourceAssigment_ID",
+ multiSelection, whereClause);
+ log.info(value);
+ setTitle(Msg.getMsg(Env.getCtx(), "InfoAssignment"));
+
+ if (!initLookups())
+ return;
+
+ statInit();
+ initInfo (value, whereClause);
+
+ int no = contentPanel.getRowCount();
+ setStatusLine(Integer.toString(no) + " " + Msg.getMsg(Env.getCtx(), "SearchRows_EnterQuery"), false);
+ setStatusDB(Integer.toString(no));
+
+ // AutoQuery
+ // if (value != null && value.length() > 0)
+ // executeQuery();
+
+ p_loadedOK = true;
+
+ //AEnv.positionCenterWindow(frame, this);
+ } // InfoAssignmentPanel
+
+ /**
+ * Initialize Lookups
+ * @return true if OK
+ */
+
+ private boolean initLookups()
+ {
+ try
+ {
+ int AD_Column_ID = 6851; // S_Resource.S_ResourceType_ID
+
+ fieldResourceType = new WSearchEditor (
+ MLookupFactory.get(Env.getCtx(), p_WindowNo, 0, AD_Column_ID, DisplayType.TableDir),
+ Msg.translate(Env.getCtx(), "S_ResourceType_ID"), "", false, false, true);
+
+ AD_Column_ID = 6826; // S_ResourceAssignment.S_Resource_ID
+
+ fieldResource = new WSearchEditor (
+ MLookupFactory.get (Env.getCtx(), p_WindowNo, 0, AD_Column_ID, DisplayType.TableDir),
+ Msg.translate(Env.getCtx(), "S_Resource_ID"), "", false, false, true);
+ }
+ catch (Exception e)
+ {
+ log.log(Level.SEVERE, "InfoAssignment.initLookup");
+ return false;
+ }
+
+ bNew.setImage("/images/New16.gif");
+
+ return true;
+ } // initLookups
+
+ /**
+ * Static Setup - add fields to parameterPanel.
+ *
+ * ResourceType Resource DateTimeFrom DateTimeTo New
+ *
+ */
+
+ private void statInit()
+ {
+ VerticalBox boxResourceType = new VerticalBox();
+ boxResourceType.appendChild(fieldResourceType.getLabel());
+ boxResourceType.appendChild(fieldResourceType.getComponent());
+
+ VerticalBox boxResource = new VerticalBox();
+ boxResource.appendChild(fieldResource.getLabel());
+ boxResource.appendChild(fieldResource.getComponent());
+
+ VerticalBox boxFrom = new VerticalBox();
+ boxFrom.appendChild(labelFrom);
+ boxFrom.appendChild(fieldFrom);
+
+ VerticalBox boxTo = new VerticalBox();
+ boxTo.appendChild(labelTo);
+ boxTo.appendChild(fieldTo);
+
+ // parameterPanel.add(labelPhone, null);
+ // parameterPanel.add(checkFuzzy, null);
+
+ Hbox mainBox = new Hbox();
+
+ bNew.addEventListener(Events.ON_CLICK, this);
+
+ mainBox.setWidth("100%");
+ mainBox.setWidths("30%, 30%, 17%, 17%, 6%");
+ mainBox.appendChild(boxResourceType);
+ mainBox.appendChild(boxResource);
+ mainBox.appendChild(boxFrom);
+ mainBox.appendChild(boxTo);
+ mainBox.appendChild(bNew);
+
+ // parameterPanel.add(checkCustomer, null);
+
+ this.setWidth("850px");
+ this.setTitle("Info Asset");
+ this.setClosable(true);
+ this.setBorder("normal");
+ this.appendChild(mainBox);
+ this.appendChild(new Separator());
+ this.appendChild(contentPanel);
+ this.appendChild(new Separator());
+ this.appendChild(confirmPanel);
+ this.appendChild(new Separator());
+ this.appendChild(statusBar);
+ }
+
+ /**
+ * Dynamic Init
+ * @param value value
+ * @param whereClause where clause
+ */
+
+ private void initInfo(String value, String whereClause)
+ {
+ // C_BPartner bp, AD_User c, C_BPartner_Location l, C_Location a
+
+ // Create Grid
+
+ StringBuffer where = new StringBuffer(s_assignmentWHERE);
+
+ if (whereClause != null && whereClause.length() > 0)
+ where.append(" AND ").append(whereClause);
+
+ prepareTable(s_assignmentLayout, s_assignmentFROM,
+ where.toString(), "rt.Name,r.Name,ra.AssignDateFrom");
+ } // initInfo
+
+ /*************************************************************************/
+
+ /**
+ * Event Listener
+ *
+ * @param e event
+ */
+ public void onEvent (Event e)
+ {
+ // don't requery if fieldValue and fieldName are empty
+ // return;
+
+ super.onEvent(e);
+ } // onEvent
+
+ /*************************************************************************/
+
+ /**
+ * Get dynamic WHERE part of SQL
+ * To be overwritten by concrete classes
+ * @return WHERE clause
+ */
+
+ String getSQLWhere()
+ {
+ StringBuffer sql = new StringBuffer();
+
+ Integer S_ResourceType_ID = (Integer)fieldResourceType.getValue();
+
+ if (S_ResourceType_ID != null)
+ sql.append(" AND rt.S_ResourceType_ID=").append(S_ResourceType_ID.intValue());
+
+ Integer S_Resource_ID = (Integer)fieldResource.getValue();
+
+ if (S_Resource_ID != null)
+ sql.append(" AND r.S_Resource_ID=").append(S_Resource_ID.intValue());
+
+ Date f = fieldFrom.getValue();
+ Timestamp ts = new Timestamp(f.getTime());
+
+ if (ts != null)
+ sql.append(" AND TRUNC(ra.AssignDateFrom)>=").append(DB.TO_DATE(ts,false));
+
+ Date t = fieldTo.getValue();
+ ts = new Timestamp(t.getTime());
+
+ if (ts != null)
+ sql.append(" AND TRUNC(ra.AssignDateTo)<=").append(DB.TO_DATE(ts,false));
+
+ return sql.toString();
+ } // getSQLWhere
+
+ /**
+ * Set Parameters for Query
+ * To be overwritten by concrete classes
+ * @param pstmt pstmt
+ * @param forCount for counting records
+ * @throws SQLException
+ */
+
+ void setParameters (PreparedStatement pstmt, boolean forCount) throws SQLException
+ {
+ }
+
+ /**
+ * History dialog
+ * To be overwritten by concrete classes
+ */
+
+ void showHistory()
+ {
+ }
+
+ /**
+ * Has History (false)
+ * To be overwritten by concrete classes
+ * @return true if it has history (default false)
+ */
+
+ boolean hasHistory()
+ {
+ return false;
+ }
+
+ /**
+ * Customize dialog
+ * To be overwritten by concrete classes
+ */
+
+ void customize()
+ {
+ }
+
+ /**
+ * Has Customize (false)
+ * To be overwritten by concrete classes
+ * @return true if it has customize (default false)
+ */
+
+ boolean hasCustomize()
+ {
+ return false;
+ }
+
+ /**
+ * Zoom action
+ * To be overwritten by concrete classes
+ */
+
+ public void zoom()
+ {
+ }
+
+ /**
+ * Has Zoom (false)
+ * To be overwritten by concrete classes
+ * @return true if it has zoom (default false)
+ */
+
+ boolean hasZoom()
+ {
+ return false;
+ }
+
+ /**
+ * Save Selection Details
+ * To be overwritten by concrete classes
+ */
+
+ void saveSelectionDetail()
+ {
+ }
+
+ public void valueChange(ValueChangeEvent evt)
+ {
+
+ }
+
+ public void tableChanged(WTableModelEvent event)
+ {
+
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoBPartnerPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoBPartnerPanel.java
new file mode 100644
index 0000000000..3eaf0a0d3f
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoBPartnerPanel.java
@@ -0,0 +1,511 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.ArrayList;
+
+import org.adempiere.webui.component.Checkbox;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.Panel;
+import org.adempiere.webui.component.Textbox;
+import org.adempiere.webui.component.WListbox;
+import org.adempiere.webui.event.WTableModelEvent;
+import org.adempiere.webui.event.WTableModelListener;
+import org.compiere.minigrid.ColumnInfo;
+import org.compiere.minigrid.IDColumn;
+import org.compiere.util.CLogger;
+import org.compiere.util.Env;
+import org.compiere.util.KeyNamePair;
+import org.compiere.util.Msg;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zk.ui.event.Events;
+import org.zkoss.zul.Hbox;
+import org.zkoss.zul.Intbox;
+import org.zkoss.zul.Vbox;
+
+/**
+* Search Business Partner and return selection
+* Based on InfoBPartner written by Jorg Janke
+* @author Sendy Yagambrum
+*/
+
+
+public class InfoBPartnerPanel extends InfoPanel implements EventListener, WTableModelListener
+{
+
+ private static final long serialVersionUID = 1L;
+
+ private Label lblValue ;
+ private Textbox fieldValue ;
+ private Label lblName;
+ private Textbox fieldName ;
+ private Label lblContact ;
+ private Textbox fieldContact;
+ private Label lblEMail ;
+ private Textbox fieldEMail;
+ private Label lblPostal;
+ private Intbox fieldPostal;
+ private Label lblPhone;
+ private Intbox fieldPhone;
+ private Checkbox checkAND ;
+ private Checkbox checkCustomer;
+ private Checkbox checkVendor;
+
+ private int m_C_BPartner_Location_ID_index = -1;
+
+ /** SalesOrder Trx */
+ private boolean m_isSOTrx;
+
+ /** Logger */
+ protected CLogger log = CLogger.getCLogger(getClass());
+
+ /** From Clause */
+ private static String s_partnerFROM = "C_BPartner"
+ + " LEFT OUTER JOIN C_BPartner_Location l ON (C_BPartner.C_BPartner_ID=l.C_BPartner_ID AND l.IsActive='Y')"
+ + " LEFT OUTER JOIN AD_User c ON (C_BPartner.C_BPartner_ID=c.C_BPartner_ID AND (c.C_BPartner_Location_ID IS NULL OR c.C_BPartner_Location_ID=l.C_BPartner_Location_ID) AND c.IsActive='Y')"
+ + " LEFT OUTER JOIN C_Location a ON (l.C_Location_ID=a.C_Location_ID)";
+
+ /** Array of Column Info */
+ private static ColumnInfo[] s_partnerLayout = {
+ new ColumnInfo(" ", "C_BPartner.C_BPartner_ID", IDColumn.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "Value"), "C_BPartner.Value", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "Name"), "C_BPartner.Name", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "Contact"), "c.Name AS Contact", KeyNamePair.class, "c.AD_User_ID"),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "SO_CreditAvailable"), "C_BPartner.SO_CreditLimit-C_BPartner.SO_CreditUsed AS SO_CreditAvailable", BigDecimal.class, true, true, null),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "SO_CreditUsed"), "C_BPartner.SO_CreditUsed", BigDecimal.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "Phone"), "c.Phone", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "Postal"), "a.Postal", KeyNamePair.class, "l.C_BPartner_Location_ID"),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "City"), "a.City", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "TotalOpenBalance"), "C_BPartner.TotalOpenBalance", BigDecimal.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "Revenue"), "C_BPartner.ActualLifetimeValue", BigDecimal.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "Address1"), "a.Address1", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "IsShipTo"), "l.IsShipTo", Boolean.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "IsBillTo"), "l.IsBillTo", Boolean.class)
+ };
+
+ /**
+ * Standard Constructor
+ * @param queryvalue Query value Name or Value if contains numbers
+ * @param isSOTrx if false, query vendors only
+ * @param whereClause where clause
+ */
+ public InfoBPartnerPanel(String queryValue,int windowNo, boolean isSOTrx,boolean multipleSelection, String whereClause)
+ {
+
+ super (windowNo, "C_BPartner", "C_BPartner_ID",multipleSelection, whereClause);
+ m_isSOTrx = isSOTrx;
+ initComponents();
+ init();
+ initInfo(queryValue, whereClause);
+
+ int no = contentPanel.getRowCount();
+ setStatusLine(Integer.toString(no) + " " + Msg.getMsg(Env.getCtx(), "SearchRows_EnterQuery"), false);
+ setStatusDB(Integer.toString(no));
+ //
+ if (queryValue != null && queryValue.length()>0)
+ {
+ executeQuery();
+ renderItems();
+ }
+
+ }
+
+ private void initComponents()
+ {
+ lblValue = new Label();
+ lblValue.setValue(Msg.translate(Env.getCtx(), "Value").substring(1));
+ lblName = new Label();
+ lblName.setValue(Msg.translate(Env.getCtx(), "Name").substring(1));
+ lblContact = new Label();
+ lblContact.setValue(Msg.translate(Env.getCtx(), "Contact"));
+ lblEMail = new Label();
+ lblEMail.setValue(Msg.getMsg(Env.getCtx(), "EMail"));
+ lblPostal = new Label();
+ lblPostal.setValue(Msg.getMsg(Env.getCtx(), "Postal"));
+ lblPhone = new Label();
+ lblPhone.setValue(Msg.translate(Env.getCtx(), "Phone"));
+
+ fieldValue = new Textbox();
+ fieldValue.setMaxlength(40);
+ fieldName = new Textbox();
+ fieldName.setMaxlength(40);
+ fieldContact = new Textbox();
+ fieldContact.setMaxlength(40);
+ fieldEMail = new Textbox();
+ fieldEMail.setMaxlength(40);
+ fieldPostal = new Intbox();
+ fieldPostal.setMaxlength(40);
+ fieldPhone = new Intbox();
+ fieldPhone.setMaxlength(40);
+
+ checkAND = new Checkbox();
+ checkAND.addEventListener(Events.ON_CHECK, this);
+ checkAND.setChecked(true);
+ checkCustomer = new Checkbox();
+ checkCustomer.setChecked(true);
+ checkCustomer.addEventListener(Events.ON_CHECK, this);
+ checkVendor = new Checkbox();
+ checkVendor.setChecked(true);
+ checkVendor.addEventListener(Events.ON_CHECK, this);
+
+ contentPanel = new WListbox();
+ contentPanel.setWidth("100%");
+ contentPanel.setHeight("400px");
+ contentPanel.setStyle("overflow:auto");
+
+ }
+
+ private void init()
+ {
+
+ Panel pnlValue = new Panel();
+ pnlValue.appendChild(lblValue);
+ pnlValue.appendChild(fieldValue);
+ pnlValue.setAlign("right");
+
+ Panel pnlName = new Panel();
+ pnlName.appendChild(lblName);
+ pnlName.appendChild(fieldName);
+ pnlName.setAlign("right");
+
+ Panel pnlContact = new Panel();
+ pnlContact.appendChild(lblContact);
+ pnlContact.appendChild(fieldContact);
+ pnlContact.setAlign("right");
+
+ Panel pnlEMail = new Panel();
+ pnlEMail.appendChild(lblEMail);
+ pnlEMail.appendChild(fieldEMail);
+ pnlEMail.setAlign("right");
+
+ Panel pnlPostal = new Panel();
+ pnlPostal.appendChild(lblPostal);
+ pnlPostal.appendChild(fieldPostal);
+ pnlPostal.setAlign("right");
+
+ Panel pnlPhone = new Panel();
+ pnlPhone.appendChild(lblPhone);
+ pnlPhone.appendChild(fieldPhone);
+ pnlPhone.setAlign("right");
+
+ Panel pnlCheckAND = new Panel();
+ Label lblAND = new Label();
+ lblAND.setValue("All/Any");
+ pnlCheckAND.appendChild(checkAND);
+ pnlCheckAND.appendChild(lblAND);
+ pnlCheckAND.setAlign("left");
+
+ Panel pnlCheckCust = new Panel();
+ Label lblCheckCust = new Label();
+ lblCheckCust.setValue("Customers Only");
+ pnlCheckCust.appendChild(checkCustomer);
+ pnlCheckCust.appendChild(lblCheckCust);
+ pnlCheckCust.setAlign("right");
+
+ Panel pnlCheckVendor = new Panel();
+ Label lblCheckVendor = new Label();
+ lblCheckVendor.setValue("Vendors Only");
+ pnlCheckVendor.appendChild(checkVendor);
+ pnlCheckVendor.appendChild(lblCheckVendor);
+ pnlCheckVendor.setAlign("right");
+
+ Vbox vbox1 = new Vbox();
+ vbox1.appendChild(pnlValue);
+ vbox1.appendChild(pnlName);
+
+ Vbox vbox2 = new Vbox();
+ vbox2.appendChild(pnlContact);
+ vbox2.appendChild(pnlEMail);
+
+ Vbox vbox3 = new Vbox();
+ vbox3.appendChild(pnlPostal);
+ vbox3.appendChild(pnlPhone);
+
+ Vbox vbox4 = new Vbox();
+ vbox4.appendChild(pnlCheckAND);
+
+ if (m_isSOTrx)
+ {
+ vbox4.appendChild(pnlCheckCust);
+ }
+ else
+ {
+ vbox4.appendChild(pnlCheckVendor);
+ }
+
+ Hbox parameterPanel = new Hbox();
+ parameterPanel.appendChild(vbox1);
+ parameterPanel.appendChild(vbox2);
+ parameterPanel.appendChild(vbox3);
+ parameterPanel.appendChild(vbox4);
+
+ Vbox mainPanel = new Vbox();
+ mainPanel.appendChild(parameterPanel);
+
+/* Div div = new Div();
+ div.setStyle("overflow:hidden");
+ div.setWidth("1000px");
+ div.appendChild(contentPanel);
+ mainPanel.appendChild(div);*/
+
+ mainPanel.setWidth("100%");
+ mainPanel.appendChild(contentPanel);
+ mainPanel.appendChild(confirmPanel);
+ mainPanel.appendChild(statusBar);
+
+ this.appendChild(mainPanel);
+
+ this.setBorder("normal");
+ this.setWidth("1000px");
+
+ }
+
+ /**
+ * Dynamic Init
+ * @param value value
+ * @param whereClause where clause
+ */
+
+ private void initInfo(String value, String whereClause)
+ {
+ /** From
+ C_BPartner
+ LEFT OUTER JOIN C_BPartner_Location l ON (C_BPartner.C_BPartner_ID=l.C_BPartner_ID AND l.IsActive='Y')
+ LEFT OUTER JOIN AD_User c ON (C_BPartner.C_BPartner_ID=c.C_BPartner_ID AND (c.C_BPartner_Location_ID IS NULL OR c.C_BPartner_Location_ID=l.C_BPartner_Location_ID) AND c.IsActive='Y')
+ LEFT OUTER JOIN C_Location a ON (l.C_Location_ID=a.C_Location_ID)
+ **/
+
+ // Create Grid
+ StringBuffer where = new StringBuffer();
+ where.append("C_BPartner.IsSummary='N' AND C_BPartner.IsActive='Y'");
+ if (whereClause != null && whereClause.length() > 0)
+ where.append(" AND ").append(whereClause);
+ //
+
+ prepareTable(s_partnerLayout, s_partnerFROM, where.toString(), "C_BPartner.Value");
+
+// Get indexes
+ for (int i = 0; i < p_layout.length; i++)
+ {
+ if (p_layout[i].getKeyPairColSQL().indexOf("C_BPartner_Location_ID") != -1)
+ m_C_BPartner_Location_ID_index = i;
+ }
+ // Set Value
+ if (value == null)
+ value = "%";
+ if (!value.endsWith("%"))
+ value += "%";
+
+ // Put query string in Name if not numeric
+ if (value.equals("%"))
+ fieldName.setText(value);
+ // No Numbers entered
+ else if ((value.indexOf('0')+value.indexOf('1')+value.indexOf('2')+value.indexOf('3')+value.indexOf('4') +value.indexOf('5')
+ +value.indexOf('6')+value.indexOf('7')+value.indexOf('8')+value.indexOf('9')) == -10)
+ {
+ if (value.startsWith("%"))
+ fieldName.setText(value);
+ else
+ fieldName.setText("%" + value);
+ }
+ // Number entered
+ else
+ fieldValue.setText(value);
+ } // initInfo
+
+ /**
+ * Set Parameters for Query.
+ * (as defined in getSQLWhere)
+ * @param pstmt pstmt
+ * @param forCount for counting records
+ * @throws SQLException
+ */
+ public void setParameters(PreparedStatement pstmt, boolean forCount) throws SQLException
+ {
+ int index = 1;
+ // => Value
+ String value = fieldValue.getText().toUpperCase();
+ if (!(value.equals("") || value.equals("%")))
+ {
+ if (!value.endsWith("%"))
+ value += "%";
+ pstmt.setString(index++, value);
+ log.fine("Value: " + value);
+ }
+ // => Name
+ String name = fieldName.getText().toUpperCase();
+ if (!(name.equals("") || name.equals("%")))
+ {
+ if (!name.endsWith("%"))
+ name += "%";
+ pstmt.setString(index++, name);
+ log.fine("Name: " + name);
+ }
+ // => Contact
+ String contact = fieldContact.getText().toUpperCase();
+ if (!(contact.equals("") || contact.equals("%")))
+ {
+ if (!contact.endsWith("%"))
+ contact += "%";
+ pstmt.setString(index++, contact);
+ log.fine("Contact: " + contact);
+ }
+ // => EMail
+ String email = fieldEMail.getText().toUpperCase();
+ if (!(email.equals("") || email.equals("%")))
+ {
+ if (!email.endsWith("%"))
+ email += "%";
+ pstmt.setString(index++, email);
+ log.fine("EMail: " + email);
+ }
+ // => Phone
+ String phone = fieldPhone.getText().toUpperCase();
+ if (!(phone.equals("") || phone.equals("%")))
+ {
+ if (!phone.endsWith("%"))
+ phone += "%";
+ pstmt.setString(index++, phone);
+ log.fine("Phone: " + phone);
+ }
+ // => Postal
+ String postal = fieldPostal.getText().toUpperCase();
+ if (!(postal.equals("") || postal.equals("%")))
+ {
+ if (!postal.endsWith("%"))
+ postal += "%";
+ pstmt.setString(index++, postal);
+ log.fine("Postal: " + postal);
+ }
+ } // setParameters
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /**
+ * Construct SQL Where Clause and define parameters.
+ * (setParameters needs to set parameters)
+ * Includes first AND
+ * @return WHERE clause
+ */
+ public String getSQLWhere()
+ {
+ ArrayList list = new ArrayList();
+ // => Value
+ String value = fieldValue.getText().toUpperCase();
+ if (!(value.equals("") || value.equals("%")))
+ list.add ("UPPER(C_BPartner.Value) LIKE ?");
+ // => Name
+ String name = fieldName.getText().toUpperCase();
+ if (!(name.equals("") || name.equals("%")))
+ list.add ("UPPER(C_BPartner.Name) LIKE ?");
+ // => Contact
+ String contact = fieldContact.getText().toUpperCase();
+ if (!(contact.equals("") || contact.equals("%")))
+ list.add ("UPPER(c.Name) LIKE ?");
+ // => EMail
+ String email = fieldEMail.getText().toUpperCase();
+ if (!(email.equals("") || email.equals("%")))
+ list.add ("UPPER(c.EMail) LIKE ?");
+ // => Phone
+ String phone = fieldPhone.getText().toUpperCase();
+ if (!(phone.equals("") || phone.equals("%")))
+ list.add ("UPPER(c.Phone) LIKE ?");
+ // => Postal
+ String postal = fieldPostal.getText().toUpperCase();
+ if (!(postal.equals("") || postal.equals("%")))
+ list.add ("UPPER(a.Postal) LIKE ?");
+ StringBuffer sql = new StringBuffer();
+ int size = list.size();
+ // Just one
+ if (size == 1)
+ sql.append(" AND ").append(list.get(0));
+ else if (size > 1)
+ {
+ boolean AND = checkAND.isChecked();
+ sql.append(" AND ");
+ if (!AND)
+ sql.append("(");
+ for (int i = 0; i < size; i++)
+ {
+ if (i > 0)
+ sql.append(AND ? " AND " : " OR ");
+ sql.append(list.get(i));
+ }
+ if (!AND)
+ sql.append(")");
+ }
+ // Static SQL
+ if (checkCustomer.isChecked())
+ {
+ sql.append(" AND ");
+ if (m_isSOTrx)
+ sql.append ("C_BPartner.IsCustomer='Y'");
+ else
+ sql.append ("C_BPartner.IsVendor='Y'");
+ }
+ return sql.toString();
+
+ } // getSQLWhere
+
+ /*************************************************************************/
+
+ /**
+ * Save Selection Details
+ * Get Location/Partner Info
+ */
+ public void saveSelectionDetail()
+ {
+ int row = contentPanel.getSelectedRow();
+ if (row == -1)
+ return;
+
+ int AD_User_ID = 0;
+ int C_BPartner_Location_ID = 0;
+
+
+ AD_User_ID = ((KeyNamePair)contentPanel.getValueAt(contentPanel.getSelectedIndex(), 3)).getKey();
+ //AD_User_ID = contentPanel.getSelectedRowKey();
+
+ if (m_C_BPartner_Location_ID_index != -1)
+ {
+ Object data =contentPanel.getValueAt(row, m_C_BPartner_Location_ID_index);
+ if (data instanceof KeyNamePair)
+ C_BPartner_Location_ID = ((KeyNamePair)data).getKey();
+ }
+ // publish for Callout to read
+ Integer ID = getSelectedRowKey();
+ Env.setContext(Env.getCtx(), Env.WINDOW_INFO, Env.TAB_INFO, "C_BPartner_ID", ID == null ? "0" : ID.toString());
+ Env.setContext(Env.getCtx(), Env.WINDOW_INFO, Env.TAB_INFO, "AD_User_ID", String.valueOf(AD_User_ID));
+ Env.setContext(Env.getCtx(), Env.WINDOW_INFO, Env.TAB_INFO, "C_BPartner_Location_ID", String.valueOf(C_BPartner_Location_ID));
+
+ } // saveSelectionDetail
+
+ public boolean isAsap()
+ {
+ return true;
+ }
+
+ public void tableChanged(WTableModelEvent event)
+ {
+
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoCashLinePanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoCashLinePanel.java
new file mode 100644
index 0000000000..243acf2981
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoCashLinePanel.java
@@ -0,0 +1,482 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Date;
+
+import org.adempiere.webui.component.Checkbox;
+import org.adempiere.webui.component.Datebox;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.Textbox;
+import org.adempiere.webui.component.VerticalBox;
+import org.adempiere.webui.editor.WEditor;
+import org.adempiere.webui.editor.WSearchEditor;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.event.ValueChangeListener;
+import org.adempiere.webui.event.WTableModelEvent;
+import org.compiere.minigrid.ColumnInfo;
+import org.compiere.minigrid.IDColumn;
+import org.compiere.model.MLookupFactory;
+import org.compiere.util.DB;
+import org.compiere.util.DisplayType;
+import org.compiere.util.Env;
+import org.compiere.util.Msg;
+import org.compiere.util.Util;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zk.ui.event.Events;
+import org.zkoss.zul.Hbox;
+import org.zkoss.zul.Separator;
+
+/**
+* Based on InfoCashLine written by Jorg Janke
+*
+* @author Niraj Sohun
+* Aug 03, 2007
+*/
+
+public class InfoCashLinePanel extends InfoPanel implements ValueChangeListener, EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ /** list of query columns */
+ private ArrayList m_queryColumns = new ArrayList();
+
+ /** Table Name */
+ private String m_tableName;
+
+ /** Key Column Name */
+ private String m_keyColumn;
+
+ private Textbox fName = new Textbox();
+ private Textbox fAmtTo = new Textbox();
+ private Textbox fAmtFrom = new Textbox();
+
+ private WEditor fCashBook_ID;
+ private WEditor fInvoice_ID;
+ private WEditor fBankAccount_ID;
+
+ private Datebox fDateFrom = new Datebox();
+ private Datebox fDateTo = new Datebox();
+
+ private Checkbox cbAbsolute = new Checkbox();
+
+ private Label lName = new Label(Msg.translate(Env.getCtx(), "Name"));
+ private Label lDateFrom = new Label(Msg.translate(Env.getCtx(), "StatementDate"));
+ private Label lDateTo = new Label("-");
+ private Label lAmtFrom = new Label(Msg.translate(Env.getCtx(), "Amount"));
+ private Label lAmtTo = new Label("-");
+
+ /** Array of Column Info */
+ private static final ColumnInfo[] s_cashLayout = {
+ new ColumnInfo(" ", "cl.C_CashLine_ID", IDColumn.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "C_CashBook_ID"),
+ "(SELECT cb.Name FROM C_CashBook cb WHERE cb.C_CashBook_ID=c.C_CashBook_ID)", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "Name"),
+ "c.Name", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "StatementDate"),
+ "c.StatementDate", Timestamp.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "Line"),
+ "cl.Line", Integer.class),
+ // new ColumnInfo(Msg.translate(Env.getCtx(), "C_Currency_ID"),
+ // "(SELECT ISO_Code FROM C_Currency c WHERE c.C_Currency_ID=cl.C_Currency_ID)", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "Amount"),
+ "cl.Amount", BigDecimal.class, true, true, null),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "C_Invoice_ID"),
+ "(SELECT i.DocumentNo||'_'||" + DB.TO_CHAR("i.DateInvoiced",DisplayType.Date,Env.getAD_Language(Env.getCtx()))
+ + "||'_'||" + DB.TO_CHAR("i.GrandTotal",DisplayType.Amount,Env.getAD_Language(Env.getCtx()))
+ + " FROM C_Invoice i WHERE i.C_Invoice_ID=cl.C_Invoice_ID)", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "C_BankAccount_ID"),
+ "(SELECT b.Name||' '||ba.AccountNo FROM C_Bank b, C_BankAccount ba WHERE b.C_Bank_ID=ba.C_Bank_ID AND ba.C_BankAccount_ID=cl.C_BankAccount_ID)", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "C_Charge_ID"),
+ "(SELECT ca.Name FROM C_Charge ca WHERE ca.C_Charge_ID=cl.C_Charge_ID)", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "DiscountAmt"),
+ "cl.DiscountAmt", BigDecimal.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "WriteOffAmt"),
+ "cl.WriteOffAmt", BigDecimal.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "Description"),
+ "cl.Description", String.class)
+ };
+
+ /**
+ * Detail Protected Constructor
+ *
+ * @param WindowNo window no
+ * @param value query value
+ * @param multiSelection multiple selections
+ * @param whereClause where clause
+ */
+
+ protected InfoCashLinePanel( int WindowNo, String value,
+ boolean multiSelection, String whereClause)
+ {
+ super (WindowNo, "cl", "C_CashLine_ID", multiSelection, whereClause);
+ log.info( "InfoCashLine");
+ setTitle(Msg.getMsg(Env.getCtx(), "InfoCashLine"));
+
+ try
+ {
+ statInit();
+ p_loadedOK = initInfo ();
+ }
+ catch (Exception e)
+ {
+ return;
+ }
+
+ int no = contentPanel.getRowCount();
+ setStatusLine(Integer.toString(no) + " " + Msg.getMsg(Env.getCtx(), "SearchRows_EnterQuery"), false);
+ setStatusDB(Integer.toString(no));
+
+ if (value != null && value.length() > 0)
+ {
+ fName .setValue(value);
+ executeQuery();
+ }
+
+ //pack();
+
+ // Focus
+ // fName.requestFocus();
+ } // InfoCashLinePanel
+
+ /**
+ * Static Setup - add fields to parameterPanel
+ * @throws Exception if Lookups cannot be created
+ */
+
+ private void statInit() throws Exception
+ {
+ Hbox boxName = new Hbox();
+
+ fName.addEventListener(Events.ON_CHANGE, this);
+
+ boxName.setWidth("100%");
+ boxName.setWidths("40%, 60%");
+ boxName.appendChild(lName );
+ boxName.appendChild(fName);
+
+ // fOrg_ID = new VLookup("AD_Org_ID", false, false, true,
+ // MLookupFactory.create(Env.getCtx(), 3486, m_WindowNo, DisplayType.TableDir, false),
+ // DisplayType.TableDir, m_WindowNo);
+ // lOrg_ID.setLabelFor(fOrg_ID);
+ // fOrg_ID.setBackground(AdempierePLAF.getInfoBackground());
+ // 5249 - C_Cash.C_CashBook_ID
+
+ Hbox boxCashBook = new Hbox();
+
+ fCashBook_ID = new WSearchEditor(
+ MLookupFactory.get (Env.getCtx(), p_WindowNo, 0, 5249, DisplayType.TableDir),
+ Msg.translate(Env.getCtx(), "C_CashBook_ID"), "", false, false, true);
+ fCashBook_ID.addValueChangeListner(this);
+
+ boxCashBook.appendChild(fCashBook_ID.getLabel());
+ boxCashBook.appendChild(fCashBook_ID.getComponent());
+
+ Hbox boxInvoice = new Hbox();
+
+ // 5354 - C_CashLine.C_Invoice_ID
+ fInvoice_ID = new WSearchEditor(
+ MLookupFactory.get (Env.getCtx(), p_WindowNo, 0, 5354, DisplayType.Search),
+ Msg.translate(Env.getCtx(), "C_Invoice_ID"), "", false, false, true);
+ fInvoice_ID.addValueChangeListner(this);
+
+ boxInvoice.appendChild(fInvoice_ID.getLabel());
+ boxInvoice.appendChild(fInvoice_ID.getComponent());
+
+ Hbox boxBankAcct = new Hbox();
+
+ // 5295 - C_CashLine.C_BankAccount_ID
+ fBankAccount_ID = new WSearchEditor(
+ MLookupFactory.get (Env.getCtx(), p_WindowNo, 0, 5295, DisplayType.TableDir),
+ Msg.translate(Env.getCtx(), "C_BankAccount_ID"), "", false, false, true);
+ fBankAccount_ID.addValueChangeListner(this);
+
+ boxBankAcct.appendChild(fBankAccount_ID.getLabel());
+ boxBankAcct.appendChild(fBankAccount_ID.getComponent());
+
+ // 5296 - C_CashLine.C_Charge_ID
+ // 5291 - C_CashLine.C_Cash_ID
+
+ cbAbsolute.setLabel(Msg.translate(Env.getCtx(), "AbsoluteAmt"));
+ cbAbsolute.addEventListener(Events.ON_CHECK, this);
+
+ Hbox boxDateFrom = new Hbox();
+ boxDateFrom.setWidth("100%");
+ boxDateFrom.setWidths("40%, 60%");
+ boxDateFrom.appendChild(lDateFrom);
+ boxDateFrom.appendChild(fDateFrom);
+
+ Hbox boxDateTo = new Hbox();
+ boxDateTo.setWidth("100%");
+ boxDateTo.setWidths("10%, 90%");
+ boxDateTo.appendChild(lDateTo);
+ boxDateTo.appendChild(fDateTo);
+
+ Hbox boxAmtFrom = new Hbox();
+ boxAmtFrom.setWidth("100%");
+ boxAmtFrom.setWidths("40%, 60%");
+ boxAmtFrom.appendChild(lAmtFrom);
+ boxAmtFrom.appendChild(fAmtFrom);
+
+ Hbox boxAmtTo = new Hbox();
+ boxAmtTo.setWidth("100%");
+ boxAmtTo.setWidths("10%, 90%");
+ boxAmtTo.appendChild(lAmtTo);
+ boxAmtTo.appendChild(fAmtTo);
+
+ VerticalBox boxCol1 = new VerticalBox();
+ boxCol1.appendChild(boxCashBook);
+ boxCol1.appendChild(new Separator());
+ boxCol1.appendChild(boxInvoice);
+ boxCol1.appendChild(new Separator());
+ boxCol1.appendChild(boxBankAcct);
+
+ VerticalBox boxCol2 = new VerticalBox();
+ boxCol2.appendChild(boxName);
+ boxCol2.appendChild(new Separator());
+ boxCol2.appendChild(boxDateFrom);
+ boxCol2.appendChild(new Separator());
+ boxCol2.appendChild(boxAmtFrom);
+
+ VerticalBox boxCol3 = new VerticalBox();
+ boxCol3.appendChild(cbAbsolute);
+ boxCol3.appendChild(new Separator());
+ boxCol3.appendChild(boxDateTo);
+ boxCol3.appendChild(new Separator());
+ boxCol3.appendChild(boxAmtTo);
+
+ // parameterPanel.add(lOrg_ID, null);
+ // parameterPanel.add(fOrg_ID, null);
+
+ Hbox mainBox = new Hbox();
+ mainBox.setWidth("100%");
+ mainBox.setWidths("40%, 50%, 10%");
+ mainBox.appendChild(boxCol1);
+ mainBox.appendChild(boxCol2);
+ mainBox.appendChild(boxCol3);
+
+ this.setWidth("850px");
+ this.setTitle("CashLine Info");
+ this.setClosable(true);
+ this.setBorder("normal");
+ this.appendChild(mainBox);
+ this.appendChild(new Separator());
+ this.appendChild(contentPanel);
+ this.appendChild(new Separator());
+ this.appendChild(confirmPanel);
+ this.appendChild(new Separator());
+ this.appendChild(statusBar);
+ }
+
+ /**
+ * General Init
+ * @return true, if success
+ */
+ private boolean initInfo ()
+ {
+ // Prepare table
+ StringBuffer where = new StringBuffer("cl.IsActive='Y'");
+
+ if (p_whereClause.length() > 0)
+ where.append(" AND ").append(Util.replace(p_whereClause, "C_CashLine.", "cl."));
+
+ prepareTable ( s_cashLayout, "C_CashLine cl INNER JOIN C_Cash c ON (cl.C_Cash_ID=c.C_Cash_ID)",
+ where.toString(), "2,3,cl.Line");
+
+ return true;
+ } // initInfo
+
+
+ /**************************************************************************
+ * Construct SQL Where Clause and define parameters
+ * (setParameters needs to set parameters)
+ * Includes first AND
+ * @return sql where clause
+ */
+
+ String getSQLWhere()
+ {
+ StringBuffer sql = new StringBuffer();
+
+ if (fName.getText().length() > 0)
+ sql.append(" AND UPPER(c.Name) LIKE ?");
+
+ if (fCashBook_ID.getDisplay() != "")
+ sql.append(" AND c.C_CashBook_ID=?");
+
+ if (fInvoice_ID.getDisplay() != "")
+ sql.append(" AND cl.C_Invoice_ID=?");
+
+ if (fDateFrom.getValue() != null || fDateTo.getValue() != null)
+ {
+ Date f = fDateFrom.getValue();
+ Timestamp from = new Timestamp(f.getTime());
+
+ Date t = fDateTo.getValue();
+ Timestamp to = new Timestamp(t.getTime());
+
+ if (from == null && to != null)
+ sql.append(" AND TRUNC(c.StatementDate) <= ?");
+ else if (from != null && to == null)
+ sql.append(" AND TRUNC(c.StatementDate) >= ?");
+ else if (from != null && to != null)
+ sql.append(" AND TRUNC(c.StatementDate) BETWEEN ? AND ?");
+ }
+
+ if (fAmtFrom.getValue() != null || fAmtTo.getValue() != null)
+ {
+ BigDecimal from = new BigDecimal(fAmtFrom.getValue());
+ BigDecimal to = new BigDecimal(fAmtTo.getValue());
+
+ if (cbAbsolute .isChecked())
+ sql.append(" AND ABS(cl.Amount)");
+ else
+ sql.append(" AND cl.Amount");
+
+ if (from == null && to != null)
+ sql.append(" <=?");
+ else if (from != null && to == null)
+ sql.append(" >=?");
+ else if (from != null && to != null)
+ {
+ if (from.compareTo(to) == 0)
+ sql.append(" =?");
+ else
+ sql.append(" BETWEEN ? AND ?");
+ }
+ }
+
+ log.fine(sql.toString());
+ return sql.toString();
+ } // getSQLWhere
+
+ /**
+ * Set Parameters for Query.
+ * (as defined in getSQLWhere)
+ * @param pstmt statement
+ * @param forCount for counting records
+ * @throws SQLException
+ */
+
+ void setParameters(PreparedStatement pstmt, boolean forCount) throws SQLException
+ {
+ int index = 1;
+ if (fName.getText().length() > 0)
+ pstmt.setString(index++, getSQLText(fName));
+
+ if (fCashBook_ID.getValue() != null)
+ {
+ Integer cb = (Integer)fCashBook_ID.getValue();
+ pstmt.setInt(index++, cb.intValue());
+ log.fine("CashBook=" + cb);
+ }
+
+ if (fInvoice_ID.getValue() != null)
+ {
+ Integer i = (Integer)fInvoice_ID.getValue();
+ pstmt.setInt(index++, i.intValue());
+ log.fine("Invoice=" + i);
+ }
+
+ if (fDateFrom.getValue() != null || fDateTo.getValue() != null)
+ {
+ Date f = fDateFrom.getValue();
+ Timestamp from = new Timestamp(f.getTime());
+
+ Date t = fDateTo.getValue();
+ Timestamp to = new Timestamp(t.getTime());
+
+ log.fine("Date From=" + from + ", To=" + to);
+
+ if (from == null && to != null)
+ pstmt.setTimestamp(index++, to);
+ else if (from != null && to == null)
+ pstmt.setTimestamp(index++, from);
+ else if (from != null && to != null)
+ {
+ pstmt.setTimestamp(index++, from);
+ pstmt.setTimestamp(index++, to);
+ }
+ }
+
+ if (fAmtFrom.getValue() != null || fAmtTo.getValue() != null)
+ {
+ BigDecimal from = new BigDecimal(fAmtFrom.getValue());
+ BigDecimal to = new BigDecimal(fAmtTo.getValue());
+
+ if (cbAbsolute.isChecked())
+ {
+ if (from != null)
+ from = from.abs();
+ if (to != null)
+ to = to.abs();
+ }
+
+ log.fine("Amt From=" + from + ", To=" + to + ", Absolute=" + cbAbsolute.isChecked());
+
+ if (from == null && to != null)
+ pstmt.setBigDecimal(index++, to);
+ else if (from != null && to == null)
+ pstmt.setBigDecimal(index++, from);
+ else if (from != null && to != null)
+ {
+ if (from.compareTo(to) == 0)
+ pstmt.setBigDecimal(index++, from);
+ else
+ {
+ pstmt.setBigDecimal(index++, from);
+ pstmt.setBigDecimal(index++, to);
+ }
+ }
+ }
+ } // setParameters
+
+ /**
+ * Get SQL WHERE parameter
+ * @param f field
+ * @return Upper case text with % at the end
+ */
+
+ private String getSQLText (Textbox f)
+ {
+ String s = f.getText().toUpperCase();
+
+ if (!s.endsWith("%"))
+ s += "%";
+
+ log.fine( "String=" + s);
+
+ return s;
+ } // getSQLText
+
+ public void valueChange(ValueChangeEvent evt)
+ {
+
+ }
+
+ public void tableChanged(WTableModelEvent event)
+ {
+
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoGeneralPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoGeneralPanel.java
new file mode 100644
index 0000000000..05fc200a00
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoGeneralPanel.java
@@ -0,0 +1,402 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.logging.Level;
+
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.Textbox;
+import org.adempiere.webui.component.WListbox;
+import org.adempiere.webui.event.WTableModelEvent;
+import org.adempiere.webui.window.FDialog;
+import org.compiere.minigrid.ColumnInfo;
+import org.compiere.minigrid.IDColumn;
+import org.compiere.util.DB;
+import org.compiere.util.DisplayType;
+import org.compiere.util.Env;
+import org.compiere.util.Msg;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zul.Div;
+import org.zkoss.zul.Hbox;
+import org.zkoss.zul.Vbox;
+
+public class InfoGeneralPanel extends InfoPanel implements EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private Textbox txt1;
+ private Textbox txt2;
+ private Textbox txt3;
+ private Textbox txt4;
+
+ private Label lbl1;
+ private Label lbl2;
+ private Label lbl3;
+ private Label lbl4;
+
+ /** String Array of Column Info */
+ private ColumnInfo[] m_generalLayout;
+
+ /** list of query columns */
+ private ArrayList m_queryColumns = new ArrayList();
+
+ /** list of query columns (SQL) */
+ private ArrayList m_queryColumnsSql = new ArrayList();
+
+ public InfoGeneralPanel(String queryValue, int windowNo,String tableName,String keyColumn, boolean isSOTrx, String whereClause)
+ {
+ super(windowNo, tableName, keyColumn, false,whereClause);
+
+ //log.info(tableName + " - " + keyColumn + " - " + whereClause);
+
+ setTitle(Msg.getMsg(Env.getCtx(), "Info"));
+
+ init();
+ initComponents();
+
+ p_loadedOK = initInfo ();
+
+
+ if (queryValue != null && queryValue.length() > 0)
+ {
+ executeQuery();
+ renderItems();
+ }
+
+ }
+
+ private void initComponents()
+ {
+
+ Hbox parameterPanel = new Hbox();
+ parameterPanel.setWidth("100%");
+ parameterPanel.appendChild(lbl1);
+ parameterPanel.appendChild(txt1);
+ parameterPanel.appendChild(lbl2);
+ parameterPanel.appendChild(txt2);
+ parameterPanel.appendChild(lbl3);
+ parameterPanel.appendChild(txt3);
+ parameterPanel.appendChild(lbl4);
+ parameterPanel.appendChild(txt4);
+
+ Vbox mainPanel = new Vbox();
+ mainPanel.appendChild(parameterPanel);
+ Div div = new Div();
+ div.setStyle("overflow:auto");
+ div.setWidth("100%");
+ div.appendChild(contentPanel);
+
+ mainPanel.appendChild(div);
+ mainPanel.appendChild(confirmPanel);
+
+ this.appendChild(mainPanel);
+ this.setBorder("normal");
+ this.setWidth("900px");
+ //this.setHeight("500px");
+ }
+
+ private void init()
+ {
+ txt1 = new Textbox();
+ txt2 = new Textbox();
+ txt3 = new Textbox();
+ txt4 = new Textbox();
+
+ lbl1 = new Label();
+ lbl2 = new Label();
+ lbl3 = new Label();
+ lbl4 = new Label();
+
+ contentPanel = new WListbox();
+ contentPanel.setWidth("100%");
+ }
+
+ private boolean initInfo ()
+ {
+ if (!initInfoTable())
+ return false;
+
+ // Prepare table
+
+ StringBuffer where = new StringBuffer("IsActive='Y'");
+
+ if (p_whereClause.length() > 0)
+ where.append(" AND ").append(p_whereClause);
+ prepareTable(m_generalLayout, p_tableName, where.toString(), "2");
+
+ // Set & enable Fields
+
+ lbl1.setValue(Msg.translate(Env.getCtx(), m_queryColumns.get(0).toString()).substring(1));
+ //txt1.addActionListener(this);
+
+ if (m_queryColumns.size() > 1)
+ {
+ lbl2.setValue(Msg.translate(Env.getCtx(), m_queryColumns.get(1).toString()));
+ //txt2.addActionListener(this);
+ }
+ else
+ {
+ lbl2.setVisible(false);
+ txt2.setVisible(false);
+ }
+
+ if (m_queryColumns.size() > 2)
+ {
+ lbl3.setValue(Msg.translate(Env.getCtx(), m_queryColumns.get(2).toString()));
+ //txt3.addActionListener(this);
+ }
+ else
+ {
+ lbl3.setVisible(false);
+ txt3.setVisible(false);
+ }
+
+ if (m_queryColumns.size() > 3)
+ {
+ lbl4.setValue(Msg.translate(Env.getCtx(), m_queryColumns.get(3).toString()));
+ //txt4.addActionListener(this);
+ }
+ else
+ {
+ lbl4.setVisible(false);
+ txt4.setVisible(false);
+ }
+ return true;
+ }
+
+ private boolean initInfoTable ()
+ {
+ // Get Query Columns
+
+ String sql = "SELECT c.ColumnName, t.AD_Table_ID, t.TableName, c.ColumnSql "
+ + "FROM AD_Table t"
+ + " INNER JOIN AD_Column c ON (t.AD_Table_ID=c.AD_Table_ID)"
+ + "WHERE c.AD_Reference_ID=10"
+ + " AND t.TableName=?" // #1
+ // Displayed in Window
+ + " AND EXISTS (SELECT * FROM AD_Field f "
+ + "WHERE f.AD_Column_ID=c.AD_Column_ID"
+ + " AND f.IsDisplayed='Y' AND f.IsEncrypted='N' AND f.ObscureType IS NULL) "
+ + "ORDER BY c.IsIdentifier DESC, c.SeqNo";
+
+ int AD_Table_ID = 0;
+ String tableName = null;
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql, null);
+ pstmt.setString(1, p_tableName);
+ ResultSet rs = pstmt.executeQuery();
+
+ while (rs.next())
+ {
+ m_queryColumns.add(rs.getString(1));
+ String columnSql = rs.getString(4);
+
+ if (columnSql != null && columnSql.length() > 0)
+ m_queryColumnsSql.add(columnSql);
+ else
+ m_queryColumnsSql.add(rs.getString(1));
+
+ if (AD_Table_ID == 0)
+ {
+ AD_Table_ID = rs.getInt(2);
+ tableName = rs.getString(3);
+ }
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql, e);
+ return false;
+ }
+
+ // Miminum check
+ if (m_queryColumns.size() == 0)
+ {
+ log.log(Level.SEVERE, "No query columns found");
+ return false;
+ }
+
+ log.finest("Table " + tableName + ", ID=" + AD_Table_ID
+ + ", QueryColumns #" + m_queryColumns.size());
+
+ // Only 4 Query Columns
+ while (m_queryColumns.size() > 4)
+ {
+ m_queryColumns.remove(m_queryColumns.size()-1);
+ m_queryColumnsSql.remove(m_queryColumnsSql.size()-1);
+ }
+
+ // Set Title
+ String title = Msg.translate(Env.getCtx(), tableName + "_ID"); // best bet
+
+ if (title.endsWith("_ID"))
+ title = Msg.translate(Env.getCtx(), tableName); // second best bet
+
+ setTitle(getTitle() + " " + title);
+
+ // Get Display Columns
+
+ ArrayList list = new ArrayList();
+ sql = "SELECT c.ColumnName, c.AD_Reference_ID, c.IsKey, f.IsDisplayed, c.AD_Reference_Value_ID, c.ColumnSql "
+ + "FROM AD_Column c"
+ + " INNER JOIN AD_Table t ON (c.AD_Table_ID=t.AD_Table_ID)"
+ + " INNER JOIN AD_Tab tab ON (t.AD_Window_ID=tab.AD_Window_ID)"
+ + " INNER JOIN AD_Field f ON (tab.AD_Tab_ID=f.AD_Tab_ID AND f.AD_Column_ID=c.AD_Column_ID) "
+ + "WHERE t.AD_Table_ID=? "
+ + " AND (c.IsKey='Y' OR "
+ // + " (f.IsDisplayed='Y' AND f.IsEncrypted='N' AND f.ObscureType IS NULL)) "
+ + " (f.IsEncrypted='N' AND f.ObscureType IS NULL)) "
+ + "ORDER BY c.IsKey DESC, f.SeqNo";
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql, null);
+ pstmt.setInt(1, AD_Table_ID);
+ ResultSet rs = pstmt.executeQuery();
+ while (rs.next())
+ {
+ String columnName = rs.getString(1);
+ int displayType = rs.getInt(2);
+ boolean isKey = rs.getString(3).equals("Y");
+ boolean isDisplayed = rs.getString(4).equals("Y");
+ int AD_Reference_Value_ID = rs.getInt(5);
+ String columnSql = rs.getString(6);
+
+ if (columnSql == null || columnSql.length() == 0)
+ columnSql = columnName;
+
+ // Default
+ StringBuffer colSql = new StringBuffer(columnSql);
+ Class colClass = null;
+
+ if (isKey)
+ colClass = IDColumn.class;
+ else if (!isDisplayed)
+ ;
+ else if (displayType == DisplayType.YesNo)
+ colClass = Boolean.class;
+ else if (displayType == DisplayType.Amount)
+ colClass = BigDecimal.class;
+ else if (displayType == DisplayType.Number || displayType == DisplayType.Quantity)
+ colClass = Double.class;
+ else if (displayType == DisplayType.Integer)
+ colClass = Integer.class;
+ else if (displayType == DisplayType.String || displayType == DisplayType.Text || displayType == DisplayType.Memo)
+ colClass = String.class;
+ else if (DisplayType.isDate(displayType))
+ colClass = Timestamp.class;
+ // ignore Binary, Button, ID, RowID
+ // else if (displayType == DisplayType.Account)
+ // else if (displayType == DisplayType.Location)
+ // else if (displayType == DisplayType.Locator)
+ else if (displayType == DisplayType.List)
+ {
+ if (Env.isBaseLanguage(Env.getCtx(), "AD_Ref_List"))
+ colSql = new StringBuffer("(SELECT l.Name FROM AD_Ref_List l WHERE l.AD_Reference_ID=")
+ .append(AD_Reference_Value_ID).append(" AND l.Value=").append(columnSql)
+ .append(") AS ").append(columnName);
+ else
+ colSql = new StringBuffer("(SELECT t.Name FROM AD_Ref_List l, AD_Ref_List_Trl t "
+ + "WHERE l.AD_Ref_List_ID=t.AD_Ref_List_ID AND l.AD_Reference_ID=")
+ .append(AD_Reference_Value_ID).append(" AND l.Value=").append(columnSql)
+ .append(" AND t.AD_Language='").append(Env.getAD_Language(Env.getCtx()))
+ .append("') AS ").append(columnName);
+ colClass = String.class;
+ }
+ // else if (displayType == DisplayType.Table)
+ // else if (displayType == DisplayType.TableDir || displayType == DisplayType.Search)
+
+ if (colClass != null)
+ {
+ list.add(new ColumnInfo(Msg.translate(Env.getCtx(), columnName), colSql.toString(), colClass));
+ log.finest("Added Column=" + columnName);
+ }
+ else
+ log.finest("Not Added Column=" + columnName);
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql, e);
+ return false;
+ }
+
+ if (list.size() == 0)
+ {
+ FDialog.error(p_WindowNo, this, "Error", "No Info Columns");
+ log.log(Level.SEVERE, "No Info for AD_Table_ID=" + AD_Table_ID + " - " + sql);
+ return false;
+ }
+
+ log.finest("InfoColumns #" + list.size());
+
+ // Convert ArrayList to Array
+ m_generalLayout = new ColumnInfo[list.size()];
+ list.toArray(m_generalLayout);
+ return true;
+ }
+
+ @Override
+ public String getSQLWhere()
+ {
+ StringBuffer sql = new StringBuffer();
+ addSQLWhere (sql, 0, txt1.getText().toUpperCase());
+ addSQLWhere (sql, 1, txt2.getText().toUpperCase());
+ addSQLWhere (sql, 2, txt3.getText().toUpperCase());
+ addSQLWhere (sql, 3, txt4.getText().toUpperCase());
+ return sql.toString();
+ }
+
+ private void addSQLWhere(StringBuffer sql, int index, String value)
+ {
+ if (!(value.equals("") || value.equals("%")) && index < m_queryColumns.size())
+ {
+ sql.append(" AND UPPER(").append(m_queryColumnsSql.get(index).toString()).append(") LIKE '");
+ sql.append(value);
+
+ if (value.endsWith("%"))
+ sql.append("'");
+ else
+ sql.append("%'");
+ }
+ }
+
+ @Override
+ void setParameters(PreparedStatement pstmt, boolean forCount) throws SQLException
+ {
+ int index = 1;
+ }
+
+ public void tableChanged(WTableModelEvent event)
+ {
+ // TODO Auto-generated method stub
+
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoInOutPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoInOutPanel.java
new file mode 100644
index 0000000000..c562bd226b
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoInOutPanel.java
@@ -0,0 +1,426 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Date;
+
+import org.adempiere.webui.component.Checkbox;
+import org.adempiere.webui.component.Datebox;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.Textbox;
+import org.adempiere.webui.component.VerticalBox;
+import org.adempiere.webui.editor.WEditor;
+import org.adempiere.webui.editor.WSearchEditor;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.event.ValueChangeListener;
+import org.adempiere.webui.event.WTableModelEvent;
+import org.compiere.minigrid.ColumnInfo;
+import org.compiere.minigrid.IDColumn;
+import org.compiere.model.MLookupFactory;
+import org.compiere.util.DisplayType;
+import org.compiere.util.Env;
+import org.compiere.util.Msg;
+import org.compiere.util.Util;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zk.ui.event.Events;
+import org.zkoss.zul.Hbox;
+import org.zkoss.zul.Separator;
+
+/**
+* Based on InfoInOut written by Jorg Janke
+*
+* @author Niraj Sohun
+* Aug 03, 2007
+*/
+
+public class InfoInOutPanel extends InfoPanel implements ValueChangeListener, EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ /** String Array of Column Info */
+ private ColumnInfo[] m_generalLayout;
+
+ /** list of query columns */
+ private ArrayList m_queryColumns = new ArrayList();
+
+ /** Table Name */
+ private String m_tableName;
+
+ /** Key Column Name */
+ private String m_keyColumn;
+
+ private Textbox fDocumentNo = new Textbox();
+
+ private WEditor fBPartner_ID;
+
+ private Textbox fDescription = new Textbox();
+ private Textbox fPOReference = new Textbox();
+
+ private Datebox fDateFrom = new Datebox();
+ private Datebox fDateTo = new Datebox();
+
+ private Checkbox fIsSOTrx = new Checkbox();
+
+ private Label lDocumentNo = new Label(Msg.translate(Env.getCtx(), "DocumentNo"));
+ private Label lDescription = new Label(Msg.translate(Env.getCtx(), "Description"));
+ private Label lPOReference = new Label(Msg.translate(Env.getCtx(), "POReference"));
+
+ private Label lDateFrom = new Label(Msg.translate(Env.getCtx(), "MovementDate"));
+ private Label lDateTo = new Label("-");
+
+ /** Array of Column Info */
+ private static final ColumnInfo[] s_invoiceLayout = {
+ new ColumnInfo(" ", "i.M_InOut_ID", IDColumn.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "C_BPartner_ID"), "(SELECT Name FROM C_BPartner bp WHERE bp.C_BPartner_ID=i.C_BPartner_ID)", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "MovementDate"), "i.MovementDate", Timestamp.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "DocumentNo"), "i.DocumentNo", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "Description"), "i.Description", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "POReference"), "i.POReference", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "IsSOTrx"), "i.IsSOTrx", Boolean.class)
+ };
+
+ /**
+ * Detail Protected Constructor
+ *
+ * @param WindowNo window no
+ * @param value query value
+ * @param multiSelection multiple selections
+ * @param whereClause where clause
+ */
+
+ protected InfoInOutPanel( int WindowNo, String value,
+ boolean multiSelection, String whereClause)
+ {
+ super (WindowNo, "i", "M_InOut_ID", multiSelection, whereClause);
+ log.info( "InfoInOut");
+ setTitle(Msg.getMsg(Env.getCtx(), "InfoInOut"));
+
+ try
+ {
+ statInit();
+ p_loadedOK = initInfo ();
+ }
+ catch (Exception e)
+ {
+ return;
+ }
+
+ int no = contentPanel.getRowCount();
+ setStatusLine(Integer.toString(no) + " " + Msg.getMsg(Env.getCtx(), "SearchRows_EnterQuery"), false);
+ setStatusDB(Integer.toString(no));
+
+ if (value != null && value.length() > 0)
+ {
+ fDocumentNo.setValue(value);
+ executeQuery();
+ }
+
+ //pack();
+
+ // Focus
+ //fDocumentNo.requestFocus();
+ } // InfoInOutPanel
+
+ /**
+ * Static Setup - add fields to parameterPanel
+ * @throws Exception if Lookups cannot be initialized
+ */
+
+ private void statInit() throws Exception
+ {
+ Hbox boxDocumentNo = new Hbox();
+
+ fDocumentNo.addEventListener(Events.ON_CHANGE, this);
+
+ boxDocumentNo.setWidth("100%");
+ boxDocumentNo.setWidths("40%, 60%");
+ boxDocumentNo.appendChild(lDocumentNo);
+ boxDocumentNo.appendChild(fDocumentNo);
+
+ Hbox boxDescription = new Hbox();
+
+ fDescription.addEventListener(Events.ON_CHANGE, this);
+
+ boxDescription.setWidth("100%");
+ boxDescription.setWidths("40%, 60%");
+ boxDescription.appendChild(lDescription);
+ boxDescription.appendChild(fDescription);
+
+ Hbox boxPORef = new Hbox();
+
+ fPOReference.addEventListener(Events.ON_CHANGE, this);
+
+ boxPORef.setWidth("100%");
+ boxPORef.setWidths("40%, 60%");
+ boxPORef.appendChild(lPOReference);
+ boxPORef.appendChild(fPOReference);
+
+ fIsSOTrx.setLabel(Msg.translate(Env.getCtx(), "IsSOTrx"));
+ fIsSOTrx.setChecked(!"N".equals(Env.getContext(Env.getCtx(), p_WindowNo, "IsSOTrx")));
+ fIsSOTrx.addEventListener(Events.ON_CHECK, this);
+
+ // fOrg_ID = new VLookup("AD_Org_ID", false, false, true,
+ // MLookupFactory.create(Env.getCtx(), 3486, m_WindowNo, DisplayType.TableDir, false),
+ // DisplayType.TableDir, m_WindowNo);
+ // lOrg_ID.setLabelFor(fOrg_ID);
+ // fOrg_ID.setBackground(AdempierePLAF.getInfoBackground());
+
+ Hbox boxBPartner = new Hbox();
+
+ fBPartner_ID = new WSearchEditor(
+ MLookupFactory.get (Env.getCtx(), p_WindowNo, 0, 3499, DisplayType.Search),
+ Msg.translate(Env.getCtx(), "BPartner"), "", false, false, true);
+ fBPartner_ID.addValueChangeListner(this);
+
+ boxBPartner.appendChild(fBPartner_ID.getLabel());
+ boxBPartner.appendChild(fBPartner_ID.getComponent());
+
+ Hbox boxDateFrom = new Hbox();
+ boxDateFrom.setWidth("100%");
+ boxDateFrom.setWidths("40%, 60%");
+ boxDateFrom.appendChild(lDateFrom);
+ boxDateFrom.appendChild(fDateFrom);
+
+ Hbox boxDateTo = new Hbox();
+ boxDateTo.setWidth("100%");
+ boxDateTo.setWidths("10%, 90%");
+ boxDateTo.appendChild(lDateTo);
+ boxDateTo.appendChild(fDateTo);
+
+ VerticalBox boxCol1 = new VerticalBox();
+ boxCol1.appendChild(boxDocumentNo);
+ boxCol1.appendChild(new Separator());
+ boxCol1.appendChild(boxDescription);
+ boxCol1.appendChild(new Separator());
+ boxCol1.appendChild(boxPORef);
+
+ VerticalBox boxCol2 = new VerticalBox();
+ boxCol2.appendChild(boxBPartner);
+ boxCol2.appendChild(new Separator());
+ boxCol2.appendChild(boxDateFrom);
+
+ VerticalBox boxCol3 = new VerticalBox();
+ boxCol3.appendChild(fIsSOTrx);
+ boxCol3.appendChild(new Separator());
+ boxCol3.appendChild(boxDateTo);
+
+ Hbox mainBox = new Hbox();
+ mainBox.setWidth("100%");
+ mainBox.setWidths("40%, 50%, 10%");
+ mainBox.appendChild(boxCol1);
+ mainBox.appendChild(boxCol2);
+ mainBox.appendChild(boxCol3);
+
+ this.setWidth("850px");
+ this.setTitle("InOut Info");
+ this.setClosable(true);
+ this.setBorder("normal");
+ this.appendChild(mainBox);
+ this.appendChild(new Separator());
+ this.appendChild(contentPanel);
+ this.appendChild(new Separator());
+ this.appendChild(confirmPanel);
+ this.appendChild(new Separator());
+ this.appendChild(statusBar);
+ }
+
+ /**
+ * General Init
+ * @return true, if success
+ */
+
+ private boolean initInfo ()
+ {
+ // Set Defaults
+ String bp = Env.getContext(Env.getCtx(), p_WindowNo, "C_BPartner_ID");
+
+ if (bp != null && bp.length() != 0)
+ fBPartner_ID.setValue(new Integer(bp));
+
+ // Prepare table
+
+ StringBuffer where = new StringBuffer("i.IsActive='Y'");
+
+ if (p_whereClause.length() > 0)
+ where.append(" AND ").append(Util.replace(p_whereClause, "M_InOut.", "i."));
+
+ prepareTable(s_invoiceLayout, " M_InOut i", where.toString(), "2,3,4");
+
+ return true;
+ } // initInfo
+
+ /*************************************************************************/
+
+ /**
+ * Construct SQL Where Clause and define parameters.
+ * (setParameters needs to set parameters)
+ * Includes first AND
+ * @return where clause
+ */
+
+ String getSQLWhere()
+ {
+ StringBuffer sql = new StringBuffer();
+
+ if (fDocumentNo.getText().length() > 0)
+ sql.append(" AND UPPER(i.DocumentNo) LIKE ?");
+
+ if (fDescription.getText().length() > 0)
+ sql.append(" AND UPPER(i.Description) LIKE ?");
+
+ if (fPOReference.getText().length() > 0)
+ sql.append(" AND UPPER(i.POReference) LIKE ?");
+
+ if (fBPartner_ID.getDisplay() != "")
+ sql.append(" AND i.C_BPartner_ID=?");
+
+ if (fDateFrom.getValue() != null || fDateTo.getValue() != null)
+ {
+ Date f = fDateFrom.getValue();
+ Timestamp from = new Timestamp(f.getTime());
+
+ Date t = fDateTo.getValue();
+ Timestamp to = new Timestamp(t.getTime());
+
+ if (from == null && to != null)
+ sql.append(" AND TRUNC(i.MovementDate) <= ?");
+ else if (from != null && to == null)
+ sql.append(" AND TRUNC(i.MovementDate) >= ?");
+ else if (from != null && to != null)
+ sql.append(" AND TRUNC(i.MovementDate) BETWEEN ? AND ?");
+ }
+ sql.append(" AND i.IsSOTrx=?");
+
+ // log.fine( "InfoInOut.setWhereClause", sql.toString());
+ return sql.toString();
+ } // getSQLWhere
+
+ /**
+ * Set Parameters for Query.
+ * (as defined in getSQLWhere)
+ * @param pstmt statement
+ * @param forCount for counting records
+ * @throws SQLException
+ */
+
+ void setParameters(PreparedStatement pstmt, boolean forCount) throws SQLException
+ {
+ int index = 1;
+
+ if (fDocumentNo.getText().length() > 0)
+ pstmt.setString(index++, getSQLText(fDocumentNo));
+
+ if (fDescription.getText().length() > 0)
+ pstmt.setString(index++, getSQLText(fDescription));
+
+ if (fPOReference.getText().length() > 0)
+ pstmt.setString(index++, getSQLText(fPOReference));
+
+ if (fBPartner_ID.getDisplay() != "")
+ {
+ Integer bp = (Integer)fBPartner_ID.getValue();
+ pstmt.setInt(index++, bp.intValue());
+ log.fine("BPartner=" + bp);
+ }
+
+ if (fDateFrom.getValue() != null || fDateTo.getValue() != null)
+ {
+ Date f = fDateFrom.getValue();
+ Timestamp from = new Timestamp(f.getTime());
+
+ Date t = fDateTo.getValue();
+ Timestamp to = new Timestamp(t.getTime());
+
+ log.fine("Date From=" + from + ", To=" + to);
+
+ if (from == null && to != null)
+ pstmt.setTimestamp(index++, to);
+ else if (from != null && to == null)
+ pstmt.setTimestamp(index++, from);
+ else if (from != null && to != null)
+ {
+ pstmt.setTimestamp(index++, from);
+ pstmt.setTimestamp(index++, to);
+ }
+ }
+ pstmt.setString(index++, fIsSOTrx .isChecked() ? "Y" : "N");
+ } // setParameters
+
+ /**
+ * Get SQL WHERE parameter
+ * @param f field
+ * @return sql part
+ */
+
+ private String getSQLText (Textbox f)
+ {
+ String s = f.getText().toUpperCase();
+
+ if (!s.endsWith("%"))
+ s += "%";
+
+ log.fine( "String=" + s);
+ return s;
+ } // getSQLText
+
+ /**
+ * Zoom
+ */
+
+ public void zoom()
+ {
+/* log.info( "InfoInOut.zoom");
+ Integer M_InOut_ID = getSelectedRowKey();
+
+ if (M_InOut_ID == null)
+ return;
+
+ MQuery query = new MQuery("M_InOut");
+ query.addRestriction("M_InOut_ID", MQuery.EQUAL, M_InOut_ID);
+ query.setRecordCount(1);
+ int AD_WindowNo = getAD_Window_ID("M_InOut", fIsSOTrx.isSelected());
+ zoom (AD_WindowNo, query);*/
+ } // zoom
+
+ /**
+ * Has Zoom
+ * @return true
+ */
+
+ boolean hasZoom()
+ {
+ return true;
+ } // hasZoom
+
+ public void valueChange(ValueChangeEvent evt)
+ {
+ if (fBPartner_ID.equals(evt.getSource()))
+ {
+ fBPartner_ID.setValue(evt.getNewValue());
+ }
+ }
+
+ public void tableChanged(WTableModelEvent event)
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoInvoicePanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoInvoicePanel.java
new file mode 100644
index 0000000000..e98c7c6f26
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoInvoicePanel.java
@@ -0,0 +1,544 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.Date;
+
+import org.adempiere.webui.component.Checkbox;
+import org.adempiere.webui.component.Datebox;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.NumberBox;
+import org.adempiere.webui.component.Panel;
+import org.adempiere.webui.component.Textbox;
+import org.adempiere.webui.component.WListbox;
+import org.adempiere.webui.editor.WSearchEditor;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.event.ValueChangeListener;
+import org.adempiere.webui.event.WTableModelEvent;
+import org.compiere.minigrid.ColumnInfo;
+import org.compiere.minigrid.IDColumn;
+import org.compiere.model.MLookup;
+import org.compiere.model.MLookupFactory;
+import org.compiere.util.DisplayType;
+import org.compiere.util.Env;
+import org.compiere.util.KeyNamePair;
+import org.compiere.util.Msg;
+import org.compiere.util.Util;
+import org.zkoss.zk.ui.WrongValueException;
+import org.zkoss.zul.Div;
+import org.zkoss.zul.Hbox;
+import org.zkoss.zul.Vbox;
+
+/**
+ * Search Invoice and return selection
+ * Based on InfoInvoice by Jorg Janke
+ * @author Sendy Yagambrum
+ * @date July 30, 2007
+ **/
+public class InfoInvoicePanel extends InfoPanel implements ValueChangeListener
+{
+ /**
+ * Detail protected constructor
+ * @param WindowNo window no
+ * @param value query value
+ * @param multiSelection multiple selection
+ * @param whereClause where clause
+ *
+ */
+ protected InfoInvoicePanel(int WindowNo, String value,
+ boolean multiSelection, String whereClause)
+ {
+ super ( WindowNo, "i", "C_Invoice_ID", multiSelection, whereClause);
+
+ setTitle(Msg.getMsg(Env.getCtx(), "InfoInvoice"));
+ //
+ initComponents();
+ init();
+
+ p_loadedOK = initInfo ();
+ int no = contentPanel.getRowCount();
+ setStatusLine(Integer.toString(no) + " " + Msg.getMsg(Env.getCtx(), "SearchRows_EnterQuery"), false);
+ setStatusDB(Integer.toString(no));
+ if (value != null && value.length() > 0)
+ {
+ String values[] = value.split("_");
+ txtDocumentNo.setText(values[0]);
+ executeQuery();
+ renderItems();
+ }
+ }
+
+ private Label lblDocumentNo;
+ private Label lblDescription;
+ private Label lblBPartner;
+ private Label lblOrder;
+ private Label lblIsSOTrx;
+ private Label lblIsPaid;
+ private Label lblDateInvoiced;
+ private Label lblGrandTotal;
+
+ private Textbox txtDocumentNo;
+ private Textbox txtDescription;
+
+ private Datebox dateFrom;
+ private Datebox dateTo;
+
+ private NumberBox amountFrom;
+ private NumberBox amountTo;
+
+ private WSearchEditor editorBPartner;
+ private WSearchEditor editorOrder;
+
+ private Checkbox isSoTrx;
+ private Checkbox isPaid;
+
+ /** Array of Column Info */
+ private static final ColumnInfo[] s_invoiceLayout = {
+ new ColumnInfo(" ", "i.C_Invoice_ID", IDColumn.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "C_BPartner_ID"), "(SELECT Name FROM C_BPartner bp WHERE bp.C_BPartner_ID=i.C_BPartner_ID)", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "DateInvoiced"), "i.DateInvoiced", Timestamp.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "DocumentNo"), "i.DocumentNo", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "C_Currency_ID"), "(SELECT ISO_Code FROM C_Currency c WHERE c.C_Currency_ID=i.C_Currency_ID)", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "GrandTotal"), "i.GrandTotal", BigDecimal.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "ConvertedAmount"), "currencyBase(i.GrandTotal, i.C_Currency_ID, i.DateAcct, i.AD_Client_ID, i.AD_Org_ID)", BigDecimal.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "OpenAmt"), "invoiceOpen(C_Invoice_ID,C_InvoicePaySchedule_ID)", BigDecimal.class, true, true, null),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "IsPaid"), "i.IsPaid", Boolean.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "IsSOTrx"), "i.IsSOTrx", Boolean.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "Description"), "i.Description", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "POReference"), "i.POReference", String.class),
+ new ColumnInfo("", "''", KeyNamePair.class, "i.C_InvoicePaySchedule_ID")
+ };
+
+ private static int INDEX_PAYSCHEDULE = s_invoiceLayout.length - 1; // last item
+
+ private static final long serialVersionUID = 1L;
+
+ private void initComponents()
+ {
+
+ lblDocumentNo = new Label(Msg.translate(Env.getCtx(), "DocumentNo").substring(1));
+ lblDescription = new Label(Msg.translate(Env.getCtx(), "Description"));
+ lblBPartner = new Label(Msg.translate(Env.getCtx(), "BPartner").substring(1));
+ lblIsSOTrx = new Label(Msg.translate(Env.getCtx(), "IsSOTrx"));
+ lblIsPaid = new Label(Msg.translate(Env.getCtx(), "IsPaid"));
+ lblDateInvoiced = new Label(Msg.translate(Env.getCtx(), "DateInvoiced"));
+ lblOrder = new Label(Msg.translate(Env.getCtx(), "POReference"));
+ lblGrandTotal = new Label(Msg.translate(Env.getCtx(), "GrandTotal"));
+
+ txtDocumentNo = new Textbox();
+ txtDescription = new Textbox();
+
+ dateFrom = new Datebox();
+ dateFrom.setWidth("180px");
+ dateTo= new Datebox();
+ dateTo.setWidth("180px");
+
+ amountFrom = new NumberBox(false);
+ amountFrom.setWidth("180px");
+ amountTo = new NumberBox(false);
+ amountTo.setWidth("180px");
+
+ isPaid = new Checkbox();
+ isPaid.setChecked(false);
+ isSoTrx = new Checkbox();
+ isSoTrx.setChecked(!"N".equals(Env.getContext(Env.getCtx(), p_WindowNo, "IsSOTrx")));
+ MLookup lookupBP = MLookupFactory.get(Env.getCtx(), p_WindowNo,
+ 0, 3499, DisplayType.Search);
+ editorBPartner = new WSearchEditor(lookupBP, Msg.translate(
+ Env.getCtx(), "C_BPartner_ID"), "", false, false, true);
+ editorBPartner.addValueChangeListner(this);
+
+ MLookup lookupOrder = MLookupFactory.get(Env.getCtx(), p_WindowNo,
+ 0, 4247, DisplayType.Search);
+ editorOrder = new WSearchEditor(lookupOrder, Msg.translate(
+ Env.getCtx(), "C_Order_ID"), "", false, false, true);
+ editorOrder.addValueChangeListner(this);
+
+ contentPanel = new WListbox();
+ contentPanel.setWidth("1300px");
+ contentPanel.setHeight("500px");
+ }
+
+ private void init()
+ {
+ Hbox pnlDocumentNo = new Hbox();
+ pnlDocumentNo.appendChild(lblDocumentNo);
+ pnlDocumentNo.appendChild(txtDocumentNo);
+ pnlDocumentNo.setStyle("text-align:right");
+
+ Hbox pnlDescription = new Hbox();
+ pnlDescription.appendChild(lblDescription);
+ pnlDescription.appendChild(txtDescription);
+ pnlDescription.setStyle("text-align:right");
+ pnlDescription.setWidth("100%");
+
+ Hbox pnlOrder = new Hbox();
+ pnlOrder.appendChild(editorOrder.getLabel());
+ pnlOrder.appendChild(editorOrder.getComponent());
+ pnlOrder.setStyle("text-align:right");
+ pnlOrder.setWidth("100%");
+
+ Hbox pnlBPartner = new Hbox();
+ pnlBPartner.appendChild(lblBPartner);
+ pnlBPartner.appendChild(editorBPartner.getComponent());
+ pnlBPartner.setStyle("text-align:right");
+ pnlBPartner.setWidth("100%");
+
+ Hbox hboxDateOrdered = new Hbox();
+ Panel pnlDateOrdered = new Panel();
+ pnlDateOrdered.appendChild(lblDateInvoiced);
+ pnlDateOrdered.appendChild(dateFrom);
+ pnlDateOrdered.setAlign("right");
+ hboxDateOrdered.appendChild(pnlDateOrdered);
+ hboxDateOrdered.setStyle("text-align:right");
+ hboxDateOrdered.setWidth("100%");
+
+ Hbox pnlGrandTotal = new Hbox();
+ pnlGrandTotal.appendChild(lblGrandTotal);
+ pnlGrandTotal.appendChild(amountFrom);
+ pnlGrandTotal.setStyle("text-align:right");
+ pnlGrandTotal.setWidth("100%");
+
+ Hbox pnlCheckbox = new Hbox();
+ Panel pnlIsSoTrx = new Panel();
+ pnlIsSoTrx.appendChild(isSoTrx);
+ pnlIsSoTrx.appendChild(lblIsSOTrx);
+ pnlIsSoTrx.setAlign("left");
+
+ Panel pnlIsPaid = new Panel();
+ pnlIsPaid.appendChild(isPaid);
+ pnlIsPaid.appendChild(lblIsPaid);
+ pnlIsPaid.setAlign("left");
+
+ pnlCheckbox.appendChild(pnlIsSoTrx);
+ pnlCheckbox.appendChild(pnlIsPaid);
+
+
+ Panel pnlDateTo = new Panel();
+ pnlDateTo.appendChild(dateTo);
+ pnlDateTo.setAlign("left");
+
+ Panel pnlAmountTo = new Panel();
+ pnlAmountTo.appendChild(amountTo);
+ pnlAmountTo.setAlign("left");
+
+ Vbox vbox1 = new Vbox();
+ vbox1.setWidth("100%");
+ vbox1.appendChild(pnlDocumentNo);
+ vbox1.appendChild(pnlDescription);
+ vbox1.appendChild(pnlOrder);
+
+ Vbox vbox2 = new Vbox();
+ vbox2.setWidth("100%");
+ vbox2.appendChild(pnlBPartner);
+ vbox2.appendChild(pnlDateOrdered);
+ vbox2.appendChild(pnlGrandTotal);
+
+ Vbox vbox3 = new Vbox();
+ vbox3.setWidth("100%");
+ vbox3.appendChild(pnlCheckbox);
+ vbox3.appendChild(pnlDateTo);
+ vbox3.appendChild(pnlAmountTo);
+
+ Hbox parameterPanel = new Hbox();
+ parameterPanel.appendChild(vbox1);
+ parameterPanel.appendChild(vbox2);
+ parameterPanel.appendChild(vbox3);
+ parameterPanel.setWidth("100%");
+
+ Vbox mainPanel = new Vbox();
+ mainPanel.setWidth("100%");
+ mainPanel.appendChild(parameterPanel);
+ Div div = new Div();
+ div.setStyle("overflow:scroll");
+ div.setWidth("100%");
+ div.appendChild(contentPanel);
+ mainPanel.appendChild(div);
+ mainPanel.appendChild(confirmPanel);
+ mainPanel.appendChild(statusBar);
+
+ this.appendChild(mainPanel);
+ this.setBorder("normal");
+ this.setWidth("850px");
+ }
+
+ /**
+ * General Init
+ * @return true, if success
+ */
+ private boolean initInfo ()
+ {
+ // Set Defaults
+ String bp = Env.getContext(Env.getCtx(), p_WindowNo, "C_BPartner_ID");
+ if (bp != null && bp.length() != 0)
+ editorBPartner.setValue(new Integer(bp));
+
+ // prepare table
+ StringBuffer where = new StringBuffer("i.IsActive='Y'");
+ if (p_whereClause.length() > 0)
+ where.append(" AND ").append(Util.replace(p_whereClause, "C_Invoice.", "i."));
+ prepareTable(s_invoiceLayout,
+ " C_Invoice_v i", // corrected for CM
+ where.toString(),
+ "2,3,4");
+ //
+ // MAllocationLine.setIsPaid(Env.getCtx(), 0, null);
+ return true;
+
+ } // initInfo
+ @Override
+ public String getSQLWhere()
+ {
+ StringBuffer sql = new StringBuffer();
+ if (txtDocumentNo.getText().length() > 0)
+ sql.append(" AND UPPER(i.DocumentNo) LIKE ?");
+ if (txtDescription.getText().length() > 0)
+ sql.append(" AND UPPER(i.Description) LIKE ?");
+ // if (fPOReference.getText().length() > 0)
+ // sql.append(" AND UPPER(i.POReference) LIKE ?");
+ //
+ if (editorBPartner.getValue() != null)
+ sql.append(" AND i.C_BPartner_ID=?");
+ //
+ if (editorOrder.getValue() != null)
+ sql.append(" AND i.C_Order_ID=?");
+ Date fromDate = null;
+ Date toDate = null;
+ try
+ {
+ fromDate = dateFrom.getValue();
+ }
+ catch (WrongValueException e)
+ {
+
+ }
+ try
+ {
+ toDate = dateTo.getValue();
+ }
+ catch (WrongValueException e)
+ {
+
+ }
+ if (fromDate == null && toDate != null)
+ {
+ sql.append(" AND TRUNC(o.DateOrdered) <= ?");
+ }
+ else if (fromDate != null && toDate == null)
+ {
+ sql.append(" AND TRUNC(o.DateOrdered) >= ?");
+ }
+ else if (fromDate != null && toDate != null)
+ {
+ sql.append(" AND TRUNC(o.DateOrdered) BETWEEN ? AND ?");
+ }
+ //
+ Double fromAmount = null;
+ Double toAmount = null;
+ if (!amountFrom.getText().equals(""))
+ {
+ try
+ {
+ fromAmount = Double.parseDouble(amountFrom.getText());
+ }
+ catch (NumberFormatException e)
+ {
+
+ }
+ }
+ if (!amountTo.getText().equals(""))
+ {
+ try
+ {
+ toAmount = Double.parseDouble(amountTo.getText());
+ }
+ catch (NumberFormatException e)
+ {
+
+ }
+ }
+ if (fromAmount == null && toAmount != null)
+ {
+ sql.append(" AND o.GrandTotal <= ?");
+ }
+ else if (fromAmount != null && toAmount == null)
+ {
+ sql.append(" AND o.GrandTotal >= ?");
+ }
+ else if (fromAmount != null && toAmount != null)
+ {
+ sql.append(" AND o.GrandTotal BETWEEN ? AND ?");
+ }
+ sql.append(" AND i.IsPaid=? AND i.IsSOTrx=?");
+
+ log.finer(sql.toString());
+ return sql.toString();
+ }
+
+ @Override
+ void setParameters(PreparedStatement pstmt, boolean forCount) throws SQLException
+ {
+ int index = 1;
+ if (txtDocumentNo.getText().length() > 0)
+ pstmt.setString(index++, getSQLText(txtDocumentNo));
+ if (txtDescription.getText().length() > 0)
+ pstmt.setString(index++, getSQLText(txtDescription));
+
+ //
+ if (editorBPartner.getValue() != null)
+ {
+ Integer bp = (Integer)editorBPartner.getValue();
+ pstmt.setInt(index++, bp.intValue());
+ log.fine("BPartner=" + bp);
+ }
+ //
+ if (editorOrder.getValue() != null)
+ {
+ Integer order = (Integer)editorOrder.getValue();
+ pstmt.setInt(index++, order.intValue());
+ log.fine("Order=" + order);
+ }
+ Date fromD = null;
+ Date toD = null;
+ Timestamp from = null;
+ Timestamp to = null;
+ try
+ {
+ if (dateFrom.getValue() != null)
+ {
+ fromD = dateFrom.getValue();
+ from = new Timestamp(fromD.getTime());
+ }
+ }
+ catch (WrongValueException e)
+ {
+
+ }
+ try
+ {
+ if (dateTo.getValue() != null)
+ {
+ toD = dateTo.getValue();
+ to = new Timestamp(toD.getTime());
+ }
+ }
+ catch (WrongValueException e)
+ {
+
+ }
+
+ log.fine("Date From=" + from + ", To=" + to);
+ if (from == null && to != null)
+ {
+ pstmt.setTimestamp(index++, to);
+ }
+ else if (from != null && to == null)
+ {
+ pstmt.setTimestamp(index++, from);
+ }
+ else if (from != null && to != null)
+ {
+ pstmt.setTimestamp(index++, from);
+ pstmt.setTimestamp(index++, to);
+ }
+
+ //
+ BigDecimal fromBD = null;
+ BigDecimal toBD = null;
+ Double fromAmt = null;
+ Double toAmt = null;
+
+ if (!amountFrom.getText().equals(""))
+ {
+ try
+ {
+ fromAmt = Double.parseDouble(amountFrom.getText());
+ fromBD = BigDecimal.valueOf(fromAmt);
+ }
+ catch (Exception e)
+ {
+
+ }
+ }
+
+ if (!amountTo.getText().equals(""))
+ {
+ try
+ {
+ toAmt = Double.parseDouble(amountTo.getText());
+ toBD = BigDecimal.valueOf(toAmt);
+ }
+ catch (Exception e)
+ {
+
+ }
+ }
+
+ if (fromBD == null && toBD != null)
+ {
+ pstmt.setBigDecimal(index++, toBD);
+ }
+ else if (fromBD != null && toBD == null)
+ {
+ pstmt.setBigDecimal(index++, fromBD);
+ }
+ else if (fromBD != null && toBD != null)
+ {
+ pstmt.setBigDecimal(index++, fromBD);
+ pstmt.setBigDecimal(index++, toBD);
+ }
+ pstmt.setString(index++,isPaid.isChecked() ? "Y" : "N");
+ pstmt.setString(index++,isSoTrx.isChecked() ? "Y" : "N");
+
+ }
+
+ /**
+ * Get SQL WHERE parameter
+ * @param f field
+ * @return sql
+ */
+ private String getSQLText (Textbox f)
+ {
+ String s = f.getText().toUpperCase();
+ if (!s.endsWith("%"))
+ s += "%";
+ log.fine("String=" + s);
+ return s;
+ } // getSQLText
+
+ public void tableChanged(WTableModelEvent event)
+ {
+
+ }
+ public void valueChange(ValueChangeEvent evt)
+ {
+ if (editorBPartner.equals(evt.getSource()))
+ {
+ editorBPartner.setValue(evt.getNewValue());
+ }
+ if (editorOrder.equals(evt.getSource()))
+ {
+ editorOrder.setValue(evt.getNewValue());
+ }
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoOrderPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoOrderPanel.java
new file mode 100644
index 0000000000..1421d16e98
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoOrderPanel.java
@@ -0,0 +1,500 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.Date;
+
+import org.adempiere.webui.component.Checkbox;
+import org.adempiere.webui.component.Datebox;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.NumberBox;
+import org.adempiere.webui.component.Panel;
+import org.adempiere.webui.component.Textbox;
+import org.adempiere.webui.component.WListbox;
+import org.adempiere.webui.editor.WSearchEditor;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.event.ValueChangeListener;
+import org.adempiere.webui.event.WTableModelEvent;
+import org.compiere.minigrid.ColumnInfo;
+import org.compiere.minigrid.IDColumn;
+import org.compiere.model.MLookup;
+import org.compiere.model.MLookupFactory;
+import org.compiere.util.DisplayType;
+import org.compiere.util.Env;
+import org.compiere.util.Msg;
+import org.compiere.util.Util;
+import org.zkoss.zk.ui.WrongValueException;
+import org.zkoss.zul.Div;
+import org.zkoss.zul.Hbox;
+import org.zkoss.zul.Vbox;
+
+/**
+ * Search Order info and return selection
+ * Based on InfoOrder by Jorg Janke
+ *
+ * @author Sendy Yagambrum
+ * @date July 27, 2007
+ **/
+public class InfoOrderPanel extends InfoPanel implements ValueChangeListener
+{
+
+ private static final long serialVersionUID = 1L;
+
+ private Label lblDocumentNo;
+ private Label lblDescription;
+ private Label lblBPartner;
+ private Label lblSalesTransaction;
+ private Label lblDateOrdered;
+ private Label lblOrderRef;
+ private Label lblGrandTotal;
+
+ private Textbox txtDocumentNo;
+ private Textbox txtDescription;
+ private Textbox txtOrderRef;
+
+ private Datebox dateFrom;
+ private Datebox dateTo;
+
+ private NumberBox amountFrom;
+ private NumberBox amountTo;
+
+ private WSearchEditor editorBPartner;
+
+ private Checkbox isSoTrx;
+
+ /** Array of Column Info */
+ private static final ColumnInfo[] s_invoiceLayout = {
+ new ColumnInfo(" ", "o.C_Order_ID", IDColumn.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "C_BPartner_ID"), "(SELECT Name FROM C_BPartner bp WHERE bp.C_BPartner_ID=o.C_BPartner_ID)", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "DateOrdered"), "o.DateOrdered", Timestamp.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "DocumentNo"), "o.DocumentNo", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "C_Currency_ID"), "(SELECT ISO_Code FROM C_Currency c WHERE c.C_Currency_ID=o.C_Currency_ID)", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "GrandTotal"), "o.GrandTotal", BigDecimal.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "ConvertedAmount"), "currencyBase(o.GrandTotal,o.C_Currency_ID,o.DateAcct, o.AD_Client_ID,o.AD_Org_ID)", BigDecimal.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "IsSOTrx"), "o.IsSOTrx", Boolean.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "Description"), "o.Description", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "POReference"), "o.POReference", String.class)
+ };
+
+ protected InfoOrderPanel(int WindowNo, String value,
+ boolean multiSelection, String whereClause)
+ {
+ super ( WindowNo, "o", "C_Order_ID", multiSelection, whereClause);
+ log.info( "InfoOrder");
+ setTitle(Msg.getMsg(Env.getCtx(), "InfoOrder"));
+ //
+ initComponents();
+ init();
+
+ p_loadedOK = initInfo ();
+ int no = contentPanel.getRowCount();
+ setStatusLine(Integer.toString(no) + " " + Msg.getMsg(Env.getCtx(), "SearchRows_EnterQuery"), false);
+ setStatusDB(Integer.toString(no));
+ //
+ if (value != null && value.length() > 0)
+ {
+ String values[] = value.split("_");
+ txtDocumentNo.setText(values[0]);
+ executeQuery();
+ renderItems();
+ }
+ }
+ public void initComponents()
+ {
+
+ lblDocumentNo = new Label(Msg.translate(Env.getCtx(), "DocumentNo").substring(1));
+ lblDescription = new Label(Msg.translate(Env.getCtx(), "Description"));
+ lblBPartner = new Label(Msg.translate(Env.getCtx(), "BPartner").substring(1));
+ lblSalesTransaction = new Label(Msg.translate(Env.getCtx(), "IsSOTrx"));
+ lblDateOrdered = new Label(Msg.translate(Env.getCtx(), "DateOrdered"));
+ lblOrderRef = new Label(Msg.translate(Env.getCtx(), "POReference"));
+ lblGrandTotal = new Label(Msg.translate(Env.getCtx(), "GrandTotal"));
+
+ txtDocumentNo = new Textbox();
+ txtDescription = new Textbox();
+ txtOrderRef = new Textbox();
+
+ dateFrom = new Datebox();
+ dateFrom.setWidth("180px");
+ dateTo= new Datebox();
+ dateTo.setWidth("180px");
+
+ amountFrom = new NumberBox(false);
+ amountFrom.setWidth("180px");
+ amountTo = new NumberBox(false);
+ amountTo.setWidth("180px");
+
+ isSoTrx = new Checkbox();
+ isSoTrx.setChecked(!"N".equals(Env.getContext(Env.getCtx(), p_WindowNo, "IsSOTrx")));
+ MLookup lookupBP = MLookupFactory.get(Env.getCtx(), p_WindowNo,
+ 0, 3499, DisplayType.Search);
+ editorBPartner = new WSearchEditor(lookupBP, Msg.translate(
+ Env.getCtx(), "C_BPartner_ID"), "", true, false, true);
+ editorBPartner.addValueChangeListner(this);
+ contentPanel = new WListbox();
+ contentPanel.setWidth("1000px");
+ contentPanel.setHeight("500px");
+ }
+
+ public void init()
+ {
+ Panel pnlDocumentNo = new Panel();
+ pnlDocumentNo.appendChild(lblDocumentNo);
+ pnlDocumentNo.appendChild(txtDocumentNo);
+ pnlDocumentNo.setAlign("right");
+
+ Panel pnlDescription = new Panel();
+ pnlDescription.appendChild(lblDescription);
+ pnlDescription.appendChild(txtDescription);
+ pnlDescription.setAlign("right");
+
+ Panel pnlOrderRef = new Panel();
+ pnlOrderRef.appendChild(lblOrderRef);
+ pnlOrderRef.appendChild(txtOrderRef);
+ pnlOrderRef.setAlign("right");
+
+ Hbox pnlBPartner = new Hbox();
+ pnlBPartner.appendChild(lblBPartner);
+ pnlBPartner.appendChild(editorBPartner.getComponent());
+ pnlBPartner.setStyle("text-align:right");
+ pnlBPartner.setWidth("100%");
+
+ Hbox hboxDateOrdered = new Hbox();
+ Panel pnlDateOrdered = new Panel();
+ pnlDateOrdered.appendChild(lblDateOrdered);
+ pnlDateOrdered.appendChild(dateFrom);
+ pnlDateOrdered.setAlign("right");
+ hboxDateOrdered.appendChild(pnlDateOrdered);
+ hboxDateOrdered.setStyle("text-align:right");
+ hboxDateOrdered.setWidth("100%");
+
+ Hbox pnlGrandTotal = new Hbox();
+ pnlGrandTotal.appendChild(lblGrandTotal);
+ pnlGrandTotal.appendChild(amountFrom);
+ pnlGrandTotal.setStyle("text-align:right");
+ pnlGrandTotal.setWidth("100%");
+ Panel pnlIsSoTrx = new Panel();
+
+ pnlIsSoTrx.appendChild(isSoTrx);
+ pnlIsSoTrx.appendChild(lblSalesTransaction);
+ pnlIsSoTrx.setAlign("left");
+
+ Panel pnlDateTo = new Panel();
+ pnlDateTo.appendChild(dateTo);
+ pnlDateTo.setAlign("left");
+
+ Panel pnlAmountTo = new Panel();
+ pnlAmountTo.appendChild(amountTo);
+ pnlAmountTo.setAlign("left");
+
+ Vbox vbox1 = new Vbox();
+ vbox1.setWidth("100%");
+ vbox1.appendChild(pnlDocumentNo);
+ vbox1.appendChild(pnlDescription);
+ vbox1.appendChild(pnlOrderRef);
+
+ Vbox vbox2 = new Vbox();
+ vbox2.setWidth("100%");
+ vbox2.appendChild(pnlBPartner);
+ vbox2.appendChild(pnlDateOrdered);
+ vbox2.appendChild(pnlGrandTotal);
+
+ Vbox vbox3 = new Vbox();
+ vbox3.setWidth("100%");
+ vbox3.appendChild(pnlIsSoTrx);
+ vbox3.appendChild(pnlDateTo);
+ vbox3.appendChild(pnlAmountTo);
+
+ Hbox parameterPanel = new Hbox();
+ parameterPanel.appendChild(vbox1);
+ parameterPanel.appendChild(vbox2);
+ parameterPanel.appendChild(vbox3);
+ parameterPanel.setWidth("100%");
+
+ Vbox mainPanel = new Vbox();
+ mainPanel.setWidth("100%");
+ mainPanel.appendChild(parameterPanel);
+ Div div = new Div();
+ div.setStyle("overflow:auto");
+ div.setWidth("100%");
+ div.appendChild(contentPanel);
+ mainPanel.appendChild(div);
+ mainPanel.appendChild(confirmPanel);
+ mainPanel.appendChild(statusBar);
+
+ this.appendChild(mainPanel);
+ this.setBorder("normal");
+ this.setWidth("850px");
+ }
+
+ /**
+ * General Init
+ * @return true, if success
+ */
+ private boolean initInfo ()
+ {
+ // Set Defaults
+ String bp = Env.getContext(Env.getCtx(), p_WindowNo, "C_BPartner_ID");
+ if (bp != null && bp.length() != 0)
+ editorBPartner.setValue(new Integer(bp));
+
+ // prepare table
+ StringBuffer where = new StringBuffer("o.IsActive='Y'");
+ if (p_whereClause.length() > 0)
+ where.append(" AND ").append(Util.replace(p_whereClause, "C_Order.", "o."));
+ prepareTable(s_invoiceLayout,
+ " C_Order o",
+ where.toString(),"2,3,4");
+
+ return true;
+ } // initInfo
+ @Override
+ public String getSQLWhere()
+ {
+ StringBuffer sql = new StringBuffer();
+ if (txtDocumentNo.getText().length() > 0)
+ sql.append(" AND UPPER(o.DocumentNo) LIKE ?");
+ if (txtDescription.getText().length() > 0)
+ sql.append(" AND UPPER(o.Description) LIKE ?");
+ if (txtOrderRef.getText().length() > 0)
+ sql.append(" AND UPPER(o.POReference) LIKE ?");
+ //
+ if (editorBPartner.getValue() != null)
+ sql.append(" AND o.C_BPartner_ID=?");
+ //
+ Date fromDate = null;
+ Date toDate = null;
+ try
+ {
+ fromDate = dateFrom.getValue();
+ }
+ catch (WrongValueException e)
+ {
+
+ }
+ try
+ {
+ toDate = dateTo.getValue();
+ }
+ catch (WrongValueException e)
+ {
+
+ }
+ if (fromDate == null && toDate != null)
+ {
+ sql.append(" AND TRUNC(o.DateOrdered) <= ?");
+ }
+ else if (fromDate != null && toDate == null)
+ {
+ sql.append(" AND TRUNC(o.DateOrdered) >= ?");
+ }
+ else if (fromDate != null && toDate != null)
+ {
+ sql.append(" AND TRUNC(o.DateOrdered) BETWEEN ? AND ?");
+ }
+ //
+ Double fromAmount = null;
+ Double toAmount = null;
+ if (!amountFrom.getText().equals(""))
+ {
+ try
+ {
+ fromAmount = Double.parseDouble(amountFrom.getText());
+ }
+ catch (NumberFormatException e)
+ {
+
+ }
+ }
+ if (!amountTo.getText().equals(""))
+ {
+ try
+ {
+ toAmount = Double.parseDouble(amountTo.getText());
+ }
+ catch (NumberFormatException e)
+ {
+
+ }
+ }
+ if (fromAmount == null && toAmount != null)
+ {
+ sql.append(" AND o.GrandTotal <= ?");
+ }
+ else if (fromAmount != null && toAmount == null)
+ {
+ sql.append(" AND o.GrandTotal >= ?");
+ }
+ else if (fromAmount != null && toAmount != null)
+ {
+ sql.append(" AND o.GrandTotal BETWEEN ? AND ?");
+ }
+ sql.append(" AND o.IsSOTrx=?");
+
+ log.finer(sql.toString());
+ return sql.toString();
+ }
+
+ @Override
+ void setParameters(PreparedStatement pstmt, boolean forCount) throws SQLException
+ {
+ int index = 1;
+ if (txtDocumentNo.getText().length() > 0)
+ pstmt.setString(index++, getSQLText(txtDocumentNo));
+ if (txtDescription.getText().length() > 0)
+ pstmt.setString(index++, getSQLText(txtDescription));
+ if (txtOrderRef.getText().length() > 0)
+ pstmt.setString(index++, getSQLText(txtOrderRef));
+ //
+ if (editorBPartner.getValue() != null)
+ {
+ Integer bp = (Integer)editorBPartner.getValue();
+ pstmt.setInt(index++, bp.intValue());
+ log.fine("BPartner=" + bp);
+ }
+ //
+
+ Date fromD = null;
+ Date toD = null;
+ Timestamp from = null;
+ Timestamp to = null;
+ try
+ {
+ if (dateFrom.getValue() != null)
+ {
+ fromD = dateFrom.getValue();
+ from = new Timestamp(fromD.getTime());
+ }
+ }
+ catch (WrongValueException e)
+ {
+
+ }
+ try
+ {
+ if (dateTo.getValue() != null)
+ {
+ toD = dateTo.getValue();
+ to = new Timestamp(toD.getTime());
+ }
+ }
+ catch (WrongValueException e)
+ {
+
+ }
+
+ log.fine("Date From=" + from + ", To=" + to);
+ if (from == null && to != null)
+ {
+ pstmt.setTimestamp(index++, to);
+ }
+ else if (from != null && to == null)
+ {
+ pstmt.setTimestamp(index++, from);
+ }
+ else if (from != null && to != null)
+ {
+ pstmt.setTimestamp(index++, from);
+ pstmt.setTimestamp(index++, to);
+ }
+
+ //
+ BigDecimal fromBD = null;
+ BigDecimal toBD = null;
+ Double fromAmt = null;
+ Double toAmt = null;
+
+ if (!amountFrom.getText().equals(""))
+ {
+ try
+ {
+ fromAmt = Double.parseDouble(amountFrom.getText());
+ fromBD = BigDecimal.valueOf(fromAmt);
+ }
+ catch (Exception e)
+ {
+
+ }
+ }
+
+ if (!amountTo.getText().equals(""))
+ {
+ try
+ {
+ toAmt = Double.parseDouble(amountTo.getText());
+ toBD = BigDecimal.valueOf(toAmt);
+ }
+ catch (Exception e)
+ {
+
+ }
+ }
+
+ if (fromBD == null && toBD != null)
+ {
+ pstmt.setBigDecimal(index++, toBD);
+ }
+ else if (fromBD != null && toBD == null)
+ {
+ pstmt.setBigDecimal(index++, fromBD);
+ }
+ else if (fromBD != null && toBD != null)
+ {
+ pstmt.setBigDecimal(index++, fromBD);
+ pstmt.setBigDecimal(index++, toBD);
+ }
+
+ pstmt.setString(index++, isSoTrx.isChecked() ? "Y" : "N");
+
+ }
+
+ /**
+ * Get SQL WHERE parameter
+ * @param f field
+ * @return sql
+ */
+ private String getSQLText (Textbox f)
+ {
+ String s = f.getText().toUpperCase();
+ if (!s.endsWith("%"))
+ s += "%";
+ log.fine("String=" + s);
+ return s;
+ } // getSQLText
+
+
+ public void tableChanged(WTableModelEvent event)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void valueChange(ValueChangeEvent evt)
+ {
+ if (editorBPartner.equals(evt.getSource()))
+ {
+ editorBPartner.setValue(evt.getNewValue());
+ }
+
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java
new file mode 100644
index 0000000000..ad31c2924b
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java
@@ -0,0 +1,842 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Vector;
+import java.util.logging.Level;
+
+import org.adempiere.webui.apps.AEnv;
+import org.adempiere.webui.component.ConfirmPanel;
+import org.adempiere.webui.component.ListModelTable;
+import org.adempiere.webui.component.WListbox;
+import org.adempiere.webui.component.WStatusBar;
+import org.adempiere.webui.component.Window;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.event.ValueChangeListener;
+import org.adempiere.webui.event.WTableModelListener;
+import org.compiere.minigrid.ColumnInfo;
+import org.compiere.minigrid.IDColumn;
+import org.compiere.model.MRole;
+import org.compiere.util.CLogger;
+import org.compiere.util.DB;
+import org.compiere.util.Env;
+import org.compiere.util.KeyNamePair;
+import org.compiere.util.Msg;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zk.ui.event.Events;
+
+/**
+ * Search Information and return selection - Base Class.
+ * Based on Info written by Jorg Janke
+ *
+ * @author Sendy Yagambrum
+ */
+public abstract class InfoPanel extends Window implements EventListener, WTableModelListener
+{
+
+ public static InfoPanel create (int WindowNo,
+ String tableName, String keyColumn, String value,
+ boolean multiSelection, String whereClause)
+ {
+ InfoPanel info = null;
+
+ if (tableName.equals("C_BPartner"))
+ info = new InfoBPartnerPanel (value,WindowNo, !Env.getContext(Env.getCtx(),"IsSOTrx").equals("N"),
+ multiSelection, whereClause);
+ else if (tableName.equals("M_Product"))
+ info = new InfoProductPanel ( WindowNo, 0,0,
+ multiSelection, value,whereClause);
+ else if (tableName.equals("C_Invoice"))
+ info = new InfoInvoicePanel ( WindowNo, value,
+ multiSelection, whereClause);
+ else if (tableName.equals("A_Asset"))
+ info = new InfoAssetPanel (WindowNo, 0, value,
+ multiSelection, whereClause);
+ else if (tableName.equals("C_Order"))
+ info = new InfoOrderPanel ( WindowNo, value,
+ multiSelection, whereClause);
+ else if (tableName.equals("M_InOut"))
+ info = new InfoInOutPanel (WindowNo, value,
+ multiSelection, whereClause);
+ else if (tableName.equals("C_Payment"))
+ info = new InfoPaymentPanel (WindowNo, value, multiSelection, whereClause);
+ else if (tableName.equals("C_CashLine"))
+ info = new InfoCashLinePanel (WindowNo, value,
+ multiSelection, whereClause);
+ else if (tableName.equals("S_ResourceAssigment"))
+ info = new InfoAssignmentPanel (WindowNo, value,
+ multiSelection, whereClause);
+ else
+ info = new InfoGeneralPanel (value, WindowNo,
+ tableName, keyColumn,
+ multiSelection, whereClause);
+ //
+ return info;
+
+ }
+
+ /**
+ * Show BPartner Info (non modal)
+ * @param WindowNo window no
+ */
+ public static void showBPartner (int WindowNo)
+ {
+ InfoBPartnerPanel infoBPanel = new InfoBPartnerPanel ( "", WindowNo,
+ !Env.getContext(Env.getCtx(),"IsSOTrx").equals("N"),false, "");
+ AEnv.showWindow(infoBPanel);
+ } // showBPartner
+
+ /**
+ * Show Asset Info (non modal)
+ * @param frame Parent Frame
+ * @param WindowNo window no
+ */
+ public static void showAsset (int WindowNo)
+ {
+ InfoPanel info = new InfoAssetPanel (WindowNo, 0, "", false, "");
+ AEnv.showWindow(info);
+ } // showBPartner
+
+ /**
+ * Show Product Info (non modal)
+ * @param frame Parent Frame
+ * @param WindowNo window no
+ */
+ /*public static void showProduct (Frame frame, int WindowNo)
+ {
+ Info info = new InfoProduct (frame, false, WindowNo,
+ Env.getContextAsInt(Env.getCtx(), WindowNo, "M_Warehouse_ID"),
+ Env.getContextAsInt(Env.getCtx(), WindowNo, "M_PriceList_ID"),
+ "", // value
+ false, "");
+ AEnv.showCenterWindow(frame, info);
+ } // showProduct
+*/
+ /**
+ * Show Order Info (non modal)
+ * @param frame Parent Frame
+ * @param WindowNo window no
+ * @param value query value
+ */
+ /*public static void showOrder (Frame frame, int WindowNo, String value)
+ {
+ Info info = new InfoOrder (frame, false, WindowNo, value,
+ false, "");
+ AEnv.showCenterWindow(frame, info);
+ } // showOrder
+*/
+ /**
+ * Show Invoice Info (non modal)
+ * @param frame Parent Frame
+ * @param WindowNo window no
+ * @param value query value
+ */
+ /*public static void showInvoice (Frame frame, int WindowNo, String value)
+ {
+ Info info = new InfoInvoice (frame, false, WindowNo, value,
+ false, "");
+ AEnv.showCenterWindow(frame, info);
+ } // showInvoice
+*/
+ /**
+ * Show Shipment Info (non modal)
+ * @param frame Parent Frame
+ * @param WindowNo window no
+ * @param value query value
+ */
+ public static void showInOut (int WindowNo, String value)
+ {
+ InfoPanel info = new InfoInOutPanel (WindowNo, value,
+ false, "");
+ AEnv.showWindow(info);
+ } // showInOut
+
+ /**
+ * Show Payment Info (non modal)
+ * @param frame Parent Frame
+ * @param WindowNo window no
+ * @param value query value
+ */
+ public static void showPayment (int WindowNo, String value)
+ {
+ InfoPanel info = new InfoPaymentPanel (WindowNo, value,
+ false, "");
+ AEnv.showWindow(info);
+ } // showPayment
+
+ /**
+ * Show Cash Line Info (non modal)
+ * @param frame Parent Frame
+ * @param WindowNo window no
+ * @param value query value
+ */
+ public static void showCashLine (int WindowNo, String value)
+ {
+ InfoPanel info = new InfoCashLinePanel (WindowNo, value,
+ false, "");
+ AEnv.showWindow(info);
+ } // showCashLine
+
+ /**
+ * Show Assignment Info (non modal)
+ * @param frame Parent Frame
+ * @param WindowNo window no
+ * @param value query value
+ */
+ public static void showAssignment (int WindowNo, String value)
+ {
+ InfoPanel info = new InfoAssignmentPanel (WindowNo, value,
+ false, "");
+ AEnv.showWindow(info);
+ } // showAssignment
+
+ /** Window Width */
+ static final int INFO_WIDTH = 800;
+
+ /**************************************************
+ * Detail Constructor
+ * @param WindowNo WindowNo
+ * @param tableName tableName
+ * @param keyColumn keyColumn
+ * @param whereClause whereClause
+ */
+ protected InfoPanel (int WindowNo,
+ String tableName, String keyColumn,boolean multipleSelection,
+ String whereClause)
+ {
+
+ log.info("WinNo=" + p_WindowNo + " " + whereClause);
+ p_WindowNo = WindowNo;
+ p_tableName = tableName;
+ p_keyColumn = keyColumn;
+ p_multipleSelection = multipleSelection;
+
+ if (whereClause == null || whereClause.indexOf('@') == -1)
+ p_whereClause = whereClause;
+ else
+ {
+ p_whereClause = Env.parseContext(Env.getCtx(), p_WindowNo, whereClause, false, false);
+ if (p_whereClause.length() == 0)
+ log.log(Level.SEVERE, "Cannot parse context= " + whereClause);
+ }
+ init();
+
+ } // InfoPanel
+
+ private void init()
+ {
+ confirmPanel = new ConfirmPanel(true,true,false,false,true,true);
+ confirmPanel.addActionListener(Events.ON_CLICK, this);
+ confirmPanel.setStyle("border-top: 2px groove #444; padding-top: 4px");
+ } // init
+ protected ConfirmPanel confirmPanel;
+ /** Master (owning) Window */
+ protected int p_WindowNo;
+ /** Table Name */
+ protected String p_tableName;
+ /** Key Column Name */
+ protected String p_keyColumn;
+ /** Enable more than one selection */
+ protected boolean p_multipleSelection;
+ /** Initial WHERE Clause */
+ protected String p_whereClause = "";
+ protected WStatusBar statusBar = new WStatusBar();
+ /** */
+ private Vector line;
+ private boolean m_ok = false;
+ /** Cancel pressed - need to differentiate between OK - Cancel - Exit */
+ private boolean m_cancel = false;
+ /** Result IDs */
+ private ArrayList m_results = new ArrayList(3);
+
+ private ListModelTable model;
+ /** Layout of Grid */
+ protected ColumnInfo[] p_layout;
+ /** Main SQL Statement */
+ private String m_sqlMain;
+ /** Count SQL Statement */
+ private String m_sqlCount;
+ /** Order By Clause */
+ private String m_sqlOrder;
+ /**ValueChange listeners */
+ private ArrayList listeners = new ArrayList();
+ /** Loading success indicator */
+ protected boolean p_loadedOK = false;
+ /** SO Zoom Window */
+ private int m_SO_Window_ID = -1;
+ /** PO Zoom Window */
+ private int m_PO_Window_ID = -1;
+
+ /** Logger */
+ protected CLogger log = CLogger.getCLogger(getClass());
+
+ protected WListbox contentPanel = new WListbox();
+
+ private static final String[] lISTENER_EVENTS = {};
+
+ /**
+ * Loaded correctly
+ * @return true if loaded OK
+ */
+ public boolean loadedOK()
+ {
+ return p_loadedOK;
+ } // loadedOK
+
+ /**
+ * Set Status Line
+ * @param text text
+ * @param error error
+ */
+ public void setStatusLine (String text, boolean error)
+ {
+ statusBar.setStatusLine(text, error);
+ Thread.yield();
+ } // setStatusLine
+
+ /**
+ * Set Status DB
+ * @param text text
+ */
+ public void setStatusDB (String text)
+ {
+ statusBar.setStatusDB(text);
+ } // setStatusDB
+
+
+
+
+ protected void prepareTable (ColumnInfo[] layout,
+ String from,
+ String where,
+ String orderBy)
+ {
+ String sql =contentPanel.prepareTable(layout, from,
+ where.toString(),false,
+ getTableName(),false);
+ p_layout = contentPanel.getLayout();
+ m_sqlMain = sql.toString();
+ m_sqlCount = "SELECT COUNT(*) FROM " + from + " WHERE " + where;
+ //
+ m_sqlOrder = "";
+ if (orderBy != null && orderBy.length() > 0)
+ m_sqlOrder = " ORDER BY " + orderBy;
+
+ } // prepareTable
+
+
+ /**************************************************************************
+ * Execute Query
+ */
+ protected void executeQuery()
+ {
+ if (!testCount())
+ {
+ return ;
+ }
+ PreparedStatement m_pstmt = null;
+ ResultSet m_rs = null;
+
+ long start = System.currentTimeMillis();
+ //
+
+ String dynWhere = getSQLWhere();
+ StringBuffer sql = new StringBuffer (m_sqlMain);
+ if (dynWhere.length() > 0)
+ sql.append(dynWhere); // includes first AND
+ 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);
+ log.finer(dataSql);
+ try
+ {
+ m_pstmt = DB.prepareStatement(dataSql, null);
+ setParameters (m_pstmt, false); // no count
+ log.fine("Start query - " + (System.currentTimeMillis()-start) + "ms");
+ m_rs = m_pstmt.executeQuery();
+ log.fine("End query - " + (System.currentTimeMillis()-start) + "ms");
+ line = new Vector();
+ while (m_rs.next())
+ {
+
+ int colOffset = 1; // columns start with 1
+ Vector data = new Vector();
+ for (int col = 0; col < p_layout.length; col++)
+ {
+ Object value = null;
+ Class c = p_layout[col].getColClass();
+ int colIndex = col + colOffset;
+ if (c == IDColumn.class)
+ {
+ value = new IDColumn(m_rs.getInt(colIndex));
+
+ }
+ else if (c == Boolean.class)
+ value = new Boolean("Y".equals(m_rs.getString(colIndex)));
+ else if (c == Timestamp.class)
+ value = m_rs.getTimestamp(colIndex);
+ else if (c == BigDecimal.class)
+ value = m_rs.getBigDecimal(colIndex);
+ else if (c == Double.class)
+ value = new Double(m_rs.getDouble(colIndex));
+ else if (c == Integer.class)
+ value = new Integer(m_rs.getInt(colIndex));
+ else if (c == KeyNamePair.class)
+ {
+ String display = m_rs.getString(colIndex);
+ int key = m_rs.getInt(colIndex+1);
+ value = new KeyNamePair(key, display);
+
+ colOffset++;
+ }
+ else
+ {
+ value = m_rs.getString(colIndex);
+ }
+ data.add(value);
+ }
+ line.add(data);
+ }
+
+ }
+
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, dataSql, e);
+ }
+
+ try
+ {
+ if (m_rs != null)
+ m_rs.close();
+ if (m_pstmt != null)
+ m_pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, "closeRS", e);
+ }
+
+ m_rs = null;
+ m_pstmt = null;
+ }
+
+ protected void renderItems()
+ {
+ Vector columnHeader = getColumnHeader(p_layout);
+ if (line != null)
+ {
+ model = new ListModelTable(line);
+ model.addTableModelListener(this);
+ contentPanel.setData(model, columnHeader);
+ }
+ int no = contentPanel.getRowCount();
+ setStatusLine(Integer.toString(no) + " " + Msg.getMsg(Env.getCtx(), "SearchRows_EnterQuery"), false);
+ setStatusDB(Integer.toString(no));
+ }
+
+
+ public Vector getColumnHeader(ColumnInfo[] p_layout)
+ {
+ Vector columnHeader = new Vector();
+
+ for (ColumnInfo info: p_layout)
+ {
+ columnHeader.add(info.getColHeader());
+ }
+ return columnHeader;
+ }
+ /**
+ * Test Row Count
+ * @return true if display
+ */
+ private boolean testCount()
+ {
+ long start = System.currentTimeMillis();
+ String dynWhere = getSQLWhere();
+ StringBuffer sql = new StringBuffer (m_sqlCount);
+
+ if (dynWhere.length() > 0)
+ sql.append(dynWhere); // includes first AND
+
+ String countSql = Msg.parseTranslation(Env.getCtx(), sql.toString()); // Variables
+ countSql = MRole.getDefault().addAccessSQL (countSql, getTableName(),
+ MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO);
+ log.finer(countSql);
+ int no = -1;
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(countSql, null);
+ setParameters (pstmt, true);
+ ResultSet rs = pstmt.executeQuery();
+
+ if (rs.next())
+ no = rs.getInt(1);
+
+ rs.close();
+ pstmt.close();
+ }
+ catch (Exception e)
+ {
+ log.log(Level.SEVERE, countSql, e);
+ no = -2;
+ }
+
+ log.fine("#" + no + " - " + (System.currentTimeMillis()-start) + "ms");
+
+ //Armen: add role checking (Patch #1694788 )
+ //MRole role = MRole.getDefault();
+ //if (role.isQueryMax(no))
+ // return ADialog.ask(p_WindowNo, this, "InfoHighRecordCount", String.valueOf(no));
+
+ return true;
+ } // testCount
+
+
+ /**
+ * Save Selection - Called by dispose
+ */
+ protected void saveSelection ()
+ {
+ // Already disposed
+ if (contentPanel == null)
+ return;
+
+ log.config( "OK=" + m_ok);
+
+ if (!m_ok) // did not press OK
+ {
+ m_results.clear();
+ contentPanel = null;
+ this.detach();
+ return;
+ }
+
+ // Multi Selection
+ if (p_multipleSelection)
+ {
+ }
+ else // singleSelection
+ {
+ Integer data = getSelectedRowKey();
+ if (data != null)
+ m_results.add(data);
+ }
+
+ log.config(getSelectedSQL());
+
+ // Save Settings of detail info screens
+ saveSelectionDetail();
+
+ } // saveSelection
+
+ /**
+ * Get the key of currently selected row
+ * @return selected key
+ */
+ protected Integer getSelectedRowKey()
+ {
+ int key = contentPanel.getSelectedRowKey();
+
+ return key;
+ } // getSelectedRowKey
+
+ /**
+ * Get selected Keys
+ * @return selected keys (Integers)
+ */
+ public Object[] getSelectedKeys()
+ {
+ if (!m_ok || m_results.size() == 0)
+ return null;
+ return m_results.toArray();
+ } // getSelectedKeys;
+
+ /**
+ * Get (first) selected Key
+ * @return selected key
+ */
+ public Object getSelectedKey()
+ {
+ if (!m_ok || m_results.size() == 0)
+ return null;
+ return m_results.get(0);
+ } // getSelectedKey
+
+ /**
+ * Is cancelled?
+ * - if pressed Cancel = true
+ * - if pressed OK or window closed = false
+ * @return true if cancelled
+ */
+ public boolean isCancelled()
+ {
+ return m_cancel;
+ } // isCancelled
+
+ /**
+ * Get where clause for (first) selected key
+ * @return WHERE Clause
+ */
+ public String getSelectedSQL()
+ {
+ // No results
+ Object[] keys = getSelectedKeys();
+ if (keys == null || keys.length == 0)
+ {
+ log.config("No Results - OK="
+ + m_ok + ", Cancel=" + m_cancel);
+ return "";
+ }
+ //
+ StringBuffer sb = new StringBuffer(getKeyColumn());
+ if (keys.length > 1)
+ sb.append(" IN (");
+ else
+ sb.append("=");
+
+ // Add elements
+ for (int i = 0; i < keys.length; i++)
+ {
+ if (getKeyColumn().endsWith("_ID"))
+ sb.append(keys[i].toString()).append(",");
+ else
+ sb.append("'").append(keys[i].toString()).append("',");
+ }
+
+ sb.replace(sb.length()-1, sb.length(), "");
+ if (keys.length > 1)
+ sb.append(")");
+ return sb.toString();
+ } // getSelectedSQL;
+
+
+
+ /**
+ * Get Table name Synonym
+ * @return table name
+ */
+ String getTableName()
+ {
+ return p_tableName;
+ } // getTableName
+
+ /**
+ * Get Key Column Name
+ * @return column name
+ */
+ String getKeyColumn()
+ {
+ return p_keyColumn;
+ } // getKeyColumn
+
+
+ public String[] getEvents()
+ {
+ return InfoPanel.lISTENER_EVENTS;
+ }
+
+ /**************************************************************************
+ * Get dynamic WHERE part of SQL
+ * To be overwritten by concrete classes
+ * @return WHERE clause
+ */
+ abstract String getSQLWhere();
+
+ /**
+ * Set Parameters for Query
+ * To be overwritten by concrete classes
+ * @param pstmt statement
+ * @param forCount for counting records
+ * @throws SQLException
+ */
+ abstract void setParameters (PreparedStatement pstmt, boolean forCount)
+ throws SQLException;
+ /**
+ * notify to search editor of a value change in the selection info
+ * @param event event
+ *
+ */
+
+ void showHistory() {}
+ /**
+ * Has History (false)
+ * To be overwritten by concrete classes
+ * @return true if it has history (default false)
+ */
+ boolean hasHistory() {return false;}
+ /**
+ * Customize dialog
+ * To be overwritten by concrete classes
+ */
+ void customize() {}
+ /**
+ * Has Customize (false)
+ * To be overwritten by concrete classes
+ * @return true if it has customize (default false)
+ */
+ boolean hasCustomize() {return false;}
+ /**
+ * Has Zoom (false)
+ * To be overwritten by concrete classes
+ * @return true if it has zoom (default false)
+ */
+ boolean hasZoom() {return false;}
+ /**
+ * Save Selection Details
+ * To be overwritten by concrete classes
+ */
+ void saveSelectionDetail() {}
+
+ /**
+ * Get Zoom Window
+ * @param tableName table name
+ * @param isSOTrx sales trx
+ * @return AD_Window_ID
+ */
+ protected int getAD_Window_ID (String tableName, boolean isSOTrx)
+ {
+ if (!isSOTrx && m_PO_Window_ID > 0)
+ return m_PO_Window_ID;
+ if (m_SO_Window_ID > 0)
+ return m_SO_Window_ID;
+ //
+ String sql = "SELECT AD_Window_ID, PO_Window_ID FROM AD_Table WHERE TableName=?";
+ PreparedStatement pstmt = null;
+ try
+ {
+ pstmt = DB.prepareStatement(sql, null);
+ pstmt.setString(1, tableName);
+ ResultSet rs = pstmt.executeQuery();
+ if (rs.next())
+ {
+ m_SO_Window_ID = rs.getInt(1);
+ m_PO_Window_ID = rs.getInt(2);
+ }
+ rs.close();
+ pstmt.close();
+ pstmt = null;
+ }
+ catch (Exception e)
+ {
+ log.log(Level.SEVERE, sql, e);
+ }
+ try
+ {
+ if (pstmt != null)
+ pstmt.close();
+ pstmt = null;
+ }
+ catch (Exception e)
+ {
+ pstmt = null;
+ }
+ //
+ if (!isSOTrx && m_PO_Window_ID > 0)
+ return m_PO_Window_ID;
+ return m_SO_Window_ID;
+ } // getAD_Window_ID
+
+ public void onEvent(Event event)
+ {
+ if (event!=null)
+ {
+ if (event.getTarget().equals(confirmPanel.getButton("Ok")))
+ {
+ if (!contentPanel.getChildren().isEmpty() && contentPanel.getSelectedRowKey()!=null)
+ {
+ dispose(true);
+ }
+ }
+ else if (event.getTarget().equals(confirmPanel.getButton("Refresh")))
+ {
+ executeQuery();
+ renderItems();
+ }
+ else if (event.getTarget().equals(confirmPanel.getButton("Cancel")))
+ {
+ dispose(false);
+ }
+ else if (event.getTarget().equals(confirmPanel.getButton("Zoom")))
+ {
+ if (!contentPanel.getChildren().isEmpty() && contentPanel.getSelectedRowKey()!=null)
+ {
+ zoom();
+ this.detach();
+ }
+ }
+ }
+ } // onEvent
+
+ public void zoom()
+ {
+ ValueChangeEvent event = new ValueChangeEvent(this,"zoom",
+ contentPanel.getSelectedRowKey(),contentPanel.getSelectedRowKey());
+ fireValueChange(event);
+ }
+
+ public void addValueChangeListener(ValueChangeListener listener)
+ {
+ if (listener == null)
+ {
+ return;
+ }
+
+ listeners.add(listener);
+ }
+
+ public void fireValueChange(ValueChangeEvent event)
+ {
+ for (ValueChangeListener listener : listeners)
+ {
+ listener.valueChange(event);
+ }
+ }
+ /**
+ * Dispose and save Selection
+ * @param ok OK pressed
+ */
+ public void dispose(boolean ok)
+ {
+ log.config("OK=" + ok);
+ m_ok = ok;
+
+ // End Worker
+ saveSelection();
+ if (contentPanel != null)
+ {
+ Object data = getSelectedKey();
+ ValueChangeEvent valuechange = new ValueChangeEvent
+ (this, p_keyColumn , data, data);
+
+ fireValueChange(valuechange);
+ }
+ this.detach();
+ } // dispose
+
+
+} // Info
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoPaymentPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoPaymentPanel.java
new file mode 100644
index 0000000000..e81f94d79f
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoPaymentPanel.java
@@ -0,0 +1,463 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Date;
+
+import org.adempiere.webui.component.Checkbox;
+import org.adempiere.webui.component.Datebox;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.Textbox;
+import org.adempiere.webui.component.VerticalBox;
+import org.adempiere.webui.editor.WEditor;
+import org.adempiere.webui.editor.WSearchEditor;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.event.ValueChangeListener;
+import org.adempiere.webui.event.WTableModelEvent;
+import org.compiere.minigrid.ColumnInfo;
+import org.compiere.minigrid.IDColumn;
+import org.compiere.model.MLookupFactory;
+import org.compiere.util.DisplayType;
+import org.compiere.util.Env;
+import org.compiere.util.Msg;
+import org.compiere.util.Util;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zk.ui.event.Events;
+import org.zkoss.zul.Hbox;
+import org.zkoss.zul.Separator;
+
+/**
+* Based on InfoPayment written by Jorg Janke
+*
+* @author Niraj Sohun
+* Aug, 02, 2007
+*/
+
+public class InfoPaymentPanel extends InfoPanel implements ValueChangeListener, EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ /** String Array of Column Info */
+ private ColumnInfo[] m_generalLayout;
+
+ /** list of query columns */
+ private ArrayList m_queryColumns = new ArrayList();
+
+ /** Table Name */
+ private String m_tableName;
+
+ /** Key Column Name */
+ private String m_keyColumn;
+
+ //private WListbox p_table = new WListbox();
+
+ private Textbox fDocumentNo = new Textbox();
+ private Textbox fAmtTo = new Textbox();
+ private Textbox fAmtFrom = new Textbox();
+
+ private WEditor fBPartner_ID;
+
+ private Datebox fDateTo = new Datebox();
+ private Datebox fDateFrom = new Datebox();
+
+ private Checkbox fIsReceipt = new Checkbox();
+
+ private Label lDocumentNo = new Label(Msg.translate(Env.getCtx(), "DocumentNo"));
+ private Label lDateFrom = new Label(Msg.translate(Env.getCtx(), "DateTrx"));
+ private Label lDateTo = new Label("-");
+ private Label lAmtFrom = new Label(Msg.translate(Env.getCtx(), "PayAmt"));
+ private Label lAmtTo = new Label("-");
+
+ /** Array of Column Info */
+ private static final ColumnInfo[] s_paymentLayout = {
+ new ColumnInfo(" ", "p.C_Payment_ID", IDColumn.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "C_BankAccount_ID"),
+ "(SELECT b.Name || ' ' || ba.AccountNo FROM C_Bank b, C_BankAccount ba WHERE b.C_Bank_ID=ba.C_Bank_ID AND ba.C_BankAccount_ID=p.C_BankAccount_ID)", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "C_BPartner_ID"),
+ "(SELECT Name FROM C_BPartner bp WHERE bp.C_BPartner_ID=p.C_BPartner_ID)", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "DateTrx"),
+ "p.DateTrx", Timestamp.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "DocumentNo"),
+ "p.DocumentNo", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "IsReceipt"),
+ "p.IsReceipt", Boolean.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "C_Currency_ID"),
+ "(SELECT ISO_Code FROM C_Currency c WHERE c.C_Currency_ID=p.C_Currency_ID)", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "PayAmt"),
+ "p.PayAmt", BigDecimal.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "ConvertedAmount"),
+ "currencyBase(p.PayAmt,p.C_Currency_ID,p.DateTrx, p.AD_Client_ID,p.AD_Org_ID)", BigDecimal.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "DiscountAmt"),
+ "p.DiscountAmt", BigDecimal.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "WriteOffAmt"),
+ "p.WriteOffAmt", BigDecimal.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "IsAllocated"),
+ "p.IsAllocated", Boolean.class)
+ };
+
+ /**
+ * Detail Protected Constructor
+ *
+ * @param modal modal
+ * @param WindowNo window no
+ * @param value query value
+ * @param multiSelection multiple selections
+ * @param whereClause where clause
+ */
+
+ protected InfoPaymentPanel(int WindowNo, String value,
+ boolean multiSelection, String whereClause)
+ {
+ super(WindowNo, "p", "C_Payment_ID", multiSelection, whereClause);
+
+ log.info( "InfoPaymentPanel");
+ setTitle(Msg.getMsg(Env.getCtx(), "InfoPayment"));
+
+ try
+ {
+ statInit();
+ p_loadedOK = initInfo();
+ }
+ catch (Exception e)
+ {
+ return;
+ }
+
+ int no = contentPanel.getRowCount();
+
+ setStatusLine(Integer.toString(no) + " " + Msg.getMsg(Env.getCtx(), "SearchRows_EnterQuery"), false);
+ setStatusDB(Integer.toString(no));
+
+ if (value != null && value.length() > 0)
+ {
+ fDocumentNo .setValue(value);
+ executeQuery();
+ }
+
+ //pack();
+
+ // Focus
+ //fDocumentNo.requestFocus();
+ } // InfoPaymentPanel
+
+ /**
+ * Static Setup - add fields to parameterPanel
+ * @throws Exception if Lookups cannot be created
+ */
+
+ private void statInit() throws Exception
+ {
+ Hbox boxDocumentNo = new Hbox();
+
+ fDocumentNo.addEventListener(Events.ON_CHANGE, this);
+
+ boxDocumentNo.setWidth("100%");
+ boxDocumentNo.setWidths("40%, 60%");
+ boxDocumentNo.appendChild(lDocumentNo);
+ boxDocumentNo.appendChild(fDocumentNo);
+
+ fIsReceipt.setLabel(Msg.translate(Env.getCtx(), "IsReceipt"));
+ fIsReceipt.addEventListener(Events.ON_CHECK, this);
+ fIsReceipt.setChecked(!"N".equals(Env.getContext(Env.getCtx(), p_WindowNo, "IsSOTrx")));
+
+ Hbox boxBPartner = new Hbox();
+
+ fBPartner_ID = new WSearchEditor(
+ MLookupFactory.get(Env.getCtx(), p_WindowNo, 0, 3499, DisplayType.Search),
+ Msg.translate(Env.getCtx(), "C_BPartner_ID"), "", false, false, true);
+ fBPartner_ID.addValueChangeListner(this);
+
+ boxBPartner.appendChild(fBPartner_ID.getLabel());
+ boxBPartner.appendChild(fBPartner_ID.getComponent());
+
+ Hbox boxDateFrom = new Hbox();
+
+ //fDateFrom.setValue(new Date(System.currentTimeMillis()));
+
+ boxDateFrom.setWidth("100%");
+ boxDateFrom.setWidths("40%, 60%");
+ boxDateFrom.appendChild(lDateFrom);
+ boxDateFrom.appendChild(fDateFrom);
+
+ Hbox boxDateTo = new Hbox();
+
+ //fDateTo.setValue(new Date(System.currentTimeMillis()));
+
+ boxDateTo.setWidth("100%");
+ boxDateTo.setWidths("10%, 90%");
+ boxDateTo.appendChild(lDateTo);
+ boxDateTo.appendChild(fDateTo);
+
+ Hbox boxAmtFrom = new Hbox();
+ boxAmtFrom.setWidth("100%");
+ boxAmtFrom.setWidths("40%, 60%");
+ boxAmtFrom.appendChild(lAmtFrom);
+ boxAmtFrom.appendChild(fAmtFrom);
+
+ Hbox boxAmtTo = new Hbox();
+ boxAmtTo.setWidth("100%");
+ boxAmtTo.setWidths("10%, 90%");
+ boxAmtTo.appendChild(lAmtTo);
+ boxAmtTo.appendChild(fAmtTo);
+
+ VerticalBox boxCol1 = new VerticalBox();
+ //boxCol1.setWidth("100%");
+ boxCol1.appendChild(boxDocumentNo);
+
+ VerticalBox boxCol2 = new VerticalBox();
+ //boxCol2.setWidth("100%");
+ boxCol2.appendChild(boxBPartner);
+ boxCol2.appendChild(new Separator());
+ boxCol2.appendChild(boxDateFrom);
+ boxCol2.appendChild(new Separator());
+ boxCol2.appendChild(boxAmtFrom);
+
+ VerticalBox boxCol3 = new VerticalBox();
+ //boxCol3.setWidth("100%");
+ boxCol3.appendChild(fIsReceipt);
+ boxCol3.appendChild(new Separator());
+ boxCol3.appendChild(boxDateTo);
+ boxCol3.appendChild(new Separator());
+ boxCol3.appendChild(boxAmtTo);
+
+ Hbox mainBox = new Hbox();
+ mainBox.setWidth("100%");
+ mainBox.setWidths("42%, 50%, 8%");
+ mainBox.appendChild(boxCol1);
+ mainBox.appendChild(boxCol2);
+ mainBox.appendChild(boxCol3);
+
+ this.setWidth("850px");
+ this.setTitle("Payment Info");
+ this.setClosable(true);
+ this.setBorder("normal");
+ this.appendChild(mainBox);
+ this.appendChild(new Separator());
+ this.appendChild(contentPanel);
+ this.appendChild(new Separator());
+ this.appendChild(confirmPanel);
+ this.appendChild(new Separator());
+ this.appendChild(statusBar);
+ }
+
+ /**
+ * General Init
+ * @return true, if success
+ */
+
+ private boolean initInfo ()
+ {
+ // Set Defaults
+ String bp = Env.getContext(Env.getCtx(), p_WindowNo, "C_BPartner_ID");
+
+ if (bp != null && bp.length() != 0)
+ fBPartner_ID.setValue(new Integer(bp));
+
+ // Prepare table
+ StringBuffer where = new StringBuffer("p.IsActive='Y'");
+
+ if (p_whereClause.length() > 0)
+ where.append(" AND ").append(Util.replace(p_whereClause, "C_Payment.", "p."));
+
+ prepareTable(s_paymentLayout, " C_Payment_v p", where.toString(), "2,3,4");
+
+ // MPayment.setIsAllocated(Env.getCtx(), 0, null);
+
+ return true;
+ } // initInfo
+
+
+ /**************************************************************************
+ * Construct SQL Where Clause and define parameters
+ * (setParameters needs to set parameters)
+ * Includes first AND
+ * @return sql where clause
+ */
+
+ String getSQLWhere()
+ {
+ StringBuffer sql = new StringBuffer();
+
+ if (fDocumentNo.getText().length() > 0)
+ sql.append(" AND UPPER(p.DocumentNo) LIKE ?");
+
+ if (fBPartner_ID.getDisplay() != "")
+ sql.append(" AND p.C_BPartner_ID=?");
+
+ if (fDateFrom.getValue() != null || fDateTo.getValue() != null)
+ {
+ Date f = fDateFrom.getValue();
+ Timestamp from = new Timestamp(f.getTime());
+
+ Date t = fDateTo.getValue();
+ Timestamp to = new Timestamp(t.getTime());
+
+ if (from == null && to != null)
+ sql.append(" AND TRUNC(p.DateTrx) <= ?");
+ else if (from != null && to == null)
+ sql.append(" AND TRUNC(p.DateTrx) >= ?");
+ else if (from != null && to != null)
+ sql.append(" AND TRUNC(p.DateTrx) BETWEEN ? AND ?");
+ }
+
+ if (fAmtFrom.getText() != "" || fAmtTo.getText() != "")
+ {
+ BigDecimal from = new BigDecimal(fAmtFrom.getValue());
+ BigDecimal to = new BigDecimal(fAmtTo.getValue());
+
+ if (from == null && to != null)
+ sql.append(" AND p.PayAmt <= ?");
+ else if (from != null && to == null)
+ sql.append(" AND p.PayAmt >= ?");
+ else if (from != null && to != null)
+ sql.append(" AND p.PayAmt BETWEEN ? AND ?");
+ }
+
+ sql.append(" AND p.IsReceipt=?");
+
+ log.fine(sql.toString());
+ return sql.toString();
+ } // getSQLWhere
+
+ /**
+ * Set Parameters for Query.
+ * (as defined in getSQLWhere)
+ * @param pstmt statement
+ * @param forCount for counting records
+ * @throws SQLException
+ */
+
+ void setParameters(PreparedStatement pstmt, boolean forCount) throws SQLException
+ {
+ int index = 1;
+
+ if (fDocumentNo.getText().length() > 0)
+ pstmt.setString(index++, getSQLText(fDocumentNo));
+
+ if (fBPartner_ID.getDisplay() != "")
+ {
+ Integer bp = (Integer)fBPartner_ID.getValue();
+ pstmt.setInt(index++, bp.intValue());
+ log.fine("BPartner=" + bp);
+ }
+
+ if (fDateFrom.getValue() != null || fDateTo.getValue() != null)
+ {
+ Date f = fDateFrom.getValue();
+ Timestamp from = new Timestamp(f.getTime());
+
+ Date t = fDateTo.getValue();
+ Timestamp to = new Timestamp(t.getTime());
+
+ log.fine("Date From=" + from + ", To=" + to);
+
+ if (from == null && to != null)
+ pstmt.setTimestamp(index++, to);
+ else if (from != null && to == null)
+ pstmt.setTimestamp(index++, from);
+ else if (from != null && to != null)
+ {
+ pstmt.setTimestamp(index++, from);
+ pstmt.setTimestamp(index++, to);
+ }
+ }
+
+ if (fAmtFrom.getText() != "" || fAmtTo.getText() != "")
+ {
+ BigDecimal from = new BigDecimal(fAmtFrom.getValue());
+ BigDecimal to = new BigDecimal(fAmtTo.getValue());
+ log.fine("Amt From=" + from + ", To=" + to);
+
+ if (from == null && to != null)
+ pstmt.setBigDecimal(index++, to);
+ else if (from != null && to == null)
+ pstmt.setBigDecimal(index++, from);
+ else if (from != null && to != null)
+ {
+ pstmt.setBigDecimal(index++, from);
+ pstmt.setBigDecimal(index++, to);
+ }
+ }
+
+ pstmt.setString(index++, fIsReceipt.isChecked() ? "Y" : "N");
+ } // setParameters
+
+ /**
+ * Get SQL WHERE parameter
+ * @param f field
+ * @return Upper case text with % at the end
+ */
+
+ private String getSQLText (Textbox f)
+ {
+ String s = f.getText().toUpperCase();
+
+ if (!s.endsWith("%"))
+ s += "%";
+
+ log.fine( "String=" + s);
+
+ return s;
+ } // getSQLText
+
+ /**
+ * Zoom
+ */
+
+/* void zoom()
+ {
+ log.info( "InfoPayment.zoom");
+ Integer C_Payment_ID = getSelectedRowKey();
+ if (C_Payment_ID == null)
+ return;
+ MQuery query = new MQuery("C_Payment");
+ query.addRestriction("C_Payment_ID", MQuery.EQUAL, C_Payment_ID);
+ query.setRecordCount(1);
+ int AD_WindowNo = getAD_Window_ID("C_Payment", fIsReceipt.isSelected());
+ zoom (AD_WindowNo, query);
+ } // zoom
+*/
+ /**
+ * Has Zoom
+ * @return true
+ */
+
+ boolean hasZoom()
+ {
+ return true;
+ } // hasZoom
+
+ public void valueChange(ValueChangeEvent evt)
+ {
+ if (fBPartner_ID.equals(evt.getSource()))
+ {
+ fBPartner_ID.setValue(evt.getNewValue());
+ }
+ }
+
+ public void tableChanged(WTableModelEvent event) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoProductPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoProductPanel.java
new file mode 100644
index 0000000000..ac5b57327c
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/InfoProductPanel.java
@@ -0,0 +1,834 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
+ * or via info@compiere.org or http://www.compiere.org/license.html *
+ *****************************************************************************/
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.logging.Level;
+
+import org.adempiere.webui.component.Button;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.ListItem;
+import org.adempiere.webui.component.Listbox;
+import org.adempiere.webui.component.Panel;
+import org.adempiere.webui.component.Textbox;
+import org.adempiere.webui.component.WListbox;
+import org.adempiere.webui.event.WTableModelEvent;
+import org.compiere.minigrid.ColumnInfo;
+import org.compiere.minigrid.IDColumn;
+import org.compiere.model.MClient;
+import org.compiere.model.MRole;
+import org.compiere.util.DB;
+import org.compiere.util.Env;
+import org.compiere.util.KeyNamePair;
+import org.compiere.util.Msg;
+import org.compiere.util.Util;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zk.ui.event.Events;
+import org.zkoss.zul.Div;
+import org.zkoss.zul.Hbox;
+import org.zkoss.zul.Vbox;
+
+/**
+ * Search Product and return selection
+ * This class is based on org.compiere.apps.search.InfoProduct written by Jorg Janke
+ * @author Sendy Yagambrum
+ *
+ */
+public final class InfoProductPanel extends InfoPanel implements EventListener
+{
+
+ /**
+ *
+ **/
+ private static final long serialVersionUID = 1L;
+
+ private Label lblValue = new Label();
+ private Textbox fieldValue = new Textbox();
+ private Label lblName = new Label();
+ private Textbox fieldName = new Textbox();
+ private Label lblUPC = new Label();
+ private Textbox fieldUPC = new Textbox();
+ private Label lblSKU = new Label();
+ private Textbox fieldSKU = new Textbox();
+ private Label lblPriceList = new Label();
+ private Listbox pickPriceList = new Listbox();
+ private Label lblWarehouse = new Label();
+ private Listbox pickWarehouse = new Listbox();
+ private Label lblVendor = new Label();
+ private Textbox fieldVendor = new Textbox();
+ private Button p_attributeInfo;
+ /** SQL From */
+ private static final String s_productFrom =
+ "M_Product p"
+ + " LEFT OUTER JOIN M_ProductPrice pr ON (p.M_Product_ID=pr.M_Product_ID AND pr.IsActive='Y')"
+ + " LEFT OUTER JOIN M_AttributeSet pa ON (p.M_AttributeSet_ID=pa.M_AttributeSet_ID)"
+ + " LEFT OUTER JOIN M_Product_PO ppo ON (p.M_Product_ID=ppo.M_Product_ID)"
+ + " LEFT OUTER JOIN C_BPartner bp ON (ppo.C_BPartner_ID=bp.C_BPartner_ID)";
+
+ /** Array of Column Info */
+ private static ColumnInfo[] s_productLayout = null;
+ private static int INDEX_NAME = 0;
+ private static int INDEX_PATTRIBUTE = 0;
+
+
+ /** ASI */
+ private int m_M_AttributeSetInstance_ID = -1;
+ /** Locator */
+ private int m_M_Locator_ID = 0;
+
+ private String m_pAttributeWhere = null;
+ private int m_C_BPartner_ID = 0;
+
+ /**
+ * Standard Constructor
+ * @param WindowNo window no
+ * @param M_Warehouse_ID warehouse
+ * @param M_PriceList_ID price list
+ * @param value Query Value or Name if enclosed in @
+ * @param whereClause where clause
+ */
+ public InfoProductPanel(int windowNo,
+ int M_Warehouse_ID, int M_PriceList_ID, boolean multipleSelection,String value,
+ String whereClause)
+ {
+ super (windowNo, "p", "M_Product_ID",multipleSelection, whereClause);
+ log.info(value + ", Wh=" + M_Warehouse_ID + ", PL=" + M_PriceList_ID + ", WHERE=" + whereClause);
+ setTitle(Msg.getMsg(Env.getCtx(), "InfoProduct"));
+ //
+ initComponents();
+ init();
+ initInfo (value, M_Warehouse_ID, M_PriceList_ID);
+ m_C_BPartner_ID = Env.getContextAsInt(Env.getCtx(), windowNo, "C_BPartner_ID");
+
+ int no = contentPanel.getRowCount();
+ setStatusLine(Integer.toString(no) + " " + Msg.getMsg(Env.getCtx(), "SearchRows_EnterQuery"), false);
+ setStatusDB(Integer.toString(no));
+ // AutoQuery
+ if (value != null && value.length() > 0)
+ {
+ executeQuery();
+ renderItems();
+ }
+ p_loadedOK = true;
+
+
+ } // InfoProductPanel
+
+
+ /**
+ * initialize fields
+ */
+ private void initComponents()
+ {
+ lblValue = new Label();
+ lblValue.setValue(Msg.translate(Env.getCtx(), "Value").substring(1));
+ lblName = new Label();
+ lblName.setValue(Msg.translate(Env.getCtx(), "Name").substring(1));
+ lblUPC = new Label();
+ lblUPC.setValue(Msg.translate(Env.getCtx(), "UPC"));
+ lblSKU = new Label();
+ lblSKU.setValue(Msg.translate(Env.getCtx(), "SKU"));
+ lblPriceList = new Label();
+ lblPriceList.setValue(Msg.getMsg(Env.getCtx(), "PriceListVersion"));
+ lblWarehouse = new Label();
+ lblWarehouse.setValue(Msg.getMsg(Env.getCtx(), "Warehouse").substring(1));
+ lblVendor = new Label();
+ lblVendor.setValue(Msg.translate(Env.getCtx(), "Vendor"));
+
+ /* p_attributeInfo = new Button();
+ p_attributeInfo.setImage("/images/PAttribute16.gif");
+ p_attributeInfo.setTooltiptext("Poduct Atribute Info");
+ p_attributeInfo.addEventListener(Events.ON_CLICK,this);*/
+
+ fieldValue = new Textbox();
+ fieldValue.setMaxlength(40);
+ fieldName = new Textbox();
+ fieldName.setMaxlength(40);
+ fieldUPC = new Textbox();
+ fieldUPC.setMaxlength(40);
+ fieldSKU = new Textbox();
+ fieldSKU.setMaxlength(40);
+ pickPriceList = new Listbox();
+ pickPriceList.setRows(0);
+ pickPriceList.setMultiple(false);
+ pickPriceList.setMold("select");
+ pickPriceList.setWidth("150px");
+ pickPriceList.addEventListener(Events.ON_SELECT, this);
+
+ pickWarehouse = new Listbox();
+ pickWarehouse.setRows(0);
+ pickWarehouse.setMultiple(false);
+ pickWarehouse.setMold("select");
+ pickWarehouse.setWidth("150px");
+ pickWarehouse.addEventListener(Events.ON_SELECT, this);
+
+ fieldVendor = new Textbox();
+ fieldVendor.setMaxlength(40);
+
+ contentPanel = new WListbox();
+ contentPanel.setWidth("1500px");
+ contentPanel.setHeight("500px");
+ } // initComponents
+
+ private void init()
+ {
+
+ Panel pnlValue = new Panel();
+ pnlValue.appendChild(lblValue);
+ pnlValue.appendChild(fieldValue);
+ pnlValue.setAlign("right");
+
+ Panel pnlName = new Panel();
+ pnlName.appendChild(lblName);
+ pnlName.appendChild(fieldName);
+ pnlName.setAlign("right");
+
+ Panel pnlUPC = new Panel();
+ pnlUPC.appendChild(lblUPC);
+ pnlUPC.appendChild(fieldUPC);
+ pnlUPC.setAlign("right");
+
+ Panel pnlSKU = new Panel();
+ pnlSKU.appendChild(lblSKU);
+ pnlSKU.appendChild(fieldSKU);
+ pnlSKU.setAlign("right");
+
+ Panel pnlPriceList = new Panel();
+ pnlPriceList.appendChild(lblPriceList);
+ pnlPriceList.appendChild(pickPriceList);
+ pnlPriceList.setAlign("right");
+
+ Panel pnlWarehouse = new Panel();
+ pnlWarehouse.appendChild(lblWarehouse);
+ pnlWarehouse.appendChild(pickWarehouse);
+ pnlWarehouse.setAlign("right");
+
+ Panel pnlVendor = new Panel();
+ pnlVendor.appendChild(lblVendor);
+ pnlVendor.appendChild(fieldVendor);
+ pnlVendor.setAlign("right");
+
+ /*Panel pnlButton = new Panel();
+ pnlButton.appendChild(p_attributeInfo);
+ pnlButton.setAlign("left");*/
+
+ Vbox vbox1 = new Vbox();
+ vbox1.appendChild(pnlValue);
+ vbox1.appendChild(pnlName);
+
+ Vbox vbox2 = new Vbox();
+ vbox2.appendChild(pnlUPC);
+ vbox2.appendChild(pnlSKU);
+
+ Vbox vbox3 = new Vbox();
+ vbox3.appendChild(pnlWarehouse);
+ vbox3.appendChild(pnlVendor);
+
+ Vbox vbox4 = new Vbox();
+ /*vbox4.appendChild(pnlButton);*/
+ vbox4.appendChild(pnlPriceList);
+
+
+ Hbox parameterPanel = new Hbox();
+ parameterPanel.appendChild(vbox1);
+ parameterPanel.appendChild(vbox2);
+ parameterPanel.appendChild(vbox3);
+ parameterPanel.appendChild(vbox4);
+
+ Vbox mainPanel = new Vbox();
+ mainPanel.setWidth("100%");
+ mainPanel.appendChild(parameterPanel);
+ Div div = new Div();
+ div.setStyle("overflow:auto");
+ div.setWidth("100%");
+ div.appendChild(contentPanel);
+ mainPanel.appendChild(div);
+ mainPanel.appendChild(confirmPanel);
+
+ this.appendChild(mainPanel);
+ this.setBorder("normal");
+ this.setWidth("1000px");
+ }
+
+ /**
+ * Dynamic Init
+ *
+ * @param value value
+ * @param M_Warehouse_ID warehouse
+ * @param M_PriceList_ID price list
+ */
+ private void initInfo (String value, int M_Warehouse_ID, int M_PriceList_ID)
+ {
+ // Pick init
+ fillPicks(M_PriceList_ID);
+ int M_PriceList_Version_ID = findPLV (M_PriceList_ID);
+ // Set Value or Name
+ if (value.startsWith("@") && value.endsWith("@"))
+ fieldName.setText(value.substring(1,value.length()-1));
+ else
+ fieldValue.setText(value);
+ // Set Warehouse
+ if (M_Warehouse_ID == 0)
+ M_Warehouse_ID = Env.getContextAsInt(Env.getCtx(), "#M_Warehouse_ID");
+ if (M_Warehouse_ID != 0)
+ setWarehouse (M_Warehouse_ID);
+ // Set PriceList Version
+ if (M_PriceList_Version_ID != 0)
+ setPriceListVersion (M_PriceList_Version_ID);
+
+ // Create Grid
+ StringBuffer where = new StringBuffer();
+ where.append("p.IsActive='Y'");
+ if (M_Warehouse_ID != 0)
+ where.append(" AND p.IsSummary='N'");
+ // dynamic Where Clause
+ if (p_whereClause != null && p_whereClause.length() > 0)
+ where.append(" AND ") // replace fully qalified name with alias
+ .append(Util.replace(p_whereClause, "M_Product.", "p."));
+ //
+ prepareTable(getProductLayout(),
+ s_productFrom,
+ where.toString(),
+ "QtyAvailable DESC, Margin DESC");
+
+ //
+ pickWarehouse.addEventListener(Events.ON_SELECT,this);
+ pickPriceList.addEventListener(Events.ON_SELECT,this);
+ } // initInfo
+
+ /**
+ * Fill Picks with values
+ *
+ * @param M_PriceList_ID price list
+ */
+ private void fillPicks (int M_PriceList_ID)
+ {
+ // Price List
+ String SQL = "SELECT M_PriceList_Version.M_PriceList_Version_ID,"
+ + " M_PriceList_Version.Name || ' (' || c.Iso_Code || ')' AS ValueName "
+ + "FROM M_PriceList_Version, M_PriceList pl, C_Currency c "
+ + "WHERE M_PriceList_Version.M_PriceList_ID=pl.M_PriceList_ID"
+ + " AND pl.C_Currency_ID=c.C_Currency_ID"
+ + " AND M_PriceList_Version.IsActive='Y' AND pl.IsActive='Y'";
+ // Same PL currency as original one
+ if (M_PriceList_ID != 0)
+ SQL += " AND EXISTS (SELECT * FROM M_PriceList xp WHERE xp.M_PriceList_ID=" + M_PriceList_ID
+ + " AND pl.C_Currency_ID=xp.C_Currency_ID)";
+ // Add Access & Order
+ SQL = MRole.getDefault().addAccessSQL (SQL, "M_PriceList_Version", true, false) // fully qualidfied - RO
+ + " ORDER BY M_PriceList_Version.Name";
+ try
+ {
+ pickPriceList.appendItem("",new Integer(0));
+ PreparedStatement pstmt = DB.prepareStatement(SQL, null);
+ ResultSet rs = pstmt.executeQuery();
+ while (rs.next())
+ {
+ KeyNamePair kn = new KeyNamePair (rs.getInt(1), rs.getString(2));
+ pickPriceList.appendItem(rs.getString(2),new Integer(rs.getInt(1)));
+ }
+ rs.close();
+ pstmt.close();
+
+ // Warehouse
+ SQL = MRole.getDefault().addAccessSQL (
+ "SELECT M_Warehouse_ID, Value || ' - ' || Name AS ValueName "
+ + "FROM M_Warehouse "
+ + "WHERE IsActive='Y'",
+ "M_Warehouse", MRole.SQL_NOTQUALIFIED, MRole.SQL_RO)
+ + " ORDER BY Value";
+ pickWarehouse.appendItem("", new Integer(0));
+ pstmt = DB.prepareStatement(SQL, null);
+ rs = pstmt.executeQuery();
+ while (rs.next())
+ {
+ KeyNamePair kn = new KeyNamePair
+ (rs.getInt("M_Warehouse_ID"), rs.getString("ValueName"));
+ pickWarehouse.appendItem(rs.getString("ValueName"), new Integer(rs.getInt("M_Warehouse_ID")));
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, SQL, e);
+ setStatusLine(e.getLocalizedMessage(), true);
+ }
+ } // fillPicks
+
+ /**
+ * Set Warehouse
+ *
+ * @param M_Warehouse_ID warehouse
+ */
+ private void setWarehouse(int M_Warehouse_ID)
+ {
+ for (int i = 0; i < pickWarehouse.getItemCount(); i++)
+ {
+ Integer key = (Integer) pickWarehouse.getItemAtIndex(i).getValue();
+ if (key == M_Warehouse_ID)
+ {
+ pickWarehouse.setSelectedIndex(i);
+ return;
+ }
+ }
+ } // setWarehouse
+
+ /**
+ * Set PriceList
+ *
+ * @param M_PriceList_Version_ID price list
+ */
+ private void setPriceListVersion(int M_PriceList_Version_ID)
+ {
+ log.config("M_PriceList_Version_ID=" + M_PriceList_Version_ID);
+ for (int i = 0; i < pickPriceList.getItemCount(); i++)
+ {
+ Integer key = (Integer) pickPriceList.getItemAtIndex(i).getValue();
+ if (key == M_PriceList_Version_ID)
+ {
+ pickPriceList.setSelectedIndex(i);
+ return;
+ }
+ }
+ log.fine("NOT found");
+ } // setPriceList
+
+ /**
+ * Find Price List Version and update context
+ *
+ * @param M_PriceList_ID price list
+ * @return M_PriceList_Version_ID price list version
+ */
+ private int findPLV (int M_PriceList_ID)
+ {
+ Timestamp priceDate = null;
+ // Sales Order Date
+ String dateStr = Env.getContext(Env.getCtx(), p_WindowNo, "DateOrdered");
+ if (dateStr != null && dateStr.length() > 0)
+ priceDate = Env.getContextAsDate(Env.getCtx(), p_WindowNo, "DateOrdered");
+ else // Invoice Date
+ {
+ dateStr = Env.getContext(Env.getCtx(), p_WindowNo, "DateInvoiced");
+ if (dateStr != null && dateStr.length() > 0)
+ priceDate = Env.getContextAsDate(Env.getCtx(), p_WindowNo, "DateInvoiced");
+ }
+ // Today
+ if (priceDate == null)
+ priceDate = new Timestamp(System.currentTimeMillis());
+ //
+ log.config("M_PriceList_ID=" + M_PriceList_ID + " - " + priceDate);
+ int retValue = 0;
+ String sql = "SELECT plv.M_PriceList_Version_ID, plv.ValidFrom "
+ + "FROM M_PriceList pl, M_PriceList_Version plv "
+ + "WHERE pl.M_PriceList_ID=plv.M_PriceList_ID"
+ + " AND plv.IsActive='Y'"
+ + " AND pl.M_PriceList_ID=? " // 1
+ + "ORDER BY plv.ValidFrom DESC";
+ // find newest one
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql, null);
+ pstmt.setInt(1, M_PriceList_ID);
+ ResultSet rs = pstmt.executeQuery();
+ while (rs.next() && retValue == 0)
+ {
+ Timestamp plDate = rs.getTimestamp(2);
+ if (!priceDate.before(plDate))
+ retValue = rs.getInt(1);
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql, e);
+ }
+ Env.setContext(Env.getCtx(), p_WindowNo, "M_PriceList_Version_ID", retValue);
+ return retValue;
+ } // findPLV
+
+
+ /**************************************************************************
+ * Construct SQL Where Clause and define parameters
+ * (setParameters needs to set parameters)
+ * Includes first AND
+ * @return SQL WHERE clause
+ */
+ public String getSQLWhere()
+ {
+ StringBuffer where = new StringBuffer();
+
+ // Optional PLV
+ int M_PriceList_Version_ID = 0;
+ ListItem listitem = pickPriceList.getSelectedItem();
+ if (listitem != null)
+ M_PriceList_Version_ID = (Integer)listitem.getValue();
+ if (M_PriceList_Version_ID != 0)
+ where.append(" AND pr.M_PriceList_Version_ID=?");
+
+ // Product Attribute Search
+ if (m_pAttributeWhere != null)
+ {
+ where.append(m_pAttributeWhere);
+ return where.toString();
+ }
+
+ // => Value
+ String value = fieldValue.getText().toUpperCase();
+ if (!(value.equals("") || value.equals("%")))
+ where.append(" AND UPPER(p.Value) LIKE ?");
+
+ // => Name
+ String name = fieldName.getText().toUpperCase();
+ if (!(name.equals("") || name.equals("%")))
+ where.append(" AND UPPER(p.Name) LIKE ?");
+
+ // => UPC
+ String upc = fieldUPC.getText().toUpperCase();
+ if (!(upc.equals("") || upc.equals("%")))
+ where.append(" AND UPPER(p.UPC) LIKE ?");
+
+ // => SKU
+ String sku = fieldSKU.getText().toUpperCase();
+ if (!(sku.equals("") || sku.equals("%")))
+ where.append(" AND UPPER(p.SKU) LIKE ?");
+ // => Vendor
+ String vendor = fieldVendor.getText().toUpperCase();
+ if (!(vendor.equals("") || vendor.equals("%")))
+ where.append(" AND UPPER(bp.Name) LIKE ?");
+
+ return where.toString();
+ } // getSQLWhere
+
+ /**
+ * Set Parameters for Query
+ * (as defined in getSQLWhere) *
+ * @param pstmt pstmt
+ * @param forCount for counting records
+ * @throws SQLException
+ */
+ void setParameters(PreparedStatement pstmt, boolean forCount) throws SQLException
+ {
+ int index = 1;
+
+ // => Warehouse
+ int M_Warehouse_ID = 0;
+ ListItem listitem = pickWarehouse.getSelectedItem();
+ if (listitem != null)
+ M_Warehouse_ID = (Integer)listitem.getValue();
+ if (!forCount) // parameters in select
+ {
+ for (int i = 0; i < p_layout.length; i++)
+ {
+ if (p_layout[i].getColSQL().indexOf('?') != -1)
+ pstmt.setInt(index++, M_Warehouse_ID);
+ }
+ }
+ log.fine("M_Warehouse_ID=" + M_Warehouse_ID + " (" + (index-1) + "*)");
+
+ // => PriceList
+ int M_PriceList_Version_ID = 0;
+ ListItem lstitem = pickPriceList.getSelectedItem();
+ if (lstitem != null)
+ M_PriceList_Version_ID = (Integer)lstitem.getValue();
+ if (M_PriceList_Version_ID != 0)
+ {
+ pstmt.setInt(index++, M_PriceList_Version_ID);
+ log.fine("M_PriceList_Version_ID=" + M_PriceList_Version_ID);
+ }
+ // Rest of Parameter in Query for Attribute Search
+ if (m_pAttributeWhere != null)
+ return;
+
+ // => Value
+ String value = fieldValue.getText().toUpperCase();
+ if (!(value.equals("") || value.equals("%")))
+ {
+ if (!value.endsWith("%"))
+ value += "%";
+ pstmt.setString(index++, value);
+ log.fine("Value: " + value);
+ }
+
+ // => Name
+ String name = fieldName.getText().toUpperCase();
+ if (!(name.equals("") || name.equals("%")))
+ {
+ if (!name.endsWith("%"))
+ name += "%";
+ pstmt.setString(index++, name);
+ log.fine("Name: " + name);
+ }
+
+ // => UPC
+ String upc = fieldUPC.getText().toUpperCase();
+ if (!(upc.equals("") || upc.equals("%")))
+ {
+ if (!upc.endsWith("%"))
+ upc += "%";
+ pstmt.setString(index++, upc);
+ log.fine("UPC: " + upc);
+ }
+
+ // => SKU
+ String sku = fieldSKU.getText().toUpperCase();
+ if (!(sku.equals("") || sku.equals("%")))
+ {
+ if (!sku.endsWith("%"))
+ sku += "%";
+ pstmt.setString(index++, sku);
+ log.fine("SKU: " + sku);
+ }
+
+ // => Vendor
+ String vendor = fieldVendor.getText().toUpperCase();
+ if (!(vendor.equals("") || vendor.equals("%")))
+ {
+ if (!vendor.endsWith("%"))
+ vendor += "%";
+ pstmt.setString(index++, vendor);
+ log.fine("Vendor: " + vendor);
+ }
+
+ } // setParameters
+
+
+
+
+ /**
+ * Query per Product Attribute.
+ *
+ * Available synonyms:
+ * M_Product p
+ * M_ProductPrice pr
+ * M_AttributeSet pa
+ *
+ */
+ private void cmd_InfoPAttribute()
+ {
+ /*InfoPAttributePanel ia = new InfoPAttributePanel();
+ m_pAttributeWhere = ia.getWhereClause();
+ if (m_pAttributeWhere != null)
+ executeQuery();*/
+ } // cmdInfoAttribute
+
+ /**
+ * Show History
+ */
+ void showHistory()
+ {
+ /*log.info("");
+ Integer M_Product_ID = getSelectedRowKey();
+ if (M_Product_ID == null)
+ return;
+ KeyNamePair kn = (KeyNamePair)pickWarehouse.getSelectedItem();
+ int M_Warehouse_ID = kn.getKey();
+ int M_AttributeSetInstance_ID = m_M_AttributeSetInstance_ID;
+ if (m_M_AttributeSetInstance_ID < -1) // not selected
+ M_AttributeSetInstance_ID = 0;
+ //
+ InvoiceHistory ih = new InvoiceHistory (this, 0,
+ M_Product_ID.intValue(), M_Warehouse_ID, M_AttributeSetInstance_ID);
+ ih.setVisible(true);
+ ih = null;*/
+ } // showHistory
+
+ /**
+ * Has History
+ *
+ * @return true (has history)
+ */
+ boolean hasHistory()
+ {
+ return true;
+ } // hasHistory
+
+ /**
+ * Has Zoom
+ * @return (has zoom)
+ */
+ boolean hasZoom()
+ {
+ return true;
+ } // hasZoom
+
+ /**
+ * Customize
+ */
+ void customize()
+ {
+ log.info("");
+ } // customize
+
+ /**
+ * Has Customize
+ * @return false (no customize)
+ */
+ boolean hasCustomize()
+ {
+ return false; // for now
+ } // hasCustomize
+
+ /**
+ * Save Selection Settings for PriceList
+ */
+ void saveSelectionDetail()
+ {
+ // publish for Callout to read
+ Integer ID = getSelectedRowKey();
+ Env.setContext(Env.getCtx(), Env.WINDOW_INFO, Env.TAB_INFO, "M_Product_ID", ID == null ? "0" : ID.toString());
+ ListItem pickPL = (ListItem)pickPriceList.getSelectedItem();
+ if (pickPL!=null)
+ {
+ Env.setContext(Env.getCtx(), Env.WINDOW_INFO, Env.TAB_INFO, "M_PriceList_Version_ID",pickPL.getValue().toString());
+ }
+ ListItem pickWH = (ListItem)pickWarehouse.getSelectedItem();
+ if (pickWH != null)
+ {
+ Env.setContext(Env.getCtx(), Env.WINDOW_INFO, Env.TAB_INFO, "M_Warehouse_ID",pickWH.getValue().toString());
+ }
+ //
+ if (m_M_AttributeSetInstance_ID == -1) // not selected
+ {
+ Env.setContext(Env.getCtx(), Env.WINDOW_INFO, Env.TAB_INFO, "M_AttributeSetInstance_ID", "0");
+ Env.setContext(Env.getCtx(), Env.WINDOW_INFO, Env.TAB_INFO, "M_Locator_ID", "0");
+ }
+ else
+ {
+ Env.setContext(Env.getCtx(), Env.WINDOW_INFO, Env.TAB_INFO, "M_AttributeSetInstance_ID",
+ String.valueOf(m_M_AttributeSetInstance_ID));
+ Env.setContext(Env.getCtx(), Env.WINDOW_INFO, Env.TAB_INFO, "M_Locator_ID",
+ String.valueOf(m_M_Locator_ID));
+ }
+ } // saveSelectionDetail
+
+ /**
+ * Get Product Layout
+ *
+ * @return array of Column_Info
+ */
+ private ColumnInfo[] getProductLayout()
+ {
+ if (s_productLayout != null)
+ return s_productLayout;
+ // Euro 13
+ MClient client = MClient.get(Env.getCtx());
+ if ("FRIE".equals(client.getValue()))
+ {
+ final ColumnInfo[] frieLayout = {
+ new ColumnInfo(" ", "p.M_Product_ID", IDColumn.class),
+ // new Info_Column(Msg.translate(Env.getCtx(), "Value"), "p.Value", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "Name"), "p.Name", String.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "QtyAvailable"), "bomQtyAvailable(p.M_Product_ID,?,0) AS QtyAvailable", Double.class, true, true, null),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "PriceList"), "bomPriceList(p.M_Product_ID, pr.M_PriceList_Version_ID) AS PriceList", BigDecimal.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "PriceStd"), "bomPriceStd(p.M_Product_ID, pr.M_PriceList_Version_ID) AS PriceStd", BigDecimal.class),
+ new ColumnInfo("Einzel MWSt", "pr.PriceStd * 1.16", BigDecimal.class),
+ new ColumnInfo("Einzel kompl", "(pr.PriceStd+13) * 1.16", BigDecimal.class),
+ new ColumnInfo("Satz kompl", "((pr.PriceStd+13) * 1.16) * 4", BigDecimal.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "QtyOnHand"), "bomQtyOnHand(p.M_Product_ID,?,0) AS QtyOnHand", Double.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "QtyReserved"), "bomQtyReserved(p.M_Product_ID,?,0) AS QtyReserved", Double.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "QtyOrdered"), "bomQtyOrdered(p.M_Product_ID,?,0) AS QtyOrdered", Double.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "Discontinued").substring(0, 1), "p.Discontinued", Boolean.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "Margin"), "bomPriceStd(p.M_Product_ID, pr.M_PriceList_Version_ID)-bomPriceLimit(p.M_Product_ID, pr.M_PriceList_Version_ID) AS Margin", BigDecimal.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "PriceLimit"), "bomPriceLimit(p.M_Product_ID, pr.M_PriceList_Version_ID) AS PriceLimit", BigDecimal.class),
+ new ColumnInfo(Msg.translate(Env.getCtx(), "IsInstanceAttribute"), "pa.IsInstanceAttribute", Boolean.class)
+ };
+ INDEX_NAME = 2;
+ INDEX_PATTRIBUTE = frieLayout.length - 1; // last item
+ s_productLayout = frieLayout;
+ return s_productLayout;
+ }
+ //
+ if (s_productLayout == null)
+ {
+ ArrayList list = new ArrayList();
+ list.add(new ColumnInfo(" ", "p.M_Product_ID", IDColumn.class));
+ list.add(new ColumnInfo(Msg.translate(Env.getCtx(), "Discontinued").substring(0, 1), "p.Discontinued", Boolean.class));
+ list.add(new ColumnInfo(Msg.translate(Env.getCtx(), "Value"), "p.Value", String.class));
+ list.add(new ColumnInfo(Msg.translate(Env.getCtx(), "Name"), "p.Name", String.class));
+ list.add(new ColumnInfo(Msg.translate(Env.getCtx(), "QtyAvailable"), "bomQtyAvailable(p.M_Product_ID,?,0) AS QtyAvailable", Double.class, true, true, null));
+ list.add(new ColumnInfo(Msg.translate(Env.getCtx(), "PriceList"), "bomPriceList(p.M_Product_ID, pr.M_PriceList_Version_ID) AS PriceList", BigDecimal.class));
+ list.add(new ColumnInfo(Msg.translate(Env.getCtx(), "PriceStd"), "bomPriceStd(p.M_Product_ID, pr.M_PriceList_Version_ID) AS PriceStd", BigDecimal.class));
+ list.add(new ColumnInfo(Msg.translate(Env.getCtx(), "QtyOnHand"), "bomQtyOnHand(p.M_Product_ID,?,0) AS QtyOnHand", Double.class));
+ list.add(new ColumnInfo(Msg.translate(Env.getCtx(), "QtyReserved"), "bomQtyReserved(p.M_Product_ID,?,0) AS QtyReserved", Double.class));
+ list.add(new ColumnInfo(Msg.translate(Env.getCtx(), "QtyOrdered"), "bomQtyOrdered(p.M_Product_ID,?,0) AS QtyOrdered", Double.class));
+ if (isUnconfirmed())
+ {
+ list.add(new ColumnInfo(Msg.translate(Env.getCtx(), "QtyUnconfirmed"), "(SELECT SUM(c.TargetQty) FROM M_InOutLineConfirm c INNER JOIN M_InOutLine il ON (c.M_InOutLine_ID=il.M_InOutLine_ID) INNER JOIN M_InOut i ON (il.M_InOut_ID=i.M_InOut_ID) WHERE c.Processed='N' AND i.M_Warehouse_ID=? AND il.M_Product_ID=p.M_Product_ID) AS QtyUnconfirmed", Double.class));
+ list.add(new ColumnInfo(Msg.translate(Env.getCtx(), "QtyUnconfirmedMove"), "(SELECT SUM(c.TargetQty) FROM M_MovementLineConfirm c INNER JOIN M_MovementLine ml ON (c.M_MovementLine_ID=ml.M_MovementLine_ID) INNER JOIN M_Locator l ON (ml.M_LocatorTo_ID=l.M_Locator_ID) WHERE c.Processed='N' AND l.M_Warehouse_ID=? AND ml.M_Product_ID=p.M_Product_ID) AS QtyUnconfirmedMove", Double.class));
+ }
+ list.add(new ColumnInfo(Msg.translate(Env.getCtx(), "Margin"), "bomPriceStd(p.M_Product_ID, pr.M_PriceList_Version_ID)-bomPriceLimit(p.M_Product_ID, pr.M_PriceList_Version_ID) AS Margin", BigDecimal.class));
+ list.add(new ColumnInfo(Msg.translate(Env.getCtx(), "Vendor"), "bp.Name", String.class));
+ list.add(new ColumnInfo(Msg.translate(Env.getCtx(), "PriceLimit"), "bomPriceLimit(p.M_Product_ID, pr.M_PriceList_Version_ID) AS PriceLimit", BigDecimal.class));
+ list.add(new ColumnInfo(Msg.translate(Env.getCtx(), "IsInstanceAttribute"), "pa.IsInstanceAttribute", Boolean.class));
+ s_productLayout = new ColumnInfo[list.size()];
+ list.toArray(s_productLayout);
+ INDEX_NAME = 3;
+ INDEX_PATTRIBUTE = s_productLayout.length - 1; // last item
+ }
+ return s_productLayout;
+ } // getProductLayout
+
+ /**
+ * System has Unforfirmed records
+ * @return true if unconfirmed
+ */
+ private boolean isUnconfirmed()
+ {
+ int no = DB.getSQLValue(null,
+ "SELECT COUNT(*) FROM M_InOutLineConfirm WHERE AD_Client_ID=?",
+ Env.getAD_Client_ID(Env.getCtx()));
+ if (no > 0)
+ return true;
+ no = DB.getSQLValue(null,
+ "SELECT COUNT(*) FROM M_MovementLineConfirm WHERE AD_Client_ID=?",
+ Env.getAD_Client_ID(Env.getCtx()));
+ return no > 0;
+ } // isUnconfirmed
+
+ public void tableChanged(WTableModelEvent event)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+
+
+} // InfoProduct
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/LoginPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/LoginPanel.java
new file mode 100644
index 0000000000..7aadb725be
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/LoginPanel.java
@@ -0,0 +1,166 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import java.util.Properties;
+
+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.WConfirmPanel;
+import org.adempiere.webui.component.Window;
+import org.adempiere.webui.window.LoginWindow;
+import org.compiere.util.KeyNamePair;
+import org.compiere.util.Login;
+import org.zkoss.zk.ui.Component;
+import org.zkoss.zk.ui.WrongValueException;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ * @author Sendy Yagambrum
+ * @date July 18, 2007
+ */
+public class LoginPanel extends Window implements EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private Properties ctx;
+ private Label lblUserId;
+ private Label lblPassword;
+ private Textbox txtUserId;
+ private Textbox txtPassword;
+/* private Button btnOk;
+ private Button btnCancel;*/
+ private LoginWindow wndLogin;
+
+ public LoginPanel(Properties ctx, LoginWindow loginWindow)
+ {
+ this.ctx = ctx;
+ this.wndLogin = loginWindow;
+ initComponents();
+ init();
+ this.setId("loginPanel");
+ }
+
+ private void init()
+ {
+ Grid grid = new Grid();
+ grid.setId("grdLogin");
+ Rows rows = new Rows();
+ Row rowUser = new Row();
+ rowUser.setId("rowUser");
+ Row rowPassword = new Row();
+ rowPassword.setId("rowPassword");
+
+ rowUser.appendChild(lblUserId);
+ rowUser.appendChild(this.txtUserId);
+
+ rowPassword.appendChild(lblPassword);
+ rowPassword.appendChild(txtPassword);
+
+
+ Row rowButtons = new Row();
+ //rowButtons.setAlign("right");
+ //Label lblButtons = new Label();
+ rowButtons.setSpans("2");
+ //rowButtons.appendChild(lblButtons);
+ WConfirmPanel pnlButtons = new WConfirmPanel(false);
+ pnlButtons.addEventListener(this);
+ //pnlButtons.appendChild(btnOk);
+ //pnlButtons.appendChild(btnCancel);
+ rowButtons.appendChild(pnlButtons);
+
+ rows.appendChild(rowUser);
+ rows.appendChild(rowPassword);
+ rows.appendChild(rowButtons);
+ grid.appendChild(rows);
+ this.appendChild(grid);
+ }
+
+ private void initComponents()
+ {
+ lblUserId = new Label();
+ lblUserId.setId("lblUserId");
+ lblUserId.setValue("User ID: ");
+
+ lblPassword = new Label();
+ lblPassword.setId("lblPassword");
+ lblPassword.setValue("Password: ");
+
+ txtUserId = new Textbox();
+ txtUserId.setId("txtUserId");
+ txtUserId.setConstraint("no empty");
+ txtUserId.setCols(25);
+ txtUserId.setMaxlength(40);
+
+ txtPassword = new Textbox();
+ txtPassword.setId("txtPassword");
+ txtPassword.setConstraint("no empty");
+ txtPassword.setType("password");
+ txtPassword.setCols(25);
+ txtPassword.setMaxlength(40);
+
+/* btnOk = new Button();
+ btnOk.setName("btnOk");
+ btnOk.setLabel("Ok");
+ btnOk.addEventListener(EventConstants.ONCLICK, this);
+
+ btnCancel = new Button();
+ btnCancel.setName("btnCancel");
+ btnCancel.setLabel("Cancel");
+ btnCancel.addEventListener(EventConstants.ONCLICK, this);*/
+ }
+
+ public void onEvent(Event event)
+ {
+ Component eventComp = event.getTarget();
+
+ if (event.getName().equals(WConfirmPanel.A_OK))
+ {
+ validateLogin();
+ }
+ }
+ /**
+ * validates user name and password when logging in
+ *
+ **/
+ public void validateLogin()
+ {
+ Login login = new Login(ctx);
+ String userId = txtUserId.getValue();
+ String userPassword = txtPassword.getValue();
+ KeyNamePair rolesKNPairs[] = login.getRoles(userId, userPassword);
+ if(rolesKNPairs == null || rolesKNPairs.length == 0)
+ throw new WrongValueException("User Id or Password invalid!!!");
+
+ else
+ wndLogin.loginOk(userId, userPassword);
+ }
+
+ public boolean isAsap()
+ {
+ return true;
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/LogoPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/LogoPanel.java
new file mode 100644
index 0000000000..9b5d0c7c9c
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/LogoPanel.java
@@ -0,0 +1,47 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import org.adempiere.webui.component.Panel;
+import org.zkoss.zul.Image;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 1, 2007
+ * @version $Revision: 0.10 $
+ */
+public class LogoPanel extends Panel
+{
+ private static final long serialVersionUID = 1L;
+
+ private Image imgLogo;
+
+ public LogoPanel()
+ {
+ super();
+ init();
+ }
+
+ private void init()
+ {
+ imgLogo = new Image("/images/logo.png");
+ this.appendChild(imgLogo);
+ this.setWidth("250px");
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/LogoutPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/LogoutPanel.java
new file mode 100644
index 0000000000..055411d7fe
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/LogoutPanel.java
@@ -0,0 +1,67 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import org.adempiere.webui.component.Panel;
+import org.adempiere.webui.session.SessionManager;
+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.Button;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 2, 2007
+ * @version $Revision: 0.10 $
+ */
+
+public class LogoutPanel extends Panel implements EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private Button btnLogOut;
+
+ public LogoutPanel()
+ {
+ super();
+ init();
+ }
+
+ private void init()
+ {
+ btnLogOut = new Button();
+ btnLogOut.setImage("/images/Logout24.png");
+ btnLogOut.addEventListener(Events.ON_CLICK, this);
+
+ this.appendChild(btnLogOut);
+ }
+
+ public boolean isAsap()
+ {
+ return true;
+ }
+
+ public void onEvent(Event event)
+ {
+ if (btnLogOut == event.getTarget())
+ {
+ SessionManager.logoutSession();
+ }
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/MainPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/MainPanel.java
new file mode 100644
index 0000000000..a8169e51da
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/MainPanel.java
@@ -0,0 +1,103 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import org.adempiere.webui.component.Tab;
+import org.adempiere.webui.component.Tabbox;
+import org.adempiere.webui.component.Tabpanel;
+import org.adempiere.webui.component.Tabpanels;
+import org.adempiere.webui.component.Tabs;
+import org.adempiere.webui.component.Window;
+import org.zkoss.zk.ui.Component;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 3, 2007
+ * @version $Revision: 0.10 $
+ */
+public class MainPanel extends Window
+{
+ private static final long serialVersionUID = 1L;
+
+ private Tabbox tabbox;
+
+ private Tabpanels tabpanels;
+
+ private Tabs tabs;
+
+ public MainPanel()
+ {
+
+ init();
+ }
+
+ private void init()
+ {
+ tabbox = new Tabbox();
+ tabpanels = new Tabpanels();
+ tabs = new Tabs();
+
+ tabbox.appendChild(tabs);
+ tabbox.appendChild(tabpanels);
+ tabbox.setWidth("100%");
+ tabbox.setHeight("100%");
+
+ this.setWidth("100%");
+ this.appendChild(tabbox);
+ //this.setBorder("normal");
+ }
+
+ public void addWindow(Component comp, String title, boolean closeable)
+ {
+ addWindow(comp, title, closeable, true);
+ }
+
+ public void addWindow(Component comp, String title, boolean closeable, boolean enable)
+ {
+ Tab tab = new Tab();
+ tab.setLabel(title);
+ tab.setClosable(closeable);
+
+ Tabpanel tabpanel = new Tabpanel();
+ tabpanel.appendChild(comp);
+
+ tabs.appendChild(tab);
+ tabpanels.appendChild(tabpanel);
+ tabpanels.setHeight("100%");
+
+ setSelectedTab(enable, tab);
+ }
+
+ public void setSelectedTab(boolean enable, Tab tab)
+ {
+ if (enable)
+ {
+ tabbox.setSelectedTab(tab);
+ }
+ }
+
+ public void removeWindow()
+ {
+ tabbox.getSelectedTab().onClose();
+ }
+
+
+}
+
+
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/MenuPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/MenuPanel.java
new file mode 100644
index 0000000000..005ac4aa17
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/MenuPanel.java
@@ -0,0 +1,229 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Properties;
+
+import org.adempiere.webui.AdempiereWebUI;
+import org.adempiere.webui.component.Panel;
+import org.adempiere.webui.component.Window;
+import org.adempiere.webui.constants.EventConstants;
+import org.adempiere.webui.event.MenuListener;
+import org.adempiere.webui.exception.ApplicationException;
+import org.adempiere.webui.session.SessionManager;
+import org.compiere.model.MTree;
+import org.compiere.model.MTreeNode;
+import org.compiere.util.DB;
+import org.compiere.util.Env;
+import org.zkoss.zk.ui.Component;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zul.Separator;
+import org.zkoss.zul.Tree;
+import org.zkoss.zul.Treechildren;
+import org.zkoss.zul.Treecol;
+import org.zkoss.zul.Treecols;
+import org.zkoss.zul.Treeitem;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class MenuPanel extends Window implements EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private Properties ctx;
+ private MenuSearchPanel pnlSearch;
+ private Tree menuTree;
+ private ArrayList menuListeners = new ArrayList();
+
+ public MenuPanel()
+ {
+ ctx = Env.getCtx();
+ int adRoleId = Env.getAD_Role_ID(ctx);
+ int adTreeId = getTreeId(ctx, adRoleId);
+ MTree mTree = new MTree(ctx, adTreeId, false, true, null);
+
+ if(mTree == null)
+ {
+ throw new ApplicationException("Could not load menu tree");
+ }
+
+ MTreeNode rootNode = mTree.getRoot();
+ init();
+ initMenu(rootNode);
+ pnlSearch.initialise();
+ }
+
+ private void init()
+ {
+ menuTree = new Tree();
+ menuTree.setMultiple(false);
+ menuTree.setId("mnuMain");
+ menuTree.addEventListener(EventConstants.ONSELECT, this);
+ menuTree.setWidth("250px");
+ menuTree.setHeight("550px");
+ menuTree.setVflex(true);
+ menuTree.setPageSize(-1); // Due to bug in the new paging functionality
+
+ Panel menuPanel = new Panel();
+ pnlSearch = new MenuSearchPanel(this);
+ menuPanel.appendChild(new Separator());
+ menuPanel.appendChild(pnlSearch);
+ menuPanel.appendChild(new Separator());
+ menuPanel.appendChild(new Separator());
+ menuPanel.appendChild(new Separator());
+ menuPanel.appendChild(menuTree);
+ this.appendChild(menuPanel);
+ }
+
+ private void initMenu(MTreeNode rootNode)
+ {
+ Treecols treeCols = new Treecols();
+ Treecol treeCol = new Treecol();
+ treeCol.setLabel(AdempiereWebUI.UID);
+
+ Treechildren rootTreeChildren = new Treechildren();
+ generateMenu(rootTreeChildren, rootNode);
+
+ treeCols.appendChild(treeCol);
+ menuTree.appendChild(treeCols);
+ menuTree.appendChild(rootTreeChildren);
+ }
+
+ private int getTreeId(Properties ctx, int adRoleId)
+ {
+ int AD_Tree_ID = DB.getSQLValue(null,
+ "SELECT COALESCE(r.AD_Tree_Menu_ID, ci.AD_Tree_Menu_ID)"
+ + "FROM AD_ClientInfo ci"
+ + " INNER JOIN AD_Role r ON (ci.AD_Client_ID=r.AD_Client_ID) "
+ + "WHERE AD_Role_ID=?", adRoleId);
+ if (AD_Tree_ID <= 0)
+ AD_Tree_ID = 10; // Menu
+ return AD_Tree_ID;
+ }
+
+ private void generateMenu(Treechildren treeChildren, MTreeNode mNode)
+ {
+ Enumeration nodeEnum = mNode.children();
+
+ while(nodeEnum.hasMoreElements())
+ {
+ MTreeNode mChildNode = (MTreeNode)nodeEnum.nextElement();
+ Treeitem treeitem = new Treeitem();
+ treeChildren.appendChild(treeitem);
+ treeitem.setLabel(mChildNode.getName());
+ treeitem.setTooltiptext(mChildNode.getDescription());
+
+ if(mChildNode.getChildCount() != 0)
+ {
+ treeitem.setOpen(false);
+ Treechildren treeItemChildren = new Treechildren();
+ generateMenu(treeItemChildren, mChildNode);
+ if(treeItemChildren.getChildren().size() != 0)
+ treeitem.appendChild(treeItemChildren);
+ }
+ else
+ {
+ treeitem.setValue(String.valueOf(mChildNode.getNode_ID()));
+
+ if (mChildNode.isReport())
+ treeitem.setImage("/images/mReport.gif");
+ else if (mChildNode.isProcess())
+ treeitem.setImage("/images/mProcess.gif");
+ else if (mChildNode.isWorkFlow())
+ treeitem.setImage("/images/mWorkFlow.gif");
+ else
+ treeitem.setImage("/images/mWindow.gif");
+
+ pnlSearch.addTreeItem(treeitem);
+ }
+ }
+ }
+
+ public ArrayList getMenuItems()
+ {
+ ArrayList ret = new ArrayList();
+
+ return ret;
+ }
+
+ public void addMenuListener(MenuListener menuListener)
+ {
+ menuListeners.add(menuListener);
+ }
+
+ public void removeMenuListener(MenuListener menuListener)
+ {
+ menuListeners.remove(menuListener);
+ }
+
+ public void onEvent(Event event)
+ {
+ Component comp = event.getTarget();
+ String eventName = event.getName();
+
+ if(eventName.equals(EventConstants.ONSELECT))
+ {
+ if(comp.equals(menuTree))
+ {
+ Treeitem selectedItem = menuTree.getSelectedItem();
+ if(selectedItem.getValue() != null)
+ {
+ fireMenuSelectedEvent(selectedItem);
+ }
+ }
+ }
+ }
+
+ protected void fireMenuSelectedEvent(Treeitem selectedItem) {
+ int nodeId = Integer.parseInt((String)selectedItem.getValue());
+
+ try
+ {
+ /*Iterator menuListenersIter = menuListeners.iterator();
+ while(menuListenersIter.hasNext())
+ {
+ menuListenersIter.next().onMenuSelected(nodeId);
+ menuTree.setSelectedItem(null);
+ }*/
+
+ SessionManager.getAppDesktop().onMenuSelected(nodeId);
+ menuTree.setSelectedItem(null);
+ }
+ catch (Exception e)
+ {
+ throw new ApplicationException(e.getMessage(), e);
+ }
+ }
+
+ public void setWidth(String width)
+ {
+ menuTree.setWidth(width);
+ }
+
+ public boolean isAsap()
+ {
+ return true;
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/MenuSearchPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/MenuSearchPanel.java
new file mode 100644
index 0000000000..a1362f98af
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/MenuSearchPanel.java
@@ -0,0 +1,117 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import java.util.TreeMap;
+
+import org.adempiere.webui.component.AutoComplete;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.Panel;
+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.Treeitem;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 3, 2007
+ * @version $Revision: 0.10 $
+ */
+public class MenuSearchPanel extends Panel implements EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private TreeMap treeNodeItemMap = new TreeMap();
+ private String[] treeValues;
+ private String[] treeDescription;
+
+ private Label lblSearch;
+ private AutoComplete cmbSearch;
+
+ private MenuPanel menuPanel;
+
+
+ public MenuSearchPanel(MenuPanel menuPanel)
+ {
+ super();
+ this.menuPanel = menuPanel;
+ init();
+ }
+
+ private void init()
+ {
+ lblSearch = new Label();
+ lblSearch.setValue("Search:");
+
+ cmbSearch = new AutoComplete();
+ cmbSearch.setAutodrop(true);
+
+ cmbSearch.addEventListener(Events.ON_CHANGE, this);
+ cmbSearch.addEventListener(Events.ON_CHANGING, this);
+
+ this.appendChild(lblSearch);
+ this.appendChild(cmbSearch);
+ }
+
+ public void addTreeItem(Treeitem treeItem)
+ {
+ String key = treeItem.getLabel();
+ treeNodeItemMap.put(key, treeItem);
+ }
+
+ public void initialise()
+ {
+ treeValues = new String[treeNodeItemMap.size()];
+ treeDescription = new String[treeNodeItemMap.size()];
+
+ int i = -1;
+
+ for (Treeitem treeItem: treeNodeItemMap.values())
+ {
+ i++;
+
+ treeValues[i] = treeItem.getLabel();
+ treeDescription[i] = treeItem.getTooltiptext();
+ }
+
+ cmbSearch.setDescription(treeDescription);
+ cmbSearch.setDict(treeValues);
+ }
+
+ public boolean isAsap()
+ {
+ return true;
+ }
+
+
+ public void onEvent(Event event)
+ {
+ if (cmbSearch.equals(event.getTarget()) && (event.getName() != Events.ON_CHANGING))
+ {
+
+ String value = cmbSearch.getValue();
+ Treeitem treeItem = treeNodeItemMap.get(value);
+ if (treeItem != null)
+ {
+ treeItem.setSelected(true);
+ menuPanel.fireMenuSelectedEvent(treeItem);
+ }
+ }
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/RequestNoticePanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/RequestNoticePanel.java
new file mode 100644
index 0000000000..05386a66d0
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/RequestNoticePanel.java
@@ -0,0 +1,36 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import org.adempiere.webui.component.Panel;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 3, 2007
+ * @version $Revision: 0.10 $
+ */
+public class RequestNoticePanel extends Panel
+{
+ private static final long serialVersionUID = 1L;
+
+ public RequestNoticePanel()
+ {
+ super();
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/RolePanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/RolePanel.java
new file mode 100644
index 0000000000..b2cb4bdc64
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/RolePanel.java
@@ -0,0 +1,322 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import java.util.Properties;
+
+import org.adempiere.webui.component.WConfirmPanel;
+import org.adempiere.webui.component.Window;
+import org.adempiere.webui.exception.ApplicationException;
+import org.adempiere.webui.window.LoginWindow;
+import org.compiere.util.KeyNamePair;
+import org.compiere.util.Login;
+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.Button;
+import org.zkoss.zul.Div;
+import org.zkoss.zul.Grid;
+import org.zkoss.zul.Label;
+import org.zkoss.zul.Listbox;
+import org.zkoss.zul.Listitem;
+import org.zkoss.zul.Row;
+import org.zkoss.zul.Rows;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ * @author Sendy Yagambrum
+ * @date July 18, 2007
+ */
+public class RolePanel extends Window implements EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private LoginWindow wndLogin;
+ private Login login;
+ private KeyNamePair rolesKNPairs[];
+
+ private Label lblErrorMsg;
+ private Listbox lstRole, lstClient, lstOrganisation, lstWarehouse;
+ private Label lblRole, lblClient, lblOrganisation, lblWarehouse;
+ private Button btnOk, btnCancel;
+
+
+ public RolePanel(Properties ctx, LoginWindow loginWindow, String userName, String password)
+ {
+ this.wndLogin = loginWindow;
+ login = new Login(ctx);
+ rolesKNPairs = login.getRoles(userName, password);
+ if(rolesKNPairs == null)
+ throw new ApplicationException("Login is invalid, UserName: " + userName + " and Password:" + password);
+ initComponents();
+ init();
+ this.setId("rolePanel");
+ }
+
+ private void init()
+ {
+ Grid grid = new Grid();
+ grid.setId("grdChooseRole");
+ Rows rows = new Rows();
+ Row rowRole = new Row();
+ Row rowClient = new Row();
+ Row rowOrg = new Row();
+ Row rowWarehouse = new Row();
+
+ rowRole.appendChild(lblRole);
+ rowRole.appendChild(lstRole);
+
+ rowClient.appendChild(lblClient);
+ rowClient.appendChild(lstClient);
+
+ rowOrg.appendChild(lblOrganisation);
+ rowOrg.appendChild(lstOrganisation);
+
+ rowWarehouse.appendChild(lblWarehouse);
+ rowWarehouse.appendChild(lstWarehouse);
+
+ Row rowButtons = new Row();
+ //rowButtons.setAlign("right");
+ //Label lblButtons = new Label();
+ //rowButtons.appendChild(lblButtons);
+ //Panel pnlButtons = new Panel();
+ //divButtons.appendChild(btnOk);
+ //divButtons.appendChild(btnCancel);
+ WConfirmPanel pnlButtons = new WConfirmPanel(true, false, false, false, false, false, false);
+ pnlButtons.addEventListener(this);
+ rowButtons.setSpans("2");
+ rowButtons.appendChild(pnlButtons);
+
+ rows.appendChild(rowRole);
+ rows.appendChild(rowClient);
+ rows.appendChild(rowOrg);
+ rows.appendChild(rowWarehouse);
+ rows.appendChild(rowButtons);
+
+ grid.appendChild(rows);
+
+ Div divErr = new Div();
+ divErr.appendChild(lblErrorMsg);
+ this.appendChild(divErr);
+ this.appendChild(grid);
+ }
+
+ private void initComponents()
+ {
+ lblErrorMsg = new Label();
+ lblErrorMsg.setValue(" ");
+
+ lblRole = new Label();
+ lblRole.setId("lblRole");
+ lblRole.setValue("Role: ");
+
+ lblClient = new Label();
+ lblClient.setId("lblClient");
+ lblClient.setValue("Client: ");
+
+ lblOrganisation = new Label();
+ lblOrganisation.setId("lblOrganisation");
+ lblOrganisation.setValue("Organisation: ");
+
+ lblWarehouse = new Label();
+ lblWarehouse.setId("lblWarehouse");
+ lblWarehouse.setValue("Warehouse: ");
+
+ lstRole = new Listbox();
+ lstRole.setId("lstRole");
+ lstRole.setRows(1);
+ lstRole.setMold("select");
+ lstRole.addEventListener(Events.ON_SELECT, this);
+ lstRole.setWidth("180px");
+
+ lstClient = new Listbox();
+ lstClient.setId("lstClient");
+ lstClient.setRows(1);
+ lstClient.setMold("select");
+ lstClient.addEventListener(Events.ON_SELECT, this);
+ lstClient.setWidth("180px");
+
+ lstOrganisation = new Listbox();
+ lstOrganisation.setId("lstOrganisation");
+ lstOrganisation.setRows(1);
+ lstOrganisation.setMold("select");
+ lstOrganisation.addEventListener(Events.ON_SELECT, this);
+ lstOrganisation.setWidth("180px");
+
+ lstWarehouse = new Listbox();
+ lstWarehouse.setId("lstWarehouse");
+ lstWarehouse.setRows(1);
+ lstWarehouse.setMold("select");
+ lstWarehouse.addEventListener(Events.ON_SELECT, this);
+ lstWarehouse.setWidth("180px");
+
+ btnOk = new Button();
+ btnOk.setId("btnOk");
+ btnOk.setLabel("Ok");
+ btnOk.addEventListener("onClick", this);
+
+ btnCancel = new Button();
+ btnCancel.setId("btnCancel");
+ btnCancel.setLabel("Cancel");
+ btnCancel.addEventListener("onClick", this);
+
+ for(int i = 0; i < rolesKNPairs.length; i++)
+ lstRole.appendItem(rolesKNPairs[i].getName(), rolesKNPairs[i].getID());
+ lstRole.setSelectedIndex(0);
+ updateClientList();
+ }
+
+ private void updateClientList()
+ {
+ lstClient.getItems().clear();
+ Listitem lstItemRole = lstRole.getSelectedItem();
+ if(lstItemRole != null)
+ {
+ KeyNamePair roleKNPair = new KeyNamePair(new Integer((String)lstItemRole.getValue()), lstItemRole.getLabel());
+ KeyNamePair clientKNPairs[] = login.getClients(roleKNPair);
+ if(clientKNPairs != null && clientKNPairs.length > 0)
+ {
+ for(int i = 0; i < clientKNPairs.length; i++)
+ lstClient.appendItem(clientKNPairs[i].getName(), clientKNPairs[i].getID());
+ lstClient.setSelectedIndex(0);
+ }
+ }
+ updateOrganisationList();
+ }
+
+ private void updateOrganisationList()
+ {
+ lstOrganisation.getItems().clear();
+ Listitem lstItemClient = lstClient.getSelectedItem();
+ if(lstItemClient != null)
+ {
+ KeyNamePair clientKNPair = new KeyNamePair(new Integer((String)lstItemClient.getValue()), lstItemClient.getLabel());
+ KeyNamePair orgKNPairs[] = login.getOrgs(clientKNPair);
+ if(orgKNPairs != null && orgKNPairs.length > 0)
+ {
+ for(int i = 0; i < orgKNPairs.length; i++)
+ lstOrganisation.appendItem(orgKNPairs[i].getName(), orgKNPairs[i].getID());
+ lstOrganisation.setSelectedIndex(0);
+ }
+ }
+ updateWarehouseList();
+ }
+
+ private void updateWarehouseList()
+ {
+ lstWarehouse.getItems().clear();
+ Listitem lstItemOrganisation = lstOrganisation.getSelectedItem();
+ if(lstItemOrganisation != null)
+ {
+ KeyNamePair organisationKNPair = new KeyNamePair(new Integer((String)lstItemOrganisation.getValue()), lstItemOrganisation.getLabel());
+ KeyNamePair warehouseKNPairs[] = login.getWarehouses(organisationKNPair);
+ if(warehouseKNPairs != null && warehouseKNPairs.length > 0)
+ {
+ for(int i = 0; i < warehouseKNPairs.length; i++)
+ lstWarehouse.appendItem(warehouseKNPairs[i].getName(), warehouseKNPairs[i].getID());
+ }
+ }
+ }
+
+ public void onEvent(Event event)
+ {
+ String eventCompId = event.getTarget().getId();
+ String eventName = event.getName();
+ if(eventName.equals("onSelect"))
+ {
+ if(eventCompId.equals(lstRole.getId()))
+ updateClientList();
+ else if(eventCompId.equals(lstClient.getId()))
+ updateOrganisationList();
+ else if(eventCompId.equals(lstOrganisation.getId()))
+ updateWarehouseList();
+ }
+/* else if(eventName.equals("onClick"))
+ {
+ if(eventCompId.equals(btnOk.getId()))
+ {
+ validateRoles();
+ }
+ else if(eventCompId.equals(btnCancel.getId()))
+ {
+
+ }
+ }*/
+ if (event.getName().equals(WConfirmPanel.A_OK))
+ {
+ validateRoles();
+ }
+ else if (event.getName().equals(WConfirmPanel.A_CANCEL))
+ {
+ wndLogin.loginCancelled();
+ }
+ }
+ /**
+ * validate Roles
+ *
+ **/
+ public void validateRoles()
+ {
+ Listitem lstItemRole = lstRole.getSelectedItem();
+ Listitem lstItemClient = lstClient.getSelectedItem();
+ Listitem lstItemOrg = lstOrganisation.getSelectedItem();
+ Listitem lstItemWarehouse = lstOrganisation.getSelectedItem();
+
+ if(lstItemRole == null || lstItemRole.getValue() == null)
+ {
+ lblErrorMsg.setValue("Role is mandatory!!!");
+ return ;
+ }
+ else if(lstItemClient == null || lstItemClient.getValue() == null)
+ {
+ lblErrorMsg.setValue("Client is mandatory!!!");
+ return ;
+ }
+ else if(lstItemOrg == null || lstItemOrg.getValue() == null)
+ {
+ lblErrorMsg.setValue("Organisation is mandatory!!!");
+ return ;
+ }
+ lblErrorMsg.setValue(" ");
+ int orgId = 0, warehouseId = 0;
+ orgId = Integer.parseInt((String)lstItemOrg.getValue());
+ KeyNamePair orgKNPair = new KeyNamePair(orgId, lstItemOrg.getLabel());
+ KeyNamePair warehouseKNPair = null;
+ if(lstItemWarehouse != null && lstItemWarehouse.getValue() != null)
+ {
+ warehouseId = Integer.parseInt((String)lstItemWarehouse.getValue());
+ warehouseKNPair = new KeyNamePair(warehouseId, lstItemWarehouse.getLabel());
+ }
+
+ String msg = login.loadPreferences(orgKNPair, warehouseKNPair, null, null);
+ if(!(msg == null || msg.length() == 0))
+ {
+ lblErrorMsg.setValue("Error for user login: " + msg);
+ return ;
+ }
+ wndLogin.loginCompleted();
+ }
+
+ public boolean isAsap()
+ {
+ return true;
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/SidePanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/SidePanel.java
new file mode 100644
index 0000000000..049ec65709
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/SidePanel.java
@@ -0,0 +1,112 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import org.adempiere.webui.component.Panel;
+import org.adempiere.webui.component.VerticalBox;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 2, 2007
+ * @version $Revision: 0.10 $
+ */
+public class SidePanel extends Panel implements EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private RequestNoticePanel pnlRequestNotice;
+ private MenuPanel pnlMenu;
+ //private SideUserPanel pnlSideUser;
+ //private HeaderPanel pnlHead;
+
+/* private Tabs tabs = new Tabs();
+ private Tab tabUser = new Tab();
+ private Tab tabSearch = new Tab();
+ private Tab tabMenu = new Tab();
+
+ private Tabpanels tabpanels = new Tabpanels();
+
+ private Tabbox tabbox = new Tabbox();
+*/
+ public SidePanel()
+ {
+ init();
+ }
+
+ private void init()
+ {
+ pnlRequestNotice = new RequestNoticePanel();
+ pnlMenu = new MenuPanel();
+ //pnlSideUser = new SideUserPanel();
+ //pnlHead = new HeaderPanel();
+
+/* tabUser.setLabel("Logout");
+ tabSearch.setLabel("Search");
+ tabMenu.setLabel("Menu");
+
+ tabs.appendChild(tabUser);
+ tabs.appendChild(tabSearch);
+ tabs.appendChild(tabMenu);
+
+ Tabpanel tabPanelMenu = new Tabpanel();
+ tabPanelMenu.appendChild(new Separator());
+ tabPanelMenu.appendChild(pnlMenu.getSearchPanel());
+ tabPanelMenu.appendChild(new Separator());
+
+ tabpanels.appendChild(pnlSideUser);
+ tabpanels.appendChild(tabPanelMenu);
+ tabpanels.appendChild(pnlMenu);
+
+ tabbox.setWidth("300px");
+ tabbox.setOrient("horizontal");
+ tabbox.setMold("accordion");
+ tabbox.appendChild(tabs);
+ tabbox.appendChild(tabpanels);*/
+
+ VerticalBox mainBox = new VerticalBox();
+ //mainBox.appendChild(pnlHead);
+ //mainBox.appendChild(pnlSideUser);
+
+ //Iframe menuFrame = new Iframe("/zul/menu.zul");
+ //menuFrame.setWidth("300px");
+ //menuFrame.setHeight("650px");
+
+ //mainBox.appendChild(menuFrame);
+ mainBox.appendChild(pnlMenu);
+
+ Panel pan = new Panel();
+ pan.setAlign("center");
+ pan.appendChild(mainBox);
+
+ this.setWidth("300px");
+ this.appendChild(pan);
+ }
+
+ public MenuPanel getMenuPanel()
+ {
+ return pnlMenu;
+ }
+
+ public void onEvent(Event event) throws Exception
+ {
+
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/SideUserPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/SideUserPanel.java
new file mode 100644
index 0000000000..8bb8e11f33
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/SideUserPanel.java
@@ -0,0 +1,59 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import org.adempiere.webui.component.Panel;
+import org.zkoss.zul.Hbox;
+import org.zkoss.zul.Separator;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 2, 2007
+ * @version $Revision: 0.10 $
+ */
+public class SideUserPanel extends Panel
+{
+ private static final long serialVersionUID = 1L;
+
+ //private Hbox hBox;
+
+ private UserPanel pnlUser;
+ //private LogoutPanel pnlLogout;
+
+ public SideUserPanel()
+ {
+ super();
+ init();
+ }
+
+ private void init()
+ {
+ //hBox = new Hbox();
+ pnlUser = new UserPanel();
+ //pnlLogout = new LogoutPanel();
+
+ //hBox.appendChild(pnlUser);
+ //hBox.appendChild(pnlLogout);
+
+ this.setWidth("100%");
+ this.appendChild(new Separator());
+ this.appendChild(pnlUser);
+ this.appendChild(new Separator());
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/StatusBarPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/StatusBarPanel.java
new file mode 100644
index 0000000000..8a3042a10d
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/StatusBarPanel.java
@@ -0,0 +1,83 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.Panel;
+import org.adempiere.webui.component.VerticalBox;
+import org.compiere.model.DataStatusEvent;
+import org.zkoss.zul.Hbox;
+
+/**
+ * This class is based on org.compiere.apps.StatusBar written by Jorg Janke.
+ * @author Jorg Janke
+ *
+ * @author Ashley G Ramdass
+ * @date Mar 12, 2007
+ * @version $Revision: 0.10 $
+ */
+public class StatusBarPanel extends Panel
+{
+ private static final long serialVersionUID = 1L;
+
+ private Label statusDB;
+ private Label statusLine;
+
+ public StatusBarPanel()
+ {
+ super();
+ init();
+ }
+
+ private void init()
+ {
+ statusLine = new Label();
+ //statusLine.setWidth("100%");
+
+ statusDB = new Label();
+ statusDB.setWidth("200px");
+
+ Hbox hbox = new Hbox();
+ hbox.appendChild(statusLine);
+ hbox.appendChild(statusDB);
+
+ VerticalBox mainBox = new VerticalBox();
+ mainBox.appendChild(hbox);
+
+ this.appendChild(mainBox);
+ }
+
+ public void setStatusDB (String text, DataStatusEvent dse)
+ {
+ if (text == null || text.length() == 0)
+ {
+ statusDB.setValue("");
+ }
+ else
+ {
+ StringBuffer sb = new StringBuffer (" ");
+ sb.append(text).append(" ");
+ statusDB.setValue(sb.toString());
+ }
+ }
+
+ public void setStatusLine (String text, boolean error)
+ {
+ statusLine.setValue(text);
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/UserPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/UserPanel.java
new file mode 100644
index 0000000000..ec6daa2bba
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/UserPanel.java
@@ -0,0 +1,146 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import java.util.Properties;
+
+import org.adempiere.webui.component.Grid;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.Panel;
+import org.adempiere.webui.component.Row;
+import org.adempiere.webui.component.Rows;
+import org.adempiere.webui.session.SessionManager;
+import org.compiere.model.MClient;
+import org.compiere.model.MRole;
+import org.compiere.model.MUser;
+import org.compiere.util.Env;
+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.Hbox;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class UserPanel extends Hbox implements EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private Properties ctx;
+ private Grid grid;
+
+ private Label lblPrefix = new Label("You are logged in as: ");
+ private Label lblSeparator = new Label(" | ");
+ private Label lblLogout = new Label("logoff");
+
+ private Label lblUserNameValue = new Label();
+
+ public UserPanel()
+ {
+ this.ctx = Env.getCtx();
+ init();
+ }
+
+ private void init()
+ {
+ lblLogout.setStyle("cursor: hand;");
+
+ lblPrefix.setStyle("font-style: bold;");
+
+ lblUserNameValue.setValue(getUserName());
+
+ lblLogout.addEventListener(Events.ON_CLICK, this);
+
+ //this.setWidth("200px");
+
+ this.appendChild(lblPrefix);
+ this.appendChild(lblUserNameValue);
+ this.appendChild(lblSeparator);
+ this.appendChild(lblLogout);
+
+/* grid = new Grid();
+ grid.setWidth("200px");
+
+ Rows rows = new Rows();
+
+ Label lblUserName = new Label();
+ Label lblUserNameValue = new Label();
+ lblUserName.setValue("User Name");
+ lblUserNameValue.setValue(getUserName());
+
+ Row row = new Row();
+ row.appendChild(lblUserName);
+ row.appendChild(lblUserNameValue);
+ rows.appendChild(row);
+
+ Label lblRole = new Label();
+ Label lblRoleValue = new Label();
+ lblRole.setValue("Role");
+ lblRoleValue.setValue(getRoleName());
+
+ row = new Row();
+ row.appendChild(lblRole);
+ row.appendChild(lblRoleValue);
+ rows.appendChild(row);
+
+ Label lblClient = new Label();
+ Label lblClientValue = new Label();
+ lblRole.setValue("Client");
+ lblRoleValue.setValue(getClientName());
+
+ row = new Row();
+ row.appendChild(lblClient);
+ row.appendChild(lblClientValue);
+ rows.appendChild(row);
+
+ grid.appendChild(rows);
+ this.appendChild(grid);*/
+ }
+
+ private String getUserName()
+ {
+ MUser user = MUser.get(ctx);
+ return user.getName();
+ }
+
+ private String getRoleName()
+ {
+ MRole role = MRole.getDefault(ctx, false);
+ return role.getName();
+ }
+
+ private String getClientName()
+ {
+ MClient client = MClient.get(ctx);
+ return client.getName();
+ }
+
+ public void onEvent(Event event) throws Exception {
+ if (event == null)
+ return;
+
+ if (lblLogout == event.getTarget())
+ {
+ SessionManager.logoutSession();
+ }
+
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/WAttachment.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/WAttachment.java
new file mode 100644
index 0000000000..094698b56d
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/WAttachment.java
@@ -0,0 +1,738 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import java.awt.Dimension;
+import java.io.File;
+import java.util.logging.Level;
+
+import org.adempiere.webui.apps.AEnv;
+import org.adempiere.webui.component.Button;
+import org.adempiere.webui.component.ListItem;
+import org.adempiere.webui.component.Listbox;
+import org.adempiere.webui.component.Panel;
+import org.adempiere.webui.component.Textbox;
+import org.adempiere.webui.component.VerticalBox;
+import org.adempiere.webui.component.Window;
+import org.adempiere.webui.window.FDialog;
+import org.compiere.model.MAttachment;
+import org.compiere.model.MAttachmentEntry;
+import org.compiere.util.CLogger;
+import org.compiere.util.Env;
+import org.compiere.util.Msg;
+import org.zkoss.util.media.AMedia;
+import org.zkoss.util.media.Media;
+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.Filedownload;
+import org.zkoss.zul.Fileupload;
+import org.zkoss.zul.Hbox;
+import org.zkoss.zul.Iframe;
+import org.zkoss.zul.Image;
+import org.zkoss.zul.Separator;
+import org.zkoss.zul.Splitter;
+
+public class WAttachment extends Window implements EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private static CLogger log = CLogger.getCLogger(WAttachment.class);
+
+ /** Window No */
+ private int m_WindowNo;
+
+ /** Attachment */
+ private MAttachment m_attachment;
+
+ /** Change */
+ private boolean m_change = false;
+
+ private Iframe pdfViewer = new Iframe();
+
+ private Textbox text = new Textbox();
+ private Textbox info = new Textbox();
+
+ private Listbox cbContent = new Listbox();
+
+ private Image gifPanel = new Image();
+
+ private Button bDelete = new Button();
+ private Button bOpen = new Button();
+ private Button bSave = new Button();
+ private Button bDeleteAll = new Button();
+ private Button bLoad = new Button();
+ private Button bCancel = new Button();
+ private Button bOk = new Button();
+
+ private Panel graphPanel = new Panel();
+
+ private VerticalBox mainPanel = new VerticalBox();
+
+ private Panel northPanel = new Panel();
+
+ private Hbox toolBar = new Hbox();
+ private Hbox centerPane = new Hbox();
+
+ private Hbox confirmPanel = new Hbox();
+
+ /**
+ * Constructor.
+ * loads Attachment, if ID <> 0
+ * @param frame frame
+ * @param WindowNo window no
+ * @param AD_Attachment_ID attachment
+ * @param AD_Table_ID table
+ * @param Record_ID record key
+ * @param trxName transaction
+ */
+
+ public WAttachment( int WindowNo, int AD_Attachment_ID,
+ int AD_Table_ID, int Record_ID, String trxName)
+ {
+ super();
+
+ // needs to be modal otherwise APanel does not recognize change.
+
+ log.config("ID=" + AD_Attachment_ID + ", Table=" + AD_Table_ID + ", Record=" + Record_ID);
+
+ m_WindowNo = WindowNo;
+
+ try
+ {
+ staticInit();
+ }
+ catch (Exception ex)
+ {
+ log.log(Level.SEVERE, "", ex);
+ }
+
+ // Create Model
+
+ if (AD_Attachment_ID == 0)
+ m_attachment = new MAttachment (Env.getCtx(), AD_Table_ID, Record_ID, trxName);
+ else
+ m_attachment = new MAttachment (Env.getCtx(), AD_Attachment_ID, trxName);
+
+ loadAttachments();
+
+ try
+ {
+ AEnv.showWindow(this);
+ }
+ catch (Exception e)
+ {
+ }
+
+ //text.requestFocus();
+ } // WAttachment
+
+ /**
+ * Static setup.
+ *
+ * - northPanel
+ * - toolBar
+ * - title
+ * - centerPane [split]
+ * - graphPanel (left)
+ * - gifScroll - gifPanel
+ * - pdfViewer
+ * - text (right)
+ * - confirmPanel
+ *
+ * @throws Exception
+ */
+
+ void staticInit() throws Exception
+ {
+ this.setWidth("500px");
+ this.setHeight("600px");
+ this.setTitle("Attachment");
+ this.setClosable(true);
+ this.setBorder("normal");
+ this.appendChild(mainPanel);
+
+ northPanel.appendChild(toolBar);
+
+ cbContent.setMold("select");
+ cbContent.setRows(0);
+ cbContent.addEventListener(Events.ON_SELECT, this);
+
+ toolBar.appendChild(bLoad);
+ toolBar.appendChild(bDelete);
+ toolBar.appendChild(bSave);
+ toolBar.appendChild(bOpen);
+ toolBar.appendChild(cbContent);
+
+ mainPanel.appendChild(northPanel);
+ mainPanel.appendChild(new Separator());
+
+ bOpen.setEnabled(false);
+ bOpen.setSrc("/images/Editor24.gif");
+ bOpen.setTooltiptext(Msg.getMsg(Env.getCtx(), "Open"));
+ bOpen.addEventListener(Events.ON_CLICK, this);
+
+ bSave.setEnabled(false);
+ bSave.setSrc("/images/Export24.gif");
+ bSave.setTooltiptext(Msg.getMsg(Env.getCtx(), "AttachmentSave"));
+ bSave.addEventListener(Events.ON_CLICK, this);
+
+ bLoad.setSrc("/images/Import24.gif");
+ bLoad.setTooltiptext(Msg.getMsg(Env.getCtx(), "Load"));
+ bLoad.addEventListener(Events.ON_CLICK, this);
+
+ bDelete.setSrc("/images/Delete24.gif");
+ bDelete.setTooltiptext(Msg.getMsg(Env.getCtx(), "Delete"));
+ bDelete.addEventListener(Events.ON_CLICK, this);
+
+ //Dimension size = cbContent.getPreferredSize();
+ //size.width = 200;
+ //cbContent.setPreferredSize(size);
+ // cbContent.setToolTipText(text);
+ //cbContent.addEventListener(Events.ON_SELECT,this);
+ //cbContent.setLightWeightPopupEnabled(false); // Acrobat Panel is heavy
+
+ //text.setBackground(AdempierePLAF.getInfoBackground());
+ //text.setPreferredSize(new Dimension(200, 200));
+
+ info.setText("-");
+ info.setEnabled(false);
+ graphPanel.appendChild(info);
+
+ mainPanel.appendChild(centerPane);
+ mainPanel.appendChild(new Separator());
+
+ centerPane.appendChild(graphPanel);
+ centerPane.appendChild(new Splitter());
+ centerPane.appendChild(text);
+ //centerPane.setResizeWeight(.75); // more to graph
+
+ mainPanel.appendChild(confirmPanel);
+
+ bCancel.setImage("/images/Cancel24.gif");
+ bCancel.addEventListener(Events.ON_CLICK, this);
+
+ bOk.setImage("/images/Ok24.gif");
+ bOk.addEventListener(Events.ON_CLICK, this);
+
+ bDeleteAll.setImage("/images/Delete24.gif");
+ bDeleteAll.addEventListener(Events.ON_CLICK, this);
+
+ confirmPanel.appendChild(bDeleteAll);
+ confirmPanel.appendChild(bCancel);
+ confirmPanel.appendChild(bOk);
+ }
+
+ /**
+ * Dispose
+ */
+
+ public void dispose ()
+ {
+ pdfViewer = null;
+ this.detach();
+ } // dispose
+
+ /**
+ * Load Attachments
+ */
+
+ private void loadAttachments()
+ {
+ log.config("");
+
+ // Set Text/Description
+
+ String sText = m_attachment.getTextMsg();
+
+ if (sText == null)
+ text .setText("");
+ else
+ text.setText(sText);
+
+ // Set Combo
+
+ int size = m_attachment.getEntryCount();
+
+ for (int i = 0; i < size; i++)
+ cbContent.appendItem(m_attachment.getEntryName(i), m_attachment.getEntryName(i));
+
+ if (size > 0)
+ cbContent.setSelectedIndex(0);
+ else
+ displayData(0);
+ } // loadAttachment
+
+ /**
+ * Display gif or jpg in gifPanel
+ * @param index index
+ */
+
+ private void displayData (int index)
+ {
+ MAttachmentEntry entry = m_attachment.getEntry(index);
+ log.config("Index=" + index + " - " + entry);
+
+ // Reset UI
+
+ gifPanel.setSrc(null);
+ graphPanel.getChildren().clear();
+
+ bDelete.setEnabled(false);
+ bOpen.setEnabled(false);
+ bSave.setEnabled(false);
+
+ Dimension size = null;
+
+ // no attachment
+
+ if (entry == null || entry.getData() == null)
+ {
+ info.setText("-");
+ }
+ else
+ {
+ bOpen.setEnabled(true);
+ bSave.setEnabled(true);
+ bDelete.setEnabled(true);
+
+ log.config(entry.toStringX());
+
+ info.setText(entry.toStringX());
+
+ if (entry.isPDF() && pdfViewer != null)
+ {
+ try
+ {
+ AMedia media = new AMedia(entry.getName(), "pdf", "application/pdf", entry.getData());
+ pdfViewer.setContent(media);
+/* pdfViewer.loadPDF(entry.getInputStream());
+ pdfViewer.setScale(50);
+ size = pdfViewer.getPreferredSize();*/
+
+ // size.width = Math.min(size.width, 400);
+ // size.height = Math.min(size.height, 400);
+
+ info.setVisible(false);
+ pdfViewer.setVisible(true);
+ graphPanel.appendChild(pdfViewer);
+ }
+ catch (Exception e)
+ {
+ log.log(Level.SEVERE, "(pdf)", e);
+ }
+ }
+ else if (entry.isGraphic())
+ {
+ // Can we display it
+
+
+
+/* Image image = Toolkit.getDefaultToolkit().createImage(entry.getData());
+
+ if (image != null)
+ {
+ gifPanel.setImage(image);
+ size = gifPanel.getPreferredSize();
+
+ if (size.width == -1 && size.height == -1)
+ {
+ log.log(Level.SEVERE, "Invalid Image");
+ }
+ else
+ {
+ // size.width += 40;
+ // size.height += 40;
+ graphPanel.add(gifScroll, BorderLayout.CENTER);
+ }
+ }
+ else
+ log.log(Level.SEVERE, "Could not create image");*/
+ }
+ }
+
+ if (graphPanel.getChildren().size() == 0)
+ {
+ graphPanel.appendChild(info);
+ }
+
+ log.config("Size=" + size);
+
+ // graphPanel.setPreferredSize(size);
+ // centerPane.setDividerLocation(size.width+30);
+ // size.width += 100;
+ // size.height += 100;
+ // centerPane.setPreferredSize(size);
+ // pack();
+ } // displayData
+
+ /**
+ * Get File Name with index
+ * @param index index
+ * @return file name or null
+ */
+
+ private String getFileName (int index)
+ {
+ String fileName = null;
+
+ if (cbContent.getItemCount() > index)
+ {
+ ListItem listitem = cbContent.getItemAtIndex(index);
+ fileName = (String)listitem.getValue();
+ }
+
+ return fileName;
+ } // getFileName
+
+ /**
+ * Action Listener
+ * @param e event
+ */
+
+ public void onEvent(Event e)
+ {
+ // log.config(e.getActionCommand());
+ // Save and Close
+
+ if (e.getTarget() == bOk)
+ {
+ String newText = text.getText();
+
+ if (newText == null)
+ newText = "";
+
+ String oldText = m_attachment.getTextMsg();
+
+ if (oldText == null)
+ oldText = "";
+
+ if (!m_change)
+ m_change = !newText.equals(oldText);
+
+ if (newText.length() > 0 || m_attachment.getEntryCount() > 0)
+ {
+ if (m_change)
+ {
+ m_attachment.setTextMsg(text.getText());
+ m_attachment.save();
+ }
+ }
+ else
+ m_attachment.delete(true);
+
+ dispose();
+ }
+
+ // Cancel
+
+ else if (e.getTarget() == bCancel)
+ {
+ dispose();
+ }
+
+ // Delete Attachment
+
+ else if (e.getTarget() == bDeleteAll)
+ {
+ deleteAttachment();
+ dispose();
+ }
+
+ // Delete individual entry and Return
+
+ else if (e.getTarget() == bDelete)
+ deleteAttachmentEntry();
+
+ // Show Data
+
+ else if (e.getTarget() == cbContent)
+ displayData (cbContent.getSelectedIndex());
+
+ // Load Attachment
+
+ else if (e.getTarget() == bLoad)
+ loadFile();
+
+ // Open Attachment
+
+ else if (e.getTarget() == bSave)
+ saveAttachmentToFile();
+
+ // Open Attachment
+
+ else if (e.getTarget() == bOpen)
+ {
+ if (!openAttachment())
+ saveAttachmentToFile();
+ }
+ } // onEvent
+
+ /**************************************************************************
+ * Load file for attachment
+ */
+
+ private void loadFile()
+ {
+ log.info("");
+
+ Media media = null;
+
+ try
+ {
+ media = Fileupload.get();
+
+ if (media != null)
+ {
+ pdfViewer.setContent(media);
+ }
+ else
+ return;
+ }
+ catch (InterruptedException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ //JFileChooser chooser = new JFileChooser();
+ //chooser.setDialogType(JFileChooser.OPEN_DIALOG);
+ //chooser.setDialogTitle(Msg.getMsg(Env.getCtx(), "AttachmentNew"));
+ //int returnVal = chooser.showOpenDialog(this);
+ //if (returnVal != JFileChooser.APPROVE_OPTION)
+ // return;
+
+ String fileName = media.getName();
+ log.config(fileName);
+ File file = new File(fileName);
+ int cnt = m_attachment.getEntryCount();
+
+ //update
+
+ for (int i = 0; i < cnt; i++)
+ {
+ if (m_attachment.getEntryName(i).equals(fileName))
+ {
+ //if (m_attachment.)
+ {
+ cbContent.setSelectedIndex(i);
+ m_change = true;
+ }
+ return;
+ }
+ }
+
+ //new
+
+ if (m_attachment.addEntry(file))
+ {
+ //MAttachmentEntry attachmentEntry = new MAttachmentEntry(media.getName(), media.getByteData());
+
+ cbContent.appendItem(media.getName(), media.getName());
+ cbContent.setSelectedIndex(cbContent.getItemCount()-1);
+ m_change = true;
+ }
+ } // getFileName
+
+ /**
+ * Delete entire Attachment
+ */
+ private void deleteAttachment()
+ {
+ log.info("");
+
+ if (FDialog.ask(m_WindowNo, this, "AttachmentDelete?"))
+ m_attachment.delete(true);
+ } // deleteAttachment
+
+ /**
+ * Delete Attachment Entry
+ */
+
+ private void deleteAttachmentEntry()
+ {
+ log.info("");
+
+ int index = cbContent.getSelectedIndex();
+ String fileName = getFileName(index);
+
+ if (fileName == null)
+ return;
+
+ if (FDialog.ask(m_WindowNo, this, "AttachmentDeleteEntry?"))
+ {
+ if (m_attachment.deleteEntry(index))
+ cbContent.removeItemAt(index);
+
+ m_change = true;
+ }
+ } // deleteAttachment
+
+ /**
+ * Save Attachment to File
+ */
+
+ private void saveAttachmentToFile()
+ {
+ int index = cbContent.getSelectedIndex();
+ log.info("index=" + index);
+
+ if (m_attachment.getEntryCount() < index)
+ return;
+
+/* String fileName = getFileName(index);
+ String ext = fileName.substring (fileName.lastIndexOf('.'));
+ log.config( "Ext=" + ext);*/
+
+ ListItem listitem = cbContent.getSelectedItem();
+ Media media = (Media)listitem.getValue();
+
+ Filedownload.save(media);
+
+/* JFileChooser chooser = new JFileChooser();
+ chooser.setDialogType(JFileChooser.SAVE_DIALOG);
+ chooser.setDialogTitle(Msg.getMsg(Env.getCtx(), "AttachmentSave"));
+ File f = new File(fileName);
+ chooser.setSelectedFile(f);
+ // Show dialog
+ int returnVal = chooser.showSaveDialog(this);
+ if (returnVal != JFileChooser.APPROVE_OPTION)
+ return;
+ File saveFile = chooser.getSelectedFile();
+ if (saveFile == null)
+ return;*/
+
+ /*log.config("Save to " + saveFile.getAbsolutePath());
+ m_attachment.getEntryFile(index, saveFile);*/
+ } // saveAttachmentToFile
+
+ /**
+ * Open the temporary file with the application associated with the extension in the file name
+ * @return true if file was opened with third party application
+ */
+
+ private boolean openAttachment ()
+ {
+ int index = cbContent.getSelectedIndex();
+ byte[] data = m_attachment.getEntryData(index);
+
+ if (data == null)
+ return false;
+
+ try
+ {
+ String fileName = System.getProperty("java.io.tmpdir") + m_attachment.getEntryName(index);
+ File tempFile = new File(fileName);
+ m_attachment.getEntryFile(index, tempFile);
+
+ if (Env.isWindows())
+ {
+ // Runtime.getRuntime().exec ("rundll32 url.dll,FileProtocolHandler " + url);
+ Process p = Runtime.getRuntime().exec("rundll32 SHELL32.DLL,ShellExec_RunDLL \"" + tempFile + "\"");
+ // p.waitFor();
+ return true;
+ }
+ else if (Env.isMac())
+ {
+ String [] cmdArray = new String [] {"open", tempFile.getAbsolutePath()};
+ Process p = Runtime.getRuntime ().exec (cmdArray);
+ // p.waitFor();
+ return true;
+ }
+ else // other OS
+ {
+ }
+ }
+ catch (Exception e)
+ {
+ log.log(Level.SEVERE, "", e);
+ }
+ return false;
+ } // openFile
+
+
+ /**************************************************************************
+ * Graphic Image Panel
+ */
+
+ class GImage extends Panel
+ {
+ private static final long serialVersionUID = 1L;
+
+ /** The Image */
+ private Image m_image = null;
+
+ /**
+ * Graphic Image
+ */
+
+ public GImage()
+ {
+ super();
+ } // GImage
+
+ /**
+ * Set Image
+ * @param image image
+ */
+
+ public void setImage (Image image)
+ {
+ m_image = image;
+
+ if (m_image == null)
+ return;
+
+ //MediaTracker mt = new MediaTracker(this);
+ this.appendChild(m_image);
+
+/* try
+ {
+ mt.waitForID(0);
+ }
+ catch (Exception e)
+ {}
+
+ Dimension dim = new Dimension(m_image.getWidth(this), m_image.getHeight(this));
+ this.setPreferredSize(dim);*/
+ } // setImage
+
+ /**
+ * Paint
+ * @param g graphics
+ */
+
+/* public void paint (Graphics g)
+ {
+ Insets in = getInsets();
+
+ if (m_image != null)
+ g.drawImage(m_image, in.left, in.top, this);
+ } // paint
+*/
+ /**
+ * Update
+ * @param g graphics
+ */
+
+/* public void update (Graphics g)
+ {
+ paint(g);
+ } // update
+*/ } // GImage
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/WDocActionPanel.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/WDocActionPanel.java
new file mode 100644
index 0000000000..be977cfc4d
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/WDocActionPanel.java
@@ -0,0 +1,345 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.adempiere.webui.component.ConfirmPanel;
+import org.adempiere.webui.component.Grid;
+import org.adempiere.webui.component.Panel;
+import org.adempiere.webui.component.Row;
+import org.adempiere.webui.component.Rows;
+import org.adempiere.webui.component.Window;
+import org.adempiere.webui.constants.EventConstants;
+import org.adempiere.webui.window.FDialog;
+import org.compiere.model.GridTab;
+import org.compiere.process.DocumentEngine;
+import org.compiere.util.CLogger;
+import org.compiere.util.DB;
+import org.compiere.util.Env;
+import org.compiere.wf.MWFActivity;
+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.Label;
+import org.zkoss.zul.Listbox;
+import org.zkoss.zul.Listitem;
+
+
+
+public class WDocActionPanel extends Window implements EventListener
+{
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ private Label lblDocAction;
+ private Label label;
+ private Listbox lstDocAction;
+
+ private static GridTab gridTab;
+ private static String[] s_value = null;
+ private static String[] s_name;
+ private static String[] s_description;
+ private String DocStatus;
+ private String DocAction;
+ private int m_AD_Table_ID;
+ private boolean m_OKpressed;
+ private ConfirmPanel confirmPanel;
+
+ private static final CLogger logger;
+
+ static
+ {
+ logger = CLogger.getCLogger(WDocActionPanel.class);
+ }
+
+ public WDocActionPanel(GridTab mgridTab)
+ {
+ gridTab = mgridTab;
+ DocStatus = (String)gridTab.getValue("DocStatus");
+ DocAction = (String)gridTab.getValue("DocAction");
+ if(DocAction.equals("--"))
+ return;
+
+ m_AD_Table_ID = Env.getContextAsInt(Env.getCtx(), gridTab.getWindowNo(), "BaseTable_ID");
+
+ readReference();
+ initComponents();
+ dynInit();
+
+ init();
+ this.setAttribute("mode","modal");
+
+
+ }
+
+ /**
+ * Dynamic Init - determine valid DocActions based on DocStatus for the different documents.
+ */
+ private void dynInit()
+ {
+
+ //
+ Object Processing = gridTab.getValue("Processing");
+ String OrderType = Env.getContext(Env.getCtx(), gridTab.getWindowNo(), "OrderType");
+ String IsSOTrx = Env.getContext(Env.getCtx(), gridTab.getWindowNo(), "IsSOTrx");
+
+ if (DocStatus == null)
+ {
+ //message.setText("*** ERROR ***");
+ return;
+ }
+
+ logger.fine("DocStatus=" + DocStatus
+ + ", DocAction=" + DocAction + ", OrderType=" + OrderType
+ + ", IsSOTrx=" + IsSOTrx + ", Processing=" + Processing
+ + ", AD_Table_ID=" +gridTab.getAD_Table_ID() + ", Record_ID=" + gridTab.getRecord_ID());
+ int index = 0;
+ if(lstDocAction.getSelectedItem() != null)
+ {
+ String selected = (lstDocAction.getSelectedItem().getValue()).toString();
+
+ for(int i = 0; i < s_value.length && index == 0; i++)
+ {
+ if(s_value[i].equals(selected))
+ {
+ index = i;
+ }
+ }
+ }
+
+ String[] options = new String[s_value.length];
+ /**
+ * Check Existence of Workflow Acrivities
+ */
+ String wfStatus = MWFActivity.getActiveInfo(Env.getCtx(), m_AD_Table_ID, gridTab.getRecord_ID());
+ if (wfStatus != null)
+ {
+ FDialog.error(gridTab.getWindowNo(), this, "WFActiveForRecord", wfStatus);
+ return;
+ }
+
+ // Status Change
+ if (!checkStatus(gridTab.getTableName(), gridTab.getRecord_ID(), DocStatus))
+ {
+ FDialog.error(gridTab.getWindowNo(), this, "DocumentStatusChanged");
+ return;
+ }
+ /*******************
+ * General Actions
+ */
+
+ String[] docActionHolder = new String[]{DocAction};
+ index = DocumentEngine.getValidActions(DocStatus, Processing, OrderType, IsSOTrx,
+ m_AD_Table_ID, docActionHolder, options);
+ DocAction = docActionHolder[0];
+
+ /**
+ * Fill actionCombo
+ */
+
+ for (int i = 0; i < index; i++)
+ {
+ // Serach for option and add it
+ boolean added = false;
+
+ for (int j = 0; j < s_value.length && !added; j++)
+ {
+ if (options[i].equals(s_value[j]))
+ {
+ lstDocAction.appendItem(s_name[j],s_value[j]);
+ added = true;
+ }
+ }
+ }
+ List lst = (List)lstDocAction.getItems();
+ for(Listitem item: lst)
+ {
+ String value = item.getValue().toString();
+
+ if(DocAction.equals(value))
+ {
+ lstDocAction.setSelectedItem(item);
+ label.setValue(s_description[getSelectedIndex()]);
+ }
+ }
+ // setDefault
+ if (DocAction.equals("--")) // If None, suggest closing
+ DocAction = DocumentEngine.ACTION_Close;
+ }
+
+ private boolean checkStatus (String TableName, int Record_ID, String DocStatus)
+ {
+ String sql = "SELECT 2 FROM " + TableName
+ + " WHERE " + TableName + "_ID=" + Record_ID
+ + " AND DocStatus='" + DocStatus + "'";
+ int result = DB.getSQLValue(null, sql);
+ return result == 2;
+ }
+
+ private void initComponents()
+ {
+ lblDocAction = new Label();
+ lblDocAction.setId("lblDocAction");
+ lblDocAction.setValue("Document Action");
+
+ label = new Label();
+ label.setId("label");
+
+ lstDocAction = new Listbox();
+ lstDocAction.setId("lstDocAction");
+ lstDocAction.setRows(0);
+ lstDocAction.setMold("select");
+ lstDocAction.setWidth("100px");
+ lstDocAction.addEventListener(EventConstants.ONSELECT, this);
+
+ confirmPanel = new ConfirmPanel(true);
+ confirmPanel.addComponentsLeft(confirmPanel.createButton("Process"));
+ confirmPanel.addActionListener(Events.ON_CLICK, this);
+
+ }
+
+ private void init()
+ {
+
+ Grid grid = new Grid();
+ grid.setId("grd");
+ grid.setWidth("400px");
+
+ Rows rows = new Rows();
+
+ Row rowDocAction = new Row();
+ Row rowLabel = new Row();
+ Row rowConfirm = new Row();
+
+ Panel pnlDocAction = new Panel();
+ pnlDocAction.appendChild(lblDocAction);
+ pnlDocAction.appendChild(lstDocAction);
+
+ rowDocAction.appendChild(pnlDocAction);
+ rowDocAction.setAlign("right");
+ rowLabel.appendChild(label);
+ rowConfirm.appendChild(confirmPanel);
+ rows.appendChild(rowDocAction);
+ rows.appendChild(rowLabel);
+ rows.appendChild(rowConfirm);
+
+ grid.appendChild(rows);
+ this.setTitle("Document Action");
+ this.setWidth("410px");
+ this.setBorder("normal");
+ this.appendChild(grid);
+
+ }
+
+ /**
+ * Should the process be started?
+ * @return OK pressed
+ */
+ public boolean isStartProcess()
+ {
+ return m_OKpressed;
+ } // isStartProcess
+
+ public void onEvent(Event event)
+ {
+
+ if (Events.ON_CLICK.equals(event.getName()))
+ {
+ if (confirmPanel.getButton("Ok").equals(event.getTarget()))
+ {
+ m_OKpressed = true;
+ setValue();
+ this.detach();
+ }
+ else if (confirmPanel.getButton("Cancel").equals(event.getTarget()))
+ {
+ m_OKpressed = false;
+ this.detach();
+ }
+ else if (confirmPanel.getButton("Process").equals(event.getTarget()))
+ {
+
+ }
+ }
+ else if (Events.ON_SELECT.equals(event.getName()))
+ {
+
+ if (lstDocAction.equals(event.getTarget()))
+ {
+ label.setValue(s_description[getSelectedIndex()]);
+ }
+ }
+ }
+
+ private void setValue()
+ {
+ int index = getSelectedIndex();
+ // Save Selection
+ logger.config("DocAction=" + s_value[index]);
+ gridTab.setValue("DocAction", s_value[index]);
+ } // save
+
+ private void readReference()
+ {
+ ArrayList v_value = new ArrayList();
+ ArrayList v_name = new ArrayList();
+ ArrayList v_description = new ArrayList();
+
+ DocumentEngine.readReferenceList(v_value, v_name, v_description);
+
+ int size = v_value.size();
+ s_value = new String[size];
+ s_name = new String[size];
+ s_description = new String[size];
+
+ for (int i = 0; i < size; i++)
+ {
+ s_value[i] = (String)v_value.get(i);
+ s_name[i] = (String)v_name.get(i);
+ s_description[i] = (String)v_description.get(i);
+ }
+ } // readReference
+
+ public int getSelectedIndex()
+ {
+ int index = 0;
+ if(lstDocAction.getSelectedItem() != null)
+ {
+ String selected = (lstDocAction.getSelectedItem().getValue()).toString();
+
+ for(int i = 0; i < s_value.length && index == 0; i++)
+ {
+ if(s_value[i].equals(selected))
+ {
+ index = i;
+ break;
+ }
+ }
+ }
+ return index;
+ } // getSelectedIndex
+
+ public boolean isAsap()
+ {
+ return true;
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/WOnlyCurrentDays.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/WOnlyCurrentDays.java
new file mode 100644
index 0000000000..17ccafd336
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/panel/WOnlyCurrentDays.java
@@ -0,0 +1,150 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.panel;
+
+import java.util.logging.Level;
+
+import org.adempiere.webui.apps.AEnv;
+import org.adempiere.webui.component.Button;
+import org.adempiere.webui.component.Window;
+import org.compiere.grid.VOnlyCurrentDays;
+import org.compiere.util.CLogger;
+import org.compiere.util.Env;
+import org.compiere.util.Msg;
+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.Hbox;
+import org.zkoss.zul.Separator;
+
+
+/**
+ * Queries how many days back history is displayed as current
+ *
+ * @author Niraj Sohun
+ * @date September 24, 2007
+ */
+
+public class WOnlyCurrentDays extends Window implements EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructor
+ * @param parent parent frame
+ * @param buttonLocation lower left corner of the button
+ */
+ public WOnlyCurrentDays()
+ {
+ // How long back in History?
+ super();
+
+ try
+ {
+ jbInit();
+ }
+ catch(Exception e)
+ {
+ log.log(Level.SEVERE, "VOnlyCurrentDays", e);
+ }
+
+ this.setVisible(true);
+ AEnv.showWindow(this);
+ } // WOnlyCurrentDays
+
+ private Hbox mainPanel = new Hbox();
+ private Button bShowAll = new Button();
+ private Button bShowMonth = new Button();
+ private Button bShowWeek = new Button();
+ private Button bShowDay = new Button();
+ private Button bShowYear = new Button();
+
+ /** Days (0=all) */
+ private int m_days = 0;
+
+ /** Logger */
+ private static CLogger log = CLogger.getCLogger(VOnlyCurrentDays.class);
+
+ /**
+ * Static Initializer
+ * @throws Exception
+ */
+
+ private void jbInit() throws Exception
+ {
+ bShowAll.setLabel(Msg.getMsg(Env.getCtx(), "All"));
+ bShowAll.addEventListener(Events.ON_CLICK, this);
+
+ bShowYear.setLabel(Msg.getMsg(Env.getCtx(), "Year"));
+ bShowYear.addEventListener(Events.ON_CLICK, this);
+
+ bShowMonth.setLabel(Msg.getMsg(Env.getCtx(), "Month"));
+ bShowMonth.addEventListener(Events.ON_CLICK, this);
+
+ bShowWeek.setLabel(Msg.getMsg(Env.getCtx(), "Week"));
+ bShowWeek.addEventListener(Events.ON_CLICK, this);
+
+ bShowDay.setLabel(Msg.getMsg(Env.getCtx(), "Day"));
+ bShowDay.addEventListener(Events.ON_CLICK, this);
+
+ mainPanel.setWidth("100%");
+ mainPanel.setStyle("text-align:center");
+ mainPanel.appendChild(bShowDay);
+ mainPanel.appendChild(bShowWeek);
+ mainPanel.appendChild(bShowMonth);
+ mainPanel.appendChild(bShowYear);
+ mainPanel.appendChild(bShowAll);
+
+ this.setWidth("450px");
+ this.setBorder("normal");
+ this.setTitle(Msg.getMsg(Env.getCtx(), "VOnlyCurrentDays"));
+ this.setClosable(true);
+ this.setAttribute("mode", "modal");
+
+ this.appendChild(new Separator());
+ this.appendChild(mainPanel);
+ this.appendChild(new Separator());
+ } // jbInit
+
+ /**
+ * Get selected number of days
+ * @return days or -1 for all
+ */
+
+ public int getCurrentDays()
+ {
+ return m_days;
+ } // getCurrentDays
+
+ public void onEvent(Event event) throws Exception
+ {
+ if (event.getTarget() == bShowDay)
+ m_days = 1;
+ else if (event.getTarget() == bShowWeek)
+ m_days = 7;
+ else if (event.getTarget() == bShowMonth)
+ m_days = 31;
+ else if (event.getTarget() == bShowYear)
+ m_days = 365;
+ else
+ m_days = 0; // all
+
+ this.detach();
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/session/SessionContextListener.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/session/SessionContextListener.java
new file mode 100644
index 0000000000..39ea250453
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/session/SessionContextListener.java
@@ -0,0 +1,106 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.session;
+
+import java.util.List;
+
+import org.zkoss.lang.ThreadLocals;
+import org.zkoss.zk.ui.Component;
+import org.zkoss.zk.ui.Execution;
+import org.zkoss.zk.ui.Executions;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventThreadInit;
+import org.zkoss.zk.ui.event.EventThreadResume;
+import org.zkoss.zk.ui.util.ExecutionCleanup;
+import org.zkoss.zk.ui.util.ExecutionInit;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class SessionContextListener implements ExecutionInit,
+ ExecutionCleanup, EventThreadInit, EventThreadResume
+{
+ private static final String SESSION_CTX = "WebUISessionContext";
+
+ public void init(Execution exec, Execution parent)
+ {
+ if (parent == null)
+ {
+ WebContext ctx = (WebContext)exec.getDesktop().getSession().getAttribute(SESSION_CTX);
+ if (ctx == null)
+ {
+ ctx = new WebContext();
+ setWebContext(ctx);
+ exec.getDesktop().getSession().setAttribute(SESSION_CTX, ctx);
+ }
+ exec.setAttribute(SESSION_CTX, ctx);
+ }
+ }
+
+ public void cleanup(Execution exec, Execution parent, List errs)
+ {
+ if (parent == null)
+ {
+ exec.removeAttribute(SESSION_CTX);
+ }
+ }
+
+ public void prepare(Component comp, Event evt)
+ {
+ }
+
+ public boolean init(Component comp, Event evt)
+ {
+ WebContext ctx = (WebContext) Executions.getCurrent().getAttribute(
+ SESSION_CTX);
+ setWebContext(ctx);
+
+ return true;
+ }
+
+ public void beforeResume(Component comp, Event evt)
+ {
+ }
+
+ public void afterResume(Component comp, Event evt)
+ {
+ WebContext ctx = (WebContext) Executions.getCurrent().getAttribute(
+ SESSION_CTX);
+ setWebContext(ctx);
+ }
+
+ public void abortResume(Component comp, Event evt)
+ {
+ // do nothing
+ }
+
+ @SuppressWarnings("unchecked")
+ private void setWebContext(WebContext ctx)
+ {
+ getContextThreadLocal().set(ctx);
+ }
+
+ private ThreadLocal getContextThreadLocal()
+ {
+ return ThreadLocals.getThreadLocal(
+ "org.adempiere.webui.session.WebContext", "context");
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/session/SessionManager.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/session/SessionManager.java
new file mode 100644
index 0000000000..d22557d6cb
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/session/SessionManager.java
@@ -0,0 +1,81 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.session;
+
+import java.util.Properties;
+
+import org.adempiere.webui.AdempiereWebUI;
+import org.adempiere.webui.Desktop;
+import org.compiere.util.Env;
+import org.zkoss.zk.ui.Executions;
+import org.zkoss.zk.ui.Session;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class SessionManager
+{
+ public static final String SESSION_APPLICATION = "SessionApplication";
+
+ public static boolean isUserLoggedIn(Properties ctx)
+ {
+ String adUserId = Env.getContext(ctx, "#AD_User_ID");
+ String adRoleId = Env.getContext(ctx, "#AD_Role_ID");
+ String adClientId = Env.getContext(ctx, "#AD_Client_ID");
+ String adOrgId = Env.getContext(ctx, "#AD_Org_ID");
+
+ return (!"".equals(adUserId) && !"".equals(adRoleId)
+ && !"".equals(adClientId) && !"".equals(adOrgId));
+ }
+
+ private static Session getSession()
+ {
+ return Executions.getCurrent().getDesktop().getSession();
+ }
+
+ public static void setSessionApplication(AdempiereWebUI app)
+ {
+ Session session = getSession();
+ session.setAttribute(SESSION_APPLICATION, app);
+ }
+
+ public static Desktop getAppDesktop()
+ {
+ return getSessionApplication().getAppDeskop();
+ }
+
+ public static AdempiereWebUI getSessionApplication()
+ {
+ Session session = getSession();
+ AdempiereWebUI app = (AdempiereWebUI)session.getAttribute(SESSION_APPLICATION);
+ return app;
+ }
+
+ public static void clearSession()
+ {
+ Env.getCtx().clear();
+ }
+
+ public static void logoutSession()
+ {
+ getSessionApplication().logout();
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/session/WebContext.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/session/WebContext.java
new file mode 100644
index 0000000000..b5a9d3201e
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/session/WebContext.java
@@ -0,0 +1,60 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.session;
+
+import java.util.Properties;
+
+import org.compiere.util.Env;
+import org.compiere.util.Language;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+@SuppressWarnings("serial")
+public final class WebContext extends Properties
+{
+ public WebContext()
+ {
+ super();
+ /**
+ * Set english as default language
+ */
+ this.put(Env.LANGUAGE, Language.getBaseAD_Language());
+ }
+
+ private static InheritableThreadLocal context = new InheritableThreadLocal() {
+ protected WebContext initialValue()
+ {
+ return null;
+ }
+ };
+
+ public static WebContext getCurrentInstance()
+ {
+ return (WebContext)context.get();
+ }
+
+ @SuppressWarnings("unchecked")
+ public static void setCurrentInstance(WebContext webCtx)
+ {
+ context.set(webCtx);
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/session/WebUIServlet.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/session/WebUIServlet.java
new file mode 100644
index 0000000000..03a2eb4759
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/session/WebUIServlet.java
@@ -0,0 +1,125 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.session;
+
+import java.io.IOException;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.adempiere.webui.ZkContextProvider;
+import org.adempiere.webui.window.ZkJRViewerProvider;
+import org.adempiere.webui.window.ZkReportViewerProvider;
+import org.compiere.Adempiere;
+import org.compiere.print.ReportCtl;
+import org.compiere.report.ReportStarter;
+import org.compiere.util.CLogMgt;
+import org.compiere.util.CLogger;
+import org.compiere.util.Env;
+import org.zkoss.zk.ui.http.DHtmlLayoutServlet;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class WebUIServlet extends DHtmlLayoutServlet
+{
+ private static final long serialVersionUID = 1L;
+
+ /** Logger for the class * */
+ private static final CLogger logger;
+
+ static
+ {
+ logger = CLogger.getCLogger(WebUIServlet.class);
+ }
+
+ public void init(ServletConfig servletConfig) throws ServletException
+ {
+ super.init(servletConfig);
+
+ /** Initialise context for the current thread*/
+ WebContext.setCurrentInstance(new WebContext());
+ Env.setContextProvider(new ZkContextProvider());
+
+ /**
+ * Start ADempiere
+ */
+ logger.info("Starting ADempiere...");
+ try
+ {
+ CLogMgt.initialize(true);
+ }
+ catch(Exception ex)
+ {
+ logger.severe("Could not initialize ADempiere logging Management");
+ }
+
+ boolean started = Adempiere.startup(false);
+ if(!started)
+ {
+ throw new ServletException("Could not start ADempiere");
+ }
+ ReportCtl.setReportViewerProvider(new ZkReportViewerProvider());
+ ReportStarter.setReportViewerProvider(new ZkJRViewerProvider());
+ logger.info("ADempiere started successfully");
+ /**
+ * End ADempiere Start
+ */
+ }
+
+ protected void doGet(HttpServletRequest request,
+ HttpServletResponse response) throws ServletException, IOException
+ {
+ super.doGet(request, response);
+ }
+
+ protected void doPost(HttpServletRequest request,
+ HttpServletResponse response) throws ServletException, IOException
+ {
+
+ super.doPost(request, response);
+ }
+
+ public void service(ServletRequest request, ServletResponse response)
+ throws ServletException, IOException
+ {
+ super.service(request, response);
+ }
+
+ public ServletConfig getServletConfig()
+ {
+ return super.getServletConfig();
+ }
+
+ public String getServletInfo()
+ {
+ return super.getServletInfo();
+ }
+
+ public void destroy()
+ {
+ super.destroy();
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/ADWindow.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/ADWindow.java
new file mode 100644
index 0000000000..4df87894e7
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/ADWindow.java
@@ -0,0 +1,97 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.window;
+
+import java.util.Properties;
+
+import org.adempiere.webui.component.Window;
+import org.adempiere.webui.panel.ADWindowPanel;
+import org.adempiere.webui.session.SessionManager;
+import org.compiere.model.MQuery;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+public class ADWindow extends Window implements EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private ADWindowPanel windowPanel;
+ private Properties ctx;
+ private int adWindowId;
+ private String _title;
+ private int windowNo;
+
+ public ADWindow(Properties ctx, int adWindowId)
+ {
+ this(ctx, adWindowId, null);
+ }
+
+ public ADWindow(Properties ctx, int adWindowId, MQuery query)
+ {
+ if(adWindowId <= 0)
+ throw new IllegalArgumentException("Window Id is invalid");
+
+ this.ctx = ctx;
+ this.adWindowId = adWindowId;
+ windowNo = SessionManager.getAppDesktop().registerWindow(this);
+ init(query);
+ }
+
+ private void init(MQuery query)
+ {
+ windowPanel = new ADWindowPanel(ctx, windowNo);
+ windowPanel.initPanel(adWindowId, query);
+
+ this.appendChild(windowPanel);
+ this.setWidth("850px");
+ _title = windowPanel.getTitle();
+ }
+
+ public String getTitle()
+ {
+ return _title;
+ }
+
+ public boolean isAsap()
+ {
+ return false;
+ }
+
+ public void onEvent(Event event)
+ {
+ /* if (restoreButton.equals(event.getTarget()))
+ {
+ String mode = this.getMode();
+ if (ADWindow.MODE_EMBEDDED.equals(mode))
+ {
+ this.doOverlapped();
+ }
+ else
+ {
+ this.doEmbedded();
+ }
+ }*/
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/FDialog.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/FDialog.java
new file mode 100644
index 0000000000..2c17784c39
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/FDialog.java
@@ -0,0 +1,337 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.window;
+
+import java.util.Properties;
+
+import org.compiere.util.CLogMgt;
+import org.compiere.util.CLogger;
+import org.compiere.util.Env;
+import org.compiere.util.Msg;
+import org.compiere.util.Trace;
+
+import org.zkoss.zk.ui.Component;
+import org.adempiere.webui.component.Messagebox;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ */
+
+public class FDialog
+{
+ /** Logger */
+ private static final CLogger logger = CLogger.getCLogger(FDialog.class);
+
+
+ // TODO info
+
+ // TODO ask
+
+ // TODO clear
+
+ /**
+ * Construct a message from the AD_Message and the additional message
+ *
+ * @param adMessage AD_Message string
+ * @param message additional message
+ * @return The translated AD_Message appended with the additional message
+ */
+
+ private static StringBuffer constructMessage(String adMessage, String message)
+ {
+ StringBuffer out = new StringBuffer();
+
+ if (adMessage != null && !adMessage.equals(""))
+ {
+ out.append(Msg.getMsg(Env.getCtx(), adMessage));
+ }
+
+ if (message != null && message.length() > 0)
+ {
+ out.append("\n").append(message);
+ }
+
+ return out;
+ }
+
+
+ /**
+ * Display warning with warning icon
+ *
+ * @param windowNo Number of Window
+ * @param adMessage Message to be translated
+ * @param title Message box title
+ *
+ * @see #warn(int, String)
+ * @see #warn(int, Component, String, String, String)
+ * @see #warn(int, Component, String, String)
+ */
+
+ public static void warn(int windowNo, String adMessage, String title)
+ {
+ warn(windowNo, null, adMessage, null, title);
+ }
+
+ /**
+ * Display warning with warning icon
+ * @param windowNo Number of Window
+ * @param adMessage Message to be translated
+ * @param message Additional message
+ * @param title If none then one will be generated
+ *
+ * @see #warn(int, String)
+ * @see #warn(int, String, String)
+ * @see #warn(int, Component, String, String, String)
+ */
+
+ public static void warn(int windowNo, Component comp, String adMessage, String message)
+ {
+ warn(windowNo, comp, adMessage, message, null);
+ }
+
+ /**
+ * Display warning with warning icon
+ * @param windowNo Number of Window
+ * @param adMessage Message to be translated
+ * @param message Additional message
+ * @param title If none then one will be generated
+ *
+ * @see #warn(int, String)
+ * @see #warn(int, String, String)
+ * @see #warn(int, Component, String, String)
+ */
+
+ public static void warn(int windowNo, Component comp, String adMessage, String message, String title)
+ {
+ Properties ctx = Env.getCtx();
+ StringBuffer out = null;
+
+ logger.info(adMessage + " - " + message);
+
+ out = constructMessage(adMessage, message);
+
+ String newTitle;
+
+ if (title == null)
+ {
+ newTitle = Env.getHeader(ctx, windowNo);
+ }
+ else
+ {
+ newTitle = title;
+ }
+
+ try
+ {
+ Messagebox.showDialog(out.toString(), newTitle, Messagebox.OK, Messagebox.EXCLAMATION);
+ }
+ catch (InterruptedException exception)
+ {
+ // Restore the interrupted status
+ Thread.currentThread().interrupt();
+ }
+
+ return;
+ }
+
+ /**
+ * Display warning with warning icon
+ * @param windowNo Number of Window
+ * @param adMessage Message to be translated
+ *
+ * @see #warn(int, String, String)
+ * @see #warn(int, Component, String, String, String)
+ * @see #warn(int, Component, String, String)
+ */
+
+ public static void warn(int windowNo, String adMessage)
+ {
+ warn(windowNo, null, adMessage, null, null);
+ }
+
+ /**
+ * Display error with error icon
+ * @param windowNo Number of Window
+ * @param comp Component (unused)
+ * @param adMessage Message to be translated
+ */
+
+ public static void error(int windowNo, Component comp, String adMessage)
+ {
+ error(windowNo, comp, adMessage, null);
+ }
+
+ /**
+ * Display error with error icon
+ * @param windowNo Number of Window
+ * @param adMessage Message to be translated
+ *
+ * @see #error(int, String, String)
+ * @see #error(int, Component, String)
+ * @see #error(int, Component, String, String)
+ */
+
+ public static void error (int windowNo, String adMessage)
+ {
+ error (windowNo, null, adMessage, null);
+ } // error (int, String)
+
+ /**
+ * Display error with error icon
+ * @param windowNo Number of Window
+ * @param adMessage Message to be translated
+ * @param adMessage Additional message
+ *
+ * @see #error(int, String)
+ * @see #error(int, Component, String)
+ * @see #error(int, Component, String, String)
+ */
+
+ public static void error(int windowNo, String adMessage, String msg)
+ {
+ error(windowNo, null, adMessage, msg);
+ }
+
+ /**
+ * Display error with error icon.
+ *
+ * @param windowNo Number of Window
+ * @param comp Component (unused)
+ * @param adMessage Message to be translated
+ * @param message Additional message
+ *
+ * @see #error(int, String)
+ * @see #error(int, Component, String)
+ * @see #error(int, String, String)
+ */
+
+ public static void error(int windowNo, Component comp, String adMessage, String message)
+ {
+ Properties ctx = Env.getCtx();
+ StringBuffer out = new StringBuffer();
+
+ logger.info(adMessage + " - " + message);
+
+ if (CLogMgt.isLevelFinest())
+ {
+ Trace.printStack();
+ }
+
+ out = constructMessage(adMessage, message);
+
+ try
+ {
+ Messagebox.showDialog(out.toString(), Env.getHeader(ctx, windowNo), Messagebox.OK, Messagebox.ERROR);
+ }
+ catch (InterruptedException exception)
+ {
+ // Restore the interrupted status
+ Thread.currentThread().interrupt();
+ }
+
+ return;
+ }
+
+ /**************************************************************************
+ * Ask Question with question icon and (OK) (Cancel) buttons
+ *
+ * @param WindowNo Number of Window
+ * @param c Container (owner)
+ * @param AD_Message Message to be translated
+ * @param msg Additional clear text message
+ *
+ * @return true, if OK
+ */
+
+ public static boolean ask(int windowNo, Component comp, String adMessage)
+ {
+ try
+ {
+ int response = Messagebox.showDialog(Msg.getMsg(Env.getCtx(), adMessage), "Confirmation", Messagebox.YES | Messagebox.NO, Messagebox.QUESTION);
+
+ return (response == Messagebox.YES);
+ }
+ catch (InterruptedException ex)
+ {
+ // Restore the interrupted status
+ Thread.currentThread().interrupt();
+ }
+
+ return true;
+ }
+
+ /**
+ * Display information with information icon.
+ *
+ * @param windowNo Number of Window
+ * @param comp Component (unused)
+ * @param adMessage Message to be translated
+ *
+ * @see #info(int, Component, String, String)
+ */
+
+ public static void info(int windowNo, Component comp, String adMessage)
+ {
+ info(windowNo, comp, adMessage, null);
+
+ return;
+ }
+
+
+ /**
+ * Display information with information icon.
+ *
+ * @param windowNo Number of Window
+ * @param comp Component (unused)
+ * @param adMessage Message to be translated
+ * @param message Additional message
+ *
+ * @see #info(int, Component, String)
+ */
+
+ public static void info(int windowNo, Component comp, String adMessage, String message)
+ {
+ Properties ctx = Env.getCtx();
+
+ StringBuffer out = new StringBuffer();
+
+ logger.info(adMessage + " - " + message);
+
+ if (CLogMgt.isLevelFinest())
+ {
+ Trace.printStack();
+ }
+
+ out = constructMessage(adMessage, message);
+
+ try
+ {
+ Messagebox.showDialog(out.toString(), Env.getHeader(ctx, windowNo), Messagebox.OK, Messagebox.INFORMATION);
+ }
+ catch (InterruptedException exception)
+ {
+ // Restore the interrupted status
+ Thread.currentThread().interrupt();
+ }
+
+ return;
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/FindWindow.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/FindWindow.java
new file mode 100644
index 0000000000..db35cee3b7
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/FindWindow.java
@@ -0,0 +1,1302 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.window;
+
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+import java.util.logging.Level;
+
+import org.adempiere.webui.component.Button;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.ListCell;
+import org.adempiere.webui.component.ListHead;
+import org.adempiere.webui.component.ListHeader;
+import org.adempiere.webui.component.ListItem;
+import org.adempiere.webui.component.Listbox;
+import org.adempiere.webui.component.Panel;
+import org.adempiere.webui.component.Textbox;
+import org.adempiere.webui.component.ToolBar;
+import org.adempiere.webui.component.ToolBarButton;
+import org.adempiere.webui.component.Window;
+import org.adempiere.webui.editor.WEditor;
+import org.adempiere.webui.editor.WNumberEditor;
+import org.adempiere.webui.editor.WStringEditor;
+import org.adempiere.webui.editor.WTableDirEditor;
+import org.adempiere.webui.editor.WebEditorFactory;
+import org.adempiere.webui.event.ValueChangeEvent;
+import org.adempiere.webui.event.ValueChangeListener;
+import org.adempiere.webui.panel.MainPanel;
+import org.compiere.model.GridField;
+import org.compiere.model.MProduct;
+import org.compiere.model.MQuery;
+import org.compiere.model.MRole;
+import org.compiere.model.X_AD_Column;
+import org.compiere.util.AdempiereSystemError;
+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.ValueNamePair;
+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.Hbox;
+import org.zkoss.zul.Vbox;
+
+/**
+ * This class is based on org.compiere.apps.search.Find written by Jorg Janke.
+ * Find/Search Records.
+ *
+ * @author Sendy Yagambrum
+ * @date June 27, 2007
+ */
+public class FindWindow extends Window implements EventListener,ValueChangeListener
+{
+ private static final long serialVersionUID = 1L;
+ /** Main Window for the Lookup Panel */
+ private MainPanel winMain;
+ /** Simple Window Tab */
+ private Window winLookupRecord;
+ /** Advanced Window Tab */
+ private Window winAdvanced;
+ //
+ private Label lblDocumentNo;
+ private Label lblDescription;
+ private Label lblName;
+ private Label lblValue;
+ //
+ private Textbox fieldDocumentNo;
+ private Textbox fieldDescription;
+ private Textbox fieldName;
+ private Textbox fieldValue;
+ //
+ private Listbox advancedPanel;
+ /** container of Simple Window contents */
+ private Vbox contentSimple;
+ /** Target Window No */
+ private int m_targetWindowNo;
+ /** Table ID */
+ private int m_AD_Table_ID;
+ /** Table Name */
+ private String m_tableName;
+ /** Where */
+ private String m_whereExtended;
+ /** Search Fields */
+ private GridField[] m_findFields;
+ /** Resulting query */
+ private MQuery m_query = null;
+ /** Is cancel ? */
+ private boolean m_isCancel = false; // teo_sarca [ 1708717 ]
+ /** Logger */
+ private static CLogger log = CLogger.getCLogger(FindWindow.class);
+ /** Number of records */
+ private int m_total;
+ private PreparedStatement m_pstmt;
+ //
+ private boolean hasValue = false;
+ private boolean hasDocNo = false;
+ private boolean hasName = false;
+ private boolean hasDescription = false;
+ /** Line in Simple Content */
+ private int sLine = 6;
+ /** Value 2(to) */
+ private boolean m_valueToColumn;
+ /** Between selected */
+ private boolean m_between = false;
+ /** Editor */
+ private WEditor m_editor = null;
+ /** List of WEditors */
+ private ArrayList m_sEditors = new ArrayList();
+ /** Target Fields with AD_Column_ID as key */
+ private Hashtable m_targetFields = new Hashtable();
+ /** For Grid Controller */
+ public static final int TABNO = 99;
+ /** Length of Fields on first tab */
+ public static final int FIELDLENGTH = 20;
+
+ /**
+ * FindPanel Constructor
+ * @param targetWindowNo targetWindowNo
+ * @param title title
+ * @param AD_Table_ID AD_Table_ID
+ * @param tableName tableName
+ * @param whereExtended whereExtended
+ * @param findFields findFields
+ * @param minRecords minRecords
+ **/
+ public FindWindow (int targetWindowNo, String title,
+ int AD_Table_ID, String tableName, String whereExtended,
+ GridField[] findFields, int minRecords)
+ {
+ m_targetWindowNo = targetWindowNo;
+ m_AD_Table_ID = AD_Table_ID;
+ m_tableName = tableName;
+ m_whereExtended = whereExtended;
+ m_findFields = findFields;
+ //
+ m_query = new MQuery (m_tableName);
+ m_query.addRestriction(m_whereExtended);
+ // Required for Column Validation
+ Env.setContext(Env.getCtx(), m_targetWindowNo, "Find_Table_ID", m_AD_Table_ID);
+ // Context for Advanced Search Grid is WINDOW_FIND
+ Env.setContext(Env.getCtx(), Env.WINDOW_FIND, "Find_Table_ID", m_AD_Table_ID);
+ //
+ initPanel();
+ initFind();
+ initFindAdvanced();
+ if (m_total < minRecords)
+ {
+ return;
+ }
+ this.appendChild(winMain);
+ this.setBorder("normal");
+ this.setWidth("550px");
+ this.setTitle("Lookup Record: "+ title);
+ this.setAttribute("mode", "modal");
+ this.setClosable(true);
+ }
+ /**
+ * initialise lookup record tab
+ *
+ **/
+ private void initSimple()
+ {
+ lblDocumentNo = new Label();
+ lblDocumentNo.setValue(Msg.translate(Env.getCtx(),"DocumentNo").substring(1));
+
+ lblDescription = new Label();
+ lblDescription.setValue(Msg.translate(Env.getCtx(),"Description"));
+
+ lblName = new Label();
+ lblName.setValue(Msg.translate(Env.getCtx(),"Name").substring(1));
+
+ lblValue = new Label();
+ lblValue.setValue(Msg.translate(Env.getCtx(),"Value").substring(1));
+
+ fieldDocumentNo = new Textbox();
+ fieldDocumentNo.setId("fieldDocumentNo");
+ fieldDocumentNo.setMaxlength(40);
+
+ fieldDescription = new Textbox();
+ fieldDescription.setId("fieldDescription");
+ fieldDescription.setMaxlength(40);
+
+ fieldName = new Textbox();
+ fieldName.setMaxlength(40);
+
+ fieldValue = new Textbox();
+ fieldValue.setMaxlength(40);
+
+ Button btnNew = new Button();
+ btnNew.setName("btnNew");
+ btnNew.setSrc("/images/New24.gif");
+ btnNew.addEventListener(Events.ON_CLICK,this);
+
+ Button btnOk = new Button();
+ btnOk.setName("btnOkSimple");
+ btnOk.setSrc("/images/Ok24.gif");
+ btnOk.addEventListener(Events.ON_CLICK,this);
+
+ Button btnCancel = new Button();
+ btnCancel.setName("btnCancel");
+ btnCancel.setSrc("/images/Cancel24.gif");
+ btnCancel.addEventListener(Events.ON_CLICK,this);
+
+ Panel pnlButtonRight = new Panel();
+ pnlButtonRight.appendChild(btnOk);
+ pnlButtonRight.appendChild(btnCancel);
+ pnlButtonRight.setAlign("right");
+ pnlButtonRight.setWidth("100%");
+
+ Panel pnlButtonLeft = new Panel();
+ pnlButtonLeft.appendChild(btnNew);
+
+ Hbox hboxButton = new Hbox();
+ hboxButton.appendChild(pnlButtonLeft);
+ hboxButton.appendChild(pnlButtonRight);
+ hboxButton.setWidth("100%");
+
+ Panel pnlDocument = new Panel();
+ pnlDocument.setId("pnlDocument");
+ pnlDocument.appendChild(lblDocumentNo);
+ pnlDocument.appendChild(fieldDocumentNo);
+ pnlDocument.setWidth("70%");
+ pnlDocument.setAlign("right");
+
+ Panel pnlDescription = new Panel();
+ pnlDescription.appendChild(lblDescription);
+ pnlDescription.appendChild(fieldDescription);
+ pnlDescription.setWidth("70%");
+ pnlDescription.setAlign("right");
+
+ Panel pnlValue = new Panel();
+ pnlValue.appendChild(lblValue);
+ pnlValue.appendChild(fieldValue);
+ pnlValue.setWidth("70%");
+ pnlValue.setAlign("right");
+
+ Panel pnlName = new Panel();
+ pnlName.appendChild(lblName);
+ pnlName.appendChild(fieldName);
+ pnlName.setWidth("70%");
+ pnlName.setAlign("right");
+
+ contentSimple = new Vbox();
+ contentSimple.setId("contentSimple");
+ contentSimple.setWidth("100%");
+ contentSimple.setStyle("padding:10px; text-align:left");
+
+ contentSimple.appendChild(pnlValue);
+ contentSimple.appendChild(pnlName);
+ contentSimple.appendChild(pnlDocument);
+ contentSimple.appendChild(pnlDescription);
+
+ winLookupRecord.appendChild(contentSimple);
+ winLookupRecord.appendChild(hboxButton);
+ winLookupRecord.setWidth("100%");
+ winLookupRecord.addEventListener(Events.ON_OK, this);
+
+ } // initSimple
+
+ /**
+ * initialise Advanced Tab
+ *
+ **/
+ private void initAdvanced()
+ {
+ ToolBarButton btnNew = new ToolBarButton();
+ btnNew.setSrc("/images/New24.gif");
+ btnNew.setAttribute("name", "btnNewAdv");
+ btnNew.addEventListener(Events.ON_CLICK, this);
+
+ ToolBarButton btnDelete = new ToolBarButton();
+ btnDelete.setAttribute("name","btnDeleteAdv");
+ btnDelete.setSrc("/images/Delete24.gif");
+ btnDelete.addEventListener(Events.ON_CLICK, this);
+
+ Button btnOk = new Button();
+ btnOk.setName("btnOkAdv");
+ btnOk.setSrc("/images/Ok24.gif");
+ btnOk.addEventListener(Events.ON_CLICK, this);
+
+ Button btnCancel = new Button();
+ btnCancel.setName("btnCancel");
+ btnCancel.setSrc("/images/Cancel24.gif");
+ btnCancel.addEventListener(Events.ON_CLICK, this);
+
+ Panel pnlButtonRight = new Panel();
+ pnlButtonRight.appendChild(btnOk);
+ pnlButtonRight.appendChild(btnCancel);
+ pnlButtonRight.setAlign("right");
+
+ ToolBar toolBar = new ToolBar();
+ toolBar.appendChild(btnNew);
+ toolBar.appendChild(btnDelete);
+ toolBar.setWidth("100%");
+
+ Hbox confirmPanel = new Hbox();
+ confirmPanel.appendChild(pnlButtonRight);
+ confirmPanel.setWidth("100%");
+
+ advancedPanel = new Listbox();
+ ListHead listhead = new ListHead();
+ listhead.setSizable(true);
+
+ ListHeader lstHColumn = new ListHeader();
+ lstHColumn.setLabel("Column");
+ lstHColumn.setWidth("100px");
+
+ ListHeader lstHOperator = new ListHeader();
+ lstHOperator.setLabel("Operator");
+
+ ListHeader lstHQueryValue = new ListHeader();
+ lstHQueryValue.setLabel("Query Value");
+ lstHQueryValue.setWidth("200px");
+
+ ListHeader lstHQueryTo = new ListHeader();
+ lstHQueryTo.setLabel("To Query Value");
+ lstHQueryTo.setWidth("200px");
+
+ listhead.appendChild(lstHColumn);
+ listhead.appendChild(lstHOperator);
+ listhead.appendChild(lstHQueryValue);
+ listhead.appendChild(lstHQueryTo);
+ advancedPanel.appendChild(listhead);
+
+ Vbox advancedWindow = new Vbox();
+ advancedWindow.setWidth("100%");
+ advancedWindow.appendChild(toolBar);
+ advancedWindow.appendChild(advancedPanel);
+ advancedWindow.appendChild(confirmPanel);
+ winAdvanced.appendChild(advancedWindow);
+ winAdvanced.addEventListener(Events.ON_OK,this);
+
+ } // initAdvanced
+
+ /**
+ * initialise Main Window
+ *
+ **/
+ private void initPanel()
+ {
+ winMain = new MainPanel();
+ winMain.setWidth("100%");
+ winAdvanced = new Window();
+ winLookupRecord = new Window();
+ winMain.addWindow(winLookupRecord, "Lookup Record",false, true);
+ winMain.addWindow(winAdvanced, "Advanced", false, false);
+ initSimple();
+ initAdvanced();
+
+ } // initPanel
+
+ /**
+ * Dynamic Init.6
+ * Set up GridController
+ **/
+ private void initFind()
+ {
+ log.config("");
+
+ // Get Info from target Tab
+ for (int i = 0; i < m_findFields.length; i++)
+ {
+ GridField mField = m_findFields[i];
+ String columnName = mField.getColumnName();
+
+ if (columnName.equals("Value"))
+ hasValue = true;
+ else if (columnName.equals("Name"))
+ hasName = true;
+ else if (columnName.equals("DocumentNo"))
+ hasDocNo = true;
+ else if (columnName.equals("Description"))
+ hasDescription = true;
+ else if (mField.isSelectionColumn())
+ addSelectionColumn (mField);
+ else if (columnName.indexOf("Name") != -1)
+ addSelectionColumn (mField);
+
+ // TargetFields
+ m_targetFields.put (new Integer(mField.getAD_Column_ID()), mField);
+ } // for all target tab fields
+
+ // Disable simple query fields
+ lblValue.setVisible(hasValue);
+ fieldValue.setVisible(hasValue);
+ if (hasValue)
+ fieldValue.addEventListener(Events.ON_CHANGE,this);
+ lblDocumentNo.setVisible(hasDocNo);
+ fieldDocumentNo.setVisible(hasDocNo);
+ if (hasDocNo)
+ fieldDocumentNo.addEventListener(Events.ON_CHANGE,this);
+ lblName.setVisible(hasName);
+ fieldName.setVisible(hasName);
+ if (hasName)
+ fieldName.addEventListener(Events.ON_CHANGE,this);
+ lblDescription.setVisible(hasDescription);
+ fieldDescription.setVisible(hasDescription);
+ if (hasDescription)
+ fieldDescription.addEventListener(Events.ON_CHANGE,this);
+
+ m_total = getNoOfRecords(null, false);
+
+ } // initFind
+
+ /**
+ * initialise Advanced tab
+ **/
+ private void initFindAdvanced()
+ {
+ log.config("");
+ createFields();
+
+ } // initFindAdvanced
+
+ /**
+ * create respective fields in the advanced window tab
+ *
+ **/
+ private void createFields()
+ {
+ ListItem listItem = new ListItem();
+
+ Listbox listColumn = new Listbox();
+ listColumn.setId("listColumn"+listItem.getId());
+ listColumn.setName("listColumn");
+ listColumn.setMold("select");
+ listColumn.setWidth("150px");
+ listColumn.setRows(0);
+ listColumn.addEventListener(Events.ON_SELECT,this);
+
+ Listbox listOperator = new Listbox();
+ listOperator.setId("listOperator"+listItem.getId());
+ listOperator.setName("listOperator");
+ listOperator.setMold("select");
+ listOperator.setWidth("50px");
+ listOperator.setRows(0);
+ listOperator.addEventListener(Events.ON_SELECT,this);
+
+ setValues(listColumn, listOperator);
+
+ ListCell cellColumn = new ListCell();
+ cellColumn.appendChild(listColumn);
+ cellColumn.setId("cellColumn"+listItem.getId());
+
+ ListCell cellOperator = new ListCell();
+ cellOperator.appendChild(listOperator);
+ cellOperator.setId("cellOperator"+listItem.getId());
+
+ ListCell cellQueryFrom = new ListCell();
+ cellQueryFrom.setId("cellQueryFrom"+listItem.getId());
+
+ ListCell cellQueryTo = new ListCell();
+ cellQueryTo.setId("cellQueryTo"+listItem.getId());
+
+ listItem.appendChild(cellColumn);
+ listItem.appendChild(cellOperator);
+ listItem.appendChild(cellQueryFrom);
+ listItem.appendChild(cellQueryTo);
+
+ advancedPanel.appendChild(listItem);
+ advancedPanel.setSelectedItem(listItem);
+
+ } // createFields
+ /**
+ * sets the list of values of column and operator listboxes
+ * @param listColumn column
+ * @param listOperator operator
+ **/
+ private void setValues(Listbox listColumn, Listbox listOperator)
+ {
+ // 0 = Columns
+ ArrayList items = new ArrayList();
+ for (int c = 0; c < m_findFields.length; c++)
+ {
+ GridField field = m_findFields[c];
+ String columnName = field.getColumnName();
+ String header = field.getHeader();
+ if (header == null || header.length() == 0)
+ {
+ header = Msg.translate(Env.getCtx(), columnName);
+
+ if (header == null || header.length() == 0)
+ continue;
+ }
+ if (field.isKey())
+ header += (" (ID)");
+ ValueNamePair pp = new ValueNamePair(columnName, header);
+ items.add(pp);
+ }
+ ValueNamePair[] cols = new ValueNamePair[items.size()];
+ items.toArray(cols);
+ Arrays.sort(cols); // sort alpha
+
+ listColumn.appendItem("","" );
+ for (ValueNamePair item: cols)
+ {
+ listColumn.appendItem(item.getName(), item.getValue());
+ }
+ listColumn.setSelectedIndex(0);
+
+ ValueNamePair[] op = MQuery.OPERATORS;
+
+ for (ValueNamePair item: op)
+ {
+ listOperator.appendItem(item.getName(), item.getValue());
+ }
+ listOperator.setSelectedIndex(0);
+ } // setValues
+
+ /**
+ * Add Selection Column to first Tab
+ * @param mField field
+ **/
+ public void addSelectionColumn(GridField mField)
+ {
+ log.config(mField.getHeader());
+ int displayLength = mField.getDisplayLength();
+ if (displayLength <= 0 || displayLength > FIELDLENGTH)
+ mField.setDisplayLength(FIELDLENGTH);
+ else
+ displayLength = 0;
+
+ // Editor
+ WEditor editor = null;
+ if (mField.isLookup())
+ {
+ WTableDirEditor wd = new WTableDirEditor(mField);
+ editor = wd;
+ }
+ else
+ {
+ editor = WebEditorFactory.getEditor(mField, false);
+ editor.setMandatory(false);
+ editor.setReadWrite(true);
+ }
+ Label label = editor.getLabel();
+ Component fieldLabel = editor.getComponent();
+
+ //
+ if (displayLength > 0) // set it back
+ mField.setDisplayLength(displayLength);
+ //
+ Panel panel = new Panel();
+ panel.setWidth("70%");
+ panel.setAlign("right");
+ panel.appendChild(label);
+ panel.appendChild(fieldLabel);
+
+ contentSimple.appendChild(panel);
+ m_sEditors.add(editor);
+
+ } // addSelectionColumn
+
+ public void onEvent(Event event) throws Exception
+ {
+ if ("onSelect".equals(event.getName()))
+ {
+ if (event.getTarget() instanceof Listbox)
+ {
+ ListItem row = (ListItem)(event.getTarget().getParent().getParent());
+ Listbox listbox = (Listbox)event.getTarget();
+ advancedPanel.setSelectedItem(row);
+ Listbox listColumn = (Listbox)row.getFellow("listColumn"+row.getId());
+ Listbox listOperator = (Listbox)row.getFellow("listOperator"+row.getId());
+
+ if (listbox.getId().equals(listColumn.getId()))
+ {
+ ListItem column = listColumn.getSelectedItem();
+ if (column != null)
+ {
+ addOperators(column, listOperator);
+ }
+ }
+ Component componentFrom = getEditorCompQueryFrom(row);
+ Component componentTo = getEditorCompQueryTo(row);
+
+ addRowEditor(componentFrom, (ListCell)row.getFellow("cellQueryFrom"+row.getId()));
+ addRowEditor(componentTo,(ListCell)row.getFellow("cellQueryTo"+row.getId()));
+ }
+ } //
+ else if ("onClick".equals(event.getName()))
+ {
+ // Toolbar Buttons actions
+ if(event.getTarget() instanceof ToolBarButton)
+ {
+ ToolBarButton button = (ToolBarButton)event.getTarget();
+
+ if ("btnNewAdv".equals(button.getAttribute("name").toString()))
+ {
+ initFindAdvanced();
+ }
+
+ else if ("btnDeleteAdv".equals(button.getAttribute("name").toString()))
+ {
+
+ int index = advancedPanel.getSelectedIndex();
+ advancedPanel.getSelectedItem().detach();
+ advancedPanel.setSelectedIndex(--index);
+ }
+ }
+ // Confirm panel actions
+ else if(event.getTarget() instanceof Button)
+ {
+ Button btn = (Button)event.getTarget();
+
+ if ("btnOkSimple".equals(btn.getName()))
+ {
+ cmd_ok_Simple();
+ dispose();
+ }
+ else if ("btnOkAdv".equals(btn.getName()))
+ {
+ cmd_ok_Advanced();
+ dispose();
+ }
+ else if("btnCancel".equals(btn.getName()))
+ {
+ dispose();
+ }
+ else if ("btnNew".equals(btn.getName()))
+ {
+ m_query = MQuery.getNoRecordQuery(m_tableName, true);
+ m_total = 0;
+ dispose();
+ }
+ }
+ else if (event.getTarget() instanceof Label)
+ {
+ Label label = (Label)event.getTarget();
+ ListCell listcell = (ListCell)label.getParent();
+ ListItem row = (ListItem)listcell.getParent();
+ advancedPanel.setSelectedItem(row);
+
+ if (listcell.getId().equals("cellQueryFrom"+row.getId()))
+ {
+ Component component = getEditorCompQueryFrom(row);
+ addRowEditor(component, listcell);
+ }
+ else if (listcell.getId().equals("cellQueryTo"+row.getId()))
+ {
+ Component component = getEditorCompQueryTo(row);
+ addRowEditor(component,listcell);
+ }
+ }
+ }
+ else if ("onOK".equals(event.getName()))
+ {
+ if (winLookupRecord.equals(event.getTarget()))
+ {
+ cmd_ok_Simple();
+ dispose();
+ }
+ else if (winAdvanced.equals(event.getTarget()))
+ {
+ cmd_ok_Advanced();
+ dispose();
+ }
+ }
+
+ } // onEvent
+
+ /**
+ * retrieve the columnName of the Column item selected
+ * @param label label
+ **/
+ private String getColumnName(ListItem row)
+ {
+ /*List list = row.getChildren();
+ Panel pnlColumn = (Panel)list.get(0);
+ List lstColumn = pnlColumn.getChildren();*/
+ Listbox listColumn = (Listbox)row.getFellow("listColumn"+row.getId());
+ String columnName = listColumn.getSelectedItem().getValue().toString();
+
+ return columnName;
+
+ } // getColumnName
+
+ /**
+ * get editor component for 'query' field
+ * @param row row
+ * @return editor component
+ **/
+ private Component getEditorCompQueryFrom(ListItem row)
+ {
+ m_valueToColumn = false;
+ return getEditorComponent(row);
+ }
+
+ /**
+ * get editor component for 'query to' field
+ * @param row row
+ * @return editor component
+ **/
+ private Component getEditorCompQueryTo(ListItem row)
+ {
+ m_valueToColumn = true;
+ return getEditorComponent(row);
+ }
+
+ /**
+ * add the editor component in the 'QueryValue' field
+ * @param component editor component
+ * @param label label to replace by editor component
+ **/
+ private void addRowEditor(Component component, ListCell listcell)
+ {
+ listcell.setLabel("");
+ listcell.getChildren().clear();
+ listcell.appendChild(component);
+
+ } // addComponent
+
+ /**
+ * Retrieve operators depending on the item selected in the 'Column' field
+ * and add them to the selection
+ * @param column Column field selected
+ **/
+ private void addOperators(ListItem column, Listbox listOperator)
+ {
+ String columnName = column.getValue().toString();
+ log.config("Column: " + columnName);
+
+ if (columnName.endsWith("_ID") || columnName.endsWith("_Acct"))
+ {
+ addOperators(MQuery.OPERATORS_ID, listOperator);
+ }
+ else if (columnName.startsWith("Is"))
+ {
+ addOperators(MQuery.OPERATORS_YN, listOperator);
+ }
+ else
+ {
+ addOperators(MQuery.OPERATORS, listOperator);
+ }
+ } // addOperators
+
+ /**
+ * add Operators
+ * @param op array of operators
+ **/
+ private void addOperators(ValueNamePair[] op, Listbox listOperator)
+ {
+ List itemList = listOperator.getChildren();
+ itemList.clear();
+ for (ValueNamePair item: op)
+ {
+ listOperator.appendItem(item.getName(), item.getValue());
+ }
+ listOperator.setSelectedIndex(0);
+ } // addOperators
+
+ /**
+ * Get Editor
+ * @param row row
+ * @return Editor component
+ **/
+ public Component getEditorComponent(ListItem row)
+ {
+ String columnName = getColumnName(row);
+ m_between = false;
+ Listbox listOp = (Listbox) row.getFellow("listOperator"+row.getId());
+ String betweenValue = listOp.getSelectedItem().getValue().toString();
+ String opValue = MQuery.OPERATORS[MQuery.BETWEEN_INDEX].getValue();
+ if (m_valueToColumn && betweenValue != null
+ && betweenValue.equals(opValue))
+ m_between = true;
+
+ boolean enabled = !m_valueToColumn || (m_valueToColumn && m_between);
+
+ // Create Editor
+ GridField field = getTargetMField(columnName);
+ // log.fine( "Field=" + field.toStringX());
+ if (field.isKey())
+ m_editor = new WNumberEditor(field);
+ else
+ m_editor = WebEditorFactory.getEditor(field, true);
+ if (m_editor == null)
+ m_editor = new WStringEditor(field);
+ field.addPropertyChangeListener(m_editor);
+ m_editor.addValueChangeListner(this);
+ m_editor.setValue(null);
+ m_editor.setReadWrite(enabled);
+ m_editor.setVisible(enabled);
+ //
+ return m_editor.getComponent();
+
+ } // getTableCellEditorComponent
+
+ /**
+ * Get Target MField
+ * @param columnName column name
+ * @return MField
+ **/
+ public GridField getTargetMField (String columnName)
+ {
+ if (columnName == null)
+ return null;
+ for (int c = 0; c < m_findFields.length; c++)
+ {
+ GridField field = m_findFields[c];
+ if (columnName.equals(field.getColumnName()))
+ return field;
+ }
+ return null;
+
+ } // getTargetMField
+
+ /**
+ * Simple OK Button pressed
+ **/
+ private void cmd_ok_Simple()
+ {
+ // Create Query String
+ m_query = new MQuery(m_tableName);
+ if (hasValue && !fieldValue.getText().equals("%") && fieldValue.getText().length() != 0)
+ {
+ String value = fieldValue.getText().toUpperCase();
+
+ if (!value.endsWith("%"))
+ value += "%";
+ m_query.addRestriction("UPPER(Value)", MQuery.LIKE, value, lblValue.getValue(), value);
+ }
+ //
+ if (hasDocNo && !fieldDocumentNo.getText().equals("%") && fieldDocumentNo.getText().length() != 0)
+ {
+ String value = fieldDocumentNo.getText().toUpperCase();
+
+ if (!value.endsWith("%"))
+ value += "%";
+ m_query.addRestriction("UPPER(DocumentNo)", MQuery.LIKE, value, lblDocumentNo.getValue(),value);
+ }
+ //
+ if ((hasName) && !fieldName.getText().equals("%") && fieldName.getText().length() != 0)
+ {
+ String value = fieldName.getText().toUpperCase();
+
+ if (!value.endsWith("%"))
+ value += "%";
+ m_query.addRestriction("UPPER(Name)", MQuery.LIKE, value, lblName.getValue(), value);
+ }
+ //
+ if (hasDescription && !fieldDescription.getText().equals("%") && fieldDescription.getText().length() != 0)
+ {
+ String value = fieldDescription.getText().toUpperCase();
+ if (!value.endsWith("%"))
+ value += "%";
+ m_query.addRestriction("UPPER(Description)", MQuery.LIKE, value, lblDescription.getValue(), value);
+ }
+ // Special Editors
+ for (int i = 0; i < m_sEditors.size(); i++)
+ {
+ WEditor wed = (WEditor)m_sEditors.get(i);
+ Object value = wed.getValue();
+ if (value != null && value.toString().length() > 0)
+ {
+ String ColumnName = wed.getColumnName();
+ log.fine(ColumnName + "=" + value);
+
+ // globalqss - Carlos Ruiz - 20060711
+ // fix a bug with virtualColumn + isSelectionColumn not yielding results
+ GridField field = getTargetMField(ColumnName);
+ boolean isProductCategoryField = isProductCategoryField(field.getAD_Column_ID());
+ String ColumnSQL = field.getColumnSQL(false);
+ if (value.toString().indexOf('%') != -1)
+ m_query.addRestriction(ColumnSQL, MQuery.LIKE, value, ColumnName, wed.getDisplay());
+ else if (isProductCategoryField && value instanceof Integer)
+ m_query.addRestriction(getSubCategoryWhereClause(((Integer) value).intValue()));
+ else
+ m_query.addRestriction(ColumnSQL, MQuery.EQUAL, value, ColumnName, wed.getDisplay());
+ /*
+ if (value.toString().indexOf('%') != -1)
+ m_query.addRestriction(ColumnName, MQuery.LIKE, value, ColumnName, ved.getDisplay());
+ else
+ m_query.addRestriction(ColumnName, MQuery.EQUAL, value, ColumnName, ved.getDisplay());
+ */
+ // end globalqss patch
+ }
+ } // editors
+
+ m_isCancel = false; // teo_sarca [ 1708717 ]
+ // Test for no records
+ if (getNoOfRecords(m_query, true) != 0)
+ dispose();
+
+ } // cmd_ok_Simple
+
+ private void dispose()
+ {
+ log.config("");
+
+ // Find SQL
+ if (m_pstmt != null)
+ {
+ try {
+ m_pstmt.close();
+ } catch (SQLException e) {}
+ }
+ m_pstmt = null;
+
+
+ // TargetFields
+ if (m_targetFields != null)
+ m_targetFields.clear();
+ m_targetFields = null;
+ //
+ this.detach();
+ } // dispose
+
+ /**
+ * Advanced OK Button pressed
+ */
+ private void cmd_ok_Advanced()
+ {
+ m_isCancel = false; // teo_sarca [ 1708717 ]
+ // save pending
+ cmd_save();
+ if (getNoOfRecords(m_query, true) != 0)
+ dispose();
+ } // cmd_ok_Advanced
+
+ /**
+ * Save (Advanced)
+ */
+ private void cmd_save()
+ {
+ log.info("");
+ //
+ m_query = new MQuery(m_tableName);
+ List rowList = advancedPanel.getChildren();
+
+ for (int rowIndex = 1; rowIndex < rowList.size() ; rowIndex++)
+ {
+ // Column
+ ListItem row = (ListItem)rowList.get(rowIndex);
+ Listbox column = (Listbox)row.getFellow("listColumn"+row.getId());
+ if (column == null)
+ continue;
+ String ColumnName = column.getSelectedItem().getValue().toString();
+ String infoName = column.toString();
+ //
+ GridField field = getTargetMField(ColumnName);
+ boolean isProductCategoryField = isProductCategoryField(field.getAD_Column_ID());
+ String ColumnSQL = field.getColumnSQL(false);
+ // Op
+ Listbox op = (Listbox)row.getFellow("listOperator"+row.getId());
+ if (op == null)
+ continue;
+ String Operator = op.getSelectedItem().getValue().toString();
+
+ // Value ******
+ ListCell cellQueryFrom = (ListCell)row.getFellow("cellQueryFrom"+row.getId());
+ Label labelFrom = (Label)(cellQueryFrom.getChildren().get(0));
+ Object value = labelFrom.getAttribute("value");
+ if (value == null)
+ continue;
+ Object parsedValue = parseValue(field, value);
+ if (parsedValue == null)
+ continue;
+ String infoDisplay = value.toString();
+ if (field.isLookup())
+ infoDisplay = field.getLookup().getDisplay(value);
+ else if (field.getDisplayType() == DisplayType.YesNo)
+ infoDisplay = Msg.getMsg(Env.getCtx(), infoDisplay);
+ // Value2 ******
+ if (MQuery.OPERATORS[MQuery.BETWEEN_INDEX].equals(op))
+ {
+ ListCell cellQueryTo = (ListCell)row.getFellow("cellQueryTo"+row.getId());
+ Label labelTo = (Label)(cellQueryTo.getChildren().get(0));
+ Object value2 = labelTo.getAttribute("value");
+ if (value2 == null)
+ continue;
+ Object parsedValue2 = parseValue(field, value2);
+ String infoDisplay_to = value2.toString();
+ if (parsedValue2 == null)
+ continue;
+ m_query.addRangeRestriction(ColumnSQL, parsedValue, parsedValue2,
+ infoName, infoDisplay, infoDisplay_to);
+ }
+ else if (isProductCategoryField && MQuery.OPERATORS[MQuery.EQUAL_INDEX].equals(op)) {
+ if (!(parsedValue instanceof Integer)) {
+ continue;
+ }
+ m_query
+
+ .addRestriction(getSubCategoryWhereClause(((Integer) parsedValue).intValue()));
+ }
+ else
+ m_query.addRestriction(ColumnSQL, Operator, parsedValue,
+ infoName, infoDisplay);
+ }
+ } // cmd_save
+
+ /**
+ * Get the number of records of target tab
+ * @param query where clause for target tab
+ * @param alertZeroRecords show dialog if there are no records
+ * @return number of selected records;
+ * if the results are more then allowed this method will return 0
+ **/
+ private int getNoOfRecords (MQuery query, boolean alertZeroRecords)
+ {
+ log.config("" + query);
+ StringBuffer sql = new StringBuffer("SELECT COUNT(*) FROM ");
+ sql.append(m_tableName);
+ boolean hasWhere = false;
+ if (m_whereExtended != null && m_whereExtended.length() > 0)
+ {
+ sql.append(" WHERE ").append(m_whereExtended);
+ hasWhere = true;
+ }
+ if (query != null && query.isActive())
+ {
+ if (hasWhere)
+ sql.append(" AND ");
+ else
+ sql.append(" WHERE ");
+ sql.append(query.getWhereClause());
+ }
+ // Add Access
+ String finalSQL = MRole.getDefault().addAccessSQL(sql.toString(),
+ m_tableName, MRole.SQL_NOTQUALIFIED, MRole.SQL_RO);
+ finalSQL = Env.parseContext(Env.getCtx(), m_targetWindowNo, finalSQL, false);
+ Env.setContext(Env.getCtx(), m_targetWindowNo, TABNO, "FindSQL", finalSQL);
+
+ // Execute Qusery
+ m_total = 999999;
+ try
+ {
+ Statement stmt = DB.createStatement();
+ ResultSet rs = stmt.executeQuery(finalSQL);
+ if (rs.next())
+ m_total = rs.getInt(1);
+ rs.close();
+ stmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, finalSQL, e);
+ }
+ MRole role = MRole.getDefault();
+ // No Records
+ /* if (m_total == 0 && alertZeroRecords)
+ FDialog.warn(m_targetWindowNo, this, "FindZeroRecords");*/
+ // More then allowed
+ if (query != null && role.isQueryMax(m_total))
+ {
+ FDialog.error(m_targetWindowNo, this, "FindOverMax",
+ m_total + " > " + role.getMaxQueryRecords());
+ m_total = 0; // return 0 if more then allowed - teo_sarca [ 1708717 ]
+ }
+ else
+ log.config("#" + m_total);
+ //
+ /*if (query != null)
+ statusBar.setStatusToolTip (query.getWhereClause());*/
+ return m_total;
+
+ } // getNoOfRecords
+
+ /**
+ * Checks the given column.
+ * @param columnId
+ * @return true if the column is a product category column
+ **/
+ private boolean isProductCategoryField(int columnId) {
+ X_AD_Column col = new X_AD_Column(Env.getCtx(), columnId, null);
+ if (col.get_ID() == 0) {
+ return false; // column not found...
+ }
+ return MProduct.COLUMNNAME_M_Product_Category_ID.equals(col.getColumnName());
+
+ } // isProductCategoryField
+
+ /**
+ * Returns a sql where string with the given category id and all of its subcategory ids.
+ * It is used as restriction in MQuery.
+ * @param productCategoryId
+ * @return
+ **/
+ private String getSubCategoryWhereClause(int productCategoryId) {
+ //if a node with this id is found later in the search we have a loop in the tree
+ int subTreeRootParentId = 0;
+ String retString = " M_Product_Category_ID IN (";
+ String sql = " SELECT M_Product_Category_ID, M_Product_Category_Parent_ID FROM M_Product_Category";
+ final Vector categories = new Vector(100);
+ try {
+ Statement stmt = DB.createStatement();
+ ResultSet rs = stmt.executeQuery(sql);
+ while (rs.next()) {
+ if(rs.getInt(1)==productCategoryId) {
+ subTreeRootParentId = rs.getInt(2);
+ }
+ categories.add(new SimpleTreeNode(rs.getInt(1), rs.getInt(2)));
+ }
+ retString += getSubCategoriesString(productCategoryId, categories, subTreeRootParentId);
+ retString += ") ";
+ rs.close();
+ stmt.close();
+ } catch (SQLException e) {
+ log.log(Level.SEVERE, sql, e);
+ retString = "";
+ } catch (AdempiereSystemError e) {
+ log.log(Level.SEVERE, sql, e);
+ retString = "";
+ }
+ return retString;
+
+ } // getSubCategoryWhereClause
+
+ /**
+ * Recursive search for subcategories with loop detection.
+ * @param productCategoryId
+ * @param categories
+ * @param loopIndicatorId
+ * @return comma seperated list of category ids
+ * @throws AdempiereSystemError if a loop is detected
+ **/
+ private String getSubCategoriesString(int productCategoryId, Vector categories, int loopIndicatorId) throws AdempiereSystemError {
+ String ret = "";
+ final Iterator iter = categories.iterator();
+ while (iter.hasNext()) {
+ SimpleTreeNode node = (SimpleTreeNode) iter.next();
+ if (node.getParentId() == productCategoryId) {
+ if (node.getNodeId() == loopIndicatorId) {
+ throw new AdempiereSystemError("The product category tree contains a loop on categoryId: " + loopIndicatorId);
+ }
+ ret = ret + getSubCategoriesString(node.getNodeId(), categories, loopIndicatorId) + ",";
+ }
+ }
+ log.fine(ret);
+ return ret + productCategoryId;
+
+ } // getSubCategoriesString
+
+ /**
+ * Simple tree node class for product category tree search.
+ * @author Karsten Thiemann, kthiemann@adempiere.org
+ *
+ **/
+ private class SimpleTreeNode {
+
+ private int nodeId;
+
+ private int parentId;
+
+ public SimpleTreeNode(int nodeId, int parentId) {
+ this.nodeId = nodeId;
+ this.parentId = parentId;
+ }
+
+ public int getNodeId() {
+ return nodeId;
+ }
+
+ public int getParentId() {
+ return parentId;
+ }
+ } // SimpleTreeNode
+
+ /**
+ * Parse Value
+ * @param field column
+ * @param in value
+ * @return data type corected value
+ **/
+ private Object parseValue (GridField field, Object in)
+ {
+ if (in == null)
+ return null;
+ int dt = field.getDisplayType();
+ try
+ {
+ // Return Integer
+ if (dt == DisplayType.Integer
+ || (DisplayType.isID(dt) && field.getColumnName().endsWith("_ID")))
+ {
+ if (in instanceof Integer)
+ return in;
+ int i = Integer.parseInt(in.toString());
+ return new Integer(i);
+ }
+ // Return BigDecimal
+ else if (DisplayType.isNumeric(dt))
+ {
+ if (in instanceof BigDecimal)
+ return in;
+ return DisplayType.getNumberFormat(dt).parse(in.toString());
+ }
+ // Return Timestamp
+ else if (DisplayType.isDate(dt))
+ {
+ if (in instanceof Timestamp)
+ return in;
+ long time = 0;
+ try
+ {
+ time = DisplayType.getDateFormat_JDBC().parse(in.toString()).getTime();
+ return new Timestamp(time);
+ }
+ catch (Exception e)
+ {
+ log.log(Level.SEVERE, in + "(" + in.getClass() + ")" + e);
+ time = DisplayType.getDateFormat(dt).parse(in.toString()).getTime();
+ }
+ return new Timestamp(time);
+ }
+ // Return Y/N for Boolean
+ else if (in instanceof Boolean)
+ return ((Boolean)in).booleanValue() ? "Y" : "N";
+ }
+ catch (Exception ex)
+ {
+ log.log(Level.SEVERE, "Object=" + in, ex);
+ String error = ex.getLocalizedMessage();
+ if (error == null || error.length() == 0)
+ error = ex.toString();
+ StringBuffer errMsg = new StringBuffer();
+ errMsg.append(field.getColumnName()).append(" = ").append(in).append(" - ").append(error);
+ //
+ FDialog.error(0, this, "ValidationError", errMsg.toString());
+ return null;
+ }
+
+ return in;
+ } // parseValue
+
+ /**************************************************************************
+ * Get Query - Retrieve result
+ * @return String representation of query
+ */
+ public MQuery getQuery()
+ {
+ MRole role = MRole.getDefault();
+ if (role.isQueryMax(getTotalRecords()) && !m_isCancel)
+ {
+ m_query = MQuery.getNoRecordQuery (m_tableName, false);
+ m_total = 0;
+ log.warning("Query - over max");
+ }
+ else
+ log.info("Query=" + m_query);
+ return m_query;
+ } // getQuery
+
+ /**
+ * Get Total Records
+ * @return no of records
+ **/
+ public int getTotalRecords()
+ {
+ return m_total;
+
+ } // getTotalRecords
+
+ public void valueChange(ValueChangeEvent evt)
+ {
+ if (evt != null && evt.getSource() instanceof WEditor)
+ {
+ WEditor editor = (WEditor)evt.getSource();
+ // Editor component
+ Component component = editor.getComponent();
+
+ ListCell listcell = (ListCell)component.getParent();
+ Label label = new Label(evt.getNewValue().toString());
+ label.setAttribute("value", evt.getNewValue());
+
+ listcell.appendChild(label);
+ listcell.removeChild(component);
+ label.addEventListener(Events.ON_CLICK,this);
+ }
+ }
+
+
+} // FindPanel
\ No newline at end of file
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/LoginWindow.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/LoginWindow.java
new file mode 100644
index 0000000000..ff2597e9ea
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/LoginWindow.java
@@ -0,0 +1,113 @@
+/******************************************************************************
+ * Product: Posterita Ajax UI *
+ * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
+ * or via info@posterita.org or http://www.posterita.org/ *
+ *****************************************************************************/
+
+package org.adempiere.webui.window;
+
+import java.util.Properties;
+
+import org.adempiere.webui.AdempiereWebUI;
+import org.adempiere.webui.component.FWindow;
+import org.adempiere.webui.panel.LoginPanel;
+import org.adempiere.webui.panel.RolePanel;
+import org.compiere.util.Env;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zk.ui.event.Events;
+
+/**
+ *
+ * @author Ashley G Ramdass
+ * @date Feb 25, 2007
+ * @version $Revision: 0.10 $
+ * @author Sendy Yagambrum
+ * @date July 18, 2007
+ */
+public class LoginWindow extends FWindow implements EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private AdempiereWebUI app;
+ private Properties ctx;
+ private LoginPanel pnlLogin;
+ private RolePanel pnlRole;
+
+ public LoginWindow(AdempiereWebUI app)
+ {
+ this.ctx = Env.getCtx();
+ this.app = app;
+ initComponents();
+ init();
+ // add listener on 'ENTER' key for the login window
+ addEventListener(Events.ON_OK,this);
+ }
+
+ private void init()
+ {
+ this.appendChild(pnlLogin);
+ this.setWidth("300px");
+
+ }
+
+ private void initComponents()
+ {
+ pnlLogin = new LoginPanel(ctx, this);
+ }
+
+ public void loginOk(String userName, String password)
+ {
+ pnlRole = new RolePanel(ctx, this, userName, password);
+ this.getChildren().clear();
+ this.appendChild(pnlRole);
+ }
+
+ public void loginCompleted()
+ {
+ app.loginCompleted();
+ }
+
+ public void loginCancelled()
+ {
+ pnlLogin = new LoginPanel(ctx, this);
+ this.getChildren().clear();
+ this.appendChild(pnlLogin);
+ }
+
+ public void onEvent(Event event)
+ {
+ // check that 'ENTER' key is pressed
+ if ("onOK".equals(event.getName()))
+ {
+ /**
+ * LoginWindow can have as a child, either LoginPanel or RolePanel
+ * If LoginPanel is currently a child, validate login when
+ * 'ENTER' key is pressed or validate Roles if RolePanel is
+ * currently a child
+ */
+ RolePanel rolePanel = (RolePanel)this.getFellowIfAny("rolePanel");
+ if (rolePanel != null)
+ {
+ rolePanel.validateRoles();
+ }
+
+ LoginPanel loginPanel = (LoginPanel)this.getFellowIfAny("loginPanel");
+ if (loginPanel != null)
+ {
+ loginPanel.validateLogin();
+ }
+ }
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/WLocationDialog.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/WLocationDialog.java
new file mode 100644
index 0000000000..404b8e567c
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/WLocationDialog.java
@@ -0,0 +1,399 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
+ * or via info@compiere.org or http://www.compiere.org/license.html *
+ *****************************************************************************/
+
+/**
+ * 2007, Modified by Posterita Ltd.
+ */
+
+package org.adempiere.webui.window;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.logging.Level;
+
+import org.adempiere.webui.component.Button;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.ListItem;
+import org.adempiere.webui.component.Listbox;
+import org.adempiere.webui.component.Panel;
+import org.adempiere.webui.component.Textbox;
+import org.adempiere.webui.component.VerticalBox;
+import org.adempiere.webui.component.Window;
+import org.compiere.model.MCountry;
+import org.compiere.model.MLocation;
+import org.compiere.model.MRegion;
+import org.compiere.util.CLogger;
+import org.compiere.util.Env;
+import org.compiere.util.Msg;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zk.ui.event.Events;
+
+/**
+ * @author Sendy Yagambrum
+ * @date July 16, 2007
+ * Location Dialog Box
+ * This class is based upon VLocationDialog, written by Jorg Janke
+ *
+ **/
+public class WLocationDialog extends Window implements EventListener
+{
+
+ private static final long serialVersionUID = 1L;
+ /** Logger */
+ private static CLogger log = CLogger.getCLogger(WLocationDialog.class);
+ private Label lblAddress1;
+ private Label lblAddress2;
+ private Label lblAddress3;
+ private Label lblAddress4;
+ private Label lblCity;
+ private Label lblZip;
+ private Label lblRegion;
+ private Label lblPostal;
+ private Label lblPostalAdd;
+ private Label lblCountry;
+
+ private Textbox txtAddress1;
+ private Textbox txtAddress2;
+ private Textbox txtAddress3;
+ private Textbox txtAddress4;
+ private Textbox txtCity;
+ private Textbox txtPostal;
+ private Textbox txtPostalAdd;
+ private Listbox lstRegion;
+ private Listbox lstCountry;
+
+ private Button btnOk;
+ private Button btnCancel;
+ private VerticalBox mainPanel;
+
+ private boolean m_change = false;
+ private MLocation m_location;
+ private int m_origCountry_ID;
+ private int s_oldCountry_ID = 0;
+
+ public WLocationDialog(String title, MLocation location)
+ {
+ m_location = location;
+ if (m_location == null)
+ m_location = new MLocation (Env.getCtx(), 0, null);
+ // Overwrite title
+ if (m_location.getC_Location_ID() == 0)
+ setTitle(Msg.getMsg(Env.getCtx(), "LocationNew"));
+ else
+ setTitle(Msg.getMsg(Env.getCtx(), "LocationUpdate"));
+
+ initComponents();
+ init();
+// Current Country
+ MCountry.setDisplayLanguage(Env.getAD_Language(Env.getCtx()));
+ for (MCountry country:MCountry.getCountries(Env.getCtx()))
+ {
+ lstCountry.appendItem(country.getName(), country);
+ }
+ setCountry();
+ lstCountry.addEventListener(Events.ON_SELECT,this);
+ m_origCountry_ID = m_location.getC_Country_ID();
+ // Current Region
+ for (MRegion region : MRegion.getRegions(Env.getCtx(), m_origCountry_ID))
+ {
+ lstRegion.appendItem(region.getName(),region);
+ }
+ if (m_location.getCountry().isHasRegion())
+ lblRegion.setValue(m_location.getCountry().getRegionName()); // name for region
+
+ setRegion();
+ initLocation();
+ //
+ this.setWidth("290px");
+ this.setClosable(true);
+ this.setBorder("normal");
+ this.setAttribute("mode","modal");
+ }
+
+ private void initComponents()
+ {
+ lblAddress1 = new Label(Msg.getMsg(Env.getCtx(), "Address")+ " 1");
+ lblAddress2 = new Label(Msg.getMsg(Env.getCtx(), "Address")+ " 2");
+ lblAddress3 = new Label(Msg.getMsg(Env.getCtx(), "Address")+ " 3");
+ lblAddress4 = new Label(Msg.getMsg(Env.getCtx(), "Address")+ " 4");
+ lblCity = new Label(Msg.getMsg(Env.getCtx(), "City"));
+ lblZip = new Label(Msg.getMsg(Env.getCtx(), "Postal"));
+ lblRegion = new Label(Msg.getMsg(Env.getCtx(), "Region"));
+ lblPostal = new Label(Msg.getMsg(Env.getCtx(), "Postal"));
+ lblPostalAdd = new Label(Msg.getMsg(Env.getCtx(), "PostalAdd"));
+ lblCountry = new Label(Msg.getMsg(Env.getCtx(), "Country"));
+
+ txtAddress1 = new Textbox();
+ txtAddress1.setCols(20);
+ txtAddress2 = new Textbox();
+ txtAddress2.setCols(20);
+ txtAddress3 = new Textbox();
+ txtAddress3.setCols(20);
+ txtAddress4 = new Textbox();
+ txtAddress4.setCols(20);
+ txtCity = new Textbox();
+ txtCity.setCols(20);
+ txtPostal = new Textbox();
+ txtPostal.setCols(20);
+ txtPostalAdd = new Textbox();
+ txtPostalAdd.setCols(20);
+
+ lstRegion = new Listbox();
+ lstRegion.setMold("select");
+ lstRegion.setWidth("50px");
+ lstRegion.setRows(0);
+
+ lstCountry = new Listbox();
+ lstCountry.setMold("select");
+ lstCountry.setWidth("154px");
+ lstCountry.setRows(0);
+
+ btnOk = new Button();
+ btnOk.setImage("/images/Ok16.gif");
+ btnOk.addEventListener(Events.ON_CLICK,this);
+ btnCancel = new Button();
+ btnCancel.setImage("/images/Cancel16.gif");
+ btnCancel.addEventListener(Events.ON_CLICK,this);
+
+ mainPanel = new VerticalBox();
+ mainPanel.setStyle("padding:5px");
+ }
+
+ private void init()
+ {
+ Panel pnlAddress1 = new Panel();
+ pnlAddress1.appendChild(lblAddress1);
+ pnlAddress1.appendChild(txtAddress1);
+ pnlAddress1.setAlign("right");
+
+ Panel pnlAddress2 = new Panel();
+ pnlAddress2.appendChild(lblAddress2);
+ pnlAddress2.appendChild(txtAddress2);
+ pnlAddress2.setAlign("right");
+
+ Panel pnlAddress3 = new Panel();
+ pnlAddress3.appendChild(lblAddress3);
+ pnlAddress3.appendChild(txtAddress3);
+ pnlAddress3.setAlign("right");
+
+ Panel pnlAddress4 = new Panel();
+ pnlAddress4.appendChild(lblAddress4);
+ pnlAddress4.appendChild(txtAddress4);
+ pnlAddress4.setAlign("right");
+
+ Panel pnlCity = new Panel();
+ pnlCity.appendChild(lblCity);
+ pnlCity.appendChild(txtCity);
+ pnlCity.setAlign("right");
+
+ Panel pnlPostal = new Panel();
+ pnlPostal.appendChild(lblPostal);
+ pnlPostal.appendChild(txtPostal);
+ pnlPostal.setAlign("right");
+
+ Panel pnlPostalAdd = new Panel();
+ pnlPostalAdd.appendChild(lblPostalAdd);
+ pnlPostalAdd.appendChild(txtPostalAdd);
+
+ Panel pnlRegion = new Panel();
+ pnlRegion.appendChild(lblRegion);
+ pnlRegion.appendChild(lstRegion);
+ pnlRegion.setStyle("text-align:right;padding-right:103px");
+
+ Panel pnlCountry = new Panel();
+ pnlCountry.appendChild(lblCountry);
+ pnlCountry.appendChild(lstCountry);
+ pnlCountry.setAlign("right");
+
+ Panel pnlButton = new Panel();
+ pnlButton.appendChild(btnOk);
+ pnlButton.appendChild(btnCancel);
+ pnlButton.setWidth("100%");
+ pnlButton.setStyle("text-align:right");
+
+ this.appendChild(mainPanel);
+ this.appendChild(pnlButton);
+ }
+ /**
+ * Dynamically add fields to the Location dialog box
+ * @param panel panel to add
+ *
+ */
+ private void addComponents(Panel panel)
+ {
+ mainPanel.appendChild(panel);
+ }
+
+ private void initLocation()
+ {
+ MCountry country = m_location.getCountry();
+ log.fine(country.getName() + ", Region=" + country.isHasRegion() + " " + country.getDisplaySequence()
+ + ", C_Location_ID=" + m_location.getC_Location_ID());
+ // new Region
+ if (m_location.getC_Country_ID() != s_oldCountry_ID && country.isHasRegion())
+ {
+ for (MRegion region : MRegion.getRegions(Env.getCtx(), country.getC_Country_ID()))
+ {
+ lstRegion.appendItem(region.getName(),region);
+ }
+ if (m_location.getRegion() != null)
+ {
+ setRegion();
+ }
+ s_oldCountry_ID = m_location.getC_Country_ID();
+ }
+ addComponents((Panel)lblAddress1.getParent());
+ addComponents((Panel)lblAddress2.getParent());
+ addComponents((Panel)lblAddress3.getParent());
+ addComponents((Panel)lblAddress4.getParent());
+// sequence of City Postal Region - @P@ @C@ - @C@, @R@ @P@
+ String ds = country.getDisplaySequence();
+ if (ds == null || ds.length() == 0)
+ {
+ log.log(Level.SEVERE, "DisplaySequence empty - " + country);
+ ds = ""; // @C@, @P@
+ }
+ StringTokenizer st = new StringTokenizer(ds, "@", false);
+ while (st.hasMoreTokens())
+ {
+ String s = st.nextToken();
+ if (s.startsWith("C"))
+ addComponents((Panel)lblCity.getParent());
+ else if (s.startsWith("P"))
+ addComponents((Panel)lblPostal.getParent());
+ else if (s.startsWith("A"))
+ addComponents((Panel)lblPostalAdd.getParent());
+ else if (s.startsWith("R") && m_location.getCountry().isHasRegion())
+ addComponents((Panel)lblRegion.getParent());
+ }
+ // Country Last
+ addComponents((Panel)lblCountry.getParent());
+
+// Fill it
+ if (m_location.getC_Location_ID() != 0)
+ {
+ txtAddress1.setText(m_location.getAddress1());
+ txtAddress2.setText(m_location.getAddress2());
+ txtAddress3.setText(m_location.getAddress3());
+ txtAddress4.setText(m_location.getAddress4());
+ txtCity.setText(m_location.getCity());
+ txtPostal.setText(m_location.getPostal());
+ txtPostalAdd.setText(m_location.getPostal_Add());
+ if (m_location.getCountry().isHasRegion())
+ {
+ lblRegion.setValue(m_location.getCountry().getRegionName());
+ setRegion();
+ }
+ setCountry();
+ }
+ }
+ private void setCountry()
+ {
+ List listCountry = lstCountry.getChildren();
+ Iterator iter = listCountry.iterator();
+ while (iter.hasNext())
+ {
+ ListItem listitem = (ListItem)iter.next();
+ if (m_location.getCountry().equals(listitem.getValue()))
+ {
+ lstCountry.setSelectedItem(listitem);
+ }
+ }
+ }
+ private void setRegion()
+ {
+ List listState = lstRegion.getChildren();
+ Iterator iter = listState.iterator();
+ while (iter.hasNext())
+ {
+ ListItem listitem = (ListItem)iter.next();
+ if (m_location.getRegion().equals(listitem.getValue()))
+ {
+ lstRegion.setSelectedItem(listitem);
+ }
+ }
+
+ }
+ /**
+ * Get result
+ * @return true, if changed
+ */
+ public boolean isChanged()
+ {
+ return m_change;
+ } // getChange
+ /**
+ * Get edited Value (MLocation)
+ * @return location
+ */
+ public MLocation getValue()
+ {
+ return m_location;
+ }
+
+ public void onEvent(Event event) throws Exception
+ {
+ if (btnOk.equals(event.getTarget()))
+ {
+ action_OK();
+ m_change = true;
+ this.detach();
+ }
+ else if (btnCancel.equals(event.getTarget()))
+ {
+ m_change = false;
+ this.detach();
+ }
+
+ // Country Changed - display in new Format
+ else if (lstCountry.equals(event.getTarget()))
+ {
+ // Modifier for Mouse selection is 16 - for any key selection 0
+ MCountry c = (MCountry)lstCountry.getSelectedItem().getValue();
+ m_location.setCountry(c);
+ // refrseh
+ initLocation();
+ }
+ }
+ /**
+ * OK - check for changes (save them) & Exit
+ */
+ private void action_OK()
+ {
+ m_location.setAddress1(txtAddress1.getValue());
+ m_location.setAddress2(txtAddress2.getValue());
+ m_location.setAddress3(txtAddress3.getValue());
+ m_location.setAddress4(txtAddress4.getValue());
+ m_location.setCity(txtCity.getValue());
+ m_location.setPostal(txtPostal.getValue());
+ // Country/Region
+ MCountry c = (MCountry)lstCountry.getSelectedItem().getValue();
+ m_location.setCountry(c);
+ if (m_location.getCountry().isHasRegion())
+ {
+ MRegion r = (MRegion)lstRegion.getSelectedItem().getValue();
+ m_location.setRegion(r);
+ }
+ else
+ m_location.setC_Region_ID(0);
+ // Save chnages
+ m_location.save();
+
+ } // actionOK
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/WLocatorDialog.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/WLocatorDialog.java
new file mode 100644
index 0000000000..6cff5af3e9
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/WLocatorDialog.java
@@ -0,0 +1,558 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
+ * or via info@compiere.org or http://www.compiere.org/license.html *
+ *****************************************************************************/
+
+/**
+ * 2007, Modified by Posterita Ltd.
+ */
+
+package org.adempiere.webui.window;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.logging.Level;
+
+import org.adempiere.webui.component.Button;
+import org.adempiere.webui.component.Checkbox;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.ListItem;
+import org.adempiere.webui.component.Listbox;
+import org.adempiere.webui.component.Textbox;
+import org.adempiere.webui.component.Window;
+import org.compiere.model.MLocator;
+import org.compiere.model.MLocatorLookup;
+import org.compiere.model.MRole;
+import org.compiere.util.CLogger;
+import org.compiere.util.DB;
+import org.compiere.util.Env;
+import org.compiere.util.KeyNamePair;
+import org.compiere.util.Msg;
+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.Hbox;
+import org.zkoss.zul.Separator;
+import org.zkoss.zul.Vbox;
+
+/**
+ * Location Dialog : Based on VLocationDialog
+ *
+ * @author Niraj Sohun
+ * @date Jul 24, 2007
+ */
+
+public class WLocatorDialog extends Window implements EventListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private Vbox mainBox = new Vbox();
+
+ private Listbox lstLocator = new Listbox();
+ private Listbox lstWarehouse = new Listbox();
+
+ private Checkbox chkCreateNew = new Checkbox();
+
+ private Textbox txtWarehouse = new Textbox();
+ private Textbox txtAisleX = new Textbox();
+ private Textbox txtBinY = new Textbox();
+ private Textbox txtLevelZ = new Textbox();
+ private Textbox txtKey = new Textbox();
+
+ private Label lblLocator = new Label();
+ private Label lblWarehouse = new Label();
+ private Label lblAisleX = new Label();
+ private Label lblBinY = new Label();
+ private Label lblLevelZ = new Label();
+ private Label lblKey = new Label();
+
+ private Button btnCancel = new Button();
+ private Button btnOk = new Button();
+
+ private MLocatorLookup m_mLocator;
+
+ private int m_WindowNo;
+ private int m_M_Locator_ID;
+ private int m_AD_Client_ID;
+ private int m_AD_Org_ID;
+ private int m_only_Warehouse_ID;
+ private int m_M_Warehouse_ID;
+
+ private boolean m_mandatory;
+
+ private String m_M_WarehouseName;
+ private String m_M_WarehouseValue;
+ private String m_Separator;
+
+ private boolean m_change;
+
+ private String title;
+
+ private static CLogger log = CLogger.getCLogger(WLocatorDialog.class);
+
+ /**
+ * Constructor
+ * @param title title
+ * @param mLocator locator
+ * @param M_Locator_ID locator id
+ * @param mandatory mandatory
+ * @param only_Warehouse_ID of not 0 restrict warehouse
+ * @param windowNo
+ */
+
+ public WLocatorDialog ( String title, MLocatorLookup mLocator,
+ int M_Locator_ID, boolean mandatory, int only_Warehouse_ID,
+ int windowNo)
+ {
+ super();
+
+ m_WindowNo = windowNo;
+ this.title = title;
+ initComponents();
+
+ m_mLocator = mLocator;
+ m_M_Locator_ID = M_Locator_ID;
+ m_mandatory = mandatory;
+ m_only_Warehouse_ID = only_Warehouse_ID;
+
+
+ initLocator();
+ } // WLocatorDialog
+
+ private void initComponents()
+ {
+ txtWarehouse.setEnabled(false);
+
+ lblLocator.setValue("Locator");
+ lblWarehouse.setValue("Warehouse");
+ lblAisleX.setValue("Aisle (X)");
+ lblBinY.setValue("Bin (Y)");
+ lblLevelZ.setValue("Level (Z)");
+ lblKey.setValue("Key");
+
+ Hbox boxLocator = new Hbox();
+ boxLocator.setWidth("100%");
+ boxLocator.setWidths("30%, 70%");
+
+ lstLocator.setMold("select");
+ lstLocator.setRows(0);
+
+ boxLocator.appendChild(lblLocator);
+ boxLocator.appendChild(lstLocator);
+
+ Hbox boxCheckbox = new Hbox();
+ boxCheckbox.setWidth("100%");
+ boxCheckbox.setWidths("30%, 70%");
+ boxCheckbox.setStyle("text-align:left");
+
+ chkCreateNew.setLabel(Msg.getMsg(Env.getCtx(), "Create New Record"));
+
+ boxCheckbox.appendChild(new Label());
+ boxCheckbox.appendChild(chkCreateNew);
+
+ Hbox boxWarehouse = new Hbox();
+ boxWarehouse.setWidth("100%");
+ boxWarehouse.setWidths("30%, 70%");
+
+ lstWarehouse.setWidth("100px");
+ lstWarehouse.setMold("select");
+ lstWarehouse.setRows(0);
+
+ boxWarehouse.appendChild(lblWarehouse);
+ boxWarehouse.appendChild(lstWarehouse);
+ boxWarehouse.appendChild(txtWarehouse);
+
+ Hbox boxAisle = new Hbox();
+ boxAisle.setWidth("100%");
+ boxAisle.setWidths("30%, 70%");
+
+ boxAisle.appendChild(lblAisleX);
+ boxAisle.appendChild(txtAisleX);
+
+ Hbox boxBin = new Hbox();
+ boxBin.setWidth("100%");
+ boxBin.setWidths("30%, 70%");
+
+ boxBin.appendChild(lblBinY);
+ boxBin.appendChild(txtBinY);
+
+ Hbox boxLevel = new Hbox();
+ boxLevel.setWidth("100%");
+ boxLevel.setWidths("30%, 70%");
+
+ boxLevel.appendChild(lblLevelZ);
+ boxLevel.appendChild(txtLevelZ);
+
+ Hbox boxKey = new Hbox();
+ boxKey.setWidth("100%");
+ boxKey.setWidths("30%, 70%");
+
+ boxKey.appendChild(lblKey);
+ boxKey.appendChild(txtKey);
+
+ Hbox boxButtons = new Hbox();
+ boxButtons.setWidth("100%");
+ boxButtons.setWidths("80%, 10%, 10%");
+ boxButtons.setStyle("text-align:right");
+
+ btnCancel.setImage("/images/Cancel16.gif");
+ btnCancel.addEventListener(Events.ON_CLICK, this);
+
+ btnOk.setImage("/images/Ok16.gif");
+ btnOk.addEventListener(Events.ON_CLICK, this);
+
+ boxButtons.appendChild(new Label());
+ boxButtons.appendChild(btnCancel);
+ boxButtons.appendChild(btnOk);
+
+ mainBox.setWidth("250px");
+ mainBox.setStyle("text-align:right");
+ mainBox.appendChild(boxLocator);
+ mainBox.appendChild(new Separator());
+ mainBox.appendChild(boxCheckbox);
+ mainBox.appendChild(new Separator());
+ mainBox.appendChild(boxWarehouse);
+ mainBox.appendChild(boxAisle);
+ mainBox.appendChild(boxBin);
+ mainBox.appendChild(boxLevel);
+ mainBox.appendChild(boxKey);
+ mainBox.appendChild(new Separator());
+ mainBox.appendChild(boxButtons);
+
+ this.appendChild(mainBox);
+ this.setTitle(title);
+ this.setClosable(true);
+ this.setBorder("normal");
+ this.setWidth("260Px");
+ this.setAttribute("mode","modal");
+ }
+
+ private void initLocator()
+ {
+ log.fine("");
+
+ // Load Warehouse
+
+ String sql = "SELECT M_Warehouse_ID, Name FROM M_Warehouse";
+
+ if (m_only_Warehouse_ID != 0)
+ sql += " WHERE M_Warehouse_ID=" + m_only_Warehouse_ID;
+
+ String SQL = MRole.getDefault().addAccessSQL(
+ sql, "M_Warehouse", MRole.SQL_NOTQUALIFIED, MRole.SQL_RO)
+ + " ORDER BY 2";
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(SQL, null);
+ ResultSet rs = pstmt.executeQuery();
+
+ while (rs.next())
+ {
+ KeyNamePair key = new KeyNamePair(rs.getInt(1), rs.getString(2));
+ lstWarehouse.appendItem(key.getName(), key);
+ }
+
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, SQL, e);
+ }
+
+ log.fine("Warehouses=" + lstWarehouse.getItemCount());
+
+ // Load existing Locators
+
+ m_mLocator.fillComboBox(m_mandatory, true, true, false);
+
+ log.fine(m_mLocator.toString());
+
+ for (int i = 0; i < m_mLocator.getSize(); i++)
+ {
+ Object obj = m_mLocator.getElementAt(i);
+
+ lstLocator.appendItem(obj.toString(), obj);
+ }
+
+ //lstLocator.setModel(m_mLocator);
+ //lstLocator.setValue(m_M_Locator_ID);
+ lstLocator.setSelectedIndex(0);
+ lstLocator.addEventListener(Events.ON_SELECT, this);
+
+ displayLocator();
+
+ chkCreateNew.setChecked(false);
+ chkCreateNew.addEventListener(Events.ON_CHECK, this);
+
+ enableNew();
+
+ lstWarehouse.addEventListener(Events.ON_SELECT, this);
+
+ txtAisleX.addEventListener(Events.ON_CHANGE, this);
+ txtBinY.addEventListener(Events.ON_CHANGE, this);
+ txtLevelZ.addEventListener(Events.ON_CHANGE, this);
+
+ // Update UI
+
+ //pack();
+
+ } // initLocator
+
+ private void displayLocator()
+ {
+ MLocator l = null;
+ ListItem listitem = lstLocator.getSelectedItem();
+
+ if (listitem != null)
+ l = (MLocator) listitem.getValue();
+
+ if (l == null)
+ return;
+
+ m_M_Locator_ID = l.getM_Locator_ID();
+
+ txtWarehouse.setText(l.getWarehouseName());
+ txtAisleX.setText(l.getX());
+ txtBinY.setText(l.getY());
+ txtLevelZ.setText(l.getZ());
+ txtKey.setText(l.getValue());
+
+ getWarehouseInfo(l.getM_Warehouse_ID());
+
+ // Set Warehouse
+
+ int size = lstWarehouse.getItemCount();
+
+ for (int i = 0; i < size; i++)
+ {
+ ListItem listItem = lstWarehouse.getItemAtIndex(i);
+ KeyNamePair pp = (KeyNamePair)listItem.getValue();
+
+ if (pp.getKey() == l.getM_Warehouse_ID())
+ {
+ lstWarehouse.setSelectedIndex(i);
+ continue;
+ }
+ }
+ } // displayLocator
+
+ /**
+ * Enable/disable New data entry
+ */
+
+ private void enableNew()
+ {
+ boolean sel = chkCreateNew.isChecked();
+ //lblWarehouse.setVisible(sel);
+ lstWarehouse.setVisible(sel);
+ //lWarehouseInfo.setVisible(!sel);
+ txtWarehouse.setVisible(!sel);
+
+ txtAisleX.setReadonly(!sel);
+ txtBinY.setReadonly(!sel);
+ txtLevelZ.setReadonly(!sel);
+ txtKey.setReadonly(!sel);
+
+ //pack();
+ } // enableNew
+
+ /**
+ * Get Warehouse Info
+ * @param M_Warehouse_ID warehouse
+ */
+ private void getWarehouseInfo (int M_Warehouse_ID)
+ {
+ if (M_Warehouse_ID == m_M_Warehouse_ID)
+ return;
+
+ // Defaults
+
+ m_M_Warehouse_ID = 0;
+ m_M_WarehouseName = "";
+ m_M_WarehouseValue = "";
+ m_Separator = ".";
+ m_AD_Client_ID = 0;
+ m_AD_Org_ID = 0;
+
+ String SQL = "SELECT M_Warehouse_ID, Value, Name, Separator, AD_Client_ID, AD_Org_ID "
+ + "FROM M_Warehouse WHERE M_Warehouse_ID=?";
+
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(SQL, null);
+ pstmt.setInt(1, M_Warehouse_ID);
+ ResultSet rs = pstmt.executeQuery();
+
+ if (rs.next())
+ {
+ m_M_Warehouse_ID = rs.getInt(1);
+ m_M_WarehouseValue = rs.getString(2);
+ m_M_WarehouseName = rs.getString(3);
+ m_Separator = rs.getString(4);
+ m_AD_Client_ID = rs.getInt(5);
+ m_AD_Org_ID = rs.getInt(6);
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, SQL, e);
+ }
+ } // getWarehouseInfo
+
+ /**
+ * Create Locator-Value
+ */
+
+ private void createValue()
+ {
+ // Get Warehouse Info
+
+ ListItem listitem = lstWarehouse.getSelectedItem();
+ KeyNamePair pp = (KeyNamePair)listitem.getValue();
+
+ if (pp == null)
+ return;
+
+ getWarehouseInfo(pp.getKey());
+
+ StringBuffer buf = new StringBuffer(m_M_WarehouseValue);
+ buf.append(m_Separator).append(txtAisleX.getText());
+ buf.append(m_Separator).append(txtBinY.getText());
+ buf.append(m_Separator).append(txtLevelZ.getText());
+
+ txtKey.setText(buf.toString());
+ } // createValue
+
+ /**
+ * OK - check for changes (save them) & Exit
+ */
+
+ private void actionOK()
+ {
+ if (chkCreateNew.isChecked())
+ {
+ // Get Warehouse Info
+
+ ListItem listitem = lstWarehouse.getSelectedItem();
+ KeyNamePair pp = (KeyNamePair)listitem.getValue();
+
+ if (pp != null)
+ getWarehouseInfo(pp.getKey());
+
+ // Check mandatory values
+
+ String mandatoryFields = "";
+
+ if (m_M_Warehouse_ID == 0)
+ mandatoryFields += lblWarehouse.getValue() + " - ";
+
+ if (txtKey.getText().length()==0)
+ mandatoryFields += lblKey.getValue() + " - ";
+
+ if (txtAisleX.getText().length()==0)
+ mandatoryFields += lblAisleX.getValue() + " - ";
+
+ if (txtBinY.getText().length()==0)
+ mandatoryFields += lblBinY.getValue() + " - ";
+
+ if (txtLevelZ.getText().length()==0)
+ mandatoryFields += lblLevelZ.getValue() + " - ";
+
+ if (mandatoryFields.length() != 0)
+ {
+ FDialog.error(m_WindowNo, this, "FillMandatory", mandatoryFields.substring(0, mandatoryFields.length()-3));
+ return;
+ }
+
+ MLocator loc = MLocator.get(Env.getCtx(), m_M_Warehouse_ID, txtKey.getText(),
+ txtAisleX.getText(), txtBinY.getText(), txtLevelZ.getText());
+
+ m_M_Locator_ID = loc.getM_Locator_ID();
+
+ listitem = new ListItem();
+ listitem.setValue(loc);
+
+ lstLocator.appendItem(loc.get_TableName(), loc);
+ lstLocator.setSelectedIndex(lstLocator.getItemCount() - 1);
+ } // createNew
+
+ log.config("M_Locator_ID=" + m_M_Locator_ID);
+ } // actionOK
+
+ /**
+ * Get Selected value
+ * @return value as Integer
+ */
+
+ public Integer getValue()
+ {
+ ListItem listitem = lstLocator.getSelectedItem();
+ MLocator l = (MLocator) listitem.getValue();
+
+ if (l != null && l.getM_Locator_ID() != 0)
+ return new Integer (l.getM_Locator_ID());
+
+ return null;
+ } // getValue
+
+ /**
+ * Get result
+ * @return true if changed
+ */
+
+ public boolean isChanged()
+ {
+ if (m_change)
+ {
+ ListItem listitem = lstLocator.getSelectedItem();
+ MLocator l = (MLocator)listitem.getValue();
+
+ if (l != null)
+ return l.getM_Locator_ID() == m_M_Locator_ID;
+ }
+ return m_change;
+ } // getChange
+
+
+ public void onEvent(Event event) throws Exception
+ {
+ if (event == null)
+ return;
+
+ if (event.getTarget() == btnCancel)
+ {
+ m_change = false;
+ this.detach();
+ }
+ else if (event.getTarget() == btnOk)
+ {
+ actionOK();
+ m_change = true;
+ this.detach();
+ }
+ else if (event.getTarget() == lstLocator)
+ displayLocator();
+ else if (event.getTarget() == chkCreateNew)
+ enableNew();
+ // Entered/Changed data for Value
+ else if (chkCreateNew.isChecked() && event.getTarget() == lstWarehouse)
+ createValue();
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java
new file mode 100644
index 0000000000..a53f6655ef
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java
@@ -0,0 +1,64 @@
+package org.adempiere.webui.window;
+
+import net.sf.jasperreports.engine.JRException;
+import net.sf.jasperreports.engine.JasperExportManager;
+import net.sf.jasperreports.engine.JasperPrint;
+
+import org.adempiere.webui.component.Grid;
+import org.adempiere.webui.component.Row;
+import org.adempiere.webui.component.Rows;
+import org.adempiere.webui.component.Window;
+import org.adempiere.webui.session.SessionManager;
+import org.zkoss.util.media.AMedia;
+import org.zkoss.zul.Iframe;
+import org.zkoss.zul.Toolbar;
+import org.zkoss.zul.Toolbarbutton;
+
+public class ZkJRViewer extends Window {
+
+ private JasperPrint jasperPrint;
+
+ public ZkJRViewer(JasperPrint jasperPrint, String title) {
+ this.setTitle(title);
+ this.jasperPrint = jasperPrint;
+ init();
+ }
+
+ private void init() {
+ Grid grid = new Grid();
+ grid.setWidth("100%");
+ Rows rows = new Rows();
+ Row row = new Row();
+ Toolbar toolbar = new Toolbar();
+ toolbar.setHeight("26px");
+ Toolbarbutton button = new Toolbarbutton();
+ button.setImage("/images/Print24.gif");
+ button.setTooltip("Print");
+ toolbar.appendChild(button);
+ row.appendChild(toolbar);
+ rows.appendChild(row);
+
+ row = new Row();
+ Iframe iframe = new Iframe();
+ iframe.setId("reportFrame");
+ int height = Double.valueOf(SessionManager.getAppDesktop().getClientInfo().desktopHeight * 0.85).intValue();
+ height = height - 30;
+ iframe.setHeight(height + "px");
+ iframe.setWidth("100%");
+ byte[] data = null;
+ try {
+ data = JasperExportManager.exportReportToPdf(jasperPrint);
+ } catch (JRException e) {
+ e.printStackTrace();
+ }
+ AMedia media = new AMedia(getTitle(), "pdf", "application/pdf", data);
+ iframe.setContent(media);
+ row.appendChild(iframe);
+ rows.appendChild(row);
+
+ grid.appendChild(rows);
+ this.appendChild(grid);
+
+ this.setBorder("normal");
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/ZkJRViewerProvider.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/ZkJRViewerProvider.java
new file mode 100644
index 0000000000..bdb514b8cf
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/ZkJRViewerProvider.java
@@ -0,0 +1,21 @@
+package org.adempiere.webui.window;
+
+import net.sf.jasperreports.engine.JRException;
+import net.sf.jasperreports.engine.JasperPrint;
+
+import org.adempiere.webui.apps.AEnv;
+import org.adempiere.webui.component.Window;
+import org.compiere.report.JRViewerProvider;
+
+public class ZkJRViewerProvider implements JRViewerProvider {
+
+ public void openViewer(JasperPrint jasperPrint, String title)
+ throws JRException {
+ Window viewer = new ZkJRViewer(jasperPrint, title);
+ viewer.setAttribute("mode", "modal");
+ viewer.setClosable(true);
+ viewer.setWidth("95%");
+ AEnv.showWindow(viewer);
+ }
+
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/ZkReportViewer.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/ZkReportViewer.java
new file mode 100644
index 0000000000..7f1e9a46d3
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/ZkReportViewer.java
@@ -0,0 +1,76 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 2007 Adempiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ *
+ * Copyright (C) 2007 Low Heng Sin hengsin@avantz.com
+ * _____________________________________________
+ *****************************************************************************/
+package org.adempiere.webui.window;
+
+import org.adempiere.webui.component.Grid;
+import org.adempiere.webui.component.Row;
+import org.adempiere.webui.component.Rows;
+import org.adempiere.webui.component.Window;
+import org.adempiere.webui.session.SessionManager;
+import org.compiere.print.ReportEngine;
+import org.zkoss.util.media.AMedia;
+import org.zkoss.zul.Iframe;
+import org.zkoss.zul.Toolbar;
+import org.zkoss.zul.Toolbarbutton;
+
+
+/**
+ *
+ * @author Low Heng Sin
+ *
+ */public class ZkReportViewer extends Window {
+
+ private ReportEngine report;
+
+ public ZkReportViewer(ReportEngine re, String title) {
+ this.report = re;
+ this.setTitle(title);
+ init();
+ }
+
+ private void init() {
+ Grid grid = new Grid();
+ grid.setWidth("100%");
+ Rows rows = new Rows();
+ Row row = new Row();
+ Toolbar toolbar = new Toolbar();
+ toolbar.setHeight("26px");
+ Toolbarbutton button = new Toolbarbutton();
+ button.setImage("/images/Print24.gif");
+ button.setTooltip("Print");
+ toolbar.appendChild(button);
+ row.appendChild(toolbar);
+ rows.appendChild(row);
+
+ row = new Row();
+ Iframe iframe = new Iframe();
+ iframe.setId("reportFrame");
+ int height = Double.valueOf(SessionManager.getAppDesktop().getClientInfo().desktopHeight * 0.85).intValue();
+ height = height - 30;
+ iframe.setHeight(height + "px");
+ iframe.setWidth("100%");
+ AMedia media = new AMedia(getTitle(), "pdf", "application/pdf", report.createPDFData());
+ iframe.setContent(media);
+ row.appendChild(iframe);
+ rows.appendChild(row);
+
+ grid.appendChild(rows);
+ this.appendChild(grid);
+
+ this.setBorder("normal");
+ }
+}
diff --git a/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/ZkReportViewerProvider.java b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/ZkReportViewerProvider.java
new file mode 100644
index 0000000000..3640a97745
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/adempiere/webui/window/ZkReportViewerProvider.java
@@ -0,0 +1,38 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 2007 Adempiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ *
+ * Copyright (C) 2007 Low Heng Sin hengsin@avantz.com
+ * _____________________________________________
+ *****************************************************************************/
+package org.adempiere.webui.window;
+
+import org.adempiere.webui.apps.AEnv;
+import org.adempiere.webui.component.Window;
+import org.compiere.print.ReportEngine;
+import org.compiere.print.ReportViewerProvider;
+
+/**
+ *
+ * @author Low Heng Sin
+ *
+ */
+public class ZkReportViewerProvider implements ReportViewerProvider {
+
+ public void openViewer(ReportEngine report) {
+ Window viewer = new ZkReportViewer(report, report.getName());
+ viewer.setAttribute("mode", "overlapped");
+ viewer.setClosable(true);
+ viewer.setWidth("95%");
+ AEnv.showWindow(viewer);
+ }
+}
\ No newline at end of file
diff --git a/extend/posterita/webui/WEB-INF/src/org/compiere/model/CalloutEngine.java b/extend/posterita/webui/WEB-INF/src/org/compiere/model/CalloutEngine.java
new file mode 100644
index 0000000000..f08af4ee82
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/compiere/model/CalloutEngine.java
@@ -0,0 +1,252 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
+ * or via info@compiere.org or http://www.compiere.org/license.html *
+ *****************************************************************************/
+package org.compiere.model;
+
+import java.lang.reflect.*;
+import java.math.*;
+import java.sql.*;
+import java.util.*;
+import java.util.logging.*;
+import org.compiere.util.*;
+
+/**
+ * Callout Emgine.
+ *
+ * @author Jorg Janke
+ * @version $Id: CalloutEngine.java,v 1.3 2006/07/30 00:51:05 jjanke Exp $
+ */
+public class CalloutEngine implements Callout
+{
+ /**
+ * Constructor
+ */
+ public CalloutEngine()
+ {
+ super();
+ }
+
+ /** Logger */
+ protected CLogger log = CLogger.getCLogger(getClass());
+
+ /**
+ * Start Callout.
+ *
+ * Callout's are used for cross field validation and setting values in other fields
+ * when returning a non empty (error message) string, an exception is raised
+ *
+ * When invoked, the Tab model has the new value!
+ *
+ * @param ctx Context
+ * @param methodName Method name
+ * @param WindowNo current Window No
+ * @param mTab Model Tab
+ * @param mField Model Field
+ * @param value The new value
+ * @param oldValue The old value
+ * @return Error message or ""
+ */
+ public String start (Properties ctx, String methodName, int WindowNo,
+ GridTab mTab, GridField mField, Object value, Object oldValue)
+ {
+ if (methodName == null || methodName.length() == 0)
+ throw new IllegalArgumentException ("No Method Name");
+ //
+ String retValue = "";
+ StringBuffer msg = new StringBuffer(methodName).append(" - ")
+ .append(mField.getColumnName())
+ .append("=").append(value)
+ .append(" (old=").append(oldValue)
+ .append(") {active=").append(isCalloutActive()).append("}");
+ if (!isCalloutActive())
+ log.info (msg.toString());
+
+ // Find Method
+ Method method = getMethod(methodName);
+ if (method == null)
+ throw new IllegalArgumentException ("Method not found: " + methodName);
+ int argLength = method.getParameterTypes().length;
+ if (!(argLength == 5 || argLength == 6))
+ throw new IllegalArgumentException ("Method " + methodName
+ + " has invalid no of arguments: " + argLength);
+
+ // Call Method
+ try
+ {
+ Object[] args = null;
+ if (argLength == 6)
+ args = new Object[] {ctx, new Integer(WindowNo), mTab, mField, value, oldValue};
+ else
+ args = new Object[] {ctx, new Integer(WindowNo), mTab, mField, value};
+ retValue = (String)method.invoke(this, args);
+ }
+ catch (Exception e)
+ {
+ setCalloutActive(false);
+ Throwable ex = e.getCause(); // InvocationTargetException
+ if (ex == null)
+ ex = e;
+ log.log(Level.SEVERE, "start: " + methodName, ex);
+ ex.printStackTrace(System.err);
+ retValue = ex.getLocalizedMessage();
+ }
+ return retValue;
+ } // start
+
+ /**
+ * Conversion Rules.
+ * Convert a String
+ *
+ * @param methodName method name
+ * @param value the value
+ * @return converted String or Null if no method found
+ */
+ public String convert (String methodName, String value)
+ {
+ if (methodName == null || methodName.length() == 0)
+ throw new IllegalArgumentException ("No Method Name");
+ //
+ String retValue = null;
+ StringBuffer msg = new StringBuffer(methodName).append(" - ").append(value);
+ log.info (msg.toString());
+ //
+ // Find Method
+ Method method = getMethod(methodName);
+ if (method == null)
+ throw new IllegalArgumentException ("Method not found: " + methodName);
+ int argLength = method.getParameterTypes().length;
+ if (argLength != 1)
+ throw new IllegalArgumentException ("Method " + methodName
+ + " has invalid no of arguments: " + argLength);
+
+ // Call Method
+ try
+ {
+ Object[] args = new Object[] {value};
+ retValue = (String)method.invoke(this, args);
+ }
+ catch (Exception e)
+ {
+ setCalloutActive(false);
+ log.log(Level.SEVERE, "convert: " + methodName, e);
+ e.printStackTrace(System.err);
+ }
+ return retValue;
+ } // convert
+
+ /**
+ * Get Method
+ * @param methodName method name
+ * @return method or null
+ */
+ private Method getMethod (String methodName)
+ {
+ Method[] allMethods = getClass().getMethods();
+ for (int i = 0; i < allMethods.length; i++)
+ {
+ if (methodName.equals(allMethods[i].getName()))
+ return allMethods[i];
+ }
+ return null;
+ } // getMethod
+
+ /*************************************************************************/
+
+// private static boolean s_calloutActive = false; // Commented by Ashley
+ private static final String CALLOUT_CTX_KEY = "CalloutActive";
+
+ /**
+ * Is Callout Active
+ * Modification: Retrieves whether callout is (in)active from
+ * context rather that simple static boolean variable
+ * @return true if active
+ */
+ protected static boolean isCalloutActive()
+ {
+// return s_calloutActive;
+ String value = Env.getContext(Env.getCtx(), CALLOUT_CTX_KEY);
+ return "Y".equals(value);
+ } // isCalloutActive
+
+ /**
+ * Set Callout (in)active
+ * Modification: Change the active management from simple static boolean
+ * to context integration because in the webui concurrent
+ * environment, multiple users won't be able to invoke
+ * callout concurrently.
+ * @author ashley
+ * @param active active
+ */
+ protected static void setCalloutActive (boolean active)
+ {
+// s_calloutActive = active;
+ Env.setContext(Env.getCtx(), CALLOUT_CTX_KEY, active);
+ } // setCalloutActive
+
+ /**
+ * Set Account Date Value.
+ * org.compiere.model.CalloutEngine.dateAcct
+ * @param ctx context
+ * @param WindowNo window no
+ * @param mTab tab
+ * @param mField field
+ * @param value value
+ * @return null or error message
+ */
+ public String dateAcct (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value)
+ {
+ if (isCalloutActive()) // assuming it is resetting value
+ return "";
+ // setCalloutActive(true);
+ if (value == null || !(value instanceof Timestamp))
+ return "";
+ mTab.setValue("DateAcct", value);
+ // setCalloutActive(false);
+ return "";
+ } // dateAcct
+
+ /**
+ * Rate - set Multiply Rate from Divide Rate and vice versa
+ * org.compiere.model.CalloutEngine.rate
+ * @param ctx context
+ * @param WindowNo window no
+ * @param mTab tab
+ * @param mField field
+ * @param value value
+ * @return null or error message
+ */
+ public String rate (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value)
+ {
+ if (isCalloutActive() || value == null) // assuming it is Conversion_Rate
+ return "";
+ setCalloutActive(true);
+
+ BigDecimal rate1 = (BigDecimal)value;
+ BigDecimal rate2 = Env.ZERO;
+ BigDecimal one = new BigDecimal(1.0);
+
+ if (rate1.doubleValue() != 0.0) // no divide by zero
+ rate2 = one.divide(rate1, 12, BigDecimal.ROUND_HALF_UP);
+ //
+ if (mField.getColumnName().equals("MultiplyRate"))
+ mTab.setValue("DivideRate", rate2);
+ else
+ mTab.setValue("MultiplyRate", rate2);
+ log.info(mField.getColumnName() + "=" + rate1 + " => " + rate2);
+ setCalloutActive(false);
+ return "";
+ } // rate
+} // CalloutEngine
diff --git a/extend/posterita/webui/WEB-INF/src/org/zkoss/zk/ui/Executions.java b/extend/posterita/webui/WEB-INF/src/org/zkoss/zk/ui/Executions.java
new file mode 100644
index 0000000000..e49f8cf496
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/zkoss/zk/ui/Executions.java
@@ -0,0 +1,558 @@
+/* Executions.java
+
+{{IS_NOTE
+ Purpose:
+
+ Description:
+
+ History:
+ Fri Jun 3 17:55:08 2005, Created by tomyeh
+}}IS_NOTE
+
+Copyright (C) 2005 Potix Corporation. All Rights Reserved.
+
+{{IS_RIGHT
+ This program is distributed under GPL Version 2.0 in the hope that
+ it will be useful, but WITHOUT ANY WARRANTY.
+}}IS_RIGHT
+*/
+package org.zkoss.zk.ui;
+
+import java.util.Map;
+import java.io.Reader;
+import java.io.Writer;
+import java.io.IOException;
+
+import org.zkoss.idom.Document;
+import org.zkoss.zk.ui.metainfo.PageDefinition;
+import org.zkoss.zk.ui.metainfo.LanguageDefinition;
+import org.zkoss.zk.xel.Evaluator;
+import org.zkoss.zk.ui.sys.UiEngine;
+import org.zkoss.zk.ui.sys.WebAppCtrl;
+import org.zkoss.zk.ui.sys.DesktopCtrl;
+import org.zkoss.zk.ui.sys.ServerPush;
+
+/**
+ * Utilities to access {@link Execution}.
+ *
+ * @author tomyeh
+ */
+public class Executions {
+ /** Stores the current {@link Execution}. */
+ protected static final InheritableThreadLocal _exec = new InheritableThreadLocal();
+
+ /** Returns the current execution.
+ */
+ public static final Execution getCurrent() {
+ return (Execution)_exec.get();
+ }
+
+ /** Returns the evaluator of the current execution.
+ * It is usually used to parse the expression into {@link org.zkoss.xel.Expression}
+ * or used with {@link org.zkoss.zk.xel.ExValue}.
+ * for performance improvement.
+ *
+ * @param page the page that this evaluator is associated.
+ * If null, the current page and then the first page is assumed.
+ * @param expfcls the implementation of {@link org.zkoss.xel.ExpressionFactory},
+ * or null to use the default ({@link org.zkoss.zk.ui.util.Configuration#getExpressionFactoryClass}.
+ * @since 3.0.0
+ */
+ public static final Evaluator getEvaluator(Page page, Class expfcls) {
+ return getCurrent().getEvaluator(page, expfcls);
+ }
+ /** Returns the evaluator of the current execution.
+ * It is a shortcut of getEvaluator(comp != null ? comp.getPage(): null)
+ *
+ * @param comp the component to retrieve the page for the evaluator
+ * @param expfcls the implementation of {@link org.zkoss.xel.ExpressionFactory},
+ * or null to use the default ({@link org.zkoss.zk.ui.util.Configuration#getExpressionFactoryClass}.
+ * @since 3.0.0
+ */
+ public static final Evaluator getEvaluator(Component comp, Class expfcls) {
+ return getCurrent().getEvaluator(comp, expfcls);
+ }
+
+ /** Evluates the specified expression by use of the current context
+ * ({@link #getCurrent}).
+ *
+ *
The function mapper is retrieved from component's page's function
+ * mapper ({@link Page#getFunctionMapper}).
+ * If null, the current page, if any, is used to retrieve
+ * the mapper.
+ *
+ *
For better performance, you can use the instance returned by
+ *{@link #getEvaluator} to parse and cached the parsed expression.
+ * {@link org.zkoss.zk.xel.ExValue} is a utility class to simply
+ * the task.
+ *
+ * @param comp as the self variable (ignored if null)
+ */
+ public static final Object evaluate(Component comp,
+ String expr, Class expectedType) {
+ return getCurrent().evaluate(comp, expr, expectedType);
+ }
+ /** Evluates the specified expression with the resolver of the current
+ * execution ({@link #getCurrent}).
+ *
+ *
The function mapper is retrieved from page's function
+ * mapper ({@link Page#getFunctionMapper}).
+ * If null, the current page, if any, is used to retrieve
+ * the mapper.
+ *
+ *
For better performance, you can use the instance returned by
+ *{@link #getEvaluator} to parse and cached the parsed expression.
+ * {@link org.zkoss.zk.xel.ExValue} is a utility class to simply
+ * the task.
+ *
+ * @param page used as the self variable and to retrieve the function
+ * mapper if funmap is not defined. Ignored if null.
+ */
+ public static final Object evaluate(Page page,
+ String expr, Class expectedType) {
+ return getCurrent().evaluate(page, expr, expectedType);
+ }
+
+ /** Encodes an URL.
+ *
+ *
It resolves "*" contained in URI, if any, to the proper Locale,
+ * and the browser code.
+ * Refer to {@link org.zkoss.web.servlet.Servlets#locate(ServletContext, ServletRequest, String, Locator)}
+ * for details.
+ */
+ public static final String encodeURL(String uri) {
+ return getCurrent().encodeURL(uri);
+ }
+
+ /** Creates components from a page file specified by an URI.
+ * Shortcut to {@link Execution#createComponents(String, Component, Map)}.
+ *
+ * @param parent the parent component, or null if you want it to be
+ * a root component. If parent is null, the page is assumed to be
+ * the current page, which is determined by the execution context.
+ * @param arg a map of parameters that is accessible by the arg variable
+ * in EL, or by {@link Execution#getArg}.
+ * Ignored if null.
+ * @see #createComponents(PageDefinition, Component, Map)
+ */
+ public static final Component createComponents(
+ String uri, Component parent, Map arg) {
+ return getCurrent().createComponents(uri, parent, arg);
+ }
+ /** Creates components based on the specified page definition.
+ * Shortcut to {@link Execution#createComponents(PageDefinition, Component, Map)}.
+ *
+ * @param pagedef the page definition to use. It cannot be null.
+ * @param parent the parent component, or null if you want it to be
+ * a root component. If parent is null, the page is assumed to be
+ * the current page, which is determined by the execution context.
+ * @param arg a map of parameters that is accessible by the arg variable
+ * in EL, or by {@link Execution#getArg}.
+ * Ignored if null.
+ * @return the first component being created.
+ * @see #createComponents(String, Component, Map)
+ */
+ public static final Component createComponents(PageDefinition pagedef,
+ Component parent, Map arg) {
+ return getCurrent().createComponents(pagedef, parent, arg);
+ }
+
+ /** Creates components from the raw content specified by a string.
+ * Shortcut to {@link Execution#createComponentsDirectly(String, String, Component, Map)}.
+ *
+ * @param content the raw content of the page. It must be a XML and
+ * compliant to the page format (such as ZUL).
+ * @param extension the default extension if the content doesn't specify
+ * an language. In other words, if
+ * the content doesn't specify an language, {@link LanguageDefinition#getByExtension}
+ * is called.
+ * If extension is null and the content doesn't specify a language,
+ * the language called "xul/html" is assumed.
+ * @param parent the parent component, or null if you want it to be
+ * a root component. If parent is null, the page is assumed to be
+ * the current page, which is determined by the execution context.
+ * @param arg a map of parameters that is accessible by the arg variable
+ * in EL, or by {@link Execution#getArg}.
+ * Ignored if null.
+ * @see #createComponents(PageDefinition, Component, Map)
+ * @see #createComponents(String, Component, Map)
+ * @see #createComponentsDirectly(Document, String, Component, Map)
+ * @see #createComponentsDirectly(Reader, String, Component, Map)
+ */
+ public static final Component createComponentsDirectly(String content,
+ String extension, Component parent, Map arg) {
+ return getCurrent().createComponentsDirectly(content, extension, parent, arg);
+ }
+ /** Creates components from the raw content specified by a DOM tree.
+ * Shortcut to {@link Execution#createComponentsDirectly(Document, String, Component, Map)}.
+ *
+ * @param content the raw content in DOM.
+ * @param extension the default extension if the content doesn't specify
+ * an language. In other words, if
+ * the content doesn't specify an language, {@link LanguageDefinition#getByExtension}
+ * is called.
+ * If extension is null and the content doesn't specify a language,
+ * the language called "xul/html" is assumed.
+ * @param parent the parent component, or null if you want it to be
+ * a root component. If parent is null, the page is assumed to be
+ * the current page, which is determined by the execution context.
+ * @param arg a map of parameters that is accessible by the arg variable
+ * in EL, or by {@link Execution#getArg}.
+ * Ignored if null.
+ * @see #createComponents(PageDefinition, Component, Map)
+ * @see #createComponents(String, Component, Map)
+ * @see #createComponentsDirectly(String, String, Component, Map)
+ * @see #createComponentsDirectly(Reader, String, Component, Map)
+ */
+ public static final Component createComponentsDirectly(Document content,
+ String extension, Component parent, Map arg) {
+ return getCurrent().createComponentsDirectly(content, extension, parent, arg);
+ }
+ /** Creates components from the raw content read from the specified reader.
+ * Shortcut to {@link Execution#createComponentsDirectly(Reader, String, Component, Map)}.
+ *
+ *
The raw content is loader and parsed to a page defintion by use of
+ * {@link Execution#getPageDefinitionDirectly(Reader, String)}, and then
+ * invokes {@link #createComponents(PageDefinition,Component,Map)}
+ * to create components.
+ *
+ * @param reader the reader to retrieve the raw content.
+ * @param extension the default extension if the content doesn't specify
+ * an language. In other words, if
+ * the content doesn't specify an language, {@link LanguageDefinition#getByExtension}
+ * is called.
+ * If extension is null and the content doesn't specify a language,
+ * the language called "xul/html" is assumed.
+ * @param parent the parent component, or null if you want it to be
+ * a root component. If parent is null, the page is assumed to be
+ * the current page, which is determined by the execution context.
+ * @param arg a map of parameters that is accessible by the arg variable
+ * in EL, or by {@link Execution#getArg}.
+ * Ignored if null.
+ * @see #createComponents(PageDefinition, Component, Map)
+ * @see #createComponents(String, Component, Map)
+ * @see #createComponentsDirectly(Document, String, Component, Map)
+ * @see #createComponentsDirectly(String, String, Component, Map)
+ */
+ public static Component createComponentsDirectly(Reader reader,
+ String extension, Component parent, Map arg)
+ throws IOException {
+ return getCurrent().createComponentsDirectly(reader, extension, parent, arg);
+ }
+
+ /** Sends a temporary redirect response to the client using the specified
+ * redirect location URL by use of the current execution,
+ * {@link #getCurrent}.
+ *
+ *
After calling this method, the caller shall end the processing
+ * immediately (by returning). All pending requests and events will
+ * be dropped.
+ *
+ * @param uri the URI to redirect to, or null to reload the same page
+ * @see Execution#sendRedirect
+ */
+ public static void sendRedirect(String uri) {
+ getCurrent().sendRedirect(uri);
+ }
+
+ /** A shortcut of Executions.getCurrent().include(page).
+ *
+ * @see Execution#include(Writer,String,Map,int)
+ * @see Execution#include(String)
+ */
+ public static void include(String page)
+ throws IOException {
+ getCurrent().include(page);
+ }
+ /** A shortcut of Executions.getCurrent().forward(page).
+ *
+ * @see Execution#forward(Writer,String,Map,int)
+ * @see Execution#forward(String)
+ */
+ public static void forward(String page)
+ throws IOException {
+ getCurrent().forward(page);
+ }
+
+ //-- wait/notify --//
+ /** Suspends the current processing of an event and wait until the
+ * other thread invokes {@link #notify(Object)}, {@link #notifyAll(Object)},
+ * {@link #notify(Desktop, Object)} or {@link #notifyAll(Desktop, Object)}
+ * for the specified object.
+ *
+ *
It can only be called when the current thread is processing an event.
+ * And, when called, the current processing is suspended and ZK continues
+ * to process the next event and finally render the result.
+ *
+ *
It is typical use to implement a modal dialog where it won't return
+ * until the modal dialog ends.
+ *
+ * @param mutex any non-null object to identify what to notify.
+ * It must be same object passed to {@link #notify(Desktop, Object)}.
+ * If there is racing issue, you have to enclose it with
+ * synchronized
(though it is optional).
+ * @exception UiException if it is called not during event processing.
+ * @exception SuspendNotAllowedException if there are too many suspended
+ * exceptions.
+ * Deployers can control the maximal allowed number of suspended exceptions
+ * by specifying max-suspended-thread
in zk.xml
,
+ * or invoking {@link org.zkoss.zk.ui.util.Configuration#setMaxSuspendedThreads}.
+ */
+ public static final void wait(Object mutex)
+ throws InterruptedException, SuspendNotAllowedException {
+ getUiEngine().wait(mutex);
+ }
+ /** Wakes up a single event processing thread that is waiting on the
+ * specified object.
+ *
+ *
Unlike {@link #notify(Desktop, Object)}, this method can be invoked only
+ * in the event listener that processing the same desktop.
+ * In addition, this method can be called under the event listener.
+ *
+ *
Use {@link #notify(Desktop, Object)} if you want to notify in other
+ * thread, such as a working thread.
+ *
+ * @param mutex any non-null object to identify what to notify.
+ * It must be same object passed to {@link #wait}.
+ * If there is racing issue, you have to enclose it with
+ * synchronized
(though it is optional).
+ * @see #notify(Desktop, Object)
+ * @see #notifyAll(Object)
+ * @exception UiException if it is called not during event processing.
+ */
+ public static final void notify(Object mutex) {
+ getUiEngine().notify(mutex);
+ }
+ /** Wakes up all event processing thread that are waiting on the
+ * specified object.
+ *
+ *
Unlike {@link #notify(Desktop, Object)}, this method can be invoked only
+ * in the event listener that processing the same desktop.
+ * In addition, this method can be called under the event listener.
+ *
+ *
Use {@link #notifyAll(Desktop, Object)} if you want to notify in other
+ * thread, such as a working thread.
+ *
+ * @param mutex any non-null object to identify what to notify.
+ * It must be same object passed to {@link #wait}.
+ * If there is racing issue, you have to enclose it with
+ * synchronized
(though it is optional).
+ * @see #notify(Desktop, Object)
+ * @see #notifyAll(Object)
+ * @exception UiException if it is called not during event processing.
+ */
+ public static final void notifyAll(Object mutex) {
+ getUiEngine().notifyAll(mutex);
+ }
+ /** Wakes up a single event processing thread for the specified desktop
+ * that is waiting on the specified object.
+ *
+ *
Unlike {@link #notify(Object)}, this method can be called any time.
+ * It is designed to let working threads resume an event processing
+ * thread.
+ *
+ *
Notice: if this method is NOT called in an event processing thread,
+ * the resumed thread won't execute until the next request is received.
+ * To enforce it happen, you might use the timer component (found in ZUL).
+ *
+ *
Notice: to resolve racing issue, you usually need to follow
+ * this pattern.
+ *
+//Event Handling Thread
+synchronized (mutex) {
+ final WorkingThread worker = new WorkingThread(desktop);
+ synchronized (mutex) {
+ worker.start();
+ Executions.wait(mutex);
+ }
+ ....
+}
+//Working Thread
+public void run() {
+ ....
+ synchronized (mutex) {
+ Executions.notify(desktop, mutex);
+ }
+}
+
+ *
+ * @param desktop the desktop which the suspended thread is processing.
+ * It must be the same desktop of the suspended thread.
+ * @param mutex any non-null object to identify what to notify.
+ * It must be same object passed to {@link #wait}.
+ * If there is racing issue, you have to enclose it with
+ * synchronized
(though it is optional).
+ * @see #notify(Object)
+ * @see #notifyAll(Desktop, Object)
+ */
+ public static final void notify(Desktop desktop, Object mutex) {
+ getUiEngine(desktop).notify(desktop, mutex);
+ }
+ /** Wakes up all event processing theads for the specified desktop
+ * that are waiting on the specified object.
+ *
+ * Unlike {@link #notifyAll(Object)}, this method can be called any time.
+ * It is designed to let working threads resume an event processing
+ * thread.
+ *
+ *
Notice: if this method is NOT called in an event processing thread,
+ * the resumed thread won't execute until the next request is received.
+ * To enforce it happen, you might use the timer component (found in ZUL).
+ *
+ *
Notice: to resolve racing issue, you usually need to follow
+ * this pattern.
+ *
+//Event Handling Thread
+synchronized (mutex) {
+ final WorkingThread worker = new WorkingThread(desktop);
+ synchronized (mutex) {
+ worker.start();
+ Executions.wait(mutex);
+ }
+ ....
+}
+//Working Thread
+public void run() {
+ ....
+ synchronized (mutex) {
+ Executions.notifyAll(desktop, mutex);
+ }
+}
+
+ *
+ * @param desktop the desktop which the suspended thread is processing.
+ * It must be the same desktop of the suspended thread.
+ * @param mutex any non-null object to identify what to notify.
+ * It must be same object passed to {@link #wait}.
+ * If there is racing issue, you have to enclose it with
+ * synchronized
(though it is optional).
+ * @see #notify(Object)
+ * @see #notifyAll(Desktop, Object)
+ */
+ public static final void notifyAll(Desktop desktop, Object mutex) {
+ getUiEngine(desktop).notifyAll(desktop, mutex);
+ }
+
+ /** Activates a server-push thread.
+ * It causes the current thread to wait until the desktop is available
+ * to access, the desktop no longer exists,
+ * or some other thread interrupts this thread.
+ *
+ * A server-push thread is a working thread that manipulates a desktop
+ * independent of event listeners. It can manipulate the components
+ * of the desktop as long as it is activated.
+ *
+ *
Due to the overhead of using server-push threads, the server-push
+ * feature is disabled by default. To use it, you have to enable
+ * it first with {@link Desktop#enableServerPush}.
+ * Once enabled, you can use as many as sevrer-push threads you like
+ * (for the desktop with the server-push feature enabled).
+ *
+ *
Before a server-push thread can access the components of the
+ * desktop it belongs, you have to activate it first.
+ * To activate a server-push thread, you have to invoke {@link #activate}.
+ * Once it returns, the server-push thread is activated and it, like
+ * event listeners, can manipulate the components of the corresponding
+ * desktop directly.
+ *
+ *
A typical use pattern:
+ *
+ *
class MyWorkingThread extends Thread {
+ * public void run() {
+ * while (anything_to_publish) {
+ * //prepare something to publish
+ * //you can create new components and manipulate them before
+ * //activation, as long as they are not attached to the desktop
+ *
+ * Executions.activate(desktop);
+ * try {
+ * try {
+ * //activated
+ * //manipulate the components that are attached the desktop
+ * } finally {
+ * Executions.deactivate(desktop)
+ * }
+ * } catch (DesktopUnavailableException ex) {
+ * //clean up (since desktop is dead)
+ * }
+ * }
+ * }
+ *}
+ *
+ * Note: the access of components is sequentialized. That is,
+ * at most one server-push thread is activated. All others, including
+ * the event listeners, have to wait util it is deactivated
+ * (i.e., until {@link #deactivate} is called).
+ * Thus, it is better to minimize the time remaining activated.
+ * A typical practice is to create new components and manipulate them
+ * before activated. Then, you have to only attach them after activated.
+ *
+ *
Tree tree = new Tree();
+ * new Treechildren().setParent(tree); //initialize the tree
+ * Exections.activate(desktop);
+ * try {
+ * tree.setPage(page); //assume page is a page of desktop
+ *
+ *
+ * Note: you don't need to invoke this method in the event listener
+ * since it is already activated when an event listen starts execution.
+ *
+ * @exception InterruptedException if it is interrupted by other thread
+ * @exception DesktopUnavailableException if the desktop is removed
+ * (when activating).
+ * @since 3.0.0
+ */
+ public static final void activate(Desktop desktop)
+ throws InterruptedException, DesktopUnavailableException {
+ activate(desktop, 0);
+ }
+ /** Activates a server-push thread with, or until a certain amount of
+ * real time has elapsed.
+ * It causes the current thread to wait until the desktop is available
+ * to access, the desktop no longer exists,
+ * some other thread interrupts this thread,
+ * or a certain amount of real time has elapsed.
+ *
+ * @param timeout the maximum time to wait in milliseconds.
+ * Ingored (i.e., never timeout) if non-positive.
+ * @return whether it is activated or it is timeout.
+ * The only reason it returns false is timeout.
+ * @exception InterruptedException if it is interrupted by other thread
+ * @exception DesktopUnavailableException if the desktop is removed
+ * (when activating).
+ * @exception IllegalStateException if the server push is not
+ * enabled for this desktop yet ({@link Desktop#enableServerPush}).
+ * @since 3.0.0
+ * @see #activate(Desktop)
+ */
+ public static final boolean activate(Desktop desktop, long timeout)
+ throws InterruptedException, DesktopUnavailableException {
+ final ServerPush spush = ((DesktopCtrl)desktop).getServerPush();
+ if (spush == null)
+ if (desktop.isAlive())
+ throw new IllegalStateException("Before activation, the server push must be enabled for "+desktop);
+ else
+ throw new DesktopUnavailableException("Stopped");
+ return spush.activate(timeout);
+ }
+ /** Deactivates a server-push thread.
+ * @since 3.0.0
+ */
+ public static final void deactivate(Desktop desktop) {
+ final ServerPush spush = ((DesktopCtrl)desktop).getServerPush();
+ if (spush != null)
+ spush.deactivate();
+ }
+
+ private static final UiEngine getUiEngine(Desktop desktop) {
+ if (desktop == null)
+ throw new IllegalArgumentException("desktop cannot be null");
+ return ((WebAppCtrl)desktop.getWebApp()).getUiEngine();
+ }
+ private static final UiEngine getUiEngine() {
+ final Execution exec = getCurrent();
+ if (exec == null)
+ throw new IllegalStateException("This method can be called only under an event listener");
+ return ((WebAppCtrl)exec.getDesktop().getWebApp()).getUiEngine();
+ }
+}
\ No newline at end of file
diff --git a/extend/posterita/webui/WEB-INF/src/org/zkoss/zk/ui/sys/ExecutionsCtrl.java b/extend/posterita/webui/WEB-INF/src/org/zkoss/zk/ui/sys/ExecutionsCtrl.java
new file mode 100644
index 0000000000..b6242d2ea4
--- /dev/null
+++ b/extend/posterita/webui/WEB-INF/src/org/zkoss/zk/ui/sys/ExecutionsCtrl.java
@@ -0,0 +1,53 @@
+/* ExecutionsCtrl.java
+
+{{IS_NOTE
+ Purpose:
+
+ Description:
+
+ History:
+ Mon Jun 6 12:20:51 2005, Created by tomyeh
+}}IS_NOTE
+
+Copyright (C) 2005 Potix Corporation. All Rights Reserved.
+
+{{IS_RIGHT
+ This program is distributed under GPL Version 2.0 in the hope that
+ it will be useful, but WITHOUT ANY WARRANTY.
+}}IS_RIGHT
+*/
+package org.zkoss.zk.ui.sys;
+
+import org.zkoss.zk.ui.Execution;
+import org.zkoss.zk.ui.Executions;
+
+/**
+ * Additional utilities for {@link Execution}.
+ *
+ * @author tomyeh
+ */
+public class ExecutionsCtrl extends Executions {
+ protected ExecutionsCtrl() {} //prevent from instantiation
+
+ /** Sets the execution for the current thread.
+ * Called only internally.
+ *
+ *
Note: you have to clean up the current execution
+ * with try/finally:
+ *
+ * setCurrent(exec);
+ * try {
+ * ...
+ * finally {
+ * setCurrent(null);
+ * }
+ */
+ public static final void setCurrent(Execution exec) {
+ _exec.set(exec);
+ }
+ /** Returns the current {@link ExecutionCtrl}.
+ */
+ public static final ExecutionCtrl getCurrentCtrl() {
+ return (ExecutionCtrl)getCurrent();
+ }
+}
\ No newline at end of file