/****************************************************************************** * Copyright (C) 2008 Elaine Tan * * 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. * *****************************************************************************/ package org.adempiere.webui.panel; import java.math.BigDecimal; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Timestamp; import java.util.ArrayList; import java.util.logging.Level; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.ConfirmPanel; 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.NumberBox; import org.adempiere.webui.component.Row; import org.adempiere.webui.component.Rows; import org.adempiere.webui.component.Window; import org.adempiere.webui.editor.WNumberEditor; import org.adempiere.webui.editor.WStringEditor; import org.compiere.apps.search.InfoPAttribute; import org.compiere.model.MAttribute; import org.compiere.model.MAttributeSet; 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.zkoss.zk.ui.Component; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zul.Div; import org.zkoss.zul.Separator; import org.zkoss.zul.Textbox; import org.zkoss.zul.Vbox; /** * Search by Product Attribute. * This class is based on org.compiere.apps.search.InfoPAttribute written by Jorg Janke * @author Elaine * */ public class InfoPAttributePanel extends Window implements EventListener { /** * */ private static final long serialVersionUID = -4922961793415942591L; /* the attribute set selected on the InfoProduct window */ private int p_M_AttributeSet_ID = 0; /** * Constructor. * Called from InfoProduct,cmd_InfoPAttribute * @param parent */ public InfoPAttributePanel(Window parent) { super(); if (parent instanceof InfoProductPanel) { p_M_AttributeSet_ID = ((InfoProductPanel)parent).getM_AttributeSet_ID(); } setTitle(Msg.getMsg(Env.getCtx(), "InfoPAttribute")); this.setBorder("normal"); this.setMaximizable(true); this.setSizable(true); try { jbInit(); dynInit(); } catch (Exception e) { log.log(Level.SEVERE, "InfoPAttribute", e); } AEnv.showCenterWindow(parent, this); } // InfoPAttribute /** Resulting Query */ private String m_query = ""; /** Product Attribure Editors */ private ArrayList<Component> m_productEditors = new ArrayList<Component>(); private ArrayList<Component> m_productEditorsTo = new ArrayList<Component>(); /** Instance Attribute Editors */ private ArrayList<Component> m_instanceEditors = new ArrayList<Component>(); private ArrayList<Component> m_instanceEditorsTo = new ArrayList<Component>(); /** Logger */ private static CLogger log = CLogger.getCLogger(InfoPAttribute.class); private Rows rows = null; private ConfirmPanel confirmPanel = new ConfirmPanel(true); // private Label serNoLabel = new Label(Msg.translate(Env.getCtx(), "SerNo")); private WStringEditor serNoField = new WStringEditor("SerNo", false, false, true, 10, 20, null, null); private Label lotLabel = new Label(Msg.translate(Env.getCtx(), "Lot")); private WStringEditor lotField = new WStringEditor("Lot", false, false, true, 10, 20, null, null); private Listbox guaranteeDateSelection = null; private Datebox guaranteeDateField = new Datebox(); private Label lotLabel2 = new Label(Msg.translate(Env.getCtx(), "M_Lot_ID")); private Listbox lotSelection = null; // /** * Static Init * @throws Exception */ private void jbInit() throws Exception { Vbox vbox = new Vbox(); this.appendChild(vbox); Grid grid = new Grid(); grid.setWidth("400px"); grid.setStyle("margin:0; padding:0;"); grid.makeNoStrip(); grid.setOddRowSclass("even"); vbox.appendChild(grid); rows = new Rows(); grid.appendChild(rows); // ConfirmPanel confirmPanel.addActionListener(this); vbox.appendChild(confirmPanel); } // jbInit /** * Dynamic Init of the Center Panel */ private void dynInit() { addAttributes(); boolean isGuarantee = true; boolean isSerial = true; boolean isLot = true; if (p_M_AttributeSet_ID > 0) { MAttributeSet as = new MAttributeSet(Env.getCtx(), p_M_AttributeSet_ID, null); isGuarantee = as.isGuaranteeDate(); isSerial = as.isSerNo(); isLot = as.isLot(); } // String s = Msg.translate(Env.getCtx(), "GuaranteeDate"); guaranteeDateSelection = new Listbox(); guaranteeDateSelection.setRows(0); guaranteeDateSelection.setMultiple(false); guaranteeDateSelection.setMold("select"); guaranteeDateSelection.setWidth("150px"); guaranteeDateSelection.appendItem(s + " <", s + " <"); guaranteeDateSelection.appendItem(s + " =", s + " ="); guaranteeDateSelection.appendItem(s + " >", s + " >"); initLotSelection(); // Fixed Instance Selection Fields Row row; Div div; if (isSerial) { row = new Row(); rows.appendChild(row); div = new Div(); div.setAlign("right"); div.appendChild(serNoLabel); row.appendChild(div); row.appendChild(serNoField.getComponent()); serNoField.getComponent().setWidth("150px"); } if (isLot) { row = new Row(); rows.appendChild(row); div = new Div(); div.setAlign("right"); div.appendChild(lotLabel); row.appendChild(div); row.appendChild(lotField.getComponent()); lotField.getComponent().setWidth("150px"); row = new Row(); rows.appendChild(row); div = new Div(); div.setAlign("right"); div.appendChild(lotLabel2); row.appendChild(div); row.appendChild(lotSelection); } if (isGuarantee) { row = new Row(); rows.appendChild(row); div = new Div(); div.setAlign("right"); div.appendChild(guaranteeDateSelection); row.appendChild(div); row.appendChild(guaranteeDateField); } } // dynInit /** * Add Attributes * @return rows */ private int addAttributes() { PreparedStatement pstmt = null; ResultSet rs = null; String whereAttributeSet; if (p_M_AttributeSet_ID > 0) whereAttributeSet = "AND M_Attribute_ID IN (SELECT M_Attribute_ID FROM M_AttributeUse WHERE M_AttributeSet_ID="+p_M_AttributeSet_ID+")"; else whereAttributeSet = ""; String sql = MRole.getDefault().addAccessSQL( "SELECT M_Attribute_ID, Name, Description, AttributeValueType, IsInstanceAttribute " + "FROM M_Attribute " + "WHERE IsActive='Y' " + whereAttributeSet + " ORDER BY IsInstanceAttribute, Name", "M_Attribute", MRole.SQL_NOTQUALIFIED, MRole.SQL_RO); boolean instanceLine = false; try { pstmt = DB.prepareStatement(sql, null); rs = pstmt.executeQuery(); while (rs.next()) { int attribute_ID = rs.getInt(1); String name = rs.getString(2); String description = rs.getString(3); String attributeValueType = rs.getString(4); boolean isInstanceAttribute = "Y".equals(rs.getString(5)); // Instance switch if (!instanceLine && isInstanceAttribute) { Row row = new Row(); rows.appendChild(row); row.setSpans("2"); Label group = new Label(Msg.translate(Env.getCtx(), "IsInstanceAttribute")); row.appendChild(group); rows.appendChild(row); row = new Row(); rows.appendChild(row); row.setSpans("2"); Separator separator = new Separator(); separator.setBar(true); row.appendChild(separator); rows.appendChild(row); instanceLine = true; } // Row row = new Row(); rows.appendChild(row); Label label = new Label(name); if (description != null && description.length() > 0) label.setTooltiptext(description); Div div = new Div(); div.setAlign("right"); div.appendChild(label); row.appendChild(div); Component field = null; if (MAttribute.ATTRIBUTEVALUETYPE_List.equals(attributeValueType)) { field = new Listbox(); ((Listbox) field).setRows(0); ((Listbox) field).setMultiple(false); ((Listbox) field).setMold("select"); ((Listbox) field).setWidth("150px"); KeyNamePair[] knp = getAttributeList(attribute_ID); for(int i = 0; i < knp.length; i++) ((Listbox) field).appendItem(knp[i].getName(), knp[i]); } else if (MAttribute.ATTRIBUTEVALUETYPE_Number.equals(attributeValueType)) { field = new WNumberEditor(name, false, false, true, DisplayType.Number, name).getComponent(); ((NumberBox) field).setWidth("150px"); } else { field = new WStringEditor(name, false, false, true, 10, 40, null, null).getComponent(); ((Textbox) field).setWidth("150px"); } row.appendChild(field); // field.setId(String.valueOf(attribute_ID)); if (isInstanceAttribute) m_instanceEditors.add(field); else m_productEditors.add(field); // To (numbers) Component fieldTo = null; if (MAttribute.ATTRIBUTEVALUETYPE_Number.equals(attributeValueType)) { fieldTo = new WNumberEditor(name, false, false, true, DisplayType.Number, name).getComponent(); ((NumberBox) fieldTo).setWidth("150px"); row = new Row(); rows.appendChild(row); div = new Div(); div.setAlign("right"); div.appendChild(new Label("-")); row.appendChild(div); row.appendChild(fieldTo); } if (isInstanceAttribute) m_instanceEditorsTo.add(fieldTo); else m_productEditorsTo.add(fieldTo); } } catch (Exception e) { log.log(Level.SEVERE, sql, e); } finally { DB.close(rs, pstmt); rs = null; pstmt = null; } // print instance line if not printed if (!instanceLine) { boolean isGuarantee = true; boolean isSerial = true; boolean isLot = true; if (p_M_AttributeSet_ID > 0) { MAttributeSet as = new MAttributeSet(Env.getCtx(), p_M_AttributeSet_ID, null); isGuarantee = as.isGuaranteeDate(); isSerial = as.isSerNo(); isLot = as.isLot(); } if (isGuarantee || isSerial || isLot) { Row row = new Row(); rows.appendChild(row); row.setSpans("2"); Label group = new Label(Msg.translate(Env.getCtx(), "IsInstanceAttribute")); row.appendChild(group); rows.appendChild(row); row = new Row(); rows.appendChild(row); row.setSpans("2"); Separator separator = new Separator(); separator.setBar(true); row.appendChild(separator); rows.appendChild(row); instanceLine = true; } } return 0; } // addProductAttributes /** * Get Attribute List * @param M_Attribute_ID attribure * @return array */ private KeyNamePair[] getAttributeList(int M_Attribute_ID) { ArrayList<KeyNamePair> list = new ArrayList<KeyNamePair>(); list.add(new KeyNamePair(-1, "")); PreparedStatement pstmt = null; ResultSet rs = null; String sql = MRole.getDefault().addAccessSQL( "SELECT M_AttributeValue_ID, Value, Name " + "FROM M_AttributeValue " + "WHERE M_Attribute_ID=? " + "ORDER BY 2", "M_AttributeValue", MRole.SQL_NOTQUALIFIED, MRole.SQL_RO); try { pstmt = DB.prepareStatement(sql, null); pstmt.setInt(1, M_Attribute_ID); rs = pstmt.executeQuery(); while (rs.next()) list.add(new KeyNamePair(rs.getInt(1), rs.getString(3))); } catch (Exception e) { log.log(Level.SEVERE, sql, e); } finally { DB.close(rs, pstmt); rs = null; pstmt = null; } KeyNamePair[] retValue = new KeyNamePair[list.size()]; list.toArray(retValue); return retValue; } // getAttributeList /** * Initialize Lot Selection */ private void initLotSelection() { ArrayList<KeyNamePair> list = new ArrayList<KeyNamePair>(); list.add(new KeyNamePair(-1, "")); String whereAttributeSet; if (p_M_AttributeSet_ID > 0) whereAttributeSet = "AND M_Product_ID IN (SELECT M_Product_ID FROM M_Product WHERE M_AttributeSet_ID="+p_M_AttributeSet_ID+")"; else whereAttributeSet = ""; String sql = MRole.getDefault().addAccessSQL( "SELECT M_Lot_ID, Name FROM M_Lot WHERE IsActive='Y' " + whereAttributeSet + " ORDER BY 2", "M_Lot", MRole.SQL_NOTQUALIFIED, MRole.SQL_RO); PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = DB.prepareStatement(sql, null); rs = pstmt.executeQuery(); while (rs.next()) list.add(new KeyNamePair(rs.getInt(1), rs.getString(2))); } catch (Exception e) { log.log(Level.SEVERE, sql, e); } finally { DB.close(rs, pstmt); rs = null; pstmt = null; } // Create List KeyNamePair[] items = new KeyNamePair[list.size()]; list.toArray(items); lotSelection = new Listbox(); lotSelection.setRows(0); lotSelection.setMultiple(false); lotSelection.setMold("select"); lotSelection.setWidth("150px"); for(int i = 0; i < items.length; i++) lotSelection.appendItem(items[i].getName(), items[i]); } // initLotSelection /** * Action Listener * @param e event */ public void onEvent(Event e) throws Exception { if (e.getTarget().getId().equals(ConfirmPanel.A_OK)) { createQuery(); dispose(); } else if (e.getTarget().getId().equals(ConfirmPanel.A_CANCEL)) { m_query = null; dispose(); } } // actionPerformed /** * Create Query * <code> * Available synonyms: * M_Product p * M_ProductPrice pr * M_AttributeSet pa * </code> * @return query */ private String createQuery() { /** Base Query SELECT * FROM M_Product p INNER JOIN M_ProductPrice pr ON (p.M_Product_ID=pr.M_Product_ID) LEFT OUTER JOIN M_AttributeSet pa ON (p.M_AttributeSet_ID=pa.M_AttributeSet_ID) WHERE **/ /*** Instance Attributes */ StringBuffer sb = new StringBuffer(); // Serial No String s = serNoField.getComponent().getText(); if (s != null && s.length() > 0) { sb.append(" AND asi.SerNo"); if (s.indexOf('%') == -1 && s.indexOf('_') == 1) sb.append("="); else sb.append(" LIKE "); sb.append(DB.TO_STRING(s)); } // Lot Number s = lotField.getComponent().getText(); if (s != null && s.length() > 0) { sb.append(" AND asi.Lot"); if (s.indexOf('%') == -1 && s.indexOf('_') == 1) sb.append("="); else sb.append(" LIKE "); sb.append(DB.TO_STRING(s)); } // Lot ID ListItem li = lotSelection.getSelectedItem(); if(li != null && li.getValue() != null) { KeyNamePair pp = (KeyNamePair) li.getValue(); if (pp != null && pp.getKey() != -1) { int ID = pp.getKey(); sb.append(" AND asi.M_Lot_ID=").append(ID); } } // Guarantee Date Timestamp ts = (Timestamp)guaranteeDateField.getValue(); if (ts != null) { sb.append(" AND TRUNC(asi.GuaranteeDate, 'DD')"); int index = guaranteeDateSelection.getSelectedIndex(); // < = > if (index == 0) sb.append("<"); else if (index == 1) sb.append("="); else sb.append(">"); sb.append(DB.TO_DATE(ts,true)); } // Instance Editors for (int i = 0; i < m_instanceEditors.size(); i++) { StringBuffer iAttr = new StringBuffer(); Component c = (Component)m_instanceEditors.get(i); Component cTo = (Component)m_instanceEditorsTo.get(i); int M_Attribute_ID = Integer.parseInt(c.getId()); if (c instanceof Listbox) { Listbox field = (Listbox)c; li = field.getSelectedItem(); if(li != null && li.getValue() != null) { KeyNamePair pp = (KeyNamePair)li.getValue(); if (pp != null && pp.getKey() != -1) { iAttr.append("M_Attribute_ID=").append(M_Attribute_ID) .append(" AND M_AttributeValue_ID=").append(pp.getKey()); } } } else if (c instanceof NumberBox) { NumberBox field = (NumberBox)c; BigDecimal value = (BigDecimal)field.getValue(); NumberBox fieldTo = (NumberBox)cTo; BigDecimal valueTo = (BigDecimal)fieldTo.getValue(); if (value != null || valueTo != null) { iAttr.append("M_Attribute_ID=").append(M_Attribute_ID) .append(" AND ValueNumber"); if (value != null && valueTo == null) iAttr.append("=").append(value); else if (value == null && valueTo != null) iAttr.append("<=").append(valueTo); else if (value != null && valueTo != null) iAttr.append(" BETWEEN ").append(value) .append(" AND ").append(valueTo); } } else { Textbox field = (Textbox)c; String value = field.getText(); if (value != null && value.length() > 0) { iAttr.append("M_Attribute_ID=").append(M_Attribute_ID) .append(" AND Value"); if (value.indexOf('%') == -1 && value.indexOf('_') == -1) iAttr.append("="); else iAttr.append(" LIKE "); iAttr.append(DB.TO_STRING(value)); } } // Add to where if (iAttr.length() > 0) sb.append(" AND asi.M_AttributeSetInstance_ID IN " + "(SELECT M_AttributeSetInstance_ID FROM M_AttributeInstance " + "WHERE ") .append(iAttr).append(")"); } // finish Instance Attributes if (sb.length() > 0) { sb.insert(0, " AND EXISTS (SELECT * FROM M_Storage s" + " INNER JOIN M_AttributeSetInstance asi ON (s.M_AttributeSetInstance_ID=asi.M_AttributeSetInstance_ID) " + "WHERE s.M_Product_ID=p.M_Product_ID"); sb.append(")"); } // Product Attributes for (int i = 0; i < m_productEditors.size(); i++) { StringBuffer pAttr = new StringBuffer(); Component c = (Component)m_productEditors.get(i); Component cTo = (Component)m_productEditorsTo.get(i); int M_Attribute_ID = Integer.parseInt(c.getId()); if (c instanceof Listbox) { Listbox field = (Listbox)c; li = field.getSelectedItem(); if(li != null && li.getValue() != null) { KeyNamePair pp = (KeyNamePair)li.getValue(); if (pp != null && pp.getKey() != -1) { pAttr.append("M_Attribute_ID=").append(M_Attribute_ID) .append(" AND M_AttributeValue_ID=").append(pp.getKey()); } } } else if (c instanceof NumberBox) { NumberBox field = (NumberBox)c; BigDecimal value = (BigDecimal)field.getValue(); NumberBox fieldTo = (NumberBox)cTo; BigDecimal valueTo = (BigDecimal)fieldTo.getValue(); if (value != null || valueTo != null) { pAttr.append("M_Attribute_ID=").append(M_Attribute_ID) .append(" AND ValueNumber"); if (value != null && valueTo == null) pAttr.append("=").append(value); else if (value == null && valueTo != null) pAttr.append("<=").append(valueTo); else if (value != null && valueTo != null) pAttr.append(" BETWEEN ").append(value) .append(" AND ").append(valueTo); } } else { Textbox field = (Textbox)c; String value = field.getText(); if (value != null && value.length() > 0) { pAttr.append("M_Attribute_ID=").append(M_Attribute_ID) .append(" AND Value"); if (value.indexOf('%') == -1 && value.indexOf('_') == -1) pAttr.append("="); else pAttr.append(" LIKE "); pAttr.append(DB.TO_STRING(value)); } } // Add to Where if (pAttr.length() > 0) sb.append(" AND p.M_AttributeSetInstance_ID IN " + "(SELECT M_AttributeSetInstance_ID " + "FROM M_AttributeInstance WHERE ") .append(pAttr).append(")"); } // m_query = null; if (sb.length() > 0) m_query = sb.toString(); log.config(m_query); return m_query; } // createQuery /** * Get resulting Query WHERE * @return query or null */ public String getWhereClause() { return m_query; } // getQuery }