/******************************************************************************
* 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.MLocator;
import org.compiere.model.MOrder;
import org.compiere.model.MProduct;
import org.compiere.model.MRMA;
import org.compiere.model.MWarehouse;
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 M_InOutLine for M_InOut from Purchase Orders, Vendor Invoice or Customer RMA
*
* @author Jorg Janke
* @version $Id: VCreateFromShipment.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 CreateFromShipment extends CreateFrom
{
/** Loaded Invoice */
protected MInvoice m_invoice = null;
/** Loaded RMA */
protected MRMA m_rma = null;
private int defaultLocator_ID=0;
/**
* Constructor
* @param mTab MTab
*/
public CreateFromShipment(GridTab mTab)
{
super(mTab);
if (log.isLoggable(Level.INFO)) log.info(mTab.toString());
} // CreateFromShipment
@Override
protected boolean dynInit() throws Exception
{
if (log.isLoggable(Level.CONFIG)) log.config("");
setTitle(Msg.getElement(Env.getCtx(), "M_InOut_ID", false) + " .. " + Msg.translate(Env.getCtx(), "CreateFrom"));
return true;
} // dynInit
/**
* 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 "
+ "WHERE ISSOTRX='Y' AND r.DocStatus in ('CO', 'CL') "
+ "AND r.C_BPartner_ID=? "
+ "AND r.M_RMA_ID in (SELECT rl.M_RMA_ID FROM M_RMALine rl "
+ "WHERE rl.M_RMA_ID=r.M_RMA_ID AND rl.QtyDelivered < rl.Qty "
+ "AND rl.M_InOutLine_ID IS NOT NULL)";
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 BPartner related Invoices
* @param C_BPartner_ID
* @return list of invoice records
*/
protected ArrayList loadInvoiceData (int C_BPartner_ID)
{
ArrayList list = new ArrayList();
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) "
+ " JOIN C_Invoice i2 ON (il.C_Invoice_ID = i2.C_Invoice_ID) "
+ " WHERE i2.C_BPartner_ID=? AND i2.IsSOTrx='N' AND i2.DocStatus IN ('CL','CO') "
+ " AND il.M_Product_ID IS NOT NULL "
+ "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");
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
pstmt = DB.prepareStatement(sql.toString(), getTrxName());
pstmt.setInt(1, C_BPartner_ID);
pstmt.setInt(2, 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, sql.toString(), e);
}
finally
{
DB.close(rs, pstmt);
rs = null;
pstmt = null;
}
return list;
}
/**
* Load Order Lines
* @param C_Order_ID Order
* @param forInvoice true if for invoice vs. delivery qty
* @return Order lines (selection,qty,[c_uom_id,uomSymbol/name],[m_locator_id,value][m_product_id,name],vendorProductNo,[c_orderline_id,line],null,null)
*/
protected Vector> getOrderData (int C_Order_ID, boolean forInvoice)
{
/**
* Selected - 0
* Qty - 1
* C_UOM_ID - 2
* M_Locator_ID - 3
* M_Product_ID - 4
* VendorProductNo - 5
* OrderLine - 6
* ShipmentLine - 7
* InvoiceLine - 8
*/
if (log.isLoggable(Level.CONFIG)) log.config("C_Order_ID=" + C_Order_ID);
p_order = new MOrder (Env.getCtx(), C_Order_ID, getTrxName()); // save
Vector> data = new Vector>();
StringBuilder sql = new StringBuilder("SELECT "
// subtract drafted lines from this or other orders IDEMPIERE-2889
+ "l.QtyOrdered-SUM(COALESCE(m.Qty,0))" // 1
+ "-COALESCE((SELECT SUM(MovementQty) FROM M_InOutLine iol JOIN M_InOut io ON iol.M_InOut_ID=io.M_InOut_ID WHERE l.C_OrderLine_ID=iol.C_OrderLine_ID AND io.Processed='N'),0),"
+ " 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
+ " p.M_Locator_ID, loc.Value, " // 5..6
+ " COALESCE(l.M_Product_ID,0),COALESCE(p.Name,c.Name), " // 7..8
+ " po.VendorProductNo, " // 9
+ " l.C_OrderLine_ID,l.Line " // 10..11
+ "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 M_Locator loc on (p.M_Locator_ID=loc.M_Locator_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), p.M_Locator_ID, loc.Value, po.VendorProductNo, "
+ "l.M_Product_ID,COALESCE(p.Name,c.Name), l.Line,l.C_OrderLine_ID "
+ "ORDER BY l.Line");
//
if (log.isLoggable(Level.FINER)) log.finer(sql.toString());
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
pstmt = DB.prepareStatement(sql.toString(), getTrxName());
pstmt.setInt(1, C_Order_ID);
rs = pstmt.executeQuery();
while (rs.next())
{
Vector