diff --git a/client/src/main/java/org/spin/wms/form/OutBoundOrder.java b/client/src/main/java/org/spin/wms/form/OutBoundOrder.java new file mode 100644 index 0000000000..40fc7e7291 --- /dev/null +++ b/client/src/main/java/org/spin/wms/form/OutBoundOrder.java @@ -0,0 +1,1355 @@ +/****************************************************************************** + * Product: Adempiere ERP & CRM Smart Business Solution * + * 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 * + * Copyright (C) 2003-2013 E.R.P. Consultores y Asociados, C.A. * + * All Rights Reserved. * + * Contributor(s): Yamel Senih www.erpya.com * + *****************************************************************************/ +package org.spin.wms.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.Arrays; +import java.util.Optional; +import java.util.Vector; +import java.util.logging.Level; + +import org.adempiere.exceptions.AdempiereException; +import org.adempiere.exceptions.DocTypeNotFoundException; +import org.compiere.minigrid.IMiniTable; +import org.compiere.model.MDocType; +import org.compiere.model.MLocator; +import org.compiere.model.MOrderLine; +import org.compiere.model.MProduct; +import org.compiere.model.MRefList; +import org.compiere.model.MRole; +import org.compiere.model.MStorage; +import org.compiere.model.MUOM; +import org.compiere.model.MWarehouse; +import org.adempiere.core.domains.models.X_C_Order; +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.Util; +import org.compiere.util.ValueNamePair; +import org.adempiere.core.domains.models.I_DD_Order; +import org.eevolution.distribution.model.MDDOrderLine; +import org.eevolution.wms.model.MWMInOutBound; +import org.eevolution.wms.model.MWMInOutBoundLine; + +/** + * @author Yamel Senih 2011-06-24, 12:57 + * @author Carlos Parada, cparada@erpcya.com + *
  • FR [ 1 ] Add Support to generate load order with non stocked product + * @see https://github.com/erpcya/FTA/issues/1 + * + */ +public class OutBoundOrder { + + /** Logger */ + public static CLogger log = CLogger.getCLogger(OutBoundOrder.class); + + public final int SELECT = 0; + public final int ORDER = 2; + /** Lines */ + public final int OL_WAREHOUSE = 1; + public final int ORDER_LINE = 2; + public final int OL_PRODUCT = 3; + public final int OL_UOM = 4; + public final int OL_QTY_ON_HAND = 5; + public final int OL_QTY = 6; + public final int OL_WEIGHT = 7; + public final int OL_VOLUME = 8; + public final int OL_SEQNO = 9; + public final int OL_QTY_ENTERED = 10; + public final int OL_UOM_CONVERSION = 11; + public final int OL_QTY_ORDERED = 12; + public final int OL_QTY_RESERVERD = 13; + public final int OL_QTY_INVOICED = 14; + public final int OL_QTY_DELIVERED = 15; + public final int OL_QTY_IN_TRANSIT = 16; + public final int OL_DELIVERY_RULE = 17; + /** Warehouse and Product */ + public final int SW_PRODUCT = 0; + public final int SW_UOM = 1; + public final int SW_WAREHOUSE = 2; + public final int SW_QTY_ON_HAND = 3; + public final int SW_QTY_IN_TRANSIT = 4; + public final int SW_QTY_SET = 5; + public final int SW_QTY_AVAILABLE = 6; + + /** Buffer */ + public Vector m_BufferSelect = null; + + public StringBuffer m_Symmary = new StringBuffer(); + public StringBuffer m_QueryAdd = new StringBuffer(); + + /** Client */ + protected int clientId = 0; + /** Organization */ + protected int orgId = 0; + /** Warehouse */ + protected int salesRegionId = 0; + /** Sales Rep */ + protected int salesRepId = 0; + /** Warehouse */ + protected int warehouseId = 0; + /** Operation Type */ + protected String movementType = null; + /** Document Action */ + protected String documentAction = null; + /** Document Type */ + protected int docTypeId = 0; + /** Document Type Target*/ + protected int docTypeTargetId = 0; + /** Delivery Rule */ + protected String deliveryRule = null; + /** Delivery Via Rule */ + protected String deliveryViaRule = null; + /** Document Date */ + protected Timestamp documentDate = null; + /** Shipment Date */ + protected Timestamp shipmentDate = null; + /** Shipper */ + protected int shipperId = 0; + /** Load Capacity */ + protected BigDecimal payloadCapacity = Env.ZERO; + /** Volume Capacity */ + protected BigDecimal volumeCapacity = Env.ZERO; + /** Weight Unit Measure */ + protected int uOMWeightId = 0; + /** Volume Unit Measure */ + protected int uOMVolumeId = 0; + /** Weight Precision */ + protected int weightPrecision = 0; + /** Volume Precision */ + protected int volumePrecision = 0; + /** Rows Selected */ + protected int rowsSelected = 0; + /** UOM Weight Symbol */ + protected String uOMWeightSymbol = null; + /** UOM Volume Symbol */ + protected String uOMVolumeSymbol = null; + + /** Total Weight */ + protected BigDecimal totalWeight = Env.ZERO; + /** Total Volume */ + protected BigDecimal totalVolume = Env.ZERO; + + /** Max Sequence */ + protected int maxSeqNo = 0; + + /** Load Order */ + protected MWMInOutBound outBoundOrder = null; + /** Outbound Locator Id */ + protected Integer locatorId = null; + + /** + * Get Order data from parameters + * @return Vector> + */ + protected Vector> getOrderData(IMiniTable orderTable) { + // Load Validation Flag + ResultSet rs = null; + PreparedStatement pstmt = null; + // + Vector> data = new Vector>(); + StringBuffer sql = null; + if (movementType.equals(I_DD_Order.Table_Name)) { + //Query for Material Movement + sql = new StringBuffer("SELECT " + + "wr.Name Warehouse, ord.DD_Order_ID, ord.DocumentNo, " + // 1..3 + "ord.DateOrdered, ord.DatePromised, reg.Name, cit.Name, sr.Name SalesRep, " + // 4..8 + "cp.Name Partner, bploc.Name, " + // 9..10 + "loc.Address1, loc.Address2, loc.Address3, loc.Address4, ord.C_BPartner_Location_ID, ord.Weight, ord.Volume " + // 11..17 + "FROM DD_Order ord " + + "INNER JOIN DD_OrderLine lord ON(lord.DD_Order_ID = ord.DD_Order_ID) " + + "INNER JOIN M_Product pr ON(pr.M_Product_ID = lord.M_Product_ID) " + + "INNER JOIN C_BPartner cp ON(cp.C_BPartner_ID = ord.C_BPartner_ID) " + + "INNER JOIN AD_User sr ON(sr.AD_User_ID = ord.SalesRep_ID) " + + "INNER JOIN M_Locator wloc ON(wloc.M_Locator_ID = lord.M_Locator_ID) " + + "INNER JOIN M_Warehouse wr ON(wr.M_Warehouse_ID = wloc.M_Warehouse_ID) " + + "INNER JOIN C_BPartner_Location bploc ON(bploc.C_BPartner_Location_ID = ord.C_BPartner_Location_ID) " + + "INNER JOIN C_Location loc ON(loc.C_Location_ID = bploc.C_Location_ID) " + + "LEFT JOIN C_Region reg ON(reg.C_Region_ID = loc.C_Region_ID) " + + "LEFT JOIN C_City cit ON(cit.C_City_ID = loc.C_City_ID) " + + "LEFT JOIN (SELECT lord.DD_OrderLine_ID, " + + " (COALESCE(lord.QtyOrdered, 0) - " + + " SUM(" + + " CASE WHEN (c.IsDelivered = 'N' AND lc.DD_Order_ID IS NOT NULL AND c.DocStatus = 'CO') " + + " THEN COALESCE(lc.MovementQty, 0) " + + " ELSE 0 " + + " END" + + " )" + + " ) QtyAvailable " + + " FROM DD_OrderLine lord " + + " LEFT JOIN WM_InOutBoundLine lc ON(lc.DD_OrderLine_ID = lord.DD_OrderLine_ID) " + + " LEFT JOIN WM_InOutBound c ON(c.WM_InOutBound_ID = lc.WM_InOutBound_ID) " + + " WHERE lord.M_Product_ID IS NOT NULL " + + " GROUP BY lord.DD_Order_ID, lord.DD_OrderLine_ID, lord.QtyOrdered " + + " ORDER BY lord.DD_OrderLine_ID ASC) qafl " + + " ON(qafl.DD_OrderLine_ID = lord.DD_OrderLine_ID) " + + "WHERE wr.IsActive = 'Y' " + + "AND ord.DocStatus = 'CO' " + + "AND COALESCE(qafl.QtyAvailable, 0) > 0 " + + "AND ord.AD_Client_ID=? "); + if (orgId > 0) + sql.append("AND lord.AD_Org_ID=? "); + if (warehouseId > 0) + sql.append("AND wr.M_Warehouse_ID=? "); + if (salesRegionId > 0) + sql.append("AND bploc.C_SalesRegion_ID=? "); + if (salesRepId > 0) + sql.append("AND ord.SalesRep_ID=? "); + if (docTypeId > 0) + sql.append("AND ord.C_DocType_ID=? "); + + // Group By + sql.append("GROUP BY wr.Name, ord.DD_Order_ID, ord.DocumentNo, ord.DateOrdered, " + + "ord.DatePromised, ord.Weight, ord.Volume, sr.Name, cp.Name, bploc.Name, " + + "reg.Name, cit.Name, loc.Address1, loc.Address2, loc.Address3, loc.Address4, ord.C_BPartner_Location_ID "); + + // Having + sql.append("HAVING (SUM(COALESCE(lord.QtyOrdered, 0)) - SUM(COALESCE(lord.QtyInTransit, 0)) - SUM(COALESCE(lord.QtyDelivered, 0))) > 0 "); + + + // Order By + sql.append("ORDER BY ord.DD_Order_ID ASC"); + + // role security + } else {//Query for Sales Order + sql = new StringBuffer("SELECT " + + "wr.Name Warehouse, ord.C_Order_ID, ord.DocumentNo, " + // 1..3 + "ord.DateOrdered, ord.DatePromised, reg.Name, cit.Name, sr.Name SalesRep, " + // 4..8 + "cp.Name Partner, bploc.Name, " + // 9..10 + "loc.Address1, loc.Address2, loc.Address3, loc.Address4, ord.C_BPartner_Location_ID, ord.Weight, ord.Volume " + // 11..17 + "FROM C_Order ord " + + "INNER JOIN C_OrderLine lord ON(lord.C_Order_ID = ord.C_Order_ID) " + + "INNER JOIN M_Product pr ON(pr.M_Product_ID = lord.M_Product_ID) " + + "INNER JOIN C_BPartner cp ON(cp.C_BPartner_ID = ord.C_BPartner_ID) " + + "INNER JOIN M_Warehouse wr ON(wr.M_Warehouse_ID = ord.M_Warehouse_ID) " + + "INNER JOIN C_BPartner_Location bploc ON(bploc.C_BPartner_Location_ID = ord.C_BPartner_Location_ID) " + + "INNER JOIN C_Location loc ON(loc.C_Location_ID = bploc.C_Location_ID) " + + "LEFT JOIN AD_User sr ON(sr.AD_User_ID = ord.SalesRep_ID) " + + "LEFT JOIN C_Region reg ON(reg.C_Region_ID = loc.C_Region_ID) " + + "LEFT JOIN C_City cit ON(cit.C_City_ID = loc.C_City_ID) " + + "LEFT JOIN (SELECT lord.C_OrderLine_ID, " + + " (COALESCE(lord.QtyOrdered, 0) - " + + " SUM(" + + " CASE WHEN (c.IsDelivered = 'N' AND lc.C_Order_ID IS NOT NULL AND c.DocStatus = 'CO') " + + " THEN COALESCE(lc.MovementQty, 0) " + + " ELSE 0 " + + " END" + + " )" + + " ) QtyAvailable " + + " FROM C_OrderLine lord " + + " LEFT JOIN WM_InOutBoundLine lc ON(lc.C_OrderLine_ID = lord.C_OrderLine_ID) " + + " LEFT JOIN WM_InOutBound c ON(c.WM_InOutBound_ID = lc.WM_InOutBound_ID) " + + " WHERE lord.M_Product_ID IS NOT NULL " + + " GROUP BY lord.C_Order_ID, lord.C_OrderLine_ID, lord.QtyOrdered " + + " ORDER BY lord.C_OrderLine_ID ASC) qafl " + + " ON(qafl.C_OrderLine_ID = lord.C_OrderLine_ID) " + + "WHERE ord.IsSOTrx = 'Y' " + + "AND wr.IsActive = 'Y' " + + "AND ord.DocStatus = 'CO' " + + "AND COALESCE(qafl.QtyAvailable, 0) > 0 " + + "AND ord.AD_Client_ID=? "); + if (orgId > 0) + sql.append("AND lord.AD_Org_ID=? "); + if (warehouseId > 0) + sql.append("AND lord.M_Warehouse_ID=? "); + if (salesRegionId > 0) + sql.append("AND bploc.C_SalesRegion_ID=? "); + if (salesRepId > 0) + sql.append("AND ord.SalesRep_ID=? "); + if (docTypeId > 0 ) + sql.append("AND ord.C_DocType_ID=? "); + + // Group By + sql.append("GROUP BY wr.Name, ord.C_Order_ID, ord.DocumentNo, ord.DateOrdered, " + + "ord.DatePromised, ord.Weight, ord.Volume, sr.Name, cp.Name, bploc.Name, " + + "reg.Name, cit.Name, loc.Address1, loc.Address2, loc.Address3, loc.Address4, ord.C_BPartner_Location_ID "); + + // Having + sql.append("HAVING (SUM(COALESCE(lord.QtyOrdered, 0)) - SUM(COALESCE(lord.QtyDelivered, 0))) > 0 "); + + + // Order By + sql.append("ORDER BY ord.C_Order_ID ASC"); + + // role security + } + // + log.fine("LoadOrderSQL=" + sql.toString()); + // + try { + // + int param = 1; + int column = 1; + + pstmt = DB.prepareStatement(sql.toString(), null); + + pstmt.setInt(param++, Env.getAD_Client_ID(Env.getCtx())); + + if (orgId > 0) + pstmt.setInt(param++, orgId); + if (warehouseId > 0) + pstmt.setInt(param++, warehouseId); + if (salesRegionId > 0) + pstmt.setInt(param++, salesRegionId); + if (salesRepId > 0) + pstmt.setInt(param++, salesRepId); + if (docTypeId > 0) + pstmt.setInt(param++, docTypeId); + + log.fine("AD_Org_ID=" + orgId); + log.fine("M_Warehouse_ID=" + warehouseId); + log.fine("SalesRep_ID=" + salesRepId); + log.fine("C_DocType_ID=" + docTypeId); + + rs = pstmt.executeQuery(); + while (rs.next()) { + column = 1; + Vector line = new Vector(); + line.add(new Boolean(false)); // 0-Selection + line.add(rs.getString(column++)); // 1-Warehouse + KeyNamePair pp = new KeyNamePair(rs.getInt(column++), rs.getString(column++)); + line.add(pp); // 2-DocumentNo + line.add(rs.getTimestamp(column++)); // 3-DateOrdered + line.add(rs.getTimestamp(column++)); // 4-DatePromised + line.add(rs.getString(column++)); // 5-Region + line.add(rs.getString(column++)); // 6-City + line.add(rs.getString(column++)); // 7-Sales Representative + line.add(rs.getString(column++)); // 8-Business Partner + line.add(rs.getString(column++)); // 9-Location + line.add(rs.getString(column++)); // 10-Address 1 + line.add(rs.getString(column++)); // 11-Address 2 + line.add(rs.getString(column++)); // 12-Address 3 + line.add(rs.getString(column++)); // 13-Address 4 + line.add(rs.getBigDecimal(column++)); // 14-Weight + line.add(rs.getBigDecimal(column++)); // 15-Volume + // + data.add(line); + } + + } catch (SQLException e) { + log.log(Level.SEVERE, sql.toString(), e); + } + finally{ + DB.close(rs, pstmt); + } + + return data; + } + + /** + * Get Order Line Data + * @param orderTable + * @return + * @return StringBuffer + */ + protected StringBuffer getQueryLine(IMiniTable orderTable) { + StringBuffer sql = null; + + log.config("getQueryLine"); + + if (movementType.equals(I_DD_Order.Table_Name)) { + int rows = orderTable.getRowCount(); + rowsSelected = 0; + StringBuffer sqlWhere = new StringBuffer("ord.DD_Order_ID IN(0"); + for (int i = 0; i < rows; i++) { + if (((Boolean)orderTable.getValueAt(i, 0)).booleanValue()) { + int ID = ((KeyNamePair)orderTable.getValueAt(i, ORDER)).getKey(); + sqlWhere.append(","); + sqlWhere.append(ID); + rowsSelected ++; + } + } + sqlWhere.append(")"); + + sql = new StringBuffer("SELECT alm.M_Warehouse_ID, alm.Name Warehouse, lord.DD_OrderLine_ID OrderLine_ID, ord.DocumentNo, lord.M_Product_ID, " + + "(pro.Name || COALESCE(' - ' || productattribute(lord.M_AttributeSetInstance_ID), '')) Product, " + + "pro.C_UOM_ID, uomp.UOMSymbol, s.QtyOnHand, " + + "lord.QtyOrdered, lord.C_UOM_ID Order_UOM_ID, uom.UOMSymbol Order_UOMSymbol, lord.QtyReserved, 0 QtyInvoiced, lord.QtyDelivered, " + + "SUM(" + + " COALESCE(CASE " + + " WHEN (c.IsDelivered = 'N' AND lc.DD_OrderLine_ID IS NOT NULL AND c.DocStatus = 'CO') " + + " THEN lc.MovementQty " + + " ELSE 0 " + + " END, 0)" + + ") QtyLoc, " + + "(COALESCE(lord.QtyOrdered, 0) - COALESCE(lord.QtyInTransit, 0) - COALESCE(lord.QtyDelivered, 0) - " + + " SUM(" + + " COALESCE(CASE " + + " WHEN (c.IsDelivered = 'N' AND lc.DD_OrderLine_ID IS NOT NULL AND c.DocStatus = 'CO') " + + " THEN lc.MovementQty " + + " ELSE 0 " + + " END, 0)" + + " )" + + ") Qty, " + + "pro.Weight, pro.Volume, ord.DeliveryRule, pro.IsStocked, lord.QtyEntered " + + "FROM DD_Order ord " + + "INNER JOIN DD_OrderLine lord ON(lord.DD_Order_ID = ord.DD_Order_ID) " + + "INNER JOIN M_Locator l ON(l.M_Locator_ID = lord.M_Locator_ID) " + + "INNER JOIN M_Warehouse alm ON(alm.M_Warehouse_ID = l.M_Warehouse_ID) " + + "INNER JOIN M_Product pro ON(pro.M_Product_ID = lord.M_Product_ID) " + + "INNER JOIN C_UOM uom ON(uom.C_UOM_ID = lord.C_UOM_ID) " + + "INNER JOIN C_UOM uomp ON(uomp.C_UOM_ID = pro.C_UOM_ID) " + + "LEFT JOIN WM_InOutBoundLine lc ON(lc.DD_OrderLine_ID = lord.DD_OrderLine_ID) " + + "LEFT JOIN WM_InOutBound c ON(c.WM_InOutBound_ID = lc.WM_InOutBound_ID) " + + "LEFT JOIN (" + + " SELECT l.M_Warehouse_ID, st.M_Product_ID, " + + " COALESCE(SUM(st.QtyOnHand), 0) QtyOnHand, " + + " (CASE WHEN p.M_AttributeSet_ID IS NOT NULL THEN COALESCE(st.M_AttributeSetInstance_ID, 0) ELSE 0 END) M_AttributeSetInstance_ID " + + " FROM M_Storage st " + + " INNER JOIN M_Product p ON(p.M_Product_ID = st.M_Product_ID) " + + " INNER JOIN M_Locator l ON(l.M_Locator_ID = st.M_Locator_ID) " + + " GROUP BY l.M_Warehouse_ID, st.M_Product_ID, p.M_AttributeSet_ID, 4) s " + + " ON(s.M_Product_ID = lord.M_Product_ID " + + " AND s.M_Warehouse_ID = l.M_Warehouse_ID " + + " AND lord.M_AttributeSetInstance_ID = s.M_AttributeSetInstance_ID) ") + .append("WHERE ") + .append(sqlWhere).append(" "); + // Group By + sql.append("GROUP BY alm.M_Warehouse_ID, lord.DD_Order_ID, lord.DD_OrderLine_ID, " + + "alm.Name, ord.DocumentNo, lord.M_Product_ID, lord.M_AttributeSetInstance_ID, " + + "pro.Name, lord.C_UOM_ID, uom.UOMSymbol, lord.QtyEntered, " + + "pro.C_UOM_ID, uomp.UOMSymbol, lord.QtyOrdered, lord.QtyReserved, " + + "lord.QtyDelivered, pro.Weight, pro.Volume, ord.DeliveryRule, s.QtyOnHand,pro.IsStocked, lord.QtyEntered").append(" "); + // Having + sql.append("HAVING (COALESCE(lord.QtyOrdered, 0) - COALESCE(lord.QtyInTransit, 0) - COALESCE(lord.QtyDelivered, 0) - " + + " SUM(" + + " COALESCE(CASE " + + " WHEN (c.IsDelivered = 'N' AND lc.DD_OrderLine_ID IS NOT NULL AND c.DocStatus = 'CO') " + + " THEN lc.MovementQty " + + " ELSE 0 " + + " END, 0)" + + " )" + + " ) > 0 OR pro.IsStocked = 'N' ").append(" "); + // Order By + sql.append("ORDER BY lord.DD_Order_ID ASC"); + + } else { + + int rows = orderTable.getRowCount(); + rowsSelected = 0; + StringBuffer sqlWhere = new StringBuffer("ord.C_Order_ID IN(0"); + for (int i = 0; i < rows; i++) { + if (((Boolean)orderTable.getValueAt(i, 0)).booleanValue()) { + int ID = ((KeyNamePair)orderTable.getValueAt(i, ORDER)).getKey(); + sqlWhere.append(","); + sqlWhere.append(ID); + rowsSelected ++; + } + } + sqlWhere.append(")"); + + sql = new StringBuffer("SELECT lord.M_Warehouse_ID, alm.Name Warehouse, lord.C_OrderLine_ID OrderLine_ID, ord.DocumentNo, lord.M_Product_ID, " + + "(pro.Name || COALESCE(' - ' || productattribute(lord.M_AttributeSetInstance_ID), '')) Product, " + + "pro.C_UOM_ID, uomp.UOMSymbol, s.QtyOnHand, " + + "lord.QtyOrdered, lord.C_UOM_ID Order_UOM_ID, uom.UOMSymbol Order_UOMSymbol, lord.QtyReserved, lord.QtyInvoiced, lord.QtyDelivered, " + + "SUM(" + + " COALESCE(CASE " + + " WHEN (c.IsDelivered = 'N' AND lc.C_OrderLine_ID IS NOT NULL AND c.DocStatus = 'CO') " + + " THEN lc.MovementQty - COALESCE(iol.MovementQty, 0) " + + " ELSE 0 " + + " END, 0)" + + ") QtyLoc, " + + "(COALESCE(lord.QtyOrdered, 0) - COALESCE(lord.QtyDelivered, 0) - " + + " SUM(" + + " COALESCE(CASE " + + " WHEN (c.IsDelivered = 'N' AND lc.C_OrderLine_ID IS NOT NULL AND c.DocStatus = 'CO') " + + " THEN lc.MovementQty - COALESCE(iol.MovementQty, 0) " + + " ELSE 0 " + + " END, 0)" + + " )" + + ") Qty, " + + "pro.Weight, pro.Volume, ord.DeliveryRule, pro.IsStocked, lord.QtyEntered " + + "FROM C_Order ord " + + "INNER JOIN C_OrderLine lord ON(lord.C_Order_ID = ord.C_Order_ID) " + + "INNER JOIN M_Warehouse alm ON(alm.M_Warehouse_ID = lord.M_Warehouse_ID) " + + "INNER JOIN M_Product pro ON(pro.M_Product_ID = lord.M_Product_ID) " + + "INNER JOIN C_UOM uom ON(uom.C_UOM_ID = lord.C_UOM_ID) " + + "INNER JOIN C_UOM uomp ON(uomp.C_UOM_ID = pro.C_UOM_ID) " + + "LEFT JOIN WM_InOutBoundLine lc ON(lc.C_OrderLine_ID = lord.C_OrderLine_ID) " + + "LEFT JOIN WM_InOutBound c ON(c.WM_InOutBound_ID = lc.WM_InOutBound_ID) " + + "LEFT JOIN (SELECT iol.WM_InOutBoundLine_ID, SUM(iol.MovementQty) MovementQty " + + " FROM M_InOut io " + + " INNER JOIN M_InOutLine iol ON(iol.M_InOut_ID = io.M_InOut_ID) " + + " WHERE io.DocStatus IN('CO', 'CL') " + + " AND iol.WM_InOutBoundLine_ID IS NOT NULL" + + " GROUP BY iol.WM_InOutBoundLine_ID) iol ON(iol.WM_InOutBoundLine_ID = lc.WM_InOutBoundLine_ID) " + + "LEFT JOIN (" + + " SELECT l.M_Warehouse_ID, st.M_Product_ID, " + + " COALESCE(SUM(st.QtyOnHand), 0) QtyOnHand, " + + " (CASE WHEN p.M_AttributeSet_ID IS NOT NULL THEN COALESCE(st.M_AttributeSetInstance_ID, 0) ELSE 0 END) M_AttributeSetInstance_ID " + + " FROM M_Storage st " + + " INNER JOIN M_Product p ON(p.M_Product_ID = st.M_Product_ID) " + + " INNER JOIN M_Locator l ON(l.M_Locator_ID = st.M_Locator_ID) " + + " GROUP BY l.M_Warehouse_ID, st.M_Product_ID, p.M_AttributeSet_ID, 4) s " + + " ON(s.M_Product_ID = lord.M_Product_ID " + + " AND s.M_Warehouse_ID = lord.M_Warehouse_ID " + + " AND lord.M_AttributeSetInstance_ID = s.M_AttributeSetInstance_ID) ") + .append("WHERE ") + .append(sqlWhere).append(" "); + // Group By + sql.append("GROUP BY lord.M_Warehouse_ID, lord.C_Order_ID, lord.C_OrderLine_ID, " + + "alm.Name, ord.DocumentNo, lord.M_Product_ID, lord.M_AttributeSetInstance_ID, " + + "pro.Name, lord.C_UOM_ID, uom.UOMSymbol, lord.QtyEntered, " + + "pro.C_UOM_ID, uomp.UOMSymbol, lord.QtyOrdered, lord.QtyReserved, " + + "lord.QtyDelivered, lord.QtyInvoiced, pro.Weight, pro.Volume, ord.DeliveryRule, s.QtyOnHand, pro.IsStocked, lord.QtyEntered").append(" "); + // Having + sql.append("HAVING (COALESCE(lord.QtyOrdered, 0) - COALESCE(lord.QtyDelivered, 0) - " + + " SUM(" + + " COALESCE(CASE " + + " WHEN (c.IsDelivered = 'N' AND lc.C_OrderLine_ID IS NOT NULL AND c.DocStatus = 'CO') " + + " THEN lc.MovementQty - COALESCE(iol.MovementQty, 0) " + + " ELSE 0 " + + " END, 0)" + + " )" + + " ) > 0 OR pro.IsStocked = 'N' ").append(" "); + // Order By + sql.append("ORDER BY lord.C_Order_ID ASC"); + + } + // + log.fine("SQL Line Order=" + sql.toString()); + // Return + return sql; + } + + /** + * Get Order Column Names + * @return + * @return Vector + */ + protected Vector getOrderColumnNames() { + // Header Info + Vector columnNames = new Vector(); + columnNames.add(Msg.translate(Env.getCtx(), "Select")); + columnNames.add(Msg.translate(Env.getCtx(), "M_Warehouse_ID")); + columnNames.add(Util.cleanAmp(Msg.translate(Env.getCtx(), "DocumentNo"))); + columnNames.add(Msg.translate(Env.getCtx(), "DateOrdered")); + columnNames.add(Msg.translate(Env.getCtx(), "DatePromised")); + columnNames.add(Msg.translate(Env.getCtx(), "C_Region_ID")); + columnNames.add(Msg.translate(Env.getCtx(), "C_City_ID")); + columnNames.add(Msg.translate(Env.getCtx(), "SalesRep_ID")); + columnNames.add(Msg.translate(Env.getCtx(), "C_BPartner_ID")); + columnNames.add(Msg.translate(Env.getCtx(), "C_Location_ID")); + columnNames.add(Msg.translate(Env.getCtx(), "Address1")); + columnNames.add(Msg.translate(Env.getCtx(), "Address2")); + columnNames.add(Msg.translate(Env.getCtx(), "Address3")); + columnNames.add(Msg.translate(Env.getCtx(), "Address4")); + columnNames.add(Msg.translate(Env.getCtx(), "Weight")); + columnNames.add(Msg.translate(Env.getCtx(), "Volume")); + // + return columnNames; + } + + /** + * Set Order Column Class on Table + * @param orderTable + * @return void + */ + protected void setOrderColumnClass(IMiniTable orderTable) { + int i = 0; + orderTable.setColumnClass(i++, Boolean.class, false); // 0-Selection + orderTable.setColumnClass(i++, String.class, true); // 1-Warehouse + orderTable.setColumnClass(i++, String.class, true); // 2-DocumentNo + orderTable.setColumnClass(i++, Timestamp.class, true); // 3-DateOrdered + orderTable.setColumnClass(i++, Timestamp.class, true); // 4-DatePromiset + orderTable.setColumnClass(i++, String.class, true); // 5-Region + orderTable.setColumnClass(i++, String.class, true); // 6-City + orderTable.setColumnClass(i++, String.class, true); // 7-Sales Representative + orderTable.setColumnClass(i++, String.class, true); // 8-Business Partner + orderTable.setColumnClass(i++, String.class, true); // 9-Location + orderTable.setColumnClass(i++, String.class, true); // 10-Address 1 + orderTable.setColumnClass(i++, String.class, true); // 11-Address 2 + orderTable.setColumnClass(i++, String.class, true); // 12-Address 3 + orderTable.setColumnClass(i++, String.class, true); // 13-Address 4 + orderTable.setColumnClass(i++, BigDecimal.class, true); // 14-Weight + orderTable.setColumnClass(i++, BigDecimal.class, true); // 15-Volume + // + // Table UI + orderTable.autoSize(); + } + + /** + * Get Order Line Data + * @param orderLineTable + * @param sqlPrep + * @return + * @return Vector> + */ + protected Vector> getOrderLineData(IMiniTable orderLineTable, StringBuffer sqlPrep) { + Vector> data = new Vector>(); + PreparedStatement pstmt = null; + ResultSet rs= null; + + log.fine("LoadOrderLineSQL=" + sqlPrep.toString()); + try { + + pstmt = DB.prepareStatement(sqlPrep.toString(), null); + // Parameter + rs = pstmt.executeQuery(); + KeyNamePair warehouse = null; + KeyNamePair documentNo = null; + KeyNamePair product = null; + KeyNamePair productUOM = null; + KeyNamePair orderUOM = null; + BigDecimal qtyOnHand = Env.ZERO; + BigDecimal qtyReserved = Env.ZERO; + BigDecimal qtyInvoiced = Env.ZERO; + BigDecimal qtyDelivered = Env.ZERO; + BigDecimal qtyInTransit = Env.ZERO; + BigDecimal qtyOrdered = Env.ZERO; + BigDecimal qty = Env.ZERO; + BigDecimal qtyEntered = Env.ZERO; + BigDecimal weight = Env.ZERO; + BigDecimal volume = Env.ZERO; + String deliveryRuleKey = null; + + boolean isStocked = false; + int precision = 0; + // + while (rs.next()) { + warehouse = new KeyNamePair(rs.getInt("M_Warehouse_ID"), rs.getString("Warehouse")); + documentNo = new KeyNamePair(rs.getInt("OrderLine_ID"), rs.getString("DocumentNo")); + product = new KeyNamePair(rs.getInt("M_Product_ID"), rs.getString("Product")); + productUOM = new KeyNamePair(rs.getInt("C_UOM_ID"), rs.getString("UOMSymbol")); + qtyOnHand = rs.getBigDecimal("QtyOnHand"); + qtyOrdered = rs.getBigDecimal("QtyOrdered"); + orderUOM = new KeyNamePair(rs.getInt("Order_UOM_ID"), rs.getString("Order_UOMSymbol")); + qtyReserved = rs.getBigDecimal("QtyReserved"); + qtyInvoiced = rs.getBigDecimal("QtyInvoiced"); + qtyDelivered = rs.getBigDecimal("QtyDelivered"); + qtyInTransit = rs.getBigDecimal("QtyLoc"); + qty = rs.getBigDecimal("Qty"); + weight = rs.getBigDecimal("Weight"); + volume = rs.getBigDecimal("Volume"); + deliveryRuleKey = rs.getString("DeliveryRule"); + qtyEntered = rs.getBigDecimal("QtyEntered"); + //FR [ 1 ] + isStocked = (rs.getString("IsStocked") == null? "N": rs.getString("IsStocked")).equals("Y"); + // Get Precision + precision = MUOM.getPrecision(Env.getCtx(), productUOM.getKey()); + // + // Valid Null + if(qtyOnHand == null) + qtyOnHand = Env.ZERO; + //FR [ 1 ] + if (!isStocked) { + qtyOnHand = qty; + } + if(Util.isEmpty(deliveryRuleKey)) { + deliveryRuleKey = X_C_Order.DELIVERYRULE_Availability; + } + // Delivery Rule + ValueNamePair deliveryRule = new ValueNamePair(deliveryRuleKey, + MRefList.getListName(Env.getCtx(), + X_C_Order.DELIVERYRULE_AD_Reference_ID, deliveryRuleKey)); + // Valid Quantity On Hand + if(!deliveryRule.getID().equals(X_C_Order.DELIVERYRULE_Force) && !deliveryRule.getID().equals(X_C_Order.DELIVERYRULE_Manual)) { + //FR [ 1 ] + BigDecimal diff = ((BigDecimal)(isStocked ? Env.ONE : Env.ZERO)).multiply(qtyOnHand.subtract(qty).setScale(precision, BigDecimal.ROUND_HALF_UP)); + // Set Quantity + if(diff.doubleValue() < 0) { + qty = qty + .subtract(diff.abs()) + .setScale(precision, BigDecimal.ROUND_HALF_UP); + } + // Valid Zero + if(qty.doubleValue() <= 0) + continue; + } + // Fill Row + Vector line = new Vector(); + line.add(new Boolean(false)); // 0-Selection + line.add(warehouse); // 1-Warehouse + line.add(documentNo); // 2-DocumentNo + line.add(product); // 3-Product + line.add(productUOM); // 4-Unit Product + line.add(qtyOnHand); // 5-QtyOnHand + line.add(qty); // 6-Quantity + line.add(weight.multiply(qty)); // 7-Weight + line.add(volume.multiply(qty)); // 8-Volume + line.add(Env.ZERO); // 9-SeqNo + line.add(qtyEntered); // 10-QtyEntered + line.add(orderUOM); // 11-UOM-Conversion + line.add(qtyOrdered); // 12-QtyOrdered + line.add(qtyReserved); // 13-QtyReserved + line.add(qtyInvoiced); // 14-QtyInvoiced + line.add(qtyDelivered); // 15-QtyDelivered + line.add(qtyInTransit); // 16-QtyInTransit + line.add(deliveryRule); // 17-Delivery Rule + // Add Data + data.add(line); + } + } catch (SQLException e) { + log.log(Level.SEVERE, sqlPrep.toString(), e); + } + finally{ + DB.close(rs, pstmt); + } + // + return data; + } + + /** + * Get Column Name on Order Line + * @return + * @return Vector + */ + protected Vector getOrderLineColumnNames() { + // Header Info + Vector columnNames = new Vector(); + columnNames.add(Msg.getMsg(Env.getCtx(), "Select")); + columnNames.add(Msg.translate(Env.getCtx(), "M_Warehouse_ID")); + columnNames.add(Util.cleanAmp(Msg.translate(Env.getCtx(), "DocumentNo"))); + columnNames.add(Msg.translate(Env.getCtx(), "M_Product_ID")); + columnNames.add(Msg.translate(Env.getCtx(), "C_UOM_ID")); + columnNames.add(Msg.translate(Env.getCtx(), "QtyOnHand")); + columnNames.add(Msg.translate(Env.getCtx(), "Qty")); + columnNames.add(Msg.translate(Env.getCtx(), "Weight") + (Util.isEmpty(uOMWeightSymbol)? "": " (" + uOMWeightSymbol + ")")); + columnNames.add(Msg.translate(Env.getCtx(), "Volume") + (Util.isEmpty(uOMWeightSymbol)? "": " (" + uOMVolumeSymbol + ")")); + columnNames.add(Msg.translate(Env.getCtx(), "LoadSequence")); + columnNames.add(Msg.translate(Env.getCtx(), "QtyEntered")); + columnNames.add(Msg.translate(Env.getCtx(), "C_UOM_ID")); + columnNames.add(Msg.translate(Env.getCtx(), "QtyOrdered")); + columnNames.add(Msg.translate(Env.getCtx(), "QtyReserved")); + columnNames.add(Msg.translate(Env.getCtx(), "QtyInvoiced")); + columnNames.add(Msg.translate(Env.getCtx(), "QtyDelivered")); + columnNames.add(Msg.translate(Env.getCtx(), "QtyInTransit")); + columnNames.add(Msg.translate(Env.getCtx(), "DeliveryRule")); + return columnNames; + } + + /** + * Get Stock Column Names + * @return + * @return Vector + */ + protected Vector getStockColumnNames() { + // Header Info + Vector columnNames = new Vector(); + columnNames.add(Msg.translate(Env.getCtx(), "M_Product_ID")); + columnNames.add(Msg.translate(Env.getCtx(), "C_UOM_ID")); + columnNames.add(Msg.translate(Env.getCtx(), "M_Warehouse_ID")); + columnNames.add(Msg.translate(Env.getCtx(), "QtyOnHand")); + columnNames.add(Msg.translate(Env.getCtx(), "QtyInTransit")); + columnNames.add(Msg.translate(Env.getCtx(), "Qty")); + columnNames.add(Msg.translate(Env.getCtx(), "PickedQty")); + return columnNames; + } + + /** + * Set Stock Column Class + * @param stockTable + * @return void + */ + protected void setStockColumnClass(IMiniTable stockTable) { + int i = 0; + stockTable.setColumnClass(i++, String.class, true); // 1-Product + stockTable.setColumnClass(i++, String.class, true); // 2-Unit of Measure + stockTable.setColumnClass(i++, String.class, true); // 3-Warehouse + stockTable.setColumnClass(i++, BigDecimal.class, true); // 4-Quantity On Hand + stockTable.setColumnClass(i++, BigDecimal.class, true); // 5-Quantity In Transit + stockTable.setColumnClass(i++, BigDecimal.class, true); // 6-Quantity Set + stockTable.setColumnClass(i++, BigDecimal.class, true); // 7-Quantity Available For Load + // Table UI + stockTable.autoSize(); + } + + + /** + * Set Order Line Class on Table + * @param orderLineTable + * @return void + */ + protected void setOrderLineColumnClass(IMiniTable orderLineTable) { + int i = 0; + orderLineTable.setColumnClass(i++, Boolean.class, false); // 0-Selection + orderLineTable.setColumnClass(i++, String.class, true); // 1-Warehouse + orderLineTable.setColumnClass(i++, String.class, true); // 2-DocumentNo + orderLineTable.setColumnClass(i++, String.class, true); // 3-Product + orderLineTable.setColumnClass(i++, String.class, true); // 4-Unit Measure Product + orderLineTable.setColumnClass(i++, BigDecimal.class, true); // 5-QtyOnHand + orderLineTable.setColumnClass(i++, BigDecimal.class, false); // 6-Quantity + orderLineTable.setColumnClass(i++, BigDecimal.class, true); // 7-Weight + orderLineTable.setColumnClass(i++, BigDecimal.class, true); // 8-Volume + orderLineTable.setColumnClass(i++, Integer.class, false); // 9-Sequence No + orderLineTable.setColumnClass(i++, BigDecimal.class, true); // 10-QtyEntered + orderLineTable.setColumnClass(i++, String.class, true); // 11-Unit Measure Conversion + orderLineTable.setColumnClass(i++, BigDecimal.class, true); // 12-QtyOrdered + orderLineTable.setColumnClass(i++, BigDecimal.class, true); // 13-QtyReserved + orderLineTable.setColumnClass(i++, BigDecimal.class, true); // 14-QtyInvoiced + orderLineTable.setColumnClass(i++, BigDecimal.class, true); // 15-QtyDelivered + orderLineTable.setColumnClass(i++, BigDecimal.class, true); // 16-QtyInTransit + orderLineTable.setColumnClass(i++, String.class, true); // 17-Delivery Rule + // Table UI + orderLineTable.autoSize(); + } + + /** + * Validate Quantity + * @param orderLineTable + * @return + */ + public String validateQuantity(IMiniTable orderLineTable) { + StringBuffer errorMessage = new StringBuffer(); + DecimalFormat format = DisplayType.getNumberFormat(DisplayType.Number); + for (int row = 0; row < orderLineTable.getRowCount(); row++) { + if (((Boolean)orderLineTable.getValueAt(row, 0)).booleanValue()) { + KeyNamePair order = (KeyNamePair)orderLineTable.getValueAt(row, ORDER_LINE); + int productId = ((KeyNamePair)orderLineTable.getValueAt(row, OL_PRODUCT)).getKey(); + BigDecimal qty = (BigDecimal) orderLineTable.getValueAt(row, OL_QTY); + BigDecimal qtyOrdered = (BigDecimal) orderLineTable.getValueAt(row, OL_QTY_ORDERED); + BigDecimal qtyOrderLine = (BigDecimal) orderLineTable.getValueAt(row, OL_QTY_IN_TRANSIT); + BigDecimal qtyDelivered = (BigDecimal) orderLineTable.getValueAt(row, OL_QTY_DELIVERED); + KeyNamePair uom = (KeyNamePair) orderLineTable.getValueAt(row, OL_UOM); + ValueNamePair deliveryRule = (ValueNamePair) orderLineTable.getValueAt(row, OL_DELIVERY_RULE); + // + MProduct product = MProduct.get(Env.getCtx(), productId); + int precision = MUOM.getPrecision(Env.getCtx(), uom.getKey()); + // + if(!deliveryRule.getID().equals(X_C_Order.DELIVERYRULE_Force) && !deliveryRule.getID().equals(X_C_Order.DELIVERYRULE_Manual)) { + BigDecimal qtyAvailable = qtyOrdered + .subtract(qtyDelivered) + .subtract(qtyOrderLine) + .setScale(precision, BigDecimal.ROUND_HALF_UP); + // + if(qty.setScale(precision, BigDecimal.ROUND_HALF_UP).doubleValue() + > qtyAvailable.doubleValue()) { + if(errorMessage.length() > 0) { + errorMessage.append(Env.NL); + } else { + errorMessage.append("@Error@ @Qty@ > @QtyAvailable@ "); + } + errorMessage.append("@C_Order_ID@ " + order.getName()) + .append(", @M_Product_ID@ " + product.getValue() + "-" + product.getName()) + .append(", @Qty@ " + format.format(qty)) + .append(", @QtyAvailable@ " + format.format(qtyAvailable)); + } + } + } + } + // + if(errorMessage.length() > 0) { + return errorMessage.toString(); + } + // + return null; + } + + /** + * Generate Load Order + * @param trxName + * @param orderLineTable + * @return + * @return String + */ + public String generateLoadOrder(String trxName, IMiniTable orderLineTable) { + int quantity = 0; + int rows = orderLineTable.getRowCount(); + outBoundOrder = new MWMInOutBound(Env.getCtx(), 0, trxName); + MWMInOutBoundLine outBoundOrderLine = null; + // + BigDecimal totalWeight = Env.ZERO; + BigDecimal totalVolume = Env.ZERO; + // + if(orgId < 0) { + orgId = Env.getAD_Org_ID(Env.getCtx()); + } + if(warehouseId < 0) { + warehouseId = Env.getContextAsInt(Env.getCtx(), "#M_Warehouse_ID"); + } + outBoundOrder.setAD_Org_ID(orgId); + outBoundOrder.setDateTrx(documentDate); + outBoundOrder.setPickDate(documentDate); + outBoundOrder.setShipDate(shipmentDate); + if (docTypeTargetId > 0) { + outBoundOrder.setC_DocType_ID(docTypeTargetId); + } else { + Optional defaultDocumentType = Arrays.asList(MDocType.getOfDocBaseType(Env.getCtx(), MDocType.DOCBASETYPE_WarehouseManagementOrder)) + .stream() + .filter(documentType -> documentType.isSOTrx()) + .findFirst(); + + if (!defaultDocumentType.isPresent()) { + throw new DocTypeNotFoundException(MDocType.DOCBASETYPE_WarehouseManagementOrder, ""); + } else { + outBoundOrder.setC_DocType_ID(defaultDocumentType.get().getC_DocType_ID()); + } + docTypeTargetId = defaultDocumentType.get().getC_DocType_ID(); + } + // Validate + String errorMessage = validateQuantity(orderLineTable); + if(!Util.isEmpty(errorMessage)) { + throw new AdempiereException(errorMessage); + } + // Set Warehouse + if(warehouseId > 0) { + outBoundOrder.setM_Warehouse_ID(warehouseId); + } + // Delivery Rule + if(!Util.isEmpty(deliveryRule)) { + outBoundOrder.setDeliveryRule(deliveryRule); + } + // Delivery Via Rule + if(!Util.isEmpty(deliveryViaRule)) { + outBoundOrder.setDeliveryViaRule(deliveryViaRule); + } + // Set Shipper + if(shipperId > 0) { + outBoundOrder.setM_Shipper_ID(shipperId); + } + // Save Order + outBoundOrder.setDocStatus(MWMInOutBound.DOCSTATUS_Drafted); + outBoundOrder.setIsSOTrx(true); + outBoundOrder.saveEx(); + // Loop for add Lines + for (int i = 0; i < rows; i++) { + if (((Boolean)orderLineTable.getValueAt(i, 0)).booleanValue()) { + int orderLineId = ((KeyNamePair)orderLineTable.getValueAt(i, ORDER_LINE)).getKey(); + int productId = ((KeyNamePair)orderLineTable.getValueAt(i, OL_PRODUCT)).getKey(); + BigDecimal qty = (BigDecimal) orderLineTable.getValueAt(i, OL_QTY); + BigDecimal weight = (BigDecimal) orderLineTable.getValueAt(i, OL_WEIGHT); + BigDecimal volume = (BigDecimal) orderLineTable.getValueAt(i, OL_VOLUME); + // New Line + outBoundOrderLine = new MWMInOutBoundLine(outBoundOrder); + // Set Values + outBoundOrderLine.setAD_Org_ID(orgId); + MProduct product = MProduct.get(Env.getCtx(), productId); + if (movementType.equals(I_DD_Order.Table_Name)) { + outBoundOrderLine.setDD_OrderLine_ID(orderLineId); + MDDOrderLine line = new MDDOrderLine(Env.getCtx(), orderLineId, trxName); + outBoundOrderLine.setDD_Order_ID(line.getDD_Order_ID()); + outBoundOrderLine.setDD_OrderLine_ID(line.getDD_OrderLine_ID()); + outBoundOrderLine.setM_AttributeSetInstance_ID(line.getM_AttributeSetInstance_ID()); + outBoundOrderLine.setC_UOM_ID(product.getC_UOM_ID()); + outBoundOrderLine.setM_Locator_ID(line.getM_Locator_ID()); + outBoundOrderLine.setM_LocatorTo_ID(line.getM_LocatorTo_ID()); + } else { + outBoundOrderLine.setC_OrderLine_ID(orderLineId); + MOrderLine line = new MOrderLine(Env.getCtx(), orderLineId, trxName); + outBoundOrderLine.setC_Order_ID(line.getC_Order_ID()); + outBoundOrderLine.setC_OrderLine_ID(line.getC_OrderLine_ID()); + outBoundOrderLine.setM_AttributeSetInstance_ID(line.getM_AttributeSetInstance_ID()); + outBoundOrderLine.setC_UOM_ID(product.getC_UOM_ID()); + if (locatorId == null) + locatorId = getDefaultLocator(line.getM_Warehouse_ID(), productId, line.getM_AttributeSetInstance_ID(), qty, trxName); + + outBoundOrderLine.setM_LocatorTo_ID(locatorId); + } + outBoundOrderLine.setM_Product_ID(productId); + outBoundOrderLine.setMovementQty(qty); + outBoundOrderLine.setPickedQty(qty); + + // Add Weight + totalWeight = totalWeight.add(weight); + // Add Volume + totalVolume = totalVolume.add(volume); + // Save Line + outBoundOrderLine.saveEx(); + // Add Count + quantity ++; + } + } + // Set Header Weight + outBoundOrder.setWeight(totalWeight); + // Set Header Volume + outBoundOrder.setVolume(totalVolume); + // Save Header + outBoundOrder.saveEx(); + // Validate Document Action + if(Util.isEmpty(documentAction)) { + documentAction = MWMInOutBound.DOCACTION_Complete; + } + // Complete Order + outBoundOrder.setDocAction(documentAction); + outBoundOrder.processIt(documentAction); + outBoundOrder.saveEx(); + // Valid Error + errorMessage = outBoundOrder.getProcessMsg(); + if(errorMessage != null + && outBoundOrder.getDocStatus().equals(MWMInOutBound.DOCSTATUS_Invalid)) + throw new AdempiereException(errorMessage); + // Message + return Msg.parseTranslation(Env.getCtx(), "@Created@ = [" + outBoundOrder.getDocumentNo() + + "] || @LineNo@" + " = [" + quantity + "]" + (errorMessage != null? "\n@Errors@:" + errorMessage: "")); + } + + /** + * Get Default locator based on stock, else default + * @param warehouseId + * @param productId + * @param attributeSetInstanceId + * @param quantity + * @param transactionName + * @return + * @return int + */ + private int getDefaultLocator(int warehouseId, int productId, int attributeSetInstanceId, BigDecimal quantity, String transactionName) { + int locatorId = MStorage.getM_Locator_ID(warehouseId, + productId, + attributeSetInstanceId, + quantity, + transactionName); + if(locatorId > 0) { + return locatorId; + } + MWarehouse warehouse = MWarehouse.get(Env.getCtx(), warehouseId); + MLocator locator = MLocator.getDefault(warehouse); + if(locator == null) { + MProduct product = MProduct.get(Env.getCtx(), productId); + throw new AdempiereException("@M_Locator_ID@ @NotFound@ [@M_Product_ID@: " + product.getValue() + " - " + product.getName() + " @M_Warehouse_ID@: " + warehouse.getName() + "]"); + } + return locator.getM_Locator_ID(); + } + + /** + * Load the Default Values + * @return void + */ + protected void loadDefaultValues() { + uOMWeightId = getC_UOM_Weight_ID(); + uOMVolumeId = getC_UOM_Volume_ID(); + // Get Weight Precision + if(uOMWeightId > 0) { + weightPrecision = MUOM.getPrecision(Env.getCtx(), uOMWeightId); + } + // Get Volume Precision + if(uOMVolumeId > 0) { + volumePrecision = MUOM.getPrecision(Env.getCtx(), uOMVolumeId); + } + } + + /** + * Get default UOM + * @return + * @return int + */ + protected int getC_UOM_Weight_ID() { + return DB.getSQLValue(null, "SELECT ci.C_UOM_Weight_ID " + + "FROM AD_ClientInfo ci " + + "WHERE ci.AD_Client_ID = ?", clientId); + } + + /** + * Get default Volume UOM + * @return + * @return int + */ + protected int getC_UOM_Volume_ID() { + return DB.getSQLValue(null, "SELECT ci.C_UOM_Volume_ID " + + "FROM AD_ClientInfo ci " + + "WHERE ci.AD_Client_ID = ?", clientId); + } + + /** + * Get Data for Document Type from Operation Type + * @return + * @return KeyNamePair[] + */ + protected KeyNamePair[] getDataDocumentType() { + + if(movementType == null) + return null; + // Document Base Type + String docBaseType = (movementType.equals(I_DD_Order.Table_Name)? "DOO": "SOO"); + // + String sql = MRole.getDefault().addAccessSQL("SELECT doc.C_DocType_ID, TRIM(doc.Name) " + + "FROM C_DocType doc " + + "WHERE doc.DocBaseType = '" + docBaseType + "' " + + "AND (doc.DocSubTypeSO IS NULL OR doc.DocSubTypeSO NOT IN('RM', 'OB')) " + + "ORDER BY doc.Name", "doc", MRole.SQL_FULLYQUALIFIED, MRole.SQL_RW); + return DB.getKeyNamePairs(null, sql, false, new Object[]{}); + } + + /** + * Load the Warehouse from Organization + * @return + * @return KeyNamePair[] + */ + protected KeyNamePair[] getDataWarehouse() { + String sql = "SELECT w.M_Warehouse_ID, w.Name " + + "FROM M_Warehouse w " + + "WHERE w.IsActive = 'Y' " + + "AND w.AD_Org_ID = " + orgId + " " + + "ORDER BY w.Name"; + return DB.getKeyNamePairs(null, sql, false, new Object[]{}); + } + + /** + * Get Quantity in Transit + * @param productId + * @param warehouseId + * @return + * @return BigDecimal + */ + protected BigDecimal getQtyInTransit(int productId, int warehouseId) { + // Valid + if(productId == 0 + || warehouseId == 0) + return Env.ZERO; + // + String sql = "SELECT COALESCE(SUM(lc.MovementQty), 0) QtyLoc " + + "FROM WM_InOutBound c " + + "INNER JOIN WM_InOutBoundLine lc ON(lc.WM_InOutBound_ID = c.WM_InOutBound_ID) " + + "WHERE lc.M_Product_ID = ? " + + "AND lc.M_Warehouse_ID = ? " + + "AND c.DocStatus = 'CO' " + + "AND c.IsDelivered = 'N'"; + // Query + BigDecimal quantityInTransit = DB.getSQLValueBD(null, sql, new Object[]{productId, warehouseId}); + if(quantityInTransit == null) + quantityInTransit = Env.ZERO; + // Return + return quantityInTransit; + } + + /** + Verify if a sequence exist on table + * @param orderLineTable + * @param seqNo + * @return + */ + public boolean existsSeqNo(IMiniTable orderLineTable, int row, int seqNo) { + log.info("existsSeqNo"); + int rows = orderLineTable.getRowCount(); + int seqNoTable = 0; + for (int i = 0; i < rows; i++) { + if (((Boolean)orderLineTable.getValueAt(i, SELECT)).booleanValue() + && i != row) { + seqNoTable = (Integer) orderLineTable.getValueAt(i, OL_SEQNO); + if(seqNo == seqNoTable) { + return true; + } + } + } + return false; + } + + /** + * Valid Quantity on Stock + * @param stockTable + * @return + * @return String + */ + public String validStock(IMiniTable stockTable) { + log.info("validStock"); + return null; +// int rows = stockTable.getRowCount(); +// StringBuffer msg = new StringBuffer(); +// for (int i = 0; i < rows; i++) { +// // Get Values +// String product = ((KeyNamePair) stockTable.getValueAt(i, SW_PRODUCT)).getName(); +// String warehouse = ((KeyNamePair) stockTable.getValueAt(i, SW_WAREHOUSE)).getName(); +// BigDecimal m_QtyOnHand = ((BigDecimal) stockTable.getValueAt(i, SW_QTY_ON_HAND)); +// BigDecimal m_QtyInTransit = ((BigDecimal) stockTable.getValueAt(i, SW_QTY_IN_TRANSIT)); +// BigDecimal m_QtySet = ((BigDecimal) stockTable.getValueAt(i, SW_QTY_SET)); +// BigDecimal m_QtyAvailable = ((BigDecimal) stockTable.getValueAt(i, SW_QTY_AVAILABLE)); +// // Valid +// if(m_QtyAvailable.compareTo(Env.ZERO) >= 0) +// continue; +// // First Row +// if(msg.length() == 0) { +// msg.append("@QtyInsufficient@"); +// } +// // Add to Msg +// msg.append(Env.NL) +// .append("*") +// .append(product) +// .append("[") +// .append("@M_Warehouse_ID@=").append(warehouse) +// .append(" @QtyAvailable@=").append(m_QtyOnHand.subtract(m_QtyInTransit).doubleValue()) +// .append(" @QtyToDeliver@=").append(m_QtySet.doubleValue()) +// .append(" @PickedQty@=").append(m_QtyAvailable.doubleValue()) +// .append("]"); +// } +// // +// return msg.length() > 0 +// ? msg.toString() +// : null; + } + + /** + * Load Buffer + * @param orderLineTable + * @return void + */ + public void loadBuffer(IMiniTable orderLineTable) { + log.info("Load Buffer"); + int rows = orderLineTable.getRowCount(); + int m_C_OrderLine_ID = 0; + BigDecimal qty = Env.ZERO; + Integer seqNo = 0; + m_BufferSelect = new Vector(); + + for (int i = 0; i < rows; i++) { + if (((Boolean)orderLineTable.getValueAt(i, SELECT)).booleanValue()) { + m_C_OrderLine_ID = ((KeyNamePair)orderLineTable.getValueAt(i, ORDER_LINE)).getKey(); + qty = (BigDecimal)orderLineTable.getValueAt(i, OL_QTY); + seqNo = (Integer)orderLineTable.getValueAt(i, OL_SEQNO); + m_BufferSelect.addElement( + new BufferTableSelect(m_C_OrderLine_ID, qty, seqNo)); + } + } + } + + /** + * Verify if is Selected + * @param m_Record_ID + * @return + * @return BufferTableSelect + */ + private BufferTableSelect isSelect(int m_Record_ID) { + log.info("Is Select " + m_Record_ID); + if(m_BufferSelect != null) { + for(int i = 0; i < m_BufferSelect.size(); i++) { + if(m_BufferSelect.get(i).getRecord_ID() == m_Record_ID) { + return m_BufferSelect.get(i); + } + } + } + return null; + } + + /** + * Set the values from buffer + * @param orderLineTable + * @return void + */ + protected void setValueFromBuffer(IMiniTable orderLineTable) { + log.info("Set Value From Buffer"); + if(m_BufferSelect != null) { + int rows = orderLineTable.getRowCount(); + int m_C_OrderLine_ID = 0; + BufferTableSelect bts = null; + for (int i = 0; i < rows; i++) { + m_C_OrderLine_ID = ((KeyNamePair)orderLineTable.getValueAt(i, ORDER_LINE)).getKey(); + bts = isSelect(m_C_OrderLine_ID); + if(bts != null) { + orderLineTable.setValueAt(true, i, SELECT); + orderLineTable.setValueAt(bts.getQty(), i, OL_QTY); + orderLineTable.setValueAt(bts.getSeqNo(), i, OL_SEQNO); + } + } + } + } + + /** + * Verify if more one is selected + * @param table + * @return + * @return boolean + */ + protected boolean moreOneSelect(IMiniTable table) { + int rows = table.getRowCount(); + int cont = 0; + for (int i = 0; i < rows; i++) { + if (((Boolean)table.getValueAt(i, SELECT)).booleanValue()) { + cont++; + if(cont > 1) { + return true; + } + } + } + return false; + } + + /** + * @author Yamel Senih 2012-03-08, 23:46:54 + * + */ + public class BufferTableSelect { + /** + * Default constructor + * @param recordId + * @param qty + * @param seqNo + */ + public BufferTableSelect(int recordId, BigDecimal qty, Integer seqNo){ + this.recordId = recordId; + this.qty = qty; + this.seqNo = seqNo; + } + + /** + * Set Record Identifier + * @param recordId + */ + public void setRecord_ID(int recordId){ + this.recordId = recordId; + } + + /** + * Get Record Identifier + * @return + */ + public int getRecord_ID(){ + return this.recordId; + } + + /** + * Set Quantity + * @param qty + */ + public void setQty(BigDecimal qty){ + this.qty = qty; + } + + /** + * Get Quantity + * @return + */ + public BigDecimal getQty(){ + return this.qty; + } + + /** + * Set Sequence + * @param seqNo + */ + public void setSeqNo(Integer seqNo){ + this.seqNo = seqNo; + } + + /** + * Get Sequence + * @return + */ + public Integer getSeqNo(){ + return this.seqNo; + } + + public String toString(){ + return "Record_ID = " + recordId + + " qty = " + qty + + "seqNo = " + seqNo; + } + + /** Record ID */ + private int recordId = 0; + /** Quantity */ + private BigDecimal qty = Env.ZERO; + /** Sequence */ + private Integer seqNo = 0; + } +} diff --git a/src/main/webapp/WEB-INF/src/org/spin/wms/form/WOutBoundOrder.java b/src/main/webapp/WEB-INF/src/org/spin/wms/form/WOutBoundOrder.java new file mode 100644 index 0000000000..c4de858c6f --- /dev/null +++ b/src/main/webapp/WEB-INF/src/org/spin/wms/form/WOutBoundOrder.java @@ -0,0 +1,1201 @@ +/****************************************************************************** + * Product: Adempiere ERP & CRM Smart Business Solution * + * 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 * + * Copyright (C) 2003-2013 E.R.P. Consultores y Asociados, C.A. * + * All Rights Reserved. * + * Contributor(s): Raul Muñoz www.erpya.com * + *****************************************************************************/ +package org.spin.wms.form; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.sql.Timestamp; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Vector; + +import org.adempiere.core.domains.models.I_C_Order; +import org.adempiere.core.domains.models.I_DD_Order; +import org.adempiere.exceptions.ValueChangeEvent; +import org.adempiere.exceptions.ValueChangeListener; +import org.adempiere.webui.component.Button; +import org.adempiere.webui.component.ConfirmPanel; +import org.adempiere.webui.component.Datebox; +import org.adempiere.webui.component.Grid; +import org.adempiere.webui.component.GridFactory; +import org.adempiere.webui.component.Label; +import org.adempiere.webui.component.ListModelTable; +import org.adempiere.webui.component.Listbox; +import org.adempiere.webui.component.ListboxFactory; +import org.adempiere.webui.component.Panel; +import org.adempiere.webui.component.Row; +import org.adempiere.webui.component.Rows; +import org.adempiere.webui.component.WListbox; +import org.adempiere.webui.editor.WTableDirEditor; +import org.adempiere.webui.editor.WLocatorEditor; +import org.adempiere.webui.event.WTableModelEvent; +import org.adempiere.webui.event.WTableModelListener; +import org.adempiere.webui.panel.ADForm; +import org.adempiere.webui.panel.CustomForm; +import org.adempiere.webui.panel.IFormController; +import org.adempiere.webui.panel.StatusBarPanel; +import org.adempiere.webui.session.SessionManager; +import org.adempiere.webui.window.FDialog; +import org.compiere.minigrid.IMiniTable; +import org.compiere.model.MDocType; +import org.compiere.model.MLocatorLookup; +import org.compiere.model.MLookup; +import org.compiere.model.MLookupFactory; +import org.compiere.model.MProduct; +import org.compiere.model.MQuery; +import org.compiere.model.MUOM; +import org.compiere.model.PrintInfo; +import org.compiere.print.MPrintFormat; +import org.compiere.print.ReportCtl; +import org.compiere.print.ReportEngine; +import org.compiere.process.DocAction; +import org.compiere.util.DisplayType; +import org.compiere.util.Env; +import org.compiere.util.KeyNamePair; +import org.compiere.util.Msg; +import org.compiere.util.Trx; +import org.compiere.util.TrxRunnable; +import org.compiere.util.Util; +import org.compiere.util.ValueNamePair; +import org.eevolution.wms.model.MWMInOutBound; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zk.ui.event.Events; +import org.zkoss.zkex.zul.Borderlayout; +import org.zkoss.zkex.zul.Center; +import org.zkoss.zkex.zul.North; +import org.zkoss.zkex.zul.South; +import org.zkoss.zul.Separator; +import org.zkoss.zul.Space; + +/** + * View for generate Out Bound Order + * @author Raul Muñoz rmunoz@erpya.com + * @author Yamel Senih ysenih@erpya.com + * @author Carlos Parada cparada@erpya.com + */ +public class WOutBoundOrder extends OutBoundOrder + implements IFormController, EventListener, WTableModelListener, ValueChangeListener +{ + + /** + * + * *** Constructor *** + */ + public WOutBoundOrder() { + Env.setContext(Env.getCtx(), form.getWindowNo(), "IsSOTrx", "Y"); // defaults to no + try { + dyInit(); + zkInit(); + // Load Default Values + loadDefaultValues(); + + } catch(Exception e) { + log.severe("Error:" + e.getLocalizedMessage()); + } + } + + + /** Window No */ + private int m_WindowNo = 0; + + /** Custom Form */ + private CustomForm form = new CustomForm(); + + private Borderlayout mainLayout = new Borderlayout(); + + private Grid parameterLayout = GridFactory.newGridLayout(); + private Panel parameterPanel = new Panel(); + /** Organization */ + private WTableDirEditor organizationPick = null; + /** Sales Region */ + private WTableDirEditor salesRegionPick = null; + /** Sales Representative */ + private Label salesRepLabel = new Label(); + private WTableDirEditor salesRepSearch = null; + /** Warehouse */ + private Label warehouseLabel = new Label(); + private Listbox warehouseSearch = ListboxFactory.newDropdownListbox(); + /** Operation Type */ + private Label operationTypeLabel = new Label(); + private Listbox operationTypePick = ListboxFactory.newDropdownListbox(); + /** Document Type */ + private Label docTypeSourceLabel = new Label(); + private Listbox docTypeSourceSearch = ListboxFactory.newDropdownListbox(); + /** Document Type Target */ + private WTableDirEditor docTypeTargetPick = null; + /** Delivery Rule */ + private Label deliveryRuleLabel = new Label(); + private WTableDirEditor deliveryRulePick = null; + /** Delivery Via Rule */ + private Label deliveryViaRuleLabel = new Label(); + private WTableDirEditor deliveryViaRulePick = null; + /** Document Date */ + private Label labelDocumentDate = new Label(); + private Datebox documentDateField = new Datebox(); + /** Shipment Date */ + private Label labelShipmentDate = new Label(); + private Datebox shipmentDateField = new Datebox(); + /** Shipper */ + private Label shipperLabel = new Label(); + private WTableDirEditor shipperPick = null; + private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + /** Locator */ + protected Label locatorLabel = new Label(); + protected WLocatorEditor locatorField = new WLocatorEditor(); + + /** Panels */ + private Panel orderPanel = new Panel(); + private Panel orderLinePanel = new Panel(); + private Label orderLabel = new Label(); + private Label stockLabel = new Label(); + private Label orderLineLabel = new Label(); + private Borderlayout orderLayout = new Borderlayout(); + private Borderlayout orderLineLayout = new Borderlayout(); + private Borderlayout stockLayout = new Borderlayout(); + private Panel stockPanel = new Panel(); + private Borderlayout medioLayout = new Borderlayout(); + private Panel medioPanel = new Panel(); + private Panel southPanel = new Panel(); + private Panel allocationPanel = new Panel(); + private Grid allocationLayout = GridFactory.newGridLayout(); + private Borderlayout infoLayout = new Borderlayout(); + private South southAdded = new South(); + /** Collapsible Panel for Parameter */ + private North north = new North(); + private North northAdded = new North(); + /** Select all Button */ + private Button selectAllButton = new Button(); + /** Search */ + private Button searchButton; + /** Order Table */ + private WListbox w_orderTable = ListboxFactory.newDataTable(); + /** Order Line Table */ + private WListbox orderLineTable = ListboxFactory.newDataTable(); + /** Stock Table */ + private WListbox stockTable = ListboxFactory.newDataTable();; + private ListModelTable stockModel = null; + private int count = 0; + /** Payment Info */ + private Label paymentInfo = new Label(); + /** Stock Info */ + private Label stockInfo = new Label(); + /** Invoice Info */ + private Label invoiceInfo = new Label(); + private Label invoiceLabel = new Label(); + /** Document Action */ + private Label docActionLabel = new Label(); + private WTableDirEditor docActionPick; + /** Confirm Panel */ + private ConfirmPanel confirmPanel; + + private StatusBarPanel statusBar = new StatusBarPanel(); + /** + * Static zkInit + * @throws Exception + */ + private void zkInit() throws Exception + { + form.appendChild(mainLayout); + confirmPanel = new ConfirmPanel(true); + confirmPanel.addActionListener(this); + searchButton = confirmPanel.createButton(ConfirmPanel.A_REFRESH); + // + mainLayout.setWidth("99%"); + mainLayout.setHeight("100%"); + parameterPanel.appendChild(parameterLayout); + + Rows rows = null; + Row row = null; + parameterLayout.setWidth("100%"); + rows = parameterLayout.newRows(); + row = rows.newRow(); + // + shipperLabel.setText(Msg.translate(Env.getCtx(), "M_Shipper_ID")); + salesRegionPick.getLabel().setText(Msg.translate(Env.getCtx(), "C_SalesRegion_ID")); + salesRepLabel.setText(Msg.translate(Env.getCtx(), "SalesRep_ID")); + orderPanel.appendChild(orderLayout); + orderLinePanel.appendChild(orderLineLayout); + medioPanel.appendChild(medioLayout); + stockPanel.appendChild(stockLayout); + // Operation Type + operationTypeLabel.setText(Msg.translate(Env.getCtx(), "MovementType")); + // Document Type + docTypeSourceLabel.setText(Msg.translate(Env.getCtx(), "C_DocType_ID")); + // Document Type Target + docTypeTargetPick.getLabel().setText(Msg.translate(Env.getCtx(), "C_DocTypeTarget_ID")); + // Delivery Rule + deliveryRuleLabel.setText(Msg.translate(Env.getCtx(), "DeliveryRule")); + // Delivery Via Rule + deliveryViaRuleLabel.setText(Msg.translate(Env.getCtx(), "DeliveryViaRule")); + // Document Action + docActionLabel.setText(Msg.translate(Env.getCtx(), "DocAction")); + // Date + labelDocumentDate.setText(Msg.translate(Env.getCtx(), "DateDoc")); + labelShipmentDate.setText(Msg.translate(Env.getCtx(), "ShipDate")); + + // Warehouse + warehouseLabel.setText(Msg.translate(Env.getCtx(), "M_Warehouse_ID")); + searchButton.setLabel(Msg.translate(Env.getCtx(), "Search")); + + orderLabel.setText(" " + Msg.translate(Env.getCtx(), "C_Order_ID")); + stockLabel.setText("yruy " + Msg.translate(Env.getCtx(), "C_Order_ID")); + orderLineLabel.setText(" " + Msg.translate(Env.getCtx(), "C_OrderLine_ID")); + orderPanel.appendChild(orderLayout); + orderPanel.setWidth("100%"); + orderPanel.setHeight("100%"); + orderLayout.setWidth("100%"); + orderLayout.setHeight("50%"); + orderLayout.setStyle("border: none"); + stockPanel.appendChild(stockLayout); + stockPanel.setWidth("100%"); + stockPanel.setHeight("100%"); + stockLayout.setWidth("100%"); + stockLayout.setHeight("50%"); + stockLayout.setStyle("border: none"); + // + organizationPick.getLabel().setText(Msg.translate(Env.getCtx(), "AD_Org_ID")); + row.appendChild(organizationPick.getLabel().rightAlign()); + row.appendChild(organizationPick.getComponent()); + // Movement Type + row.appendChild(operationTypeLabel.rightAlign()); + row.appendChild(operationTypePick); + // Document Type + row.appendChild(docTypeSourceLabel.rightAlign()); + row.appendChild(docTypeSourceSearch); + // Storage + row = rows.newRow(); + row.appendChild(warehouseLabel.rightAlign()); + row.appendChild(warehouseSearch); + row.appendChild(salesRegionPick.getLabel().rightAlign()); + row.appendChild(salesRegionPick.getComponent()); + row.appendChild(salesRepLabel.rightAlign()); + row.appendChild(salesRepSearch.getComponent()); + row = rows.newRow(); + // Document Type Target + row.appendChild(docTypeTargetPick.getLabel().rightAlign()); + row.appendChild(docTypeTargetPick.getComponent()); + // Delivery Rule + row.appendChild(deliveryRuleLabel.rightAlign()); + row.appendChild(deliveryRulePick.getComponent()); + // Delivery Via Rule + row.appendChild(deliveryViaRuleLabel.rightAlign()); + row.appendChild(deliveryViaRulePick.getComponent()); + row = rows.newRow(); + // Shipper + row.appendChild(shipperLabel.rightAlign()); + row.appendChild(shipperPick.getComponent()); + // Document Date + row.appendChild(labelDocumentDate.rightAlign()); + row.appendChild(documentDateField); + // Shipment Date + row.appendChild(labelShipmentDate.rightAlign()); + row.appendChild(shipmentDateField); + // Entry Ticket + row = rows.newRow(); + // Search + row.appendChild(new Space()); + row.appendChild(new Space()); + row.appendChild(new Space()); + row.appendChild(searchButton); + searchButton.addActionListener(this); + // Document Action + row.appendChild(docActionLabel.rightAlign()); + row.appendChild(docActionPick.getComponent()); + // + northAdded = new North(); + northAdded.setCollapsible(true); + northAdded.setTitle("Parameter"); + + northAdded.setStyle("border-style: solid; border-width: 1px; border-color: rgb(0,0,255)"); + mainLayout.appendChild(northAdded); + northAdded.appendChild(parameterPanel); + + South south = new South(); + south.setStyle("border: none"); + mainLayout.appendChild(south); + + south.appendChild(southPanel); + southPanel.appendChild(allocationPanel); + southPanel.appendChild(new Separator()); + southPanel.appendChild(statusBar); + allocationPanel.appendChild(allocationLayout); + allocationLayout.setWidth("100%"); + rows = allocationLayout.newRows(); + row = rows.newRow(); + row.appendChild(selectAllButton); + selectAllButton.setImage("/images/SelectAll24.png"); + + row.appendChild(locatorLabel.rightAlign()); + row.appendChild(locatorField.getComponent()); + row.appendChild(new Space()); + row.appendChild(confirmPanel); + + invoiceLabel.setText(" " + Msg.translate(Env.getCtx(), "C_OrderLine_ID")); + + invoiceInfo.setText("."); + stockInfo.setText("."); + paymentInfo.setText("."); + orderPanel.appendChild(orderLayout); + orderPanel.setWidth("100%"); + orderPanel.setHeight("100%"); + orderLayout.setWidth("100%"); + orderLayout.setHeight("100%"); + orderLayout.setStyle("border: none"); + + orderLinePanel.appendChild(orderLineLayout); + orderLinePanel.setWidth("100%"); + orderLinePanel.setHeight("100%"); + orderLineLayout.setWidth("100%"); + orderLineLayout.setHeight("100%"); + orderLineLayout.setStyle("border: none"); + + stockPanel.appendChild(stockLayout); + stockPanel.setWidth("100%"); + stockPanel.setHeight("100%"); + stockLayout.setWidth("100%"); + stockLayout.setHeight("100%"); + stockLayout.setStyle("border: none"); + + medioPanel.appendChild(medioLayout); + medioPanel.setWidth("100%"); + medioPanel.setHeight("100%"); + medioLayout.setWidth("100%"); + medioLayout.setHeight("100%"); + medioLayout.setStyle("border: none"); + + + north = new North(); + north.setStyle("border: none"); + orderLayout.appendChild(north); + north.appendChild(orderLabel); + south = new South(); + south.setStyle("border: none"); + orderLayout.appendChild(south); + south.appendChild(paymentInfo.rightAlign()); + Center center = new Center(); + orderLayout.appendChild(center); + center.appendChild(w_orderTable); + w_orderTable.setWidth("99%"); + w_orderTable.setHeight("99%"); + center.setStyle("border: none"); + + north = new North(); + north.setStyle("border: none"); + orderLineLayout.appendChild(north); + north.appendChild(invoiceLabel); + south = new South(); + south.setStyle("border: none"); + south.appendChild(invoiceInfo.rightAlign()); + center = new Center(); + orderLineLayout.appendChild(center); + center.appendChild(orderLineTable); + orderLineLayout.appendChild(south); + orderLineTable.setWidth("100%"); + orderLineTable.setHeight("100%"); + center.setStyle("border: 1px solid #000; height:50%"); + + north = new North(); + north.setStyle("border: none; height:90%;"); + stockLayout.appendChild(north); + north.setTitle(Msg.translate(Env.getCtx(), "WarehouseStockGroup")); + north.appendChild(invoiceLabel); + north.setFlex(true); + south = new South(); + south.setStyle("border: none"); + south.appendChild(stockInfo.rightAlign()); + center = new Center(); + stockLayout.appendChild(center); + center.appendChild(stockTable); + stockLayout.appendChild(south); + stockTable.setWidth("100%"); + stockTable.setHeight("100%"); + center.setStyle("border: 1px solid #000; height:50%"); + north = new North(); + north.setStyle("border: none; height:90%;"); + north.setFlex(true); + medioLayout.appendChild(north); + north.appendChild(orderLineTable); + southAdded = new South(); + + medioLayout.appendChild(southAdded); + southAdded.appendChild(stockTable); + southAdded.setTitle(Msg.translate(Env.getCtx(), "WarehouseStockGroup")); + southAdded.setStyle("border-style: solid; border-width: 1px; border-color: rgb(0,0,255)"); + southAdded.addEventListener("onClick", this); + southAdded.setHeight("50%"); + southAdded.setZIndex(99); + southAdded.setFlex(true); + southAdded.setCollapsible(true); + southAdded.setOpen(false); + southAdded.setSplittable(true); + + center = new Center(); + mainLayout.appendChild(center); + center.appendChild(infoLayout); + center.setAutoscroll(true); + + infoLayout.setStyle("border: none"); + infoLayout.setWidth("100%"); + infoLayout.setHeight("100%"); + + north = new North(); + north.setStyle("border: none"); + north.setHeight("50%"); + infoLayout.appendChild(north); + north.appendChild(orderLayout); + north.setSplittable(true); + north.setFlex(true); + + center = new Center(); + center.setStyle("border: none"); + infoLayout.appendChild(center); + center.appendChild(medioLayout); + center.setHeight("100%"); + center.setAutoscroll(true); + } // jbInit + + /** + * Dynamic Init (prepare dynamic fields) + * @throws Exception if Lookups cannot be initialized + */ + public void dyInit() throws Exception { + // Set Client + clientId = Env.getAD_Client_ID(Env.getCtx()); + // Load Default Values + loadDefaultValues(); + // Organization filter selection + int columnId = 58193; // WM_InOutBound.AD_Org_ID + MLookup lookupOrg = MLookupFactory.get(Env.getCtx(), m_WindowNo, 0, columnId, DisplayType.TableDir); + organizationPick = new WTableDirEditor("AD_Org_ID", true, false, true, lookupOrg); + //organizationPick.setValue(Env.getAD_Org_ID(Env.getCtx())); + organizationPick.addValueChangeListener(this); + + // Sales Region + columnId = 1823; // C_SalesRegion.C_SalesRegion_ID + MLookup lookupWar = MLookupFactory.get(Env.getCtx(), m_WindowNo, 0, columnId, DisplayType.TableDir); + salesRegionPick = new WTableDirEditor("C_SalesRegion_ID", false, false, true, lookupWar); + //salesRegion.setValue(Env.getAD_Org_ID(Env.getCtx())); + salesRegionPick.addValueChangeListener(this); + + // Sales Representative + columnId = 2186; // C_Order.SalesRep_ID + MLookup lookupSal = MLookupFactory.get(Env.getCtx(), m_WindowNo, 0, columnId, DisplayType.TableDir); + salesRepSearch = new WTableDirEditor("SalesRep_ID", false, false, true, lookupSal); + //salesRepSearch.setValue(Env.getAD_Org_ID(Env.getCtx())); + salesRepSearch.addValueChangeListener(this); + // Document Type Target + columnId = 58203; // WM_InOutBound.C_DocType_ID + MLookup lookupDTT = MLookupFactory.get(Env.getCtx(), m_WindowNo, 0, columnId, DisplayType.Table); + docTypeTargetPick = new WTableDirEditor("C_DocType_ID", true, false, true, lookupDTT); + docTypeTargetPick.addValueChangeListener(this); + + columnId = 58205; // WM_InOutBound.DeliveryRule + MLookup lookupDR = MLookupFactory.get(Env.getCtx(), m_WindowNo, 0, columnId, DisplayType.List); + deliveryRulePick = new WTableDirEditor("DeliveryRule", false, false, true, lookupDR); + deliveryRulePick.addValueChangeListener(this); + + columnId = 58206; // WM_InOutBound.DeliveryViaRule + MLookup lookupDVR = MLookupFactory.get(Env.getCtx(), m_WindowNo, 0, columnId, DisplayType.List); + deliveryViaRulePick = new WTableDirEditor("DeliveryViaRule", false, false, true, lookupDVR); + deliveryViaRulePick.addValueChangeListener(this); + + // Shipper + columnId = 58221; // WM_InOutBound.M_Shipper_ID + MLookup lookupSP = MLookupFactory.get(Env.getCtx(), m_WindowNo, 0, columnId, DisplayType.TableDir); + shipperPick = new WTableDirEditor("M_Shipper_ID", false, false, true, lookupSP); + shipperPick.addValueChangeListener(this); + // + MLookup docActionL = MLookupFactory.get(Env.getCtx(), form.getWindowNo(), 58192 /* WM_InOutBound.DocAction */, + DisplayType.List, Env.getLanguage(Env.getCtx()), "DocAction", 135 /* _Document Action */, + false, "AD_Ref_List.Value IN ('CO','PR')"); + // Document Action + docActionPick = new WTableDirEditor("DocAction", true, false, true,docActionL); + docActionPick.setValue(DocAction.ACTION_Complete); + + locatorLabel.setValue(Msg.translate(Env.getCtx(), "M_Locator_ID")); + locatorLabel.setMandatory(true); + MLocatorLookup locator = new MLocatorLookup(Env.getCtx(), form.getWindowNo()); + locatorField = new WLocatorEditor ("M_Locator_ID", true, false, true, locator, form.getWindowNo()); + locatorField.setMandatory(true); + locatorField.addValueChangeListener(this); + + // + documentDateField.setValue(Env.getContextAsDate(Env.getCtx(), "#Date")); + // Set Date + shipmentDateField.setValue(Env.getContextAsDate(Env.getCtx(), "#Date")); + // Warehouse + warehouseSearch.addActionListener(this); + + // Select All Items + selectAllButton.addActionListener(this); + // Load Operation Type + operationTypePick.appendItem(Msg.translate(Env.getCtx(), I_C_Order.COLUMNNAME_C_Order_ID), I_C_Order.Table_Name); + operationTypePick.appendItem(Msg.translate(Env.getCtx(), I_DD_Order.COLUMNNAME_DD_Order_ID), I_DD_Order.Table_Name); + // Document Type Order + movementType = I_C_Order.Table_Name; + docTypeId = loadComboBoxW(docTypeSourceSearch, getDataDocumentType()); + docTypeSourceSearch.addActionListener(this); + operationTypePick.addActionListener(this); + // Translation + statusBar.setStatusLine(Msg.translate(Env.getCtx(), "WM_InOutBound_ID")); + statusBar.setStatusDB(""); + } // dynInit + + /** + * Clear Data of Table + * @return void + */ + private void clearData() { + w_orderTable.getModel().removeTableModelListener(this); + ListModelTable modelP = new ListModelTable(); + w_orderTable.setModel(modelP); + modelP = new ListModelTable(); + orderLineTable.getModel().removeTableModelListener(this); + orderLineTable.setModel(modelP); + count=0; + // Set Stock Model + if(stockTable.getColumnCount()>1){ + stockTable.setModel(stockModel); + setStockColumnClass(stockTable); + } + // Parameters + salesRegionPick.setValue(null); + salesRepSearch.setValue(null); + deliveryRulePick.setValue(null); + deliveryViaRulePick.setValue(null); + documentDateField.setValue(Env.getContextAsDate(Env.getCtx(), "#Date")); + shipmentDateField.setValue(Env.getContextAsDate(Env.getCtx(), "#Date")); + shipperPick.setValue(null); + docActionPick.setValue(DocAction.ACTION_Complete); + } + + /** + * Search Data + * @return void + */ + private void cmd_search() { + String error = validateData(); + if(!Util.isEmpty(error)) { + FDialog.info(m_WindowNo, parameterPanel, null, Msg.parseTranslation(Env.getCtx(), error)); + calculate(); + return; + } + // Load Data + if(loadDataOrder()){ + northAdded.setOpen(false); + } + } + + /** + * Get Values from Panel, refresh values + * @return void + */ + private void getPanelValues() { + // Organization + Object value = organizationPick.getValue(); + orgId = ((Integer)(value != null? value: 0)).intValue(); + // Sales Region + value = salesRegionPick.getValue(); + salesRegionId = ((Integer)(value != null? value: 0)).intValue(); + + // Sales Representative + value = salesRepSearch.getValue(); + salesRepId = ((Integer)(value != null? value: 0)).intValue(); + // Warehouse + if(warehouseSearch.getItemCount() > 0) { + value = warehouseSearch.getValue(); + warehouseId = Integer.parseInt(String.valueOf(value != null? value: "0")); + } else { + warehouseId = 0; + } + // DocumentType Source + if(docTypeSourceSearch.getItemCount() > 0) { + value = docTypeSourceSearch.getValue(); + docTypeId = Integer.parseInt(String.valueOf(value != null? value: "0")); + } else { + docTypeId = 0; + } + // Operation Type + value = operationTypePick.getValue(); + movementType = (String)value; + value = docActionPick.getValue(); + documentAction = (String) value; + // Document Type Target + value = docTypeTargetPick.getValue(); + docTypeTargetId = Integer.parseInt(String.valueOf(value != null? value: "0")); + // Delivery Rule + value = deliveryRulePick.getValue(); + deliveryRule = (String) value; + // Delivery Via Rule + value = deliveryViaRulePick.getValue(); + deliveryViaRule = (String) value; + // Document Date + String hourString = dateFormat.format(documentDateField.getValue()); + Timestamp hourTime = Timestamp.valueOf(hourString); + documentDate = hourTime; + // Shipment Date + hourString = dateFormat.format(shipmentDateField.getValue()); + hourTime = Timestamp.valueOf(hourString); + shipmentDate = hourTime; + // Shipper + value = shipperPick.getValue(); + shipperId = ((Integer)(value != null? value: 0)).intValue(); + // Weight Symbol + if(uOMWeightId != 0) { + MUOM uom = MUOM.get(Env.getCtx(), uOMWeightId); + uOMWeightSymbol = uom.getUOMSymbol(); + } + // Volume Symbol + if(uOMVolumeId != 0) { + MUOM uom = MUOM.get(Env.getCtx(), uOMVolumeId); + uOMVolumeSymbol = uom.getUOMSymbol(); + } + } + + /** + * Validate For save + * @return + */ + private boolean validateDataForSave() { + + StringBuffer errorMessage = new StringBuffer(); + + if (locatorField.getValue() == null ) + errorMessage.append(" @WM_InOutBound_ID@ @M_Locator_ID@ @NotFound@"); + else + locatorId = (Integer)locatorField.getValue(); + + String error = validateData(); + if(!Util.isEmpty(error)) { + errorMessage.append(error); + } + // Valid Message + error = validStock(stockTable); + if(!Util.isEmpty(error)) { + if(errorMessage.length() > 0) { + errorMessage.append(Env.NL); + } + errorMessage.append(error); + } + if(errorMessage.length() > 0) { + FDialog.info(m_WindowNo, parameterPanel, null, Msg.parseTranslation(Env.getCtx(), errorMessage.toString())); + calculate(); + return false; + } + // + return true; + } + + /** + * Validate data + * @return + * @return String + */ + private String validateData() { + getPanelValues(); + StringBuffer errorMessage = new StringBuffer(); + if(orgId <= 0) { + errorMessage.append("@AD_Org_ID@ @NotFound@"); + } + if(movementType == null) { + if(errorMessage.length() > 0) { + errorMessage.append(Env.NL); + } + errorMessage.append("@OperationType@ @NotFound@"); + } + if(warehouseId <= 0) { + if(errorMessage.length() > 0) { + errorMessage.append(Env.NL); + } + errorMessage.append("@M_Warehouse_ID@ @NotFound@"); + } + // + if(errorMessage.length() > 0) { + return errorMessage.toString(); + } + // + return null; + } + + /** + * Load Order Data + * @return + * @return boolean + */ + public boolean loadDataOrder() { + String name = organizationPick.getColumnName(); + Object value = organizationPick.getValue(); + orgId = ((Integer)(value != null? value: 0)).intValue(); + log.config(name + "=" + value); + + name = salesRegionPick.getColumnName(); + value = salesRegionPick.getValue(); + salesRegionId = ((Integer)(value != null? value: 0)).intValue(); + log.config(name + "=" + value); + + name = salesRepSearch.getColumnName(); + value = salesRepSearch.getValue(); + salesRepId = ((Integer)(value != null? value: 0)).intValue(); + log.config(name + "=" + value); + w_orderTable.clear(); + // Load Data + Vector> data = getOrderData(w_orderTable); + Vector columnNames = getOrderColumnNames(); + + // Remove previous listeners + w_orderTable.getModel().removeTableModelListener(this); + + // Set Model + ListModelTable modelP = new ListModelTable(data); + modelP.addTableModelListener(this); + w_orderTable.setData(modelP, columnNames); + setOrderColumnClass(w_orderTable); + + orderLineTable.clear(); + + // Remove previous listeners + orderLineTable.getModel().removeTableModelListener(this); + // Set Model Line + ListModelTable modelLine = new ListModelTable(); + orderLineTable.setData(modelLine, columnNames); + // + return !data.isEmpty(); + } + + /** + * Calculate difference + * @return void + */ + public void calculate() { + int rows = orderLineTable.getRowCount(); + if(rows > 0) { + payloadCapacity = Env.ZERO; + volumeCapacity = Env.ZERO; + totalWeight = Env.ZERO; + totalVolume = Env.ZERO; + BigDecimal weight = Env.ZERO; + BigDecimal volume = Env.ZERO; + for (int i = 0; i < rows; i++) { + if (((Boolean)orderLineTable.getValueAt(i, 0)).booleanValue()) { + // Weight + weight = (BigDecimal) (orderLineTable.getValueAt(i, OL_WEIGHT) != null + ? orderLineTable.getValueAt(i, OL_WEIGHT) + : Env.ZERO); + // Add Weight + totalWeight = totalWeight.add(weight); + // Volume + volume = (BigDecimal) (orderLineTable.getValueAt(i, OL_VOLUME) != null + ? orderLineTable.getValueAt(i, OL_VOLUME) + : Env.ZERO); + // Add Volume + totalVolume = totalVolume.add(volume); + } + } + statusBar.setStatusLine( + "(" + Msg.parseTranslation(Env.getCtx(), "@C_Order_ID@ @Selected@" + + " = " + rowsSelected + + ") " + + "[@Weight@ " + + (Util.isEmpty(uOMWeightSymbol)? "": "(" + uOMWeightSymbol + ") = ") + + totalWeight.doubleValue() + + "] | [@Volume@ " + + (Util.isEmpty(uOMVolumeSymbol)? "": "(" + uOMVolumeSymbol + ") = ") + + totalVolume.doubleValue() + + "]")); + } else { + // Set Difference + statusBar.setStatusLine( + "(" + Msg.parseTranslation(Env.getCtx(), "@C_Order_ID@ @Selected@" + + " = " + rowsSelected + + ") " + + "[@Weight@ " + + (Util.isEmpty(uOMWeightSymbol)? "": "(" + uOMWeightSymbol + ") = ") + + Env.ZERO.doubleValue() + + "] | [@Volume@ " + + (Util.isEmpty(uOMVolumeSymbol)? "": "(" + uOMVolumeSymbol + ") = ") + + Env.ZERO.doubleValue() + + "]")); + } + } + + @Override + public void valueChange(ValueChangeEvent evt) { + String name = evt.getPropertyName(); + Object value = evt.getNewValue(); + log.config(name + " = " + value); + if(name.equals("C_SalesRegion_ID") || + name.equals("SalesRep_ID")) { + clearData(); + } else if(name.equals("AD_Org_ID")) { + orgId = ((Integer)(value != null? value: 0)).intValue(); + KeyNamePair[] data = getDataWarehouse(); + warehouseSearch.removeActionListener(this); + warehouseId = loadComboBoxW(warehouseSearch, data); + warehouseSearch.addEventListener(Events.ON_SELECT, this); + Env.setContext(Env.getCtx(), m_WindowNo, "AD_Org_ID", orgId); + docTypeTargetPick.actionRefresh(); + clearData(); + } + calculate(); + } + + @Override + public void onEvent(Event eventObject) throws Exception { + if (eventObject.getTarget().getId().equals(ConfirmPanel.A_REFRESH)){ + cmd_search(); + return; + } else if(eventObject.getTarget().equals(selectAllButton)) { + int rows = orderLineTable.getRowCount(); + for (int i = 0; i < rows; i++) { + if(!((Boolean) orderLineTable.getValueAt(i, SELECT))) { + orderLineTable.setValueAt(true, i, SELECT); + } + } + return; + } else if (eventObject.getTarget().getId().equals(ConfirmPanel.A_CANCEL)) { + dispose(); + return; + } else if(eventObject.getTarget().getId().equals(ConfirmPanel.A_OK)) { + if(validateDataForSave()) { + if (FDialog.ask(m_WindowNo, parameterPanel, null, + Msg.translate(Env.getCtx(), "GenerateOrder") + "?")) { + saveData(); + return; + } + } + } else if(eventObject.getTarget().equals(operationTypePick)) { + Object value = operationTypePick.getValue(); + movementType = ((String)(value != null? value: 0)); + KeyNamePair[] data = getDataDocumentType(); + docTypeSourceSearch.removeActionListener(this); + docTypeId = loadComboBoxW(docTypeSourceSearch, data); + docTypeSourceSearch.addActionListener(this); + } else if(eventObject.getTarget().equals(docTypeSourceSearch)) { + // DocumentType Source + if(docTypeSourceSearch.getItemCount() > 0) { + Object value = docTypeSourceSearch.getValue(); + docTypeId = Integer.parseInt(String.valueOf(value != null? value: "0")); + } else { + docTypeId = 0; + } + } else if(eventObject.getTarget().equals(warehouseSearch)) { + // Warehouse + if(warehouseSearch.getItemCount() > 0) { + Object value = warehouseSearch.getValue(); + warehouseId = Integer.parseInt(String.valueOf(value != null? value: "0")); + } else { + warehouseId = 0; + } + } + clearData(); + } + + /** + * Dispose + */ + public void dispose() { + SessionManager.getAppDesktop().closeActiveWindow(); + } // dispose + + @Override + public ADForm getForm() { + return form; + } + + /** + * Load the Combo Box from ArrayList (Web Version) + * @param comboSearch + * @param data[] + * @param mandatory + * @return + * @return int + */ + protected int loadComboBoxW(Listbox comboSearch, KeyNamePair[] data, boolean mandatory) { + comboSearch.removeAllItems(); + if(!mandatory){ + comboSearch.appendItem("", "0"); + comboSearch.setName(String.valueOf(count++)); + } + int m_ID = 0; + for(KeyNamePair pp : data) { + comboSearch.appendItem(String.valueOf(pp.getName()),pp.getKey()); + } + // Set Default + if (comboSearch.getItemCount() != 0) { + comboSearch.setSelectedIndex(0); + m_ID =Integer.parseInt(comboSearch.getName()); + } + return m_ID; + } + + /** + * Load Combo Box from ArrayList (No Mandatory) + * @param comboSearch + * @param data[] + * @return + * @return int + */ + protected int loadComboBoxW(Listbox comboSearch, KeyNamePair[] data) { + return loadComboBoxW(comboSearch, data, false); + } + + @Override + public void tableChanged(WTableModelEvent event) { + boolean isUpdate = (event.getType() == WTableModelEvent.CONTENTS_CHANGED); + int row = event.getFirstRow(); + int col = event.getColumn(); + // Not a table update + if (!isUpdate) { + calculate(); + return; + } + + boolean isOrder = (event.getModel().equals(w_orderTable.getModel())); + boolean isOrderLine = (event.getModel().equals(orderLineTable.getModel())); + if(isOrder) { + // Load Lines + StringBuffer sql = getQueryLine(w_orderTable); + Vector> data = getOrderLineData(w_orderTable, sql); + Vector columnNames = getOrderLineColumnNames(); + + loadBuffer(orderLineTable); + // Remove previous listeners + orderLineTable.getModel().removeTableModelListener(this); + // Set Model + ListModelTable modelP = new ListModelTable(data); + modelP.addTableModelListener(this); + orderLineTable.setData(modelP, columnNames); + setOrderLineColumnClass(orderLineTable); + setValueFromBuffer(orderLineTable); + } else if(isOrderLine) { + if(col == OL_QTY) { // Quantity + BigDecimal qty = (BigDecimal) orderLineTable.getValueAt(row, OL_QTY); + BigDecimal weight = (BigDecimal) orderLineTable.getValueAt(row, OL_WEIGHT); + BigDecimal volume = (BigDecimal) orderLineTable.getValueAt(row, OL_VOLUME); + + // Get Precision + KeyNamePair uom = (KeyNamePair) orderLineTable.getValueAt(row, OL_UOM); + KeyNamePair pr = (KeyNamePair) orderLineTable.getValueAt(row, OL_PRODUCT); + ValueNamePair dr = (ValueNamePair) orderLineTable.getValueAt(row, OL_DELIVERY_RULE); + int productId = pr.getKey(); + MProduct product = MProduct.get(Env.getCtx(), productId); + BigDecimal unitWeight = product.getWeight(); + BigDecimal unitVolume = product.getVolume(); + // Calculate Weight + weight = qty.multiply(unitWeight).setScale(weightPrecision, RoundingMode.HALF_UP); + orderLineTable.setValueAt(weight, row, OL_WEIGHT); + // Calculate Volume + volume = qty.multiply(unitVolume).setScale(volumePrecision, RoundingMode.HALF_UP); + orderLineTable.setValueAt(volume, row, OL_VOLUME); + + // Load Stock Product + stockModel = new ListModelTable(); + stockTable.setData(stockModel, getStockColumnNames()); + setStockColumnClass(stockTable); + + } else if(col == SELECT) { + boolean select = (Boolean) orderLineTable.getValueAt(row, col); + if(select) { + maxSeqNo += 10; + orderLineTable.setValueAt(maxSeqNo, row, OL_SEQNO); + } + } else if(col == OL_SEQNO) { + int seqNo = (Integer) orderLineTable.getValueAt(row, OL_SEQNO); + if(!existsSeqNo(orderLineTable, row, seqNo)) { + if(seqNo > maxSeqNo) { + maxSeqNo = seqNo; + } + } else { + FDialog.warn(m_WindowNo, parameterPanel, null, Msg.translate(Env.getCtx(), "SeqNoEx")); + maxSeqNo += 10; + orderLineTable.setValueAt(maxSeqNo, row, OL_SEQNO); + } + } + // Load Group by Product + loadStockWarehouse(orderLineTable); + } + + calculate(); + } + /** + * Refresh Stock Values + * @param orderLineTable + * @return void + */ + private void loadStockWarehouse(IMiniTable orderLineTable) { + + log.info("Load StockWarehouse"); + int rows = orderLineTable.getRowCount(); + stockModel = new ListModelTable(); + + for (int i = 0; i < rows; i++) { + if (((Boolean)orderLineTable.getValueAt(i, SELECT)).booleanValue()) { + loadProductsStock(orderLineTable, i, true); + } + } + stockTable.setData(stockModel,getStockColumnNames()); + stockTable.autoSize(); + setStockColumnClass(stockTable); + } + + /** + * Verify if exists the product on table + * @param productKey + * @param warehouseId + * @return + * @return int + */ + private int existProductStock(KeyNamePair productKey, int warehouseId) { + for(int i = 0; i < stockModel.getRowCount(); i++) { + if(((KeyNamePair) stockModel.getValueAt(i, SW_PRODUCT)).equals(productKey) + //2016-04-06 Carlos Parada Add Support to Warehouse Filter + && ((KeyNamePair) stockModel.getValueAt(i, SW_WAREHOUSE)).getKey() == warehouseId + //End Carlos Parada + ) { + return i; + } + } + return -1; + } + + /** + * Load Product Stock + * @param orderLineTable + * @param row + * @param isSelected + * @return void + */ + private void loadProductsStock(IMiniTable orderLineTable, int row, boolean isSelected) { + KeyNamePair productKey = (KeyNamePair) orderLineTable.getValueAt(row, OL_PRODUCT); + KeyNamePair uom = (KeyNamePair) orderLineTable.getValueAt(row, OL_UOM); + KeyNamePair warehouse = (KeyNamePair) orderLineTable.getValueAt(row, OL_WAREHOUSE); + BigDecimal qtyOnHand = (BigDecimal) orderLineTable.getValueAt(row, OL_QTY_ON_HAND); + BigDecimal qtySet = (BigDecimal) orderLineTable.getValueAt(row, OL_QTY); + BigDecimal qtyInTransit = (BigDecimal) orderLineTable.getValueAt(row, OL_QTY_IN_TRANSIT); + // + int pos = existProductStock(productKey, warehouse.getKey()); + // + if(pos > -1) { + BigDecimal qtyInTransitOld = (BigDecimal) stockModel.getValueAt(pos, SW_QTY_IN_TRANSIT); + BigDecimal qtySetOld = (BigDecimal) stockModel.getValueAt(pos, SW_QTY_SET); + // Negate + if(!isSelected) + qtySet = qtySet.negate(); + // + qtySet = qtySet.add(qtySetOld); + stockModel.setValueAt(qtyOnHand, pos, SW_QTY_ON_HAND); + stockModel.setValueAt(qtyInTransitOld, pos, SW_QTY_IN_TRANSIT); + stockModel.setValueAt(qtySet, pos, SW_QTY_SET); + stockModel.setValueAt(qtyOnHand + .subtract(qtyInTransitOld) + .subtract(qtySet) + .setScale(2, RoundingMode.HALF_UP), pos, SW_QTY_AVAILABLE); + } else if(isSelected) { + // Get Quantity in Transit + Vector line = new Vector(); + line.add(productKey); + line.add(uom); + line.add(warehouse); + line.add(qtyOnHand); + line.add(qtyInTransit); + line.add(qtySet); + line.add(qtyOnHand + .subtract(qtyInTransit) + .subtract(qtySet) + .setScale(2, RoundingMode.HALF_UP)); + // + stockModel.add(line); + } + } + + /** + * Print Document + * @return void + */ + private void printDocument() { + // Get Document Type + MDocType documentType = MDocType.get(Env.getCtx(), + outBoundOrder.getC_DocType_ID()); + if(documentType == null) + return; + // + if(documentType.getAD_PrintFormat_ID() == 0) { + String msg = Msg.parseTranslation(Env.getCtx(), + "@NoDocPrintFormat@ @AD_Table_ID@ = @WM_InOutBound_ID@"); + log.warning(msg); + // + return; + } + // Get Print Format + MPrintFormat format = MPrintFormat.get(Env.getCtx(), + documentType.getAD_PrintFormat_ID(), false); + // + if(format != null) { + MQuery q = new MQuery(MWMInOutBound.Table_Name); + q.addRestriction(MWMInOutBound.Table_Name + "_ID", "=", outBoundOrder.getWM_InOutBound_ID()); + PrintInfo i = new PrintInfo(Msg.translate(Env.getCtx(), + MWMInOutBound.Table_Name + "_ID"), MWMInOutBound.Table_ID, outBoundOrder.getWM_InOutBound_ID()); + // + ReportEngine re = new ReportEngine(Env.getCtx(), format, q, i, null); + // Print + // Direct Print + //re.print(); + ReportCtl.preview(re); + } + } + /** + * Save Data + * @return void + */ + private void saveData() { + + final String[] success = new String[] { "Error" }; + final TrxRunnable r = new TrxRunnable() { + + public void run(String trxName) { + success[0] = generateLoadOrder(trxName, orderLineTable); + statusBar.setStatusLine(success[0]); + + } + }; + try { + Trx.run(r); + } catch (Exception e) { + FDialog.error(m_WindowNo, parameterPanel, "Error", e.getLocalizedMessage()); + statusBar.setStatusLine("Error: " + e.getLocalizedMessage()); + log.severe(e.getLocalizedMessage()); + return; + } finally { + + } + // Print Document + if (FDialog.ask(m_WindowNo, parameterPanel, "print.order", + Msg.parseTranslation(Env.getCtx(), + "@WM_InOutBound_ID@ " + outBoundOrder.getDocumentNo()))) { + // Print? + printDocument(); + } + // Clear + shipperPick.setValue(null); + northAdded.setOpen(true); + // Clear Data + clearData(); + calculate(); + + } // saveData +} \ No newline at end of file