/****************************************************************************** * 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.ContextMenuEvent; import org.adempiere.webui.event.ContextMenuListener; import org.adempiere.webui.event.ValueChangeEvent; import org.adempiere.webui.window.WFieldRecordInfo; import org.adempiere.webui.window.WLocatorDialog; import org.compiere.model.GridField; import org.compiere.model.MLocator; import org.compiere.model.MLocatorLookup; import org.compiere.model.MQuery; import org.compiere.model.MRole; import org.compiere.model.MTable; 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, ContextMenuListener, IZoomableEditor { private static final String[] LISTENER_EVENTS = {Events.ON_CLICK}; private MLocatorLookup m_mLocator; private Object m_value; private int m_WindowNo; private WEditorPopupMenu popupMenu; private static CLogger log = CLogger.getCLogger(WLocatorEditor.class); /** * IDE Constructor */ public WLocatorEditor() { this("M_Locator_ID", false, false, true, null, 0); } /** * 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, int windowNo) { super(new EditorBox(), "Locator", "", mandatory, isReadOnly, isUpdateable); setColumnName(columnName); m_mLocator = mLocator; getComponent().setButtonImage("/images/Locator10.png"); m_WindowNo = windowNo; //Yvonne: move it b4 setDefault_Locator_ID() setDefault_Locator_ID(); // set default locator, teo_sarca [ 1661546 ] } /** * @param gridField */ public WLocatorEditor(GridField gridField) { super(new EditorBox(), gridField); m_mLocator = (MLocatorLookup)gridField.getLookup(); getComponent().setButtonImage("/images/Locator10.png"); setDefault_Locator_ID(); // set default locator, teo_sarca [ 1661546 ] m_WindowNo = gridField.getWindowNo(); if (gridField != null) { popupMenu = new WEditorPopupMenu(true, true, false); if (gridField != null && gridField.getGridTab() != null) { WFieldRecordInfo.addMenu(popupMenu); } getComponent().setContext(popupMenu.getId()); } } 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 = value; getComponent().setText(m_mLocator.getDisplay(value)); // loads value // Data Binding if (fire) { ValueChangeEvent val = new ValueChangeEvent(this, getColumnName(), null, value); fireValueChange(val); } } /** * Return Editor value * @return value */ public Object getValue() { if (getM_Locator_ID() == 0) return null; return m_value; } // getValue @Override public EditorBox getComponent() { return (EditorBox) component; } @Override public boolean isReadWrite() { return getComponent().isEnabled(); } @Override public void setReadWrite(boolean readWrite) { getComponent().setEnabled(readWrite); } /** * Get M_Locator_ID * @return id */ public int getM_Locator_ID() { if (m_value != null && m_value instanceof Integer) return ((Integer)m_value).intValue(); return 0; } // getM_Locator_ID /** * Return Display Value * @return display value */ public String getDisplay() { return getComponent().getText(); } // getDisplay public void onEvent(Event event) throws Exception { if (Events.ON_CLICK.equalsIgnoreCase(event.getName())) { // 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() == getComponent() && actionText(only_Warehouse_ID, only_Product_ID)) return; // Button - Start Dialog int M_Locator_ID = 0; if (m_value instanceof Integer) M_Locator_ID = ((Integer)m_value).intValue(); m_mLocator.setOnly_Warehouse_ID(only_Warehouse_ID); m_mLocator.setOnly_Product_ID(getOnly_Product_ID()); WLocatorDialog ld = new WLocatorDialog(Msg.translate(Env.getCtx(), getColumnName()), 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); } } public WEditorPopupMenu getPopupMenu() { return popupMenu; } public void actionRefresh() { if (m_mLocator != null) { Object curValue = getValue(); if (isReadWrite()) m_mLocator.refresh(); if (curValue != null) { setValue(curValue); } } } public void actionZoom() { int AD_Window_ID = MTable.get(Env.getCtx(), MLocator.Table_ID).getAD_Window_ID(); if (AD_Window_ID <= 0) AD_Window_ID = 139; // hardcoded window Warehouse & Locators log.info(""); // MQuery zoomQuery = new MQuery(); zoomQuery.addRestriction(MLocator.COLUMNNAME_M_Locator_ID, MQuery.EQUAL, getValue()); zoomQuery.setRecordCount(1); // guess AEnv.zoom(AD_Window_ID, zoomQuery); } 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.CHANGE_LOG_EVENT.equals(evt.getContextEvent())) { WFieldRecordInfo.start(gridField); } } /** * 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 = getComponent().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; } }