/****************************************************************************** * Copyright (C) 2009 Low Heng Sin * * Copyright (C) 2009 Idalica Corporation * * 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.compiere.grid; import java.math.BigDecimal; import java.math.RoundingMode; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Vector; import java.util.logging.Level; import org.compiere.apps.IStatusBar; import org.compiere.minigrid.IMiniTable; import org.compiere.model.GridTab; import org.compiere.model.MInOut; import org.compiere.model.MInvoice; import org.compiere.model.MOrder; import org.compiere.model.MProduct; import org.compiere.model.MRMA; 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; /** * Create Invoice Lines from Purchase Order, Material Receipt or Vendor RMA * * @author Jorg Janke * @version $Id: VCreateFromInvoice.java,v 1.4 2006/07/30 00:51:28 jjanke Exp $ * * @author Teo Sarca, SC ARHIPAC SERVICE SRL *
  • BF [ 1896947 ] Generate invoice from Order error *
  • BF [ 2007837 ] VCreateFrom.save() should run in trx */ public abstract class CreateFromInvoice extends CreateFrom { /** * Constructor * @param mTab MTab */ public CreateFromInvoice(GridTab mTab) { super(mTab); if (log.isLoggable(Level.INFO)) log.info(mTab.toString()); } // CreateFromInvoice @Override protected boolean dynInit() throws Exception { log.config(""); setTitle(Msg.getElement(Env.getCtx(), "C_Invoice_ID", false) + " .. " + Msg.translate(Env.getCtx(), "CreateFrom")); return true; } // dynInit /** * Load BPartner related Shipment records. * @param C_BPartner_ID * @return list of shipment records */ protected ArrayList loadShipmentData (int C_BPartner_ID) { String isSOTrxParam = isSOTrx ? "Y":"N"; ArrayList list = new ArrayList(); // 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=? AND s.DocStatus IN ('CL','CO')" + " AND s.M_InOut_ID IN " + "(SELECT sl.M_InOut_ID FROM M_InOutLine sl"); if(!isSOTrx) sql.append(" LEFT OUTER JOIN M_MatchInv mi ON (sl.M_InOutLine_ID=mi.M_InOutLine_ID) " + " JOIN M_InOut s2 ON (sl.M_InOut_ID=s2.M_InOut_ID) " + " WHERE s2.C_BPartner_ID=? AND s2.IsSOTrx=? AND s2.DocStatus IN ('CL','CO') " + " GROUP BY sl.M_InOut_ID,sl.MovementQty,s2.MovementType,mi.M_InOutLine_ID" + " HAVING (sl.MovementQty <> SUM(mi.Qty) * CASE WHEN s2.MovementType = 'V-' THEN -1 ELSE 1 END" + " AND mi.M_InOutLine_ID IS NOT NULL) OR mi.M_InOutLine_ID IS NULL "); else sql.append(" INNER JOIN M_InOut s2 ON (sl.M_InOut_ID=s2.M_InOut_ID)" + " LEFT JOIN C_InvoiceLine il ON sl.M_InOutLine_ID = il.M_InOutLine_ID" + " WHERE s2.C_BPartner_ID=? AND s2.IsSOTrx=? AND s2.DocStatus IN ('CL','CO')" + " GROUP BY sl.M_InOutLine_ID" + " HAVING sl.MovementQty - sum(COALESCE(il.QtyInvoiced,0)) > 0"); sql.append(") ORDER BY s.MovementDate"); PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = DB.prepareStatement(sql.toString(), getTrxName()); pstmt.setInt(1, C_BPartner_ID); pstmt.setString(2, isSOTrxParam); pstmt.setInt(3, C_BPartner_ID); pstmt.setString(4, isSOTrxParam); rs = pstmt.executeQuery(); while (rs.next()) { list.add(new KeyNamePair(rs.getInt(1), rs.getString(2))); } } catch (SQLException e) { log.log(Level.SEVERE, sql.toString(), e); } finally { DB.close(rs, pstmt); rs = null; pstmt = null; } return list; } /** * Load BPartner related RMA records * @param C_BPartner_ID BPartner * @return list of RMA records */ protected ArrayList loadRMAData(int C_BPartner_ID) { ArrayList list = new ArrayList(); String sqlStmt = "SELECT r.M_RMA_ID, r.DocumentNo || '-' || r.Amt from M_RMA r " + "INNER JOIN M_RMALine l ON (l.M_RMA_ID = r.M_RMA_ID) " + "WHERE ISSOTRX='N' AND r.DocStatus in ('CO', 'CL') " + "AND r.C_BPartner_ID=? " + "AND COALESCE(l.QtyInvoiced,0) < l.Qty "; PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = DB.prepareStatement(sqlStmt, getTrxName()); pstmt.setInt(1, C_BPartner_ID); rs = pstmt.executeQuery(); while (rs.next()) { list.add(new KeyNamePair(rs.getInt(1), rs.getString(2))); } } catch (SQLException e) { log.log(Level.SEVERE, sqlStmt.toString(), e); } finally{ DB.close(rs, pstmt); rs = null; pstmt = null; } return list; } /** * Load Shipment Lines not invoiced * @param M_InOut_ID InOut * @return shipment lines (selection,qty,[c_uom_id,uomSymbol/name],[m_product_id,name],vendorProductNo,[c_orderline_id,.],[m_inoutline_id,line],null) */ protected Vector> getShipmentData(int M_InOut_ID) { if (log.isLoggable(Level.CONFIG)) log.config("M_InOut_ID=" + M_InOut_ID); MInOut inout = new MInOut(Env.getCtx(), M_InOut_ID, getTrxName()); p_order = null; if (inout.getC_Order_ID() != 0) p_order = new MOrder (Env.getCtx(), inout.getC_Order_ID(), getTrxName()); m_rma = null; if (inout.getM_RMA_ID() != 0) m_rma = new MRMA (Env.getCtx(), inout.getM_RMA_ID(), getTrxName()); // Vector> data = new Vector>(); StringBuilder sql = new StringBuilder("SELECT "); // QtyEntered if(!isSOTrx) sql.append("l.Movementqty-SUM(COALESCE(mi.Qty, 0))*CASE WHEN io.MovementType = 'V-' THEN -1 ELSE 1 END,"); else sql.append("l.MovementQty-SUM(COALESCE(il.QtyInvoiced,0)),"); sql.append(" 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)"); if(!isSOTrx) sql.append(" LEFT OUTER JOIN M_MatchInv mi ON (l.M_InOutLine_ID=mi.M_InOutLine_ID)"); else sql.append(" LEFT JOIN C_InvoiceLine il ON l.M_InOutLine_ID = il.M_InOutLine_ID"); sql.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(" WHERE l.M_InOut_ID=? AND l.MovementQty<>0 ") .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, io.MovementType "); if(!isSOTrx) sql.append(" HAVING l.MovementQty-SUM(COALESCE(mi.Qty, 0)) <>0"); else sql.append(" HAVING l.MovementQty-SUM(COALESCE(il.QtyInvoiced,0)) <>0"); sql.append(" ORDER BY l.Line"); PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = DB.prepareStatement(sql.toString(), getTrxName()); pstmt.setInt(1, M_InOut_ID); rs = pstmt.executeQuery(); while (rs.next()) { Vector line = new Vector(7); line.add(Boolean.FALSE); // 0-Selection BigDecimal qtyMovement = rs.getBigDecimal(1); BigDecimal multiplier = rs.getBigDecimal(2); BigDecimal qtyEntered = qtyMovement.multiply(multiplier); line.add(qtyEntered); // 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-RMA data.add(line); } } catch (SQLException e) { log.log(Level.SEVERE, sql.toString(), e); } finally { DB.close(rs, pstmt); rs = null; pstmt = null; } return data; } // getShipmentData /** * Load RMA line records * @param M_RMA_ID RMA * @return RMA lines (selection,qty,[c_uom_id,uomSymbol/name],[m_product_id,name],null,null,null,[m_rmaline_id,line]) */ protected Vector> getRMAData(int M_RMA_ID) { p_order = null; Vector> data = new Vector>(); StringBuilder sqlStmt = new StringBuilder(); sqlStmt.append("SELECT rl.M_RMALine_ID, rl.line, rl.Qty - COALESCE(rl.QtyInvoiced, 0), iol.M_Product_ID, p.Name, uom.C_UOM_ID, COALESCE(uom.UOMSymbol,uom.Name) "); sqlStmt.append("FROM M_RMALine rl INNER JOIN M_InOutLine iol ON rl.M_InOutLine_ID=iol.M_InOutLine_ID "); if (Env.isBaseLanguage(Env.getCtx(), "C_UOM")) { sqlStmt.append("LEFT OUTER JOIN C_UOM uom ON (uom.C_UOM_ID=iol.C_UOM_ID) "); } else { sqlStmt.append("LEFT OUTER JOIN C_UOM_Trl uom ON (uom.C_UOM_ID=iol.C_UOM_ID AND uom.AD_Language='"); sqlStmt.append(Env.getAD_Language(Env.getCtx())).append("') "); } sqlStmt.append("LEFT OUTER JOIN M_Product p ON p.M_Product_ID=iol.M_Product_ID "); sqlStmt.append("WHERE rl.M_RMA_ID=? "); sqlStmt.append("AND rl.M_INOUTLINE_ID IS NOT NULL"); sqlStmt.append(" UNION "); sqlStmt.append("SELECT rl.M_RMALine_ID, rl.line, rl.Qty - rl.QtyDelivered, 0, c.Name, uom.C_UOM_ID, COALESCE(uom.UOMSymbol,uom.Name) "); sqlStmt.append("FROM M_RMALine rl INNER JOIN C_Charge c ON c.C_Charge_ID = rl.C_Charge_ID "); if (Env.isBaseLanguage(Env.getCtx(), "C_UOM")) { sqlStmt.append("LEFT OUTER JOIN C_UOM uom ON (uom.C_UOM_ID=100) "); } else { sqlStmt.append("LEFT OUTER JOIN C_UOM_Trl uom ON (uom.C_UOM_ID=100 AND uom.AD_Language='"); sqlStmt.append(Env.getAD_Language(Env.getCtx())).append("') "); } sqlStmt.append("WHERE rl.M_RMA_ID=? "); sqlStmt.append("AND rl.C_Charge_ID IS NOT NULL"); PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = DB.prepareStatement(sqlStmt.toString(), getTrxName()); pstmt.setInt(1, M_RMA_ID); pstmt.setInt(2, M_RMA_ID); rs = pstmt.executeQuery(); while (rs.next()) { Vector line = new Vector(7); line.add(Boolean.FALSE); // 0-Selection line.add(rs.getBigDecimal(3)); // 1-Qty KeyNamePair pp = new KeyNamePair(rs.getInt(6), rs.getString(7)); line.add(pp); // 2-UOM pp = new KeyNamePair(rs.getInt(4), rs.getString(5)); line.add(pp); // 3-Product line.add(null); //4-Vendor Product No line.add(null); //5-Order pp = new KeyNamePair(rs.getInt(1), rs.getString(2)); line.add(null); //6-Ship line.add(pp); //7-RMA data.add(line); } } catch (Exception ex) { log.log(Level.SEVERE, sqlStmt.toString(), ex); } finally { DB.close(rs, pstmt); rs = null; pstmt = null; } return data; } @Override public void info(IMiniTable miniTable, IStatusBar statusBar) { } /** * set class/type of columns * @param miniTable */ protected void configureMiniTable (IMiniTable miniTable) { miniTable.setColumnClass(0, Boolean.class, false); // 0-Selection miniTable.setColumnClass(1, BigDecimal.class, false); // 1-Qty miniTable.setColumnClass(2, String.class, true); // 2-UOM miniTable.setColumnClass(3, String.class, true); // 3-Product miniTable.setColumnClass(4, String.class, true); // 4-VendorProductNo miniTable.setColumnClass(5, String.class, true); // 5-Order miniTable.setColumnClass(6, String.class, true); // 6-Ship miniTable.setColumnClass(7, String.class, true); // 7-Invoice // Table UI miniTable.autoSize(); } /** * Save - Create Invoice Lines * @return true if saved */ @Override public boolean save(IMiniTable miniTable, String trxName) { // Invoice int C_Invoice_ID = ((Integer)getGridTab().getValue("C_Invoice_ID")).intValue(); MInvoice invoice = new MInvoice (Env.getCtx(), C_Invoice_ID, trxName); if (log.isLoggable(Level.CONFIG)) log.config(invoice.toString()); if (p_order != null) { invoice.setOrder(p_order); // overwrite header values invoice.saveEx(); } if (m_rma != null) { invoice.setM_RMA_ID(m_rma.getM_RMA_ID()); invoice.saveEx(); } // Lines for (int i = 0; i < miniTable.getRowCount(); i++) { if (((Boolean)miniTable.getValueAt(i, 0)).booleanValue()) { MProduct product = null; // variable values BigDecimal QtyEntered = (BigDecimal)miniTable.getValueAt(i, 1); // 1-Qty KeyNamePair pp = (KeyNamePair)miniTable.getValueAt(i, 2); // 2-UOM int C_UOM_ID = pp.getKey(); // pp = (KeyNamePair)miniTable.getValueAt(i, 3); // 3-Product int M_Product_ID = 0; if (pp != null) M_Product_ID = pp.getKey(); // int C_OrderLine_ID = 0; pp = (KeyNamePair)miniTable.getValueAt(i, 5); // 5-OrderLine if (pp != null) C_OrderLine_ID = pp.getKey(); int M_InOutLine_ID = 0; pp = (KeyNamePair)miniTable.getValueAt(i, 6); // 6-Shipment if (pp != null) M_InOutLine_ID = pp.getKey(); // int M_RMALine_ID = 0; pp = (KeyNamePair)miniTable.getValueAt(i, 7); // 7-RMALine if (pp != null) M_RMALine_ID = pp.getKey(); // Precision of Qty UOM int precision = 2; if (M_Product_ID != 0) { product = MProduct.get(Env.getCtx(), M_Product_ID); precision = product.getUOMPrecision(); } QtyEntered = QtyEntered.setScale(precision, RoundingMode.HALF_DOWN); // if (log.isLoggable(Level.FINE)) log.fine("Line QtyEntered=" + QtyEntered + ", Product_ID=" + M_Product_ID + ", OrderLine_ID=" + C_OrderLine_ID + ", InOutLine_ID=" + M_InOutLine_ID); // Create new Invoice Line invoice.createLineFrom(C_OrderLine_ID, M_InOutLine_ID, M_RMALine_ID, M_Product_ID, C_UOM_ID, QtyEntered); } // if selected } // for all rows // Update Header invoice.updateFrom(p_order); return true; } // save /** * * @return column header names (select,quantity,uom,product,vendorProductNo,order,shipment,rma) */ protected Vector getOISColumnNames() { // Header Info Vector columnNames = new Vector(7); 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", isSOTrx)); columnNames.add(Msg.getElement(Env.getCtx(), "C_Order_ID", isSOTrx)); columnNames.add(Msg.getElement(Env.getCtx(), "M_InOut_ID", isSOTrx)); columnNames.add(Msg.getElement(Env.getCtx(), "M_RMA_ID", isSOTrx)); return columnNames; } }