diff --git a/org.adempiere.base.process/src/org/compiere/process/BOMFlagValidate.java b/org.adempiere.base.process/src/org/compiere/process/BOMFlagValidate.java new file mode 100644 index 0000000000..1f76487243 --- /dev/null +++ b/org.adempiere.base.process/src/org/compiere/process/BOMFlagValidate.java @@ -0,0 +1,128 @@ +package org.compiere.process; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.logging.Level; + +import org.compiere.process.ProcessInfoParameter; +import org.compiere.process.SvrProcess; +import org.compiere.util.DB; +import org.compiere.util.Env; + + +public class BOMFlagValidate extends SvrProcess { + + /** Product Category */ + private int p_M_Product_Category_ID = 0; + + + protected void prepare() { + ProcessInfoParameter[] para = getParameter(); + for (int i = 0; i < para.length; i++) + { + String name = para[i].getParameterName(); + if (para[i].getParameter() == null) + ; + else if (name.equals("M_Product_Category_ID")) + p_M_Product_Category_ID = para[i].getParameterAsInt(); + else + log.log(Level.SEVERE, "Unknown Parameter: " + name); + } + } + + @Override + protected String doIt() throws Exception { + + flagNonBOMs(); + flagBOMs(); + return "BOM Flags set correctly"; + } + + private void flagNonBOMs() throws Exception + { + + //Select Products where there's a BOM, and there are no lines + String sql = "SELECT NAME FROM M_PRODUCT WHERE ISBOM = 'Y' AND " + + "M_PRODUCT_ID NOT IN (SELECT M_PRODUCT_ID FROM M_PRODUCT_BOM ) AND "; + if (p_M_Product_Category_ID == 0) + sql += "AD_Client_ID= ?"; + + else + sql += "M_Product_Category_ID= ?"; + PreparedStatement pstmt = null; + pstmt = DB.prepareStatement (sql, null); + if (p_M_Product_Category_ID == 0) + pstmt.setInt (1, Env.getAD_Client_ID(getCtx())); + else + pstmt.setInt(1, p_M_Product_Category_ID); + ResultSet rs = pstmt.executeQuery (); + + while (rs.next()) + { + addLog(0, null, null, rs.getString(1) + "Has Been Flagged as NonBOM as it has no lines"); + } + + rs.close(); + pstmt.close(); + + String update = "UPDATE M_Product SET ISBOM = 'N' WHERE ISBOM = 'Y' AND M_PRODUCT_ID NOT IN " + + "(SELECT M_PRODUCT_ID FROM M_PRODUCT_BOM ) AND "; + if (p_M_Product_Category_ID == 0) + update += "AD_Client_ID= ?"; + else + update += "M_Product_Category_ID= ?"; + pstmt = null; + pstmt = DB.prepareStatement (update, null); + if (p_M_Product_Category_ID == 0) + pstmt.setInt (1, Env.getAD_Client_ID(getCtx())); + else + pstmt.setInt(1, p_M_Product_Category_ID); + pstmt.executeUpdate(); + pstmt.close(); + + } + + private void flagBOMs() throws Exception + { + + //Select Products where there's a BOM, and there are no lines + String sql = "SELECT NAME FROM M_PRODUCT WHERE ISBOM = 'N' AND " + + "M_PRODUCT_ID IN (SELECT M_PRODUCT_ID FROM M_PRODUCT_BOM ) AND "; + if (p_M_Product_Category_ID == 0) + sql += "AD_Client_ID= ?"; + + else + sql += "M_Product_Category_ID= ?"; + PreparedStatement pstmt = null; + pstmt = DB.prepareStatement (sql, null); + if (p_M_Product_Category_ID == 0) + pstmt.setInt (1, Env.getAD_Client_ID(getCtx())); + else + pstmt.setInt(1, p_M_Product_Category_ID); + ResultSet rs = pstmt.executeQuery (); + + while (rs.next()) + { + addLog(0, null, null, rs.getString(1) + "Has Been Flagged as BOM as it has BOM lines"); + } + rs.close(); + pstmt.close(); + + String update = "UPDATE M_Product SET ISBOM = 'Y' WHERE ISBOM = 'N' AND M_PRODUCT_ID IN " + + "(SELECT M_PRODUCT_ID FROM M_PRODUCT_BOM ) AND "; + if (p_M_Product_Category_ID == 0) + update += "AD_Client_ID= ?"; + else + update += "M_Product_Category_ID= ?"; + pstmt = null; + pstmt = DB.prepareStatement (update, null); + if (p_M_Product_Category_ID == 0) + pstmt.setInt (1, Env.getAD_Client_ID(getCtx())); + else + pstmt.setInt(1, p_M_Product_Category_ID); + pstmt.executeUpdate(); + pstmt.close(); + + } + +} diff --git a/org.adempiere.base.process/src/org/compiere/process/BOMVerify.java b/org.adempiere.base.process/src/org/compiere/process/BOMVerify.java new file mode 100644 index 0000000000..f48d2d2db9 --- /dev/null +++ b/org.adempiere.base.process/src/org/compiere/process/BOMVerify.java @@ -0,0 +1,233 @@ +/****************************************************************************** + * Product: Compiere ERP & CRM Smart Business Solution * + * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * + * This program is free software; you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * + * by the Free Software Foundation. This program is distributed in the hope * + * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the GNU General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.process; + +import java.sql.*; +import java.util.*; +import java.util.logging.*; +import org.compiere.model.*; +import org.compiere.process.ProcessInfoParameter; +import org.compiere.process.SvrProcess; +import org.compiere.util.*; + +/** + * Validate BOM + * + * @author Jorg Janke + * @version $Id: BOMVerify.java,v 1.1 2007/07/23 05:34:35 mfuggle Exp $ + */ +public class BOMVerify extends SvrProcess +{ + /** The Product */ + private int p_M_Product_ID = 0; + /** Product Category */ + private int p_M_Product_Category_ID = 0; + /** Re-Validate */ + private boolean p_IsReValidate = false; + + /** Product */ + private MProduct m_product = null; + /** List of Products */ + private ArrayList foundproducts = new ArrayList(); + private ArrayList validproducts = new ArrayList(); + private ArrayList invalidproducts = new ArrayList(); + private ArrayList containinvalidproducts = new ArrayList(); + private ArrayList checkedproducts = new ArrayList(); + + /** + * Prepare + */ + protected void prepare () + { + ProcessInfoParameter[] para = getParameter(); + for (int i = 0; i < para.length; i++) + { + String name = para[i].getParameterName(); + if (para[i].getParameter() == null) + ; + else if (name.equals("M_Product_ID")) + p_M_Product_ID = para[i].getParameterAsInt(); + else if (name.equals("M_Product_Category_ID")) + p_M_Product_Category_ID = para[i].getParameterAsInt(); + else if (name.equals("IsReValidate")) + p_IsReValidate = "Y".equals(para[i].getParameter()); + else + log.log(Level.SEVERE, "Unknown Parameter: " + name); + } + if ( p_M_Product_ID == 0 ) + p_M_Product_ID = getRecord_ID(); + } // prepare + + /** + * Process + * @return Info + * @throws Exception + */ + protected String doIt() throws Exception + { + if (p_M_Product_ID != 0) + { + log.info("M_Product_ID=" + p_M_Product_ID); + checkProduct(new MProduct(getCtx(), p_M_Product_ID, get_TrxName())); + return "Product Checked"; + } + log.info("M_Product_Category_ID=" + p_M_Product_Category_ID + + ", IsReValidate=" + p_IsReValidate); + // + int counter = 0; + PreparedStatement pstmt = null; + String sql = "SELECT M_Product_ID FROM M_Product " + + "WHERE IsBOM='Y' AND "; + if (p_M_Product_Category_ID == 0) + sql += "AD_Client_ID=? "; + else + sql += "M_Product_Category_ID=? "; + if (!p_IsReValidate) + sql += "AND IsVerified<>'Y' "; + sql += "ORDER BY Name"; + int AD_Client_ID = Env.getAD_Client_ID(getCtx()); + try + { + pstmt = DB.prepareStatement (sql, null); + if (p_M_Product_Category_ID == 0) + pstmt.setInt (1, AD_Client_ID); + else + pstmt.setInt(1, p_M_Product_Category_ID); + ResultSet rs = pstmt.executeQuery (); + while (rs.next ()) + { + p_M_Product_ID = rs.getInt(1); //ADAXA - validate the product retrieved from database + checkProduct(new MProduct(getCtx(), p_M_Product_ID, get_TrxName())); + + counter++; + } + rs.close (); + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + log.log (Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + return "#" + counter; + } // doIt + + private void checkProduct(MProduct product) + { + if (product.isBOM() && !checkedproducts.contains(product)) + { + validateProduct(product); + } + + } + + /** + * Validate Product + * @param product product + * @return Info + */ + private boolean validateProduct (MProduct product) + { + if (!product.isBOM()) + return false; + + + // Check Old Product BOM Structure + log.config(product.getName()); + + + foundproducts.add(product); + MProductBOM[] productsBOMs = MProductBOM.getBOMLines(product); + boolean containsinvalid = false; + boolean invalid = false; + for (int i = 0; i < productsBOMs.length; i++) + { + MProductBOM productsBOM = productsBOMs[i]; + MProduct pp = new MProduct(getCtx(), productsBOM.getM_ProductBOM_ID(), get_TrxName()); + if (!pp.isBOM()) + log.finer(pp.getName()); + else + { + if (validproducts.contains(pp)) + { + //Do nothing, no need to recheck + } + if (invalidproducts.contains(pp)) + { + containsinvalid = true; + } + else if (foundproducts.contains(pp)) + { + invalid = true; + addLog(0, null, null, product.getValue() + " recursively contains " + pp.getValue()); + } + else + { + if (!validateProduct(pp)) + { + containsinvalid = true; + } + + } + } + + + + } + + checkedproducts.add(product); + foundproducts.remove(product); + if (invalid) + { + invalidproducts.add(product); + product.setIsVerified(false); + product.save(); + return false; + } + else if (containsinvalid) + { + containinvalidproducts.add(product); + product.setIsVerified(false); + product.save(); + return false; + } + else + { + validproducts.add(product); + product.setIsVerified(true); + product.save(); + return true; + } + + + + } // validateProduct + + + +} // BOMValidate + diff --git a/org.adempiere.base.process/src/org/compiere/process/IndentedBOM.java b/org.adempiere.base.process/src/org/compiere/process/IndentedBOM.java new file mode 100644 index 0000000000..69855e666f --- /dev/null +++ b/org.adempiere.base.process/src/org/compiere/process/IndentedBOM.java @@ -0,0 +1,197 @@ +/****************************************************************************** + * 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-2007 e-Evolution,SC. All Rights Reserved. * + * Contributor(s): Victor Perez www.e-evolution.com * + * Teo Sarca, www.arhipac.ro * + *****************************************************************************/ +package org.compiere.process; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; + +import org.adempiere.exceptions.FillMandatoryException; +import org.apache.commons.lang.StringUtils; +import org.compiere.model.MAcctSchema; +import org.compiere.model.MCost; +import org.compiere.model.MCostElement; +import org.compiere.model.MProduct; +import org.compiere.model.MProductBOM; +import org.compiere.model.Query; +import org.compiere.model.X_T_BOM_Indented; +import org.compiere.process.ProcessInfoParameter; +import org.compiere.process.SvrProcess; +import org.compiere.util.Env; + +/** + * Cost Multi-Level BOM & Formula Review + * + * @author victor.perez@e-evolution.com + * @author Teo Sarca, www.arhipac.ro + * + * @author pbowden@adaxa.com modified for manufacturing light + * + */ +public class IndentedBOM extends SvrProcess +{ + // + private int p_AD_Org_ID = 0; + private int p_C_AcctSchema_ID = 0; + private int p_M_Product_ID = 0; + private int p_M_CostElement_ID = 0; + private String p_CostingMethod = MCostElement.COSTINGMETHOD_StandardCosting; + // + private int m_LevelNo = 0; + private int m_SeqNo = 0; + private MAcctSchema m_as = null; + private BigDecimal m_currentCost = Env.ZERO; + private BigDecimal m_futureCost = Env.ZERO; + + protected void prepare() + { + for (ProcessInfoParameter para : getParameter()) + { + String name = para.getParameterName(); + if (para.getParameter() == null) + ; + else if (name.equals(MCost.COLUMNNAME_C_AcctSchema_ID)) + { + p_C_AcctSchema_ID= para.getParameterAsInt(); + m_as = MAcctSchema.get(getCtx(), p_C_AcctSchema_ID); + } + else if (name.equals(MCost.COLUMNNAME_M_CostElement_ID)) + { + p_M_CostElement_ID = para.getParameterAsInt(); + } + else if (name.equals(MCost.COLUMNNAME_M_Product_ID)) + p_M_Product_ID = para.getParameterAsInt(); + else + log.log(Level.SEVERE, "prepare - Unknown Parameter: " + name); + } + } // prepare + + /** + * Perform process. + * + * @return Message (clear text) + * @throws Exception + * if not successful + */ + protected String doIt() throws Exception + { + if (p_M_Product_ID == 0) + { + throw new FillMandatoryException("M_Product_ID"); + } + explodeProduct(p_M_Product_ID, Env.ONE, Env.ONE); + // + return ""; + } // doIt + + /** + * Generate an Explosion for this product + * @param product + * @param isComponent component / header + */ + private llCost explodeProduct(int M_Product_ID, BigDecimal qty, BigDecimal accumQty) + { + MProduct product = MProduct.get(getCtx(), M_Product_ID); + + X_T_BOM_Indented tboml = new X_T_BOM_Indented(getCtx(), 0, get_TrxName()); + + tboml.setAD_Org_ID(p_AD_Org_ID); + tboml.setC_AcctSchema_ID(p_C_AcctSchema_ID); + tboml.setAD_PInstance_ID(getAD_PInstance_ID()); + tboml.setM_CostElement_ID(p_M_CostElement_ID); + tboml.setSel_Product_ID(product.get_ID()); + tboml.setM_Product_ID(p_M_Product_ID); + tboml.setQtyBOM(qty); + tboml.setQty(accumQty); + // + tboml.setSeqNo(m_SeqNo); + tboml.setLevelNo(m_LevelNo); + tboml.setLevels( (m_LevelNo > 0 ? ":" : "") + StringUtils.repeat(" ", m_LevelNo) +" " + product.getValue()); + // + // Set Costs: + MCost cost = MCost.get(product, 0, m_as, p_AD_Org_ID, p_M_CostElement_ID, get_TrxName()); + tboml.setCurrentCostPrice(cost.getCurrentCostPrice()); + tboml.setCost(cost.getCurrentCostPrice().multiply(accumQty)); + tboml.setFutureCostPrice(cost.getFutureCostPrice()); + tboml.setCostFuture(cost.getFutureCostPrice().multiply(accumQty)); + m_SeqNo++; + + BigDecimal llCost = Env.ZERO; + BigDecimal llFutureCost = Env.ZERO; + List list = getBOMs(product); + for (MProductBOM bom : list) + { + m_LevelNo++; + llCost ll = explodeProduct(bom.getM_ProductBOM_ID(), bom.getBOMQty(), accumQty.multiply(bom.getBOMQty())); + llCost = llCost.add(ll.currentCost.multiply(accumQty.multiply(bom.getBOMQty()))); + llFutureCost = llFutureCost.add(ll.futureCost.multiply(accumQty.multiply(bom.getBOMQty()))); + m_LevelNo--; + } + + llCost retVal = new llCost(); + if (list.size() == 0 ) + { + tboml.setCurrentCostPriceLL(cost.getCurrentCostPrice()); + tboml.setFutureCostPriceLL(cost.getFutureCostPrice()); + + // + retVal.currentCost = cost.getCurrentCostPrice(); + retVal.futureCost = cost.getFutureCostPrice(); + } + else + { + tboml.setCurrentCostPriceLL(llCost); + tboml.setFutureCostPriceLL(llFutureCost); + + // + retVal.currentCost = llCost; + retVal.futureCost = llFutureCost; + } + + tboml.saveEx(); + return retVal; + + } + + /** + * Get BOMs for given product + * @param product + * @param isComponent + * @return list of MProductBOM + */ + private List getBOMs(MProduct product) + { + ArrayList params = new ArrayList(); + StringBuffer whereClause = new StringBuffer(); + whereClause.append(MProductBOM.COLUMNNAME_M_Product_ID).append("=?"); + params.add(product.get_ID()); + + List list = new Query(getCtx(), MProductBOM.Table_Name, whereClause.toString(), null) + .setParameters(params) + .setOnlyActiveRecords(true) + .setOrderBy(MProductBOM.COLUMNNAME_Line) + .list(); + return list; + } + + private class llCost { + BigDecimal currentCost = Env.ZERO; + BigDecimal futureCost = Env.ZERO; + } + +} diff --git a/org.adempiere.base.process/src/org/compiere/process/OrderLineCreateProduction.java b/org.adempiere.base.process/src/org/compiere/process/OrderLineCreateProduction.java new file mode 100644 index 0000000000..9650a3d1f8 --- /dev/null +++ b/org.adempiere.base.process/src/org/compiere/process/OrderLineCreateProduction.java @@ -0,0 +1,135 @@ +/****************************************************************************** + * The contents of this file are subject to the Compiere License Version 1.1 + * ("License"); You may not use this file except in compliance with the License + * You may obtain a copy of the License at http://www.compiere.org/license.html + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for + * the specific language governing rights and limitations under the License. + * The Original Code is Compiere ERP & CRM Smart Business Solution. The Initial + * Developer of the Original Code is Jorg Janke. Portions created by Jorg Janke + * are Copyright (C) 1999-2005 Jorg Janke. + * All parts are Copyright (C) 1999-2005 ComPiere, Inc. All Rights Reserved. + * Contributor(s): ______________________________________. + * + * Modified by Paul Bowden + * ADAXA + *****************************************************************************/ +package org.compiere.process; + +import java.sql.Timestamp; +import java.util.logging.*; + +import org.apache.commons.net.ntp.TimeStamp; +import org.compiere.model.*; +import org.compiere.process.ProcessInfoParameter; +import org.compiere.process.SvrProcess; +import org.compiere.util.DB; +import org.compiere.util.Env; + +/** + * Create (Generate) Invoice from Shipment + * + * @author Jorg Janke + * @version $Id: OrderLineCreateProduction.java,v 1.1 2007/07/23 05:34:35 mfuggle Exp $ + */ +public class OrderLineCreateProduction extends SvrProcess +{ + /** Shipment */ + private int p_C_OrderLine_ID = 0; + private Timestamp p_MovementDate = null; + private boolean ignorePrevProduction = false; + + /** + * Prepare - e.g., get Parameters. + */ + protected void prepare() + { + ProcessInfoParameter[] para = getParameter(); + for (int i = 0; i < para.length; i++) + { + String name = para[i].getParameterName(); + if (para[i].getParameter() == null) + ; + if (name.equals("MovementDate")) + p_MovementDate = (Timestamp) para[i].getParameter(); + else if (name.equals("IgnorePrevProduction")) + ignorePrevProduction = "Y".equals(para[i].getParameter()); + else + log.log(Level.SEVERE, "Unknown Parameter: " + name); + } + + if (p_MovementDate == null) + p_MovementDate = Env.getContextAsDate(getCtx(), "#Date"); + if ( p_MovementDate==null) + p_MovementDate = new Timestamp(System.currentTimeMillis()); + + p_C_OrderLine_ID = getRecord_ID(); + } // prepare + + /** + * Create Production Header and Plan for single ordered product + * + * @throws Exception + */ + protected String doIt () throws Exception + { + log.info("C_OrderLine_ID=" + p_C_OrderLine_ID ); + if (p_C_OrderLine_ID == 0) + throw new IllegalArgumentException("No OrderLine"); + // + MOrderLine line = new MOrderLine (getCtx(), p_C_OrderLine_ID, get_TrxName()); + if (line.get_ID() == 0) + throw new IllegalArgumentException("Order line not found"); + MOrder order = new MOrder (getCtx(), line.getC_Order_ID(), get_TrxName()); + if (!MOrder.DOCSTATUS_Completed.equals(order.getDocStatus())) + throw new IllegalArgumentException("Order not completed"); + + MDocType doc = new MDocType(getCtx(), order.getC_DocType_ID(), get_TrxName()); + + if ( (line.getQtyOrdered().subtract(line.getQtyDelivered())).compareTo(Env.ZERO) <= 0 ) + { + if (!doc.getDocSubTypeSO().equals("ON")) //Consignment and stock orders both have subtype of ON + { + return "Ordered quantity already shipped"; + } + } + + + // If we don't ignore previous production, and there has been a previous one, + //throw an exception + if (!ignorePrevProduction) + { + String docNo = DB.getSQLValueString(get_TrxName(), + "SELECT max(DocumentNo) " + + "FROM M_Production WHERE C_OrderLine_ID = ?", + p_C_OrderLine_ID); + if (docNo != null) + { + throw new IllegalArgumentException("Production has already been created: " + docNo); + } + } + + MProduction production = new MProduction( line ); + MProduct product = new MProduct (getCtx(), line.getM_Product_ID(), get_TrxName()); + + production.setM_Product_ID(line.getM_Product_ID()); + production.setProductionQty(line.getQtyOrdered().subtract(line.getQtyDelivered())); + production.setDatePromised(line.getDatePromised()); + if ( product.getM_Locator_ID() > 0 ) + production.setM_Locator_ID(product.getM_Locator_ID()); + production.setC_OrderLine_ID(p_C_OrderLine_ID); + + int locator = product.getM_Locator_ID(); + if ( locator == 0 ) + locator = MWarehouse.get(getCtx(), line.getM_Warehouse_ID()).getDefaultLocator().get_ID(); + production.setM_Locator_ID(locator); + production.saveEx(); + + production.createLines(false); + production.setIsCreated("Y"); + production.saveEx(); + + return "Production created -- " + production.get_ValueAsString("DocumentNo"); + } // OrderLineCreateShipment + +} // OrderLineCreateShipment diff --git a/org.adempiere.base.process/src/org/compiere/process/OrderLineCreateShipment.java b/org.adempiere.base.process/src/org/compiere/process/OrderLineCreateShipment.java new file mode 100644 index 0000000000..637139fc72 --- /dev/null +++ b/org.adempiere.base.process/src/org/compiere/process/OrderLineCreateShipment.java @@ -0,0 +1,111 @@ +/****************************************************************************** + * The contents of this file are subject to the Compiere License Version 1.1 + * ("License"); You may not use this file except in compliance with the License + * You may obtain a copy of the License at http://www.compiere.org/license.html + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for + * the specific language governing rights and limitations under the License. + * The Original Code is Compiere ERP & CRM Smart Business Solution. The Initial + * Developer of the Original Code is Jorg Janke. Portions created by Jorg Janke + * are Copyright (C) 1999-2005 Jorg Janke. + * All parts are Copyright (C) 1999-2005 ComPiere, Inc. All Rights Reserved. + * Contributor(s): ______________________________________. + * + * Modified by Paul Bowden + * ADAXA + *****************************************************************************/ +package org.compiere.process; + +import java.sql.Timestamp; +import java.util.logging.*; + +import org.apache.commons.net.ntp.TimeStamp; +import org.compiere.model.*; +import org.compiere.process.ProcessInfoParameter; +import org.compiere.process.SvrProcess; +import org.compiere.util.DB; +import org.compiere.util.Env; + +/** + * Create (Generate) Invoice from Shipment + * + * @author Jorg Janke + * @version $Id: OrderLineCreateShipment.java,v 1.1 2007/07/23 05:34:35 mfuggle Exp $ + */ +public class OrderLineCreateShipment extends SvrProcess +{ + /** Shipment */ + private int p_C_OrderLine_ID = 0; + private Timestamp p_MovementDate = null; + + /** + * Prepare - e.g., get Parameters. + */ + protected void prepare() + { + ProcessInfoParameter[] para = getParameter(); + for (int i = 0; i < para.length; i++) + { + String name = para[i].getParameterName(); + if (para[i].getParameter() == null) + ; + if (name.equals("MovementDate")) + p_MovementDate = (Timestamp) para[i].getParameter(); + else + log.log(Level.SEVERE, "Unknown Parameter: " + name); + } + + if (p_MovementDate == null) + p_MovementDate = Env.getContextAsDate(getCtx(), "#Date"); + if ( p_MovementDate==null) + p_MovementDate = new Timestamp(System.currentTimeMillis()); + + p_C_OrderLine_ID = getRecord_ID(); + } // prepare + + /** + * Create Invoice. + * @return document no + * @throws Exception + */ + protected String doIt () throws Exception + { + log.info("C_OrderLine_ID=" + p_C_OrderLine_ID ); + if (p_C_OrderLine_ID == 0) + throw new IllegalArgumentException("No OrderLine"); + // + MOrderLine line = new MOrderLine (getCtx(), p_C_OrderLine_ID, get_TrxName()); + if (line.get_ID() == 0) + throw new IllegalArgumentException("Order line not found"); + MOrder order = new MOrder (getCtx(), line.getC_Order_ID(), get_TrxName()); + if (!MOrder.DOCSTATUS_Completed.equals(order.getDocStatus())) + throw new IllegalArgumentException("Order not completed"); + + if ( (line.getQtyOrdered().subtract(line.getQtyDelivered())).compareTo(Env.ZERO) <= 0 ) + return "Ordered quantity already shipped"; + + int C_DocTypeShipment_ID = DB.getSQLValue(get_TrxName(), + "SELECT C_DocTypeShipment_ID FROM C_DocType WHERE C_DocType_ID=?", + order.getC_DocType_ID()); + + MInOut shipment = new MInOut (order, C_DocTypeShipment_ID, p_MovementDate); + shipment.setM_Warehouse_ID(line.getM_Warehouse_ID()); + shipment.setMovementDate(line.getDatePromised()); + if (!shipment.save()) + throw new IllegalArgumentException("Cannot save shipment header"); + + + MInOutLine sline = new MInOutLine( shipment ); + sline.setOrderLine(line, 0, line.getQtyReserved()); + //sline.setDatePromised(line.getDatePromised()); + sline.setQtyEntered(line.getQtyReserved()); + sline.setC_UOM_ID(line.getC_UOM_ID()); + sline.setQty(line.getQtyReserved()); + sline.setM_Warehouse_ID(line.getM_Warehouse_ID()); + if (!sline.save()) + throw new IllegalArgumentException("Cannot save Shipment Line"); + + return shipment.getDocumentNo(); + } // OrderLineCreateShipment + +} // OrderLineCreateShipment diff --git a/org.adempiere.base.process/src/org/compiere/process/ProductionCreate.java b/org.adempiere.base.process/src/org/compiere/process/ProductionCreate.java new file mode 100644 index 0000000000..68e56f8c7c --- /dev/null +++ b/org.adempiere.base.process/src/org/compiere/process/ProductionCreate.java @@ -0,0 +1,124 @@ +package org.compiere.process; + +import java.math.BigDecimal; +import java.util.logging.Level; + +import org.compiere.model.MProduction; +import org.compiere.util.AdempiereUserError; +import org.compiere.util.DB; + + +/** + * + * Process to create production lines based on the plans + * defined for a particular production header + * @author Paul Bowden + * + */ +public class ProductionCreate extends SvrProcess { + + private int p_M_Production_ID=0; + private MProduction m_production = null; + private boolean mustBeStocked = false; //not used + private boolean recreate = false; + private BigDecimal newQty = null; + //private int p_M_Locator_ID=0; + + + protected void prepare() { + + ProcessInfoParameter[] para = getParameter(); + for (int i = 0; i < para.length; i++) + { + String name = para[i].getParameterName(); + if ("Recreate".equals(name)) + recreate = "Y".equals(para[i].getParameter()); + else if ("ProductionQty".equals(name)) + newQty = (BigDecimal) para[i].getParameter(); + else + log.log(Level.SEVERE, "Unknown Parameter: " + name); + } + + p_M_Production_ID = getRecord_ID(); + m_production = new MProduction(getCtx(), p_M_Production_ID, get_TrxName()); + + } //prepare + + @Override + protected String doIt() throws Exception { + + if ( m_production.get_ID() == 0 ) + throw new AdempiereUserError("Could not load production header"); + + if ( m_production.isProcessed() ) + return "Already processed"; + + return createLines(); + + } + + private boolean costsOK(int M_Product_ID) throws AdempiereUserError { + // Warning will not work if non-standard costing is used + String sql = "SELECT ABS(((cc.currentcostprice-(SELECT SUM(c.currentcostprice*bom.bomqty)" + + " FROM m_cost c" + + " INNER JOIN m_product_bom bom ON (c.m_product_id=bom.m_productbom_id)" + + " WHERE bom.m_product_id = pp.m_product_id)" + + " )/cc.currentcostprice))" + + " FROM m_product pp" + + " INNER JOIN m_cost cc on (cc.m_product_id=pp.m_product_id)" + + " INNER JOIN m_costelement ce ON (cc.m_costelement_id=ce.m_costelement_id)" + + " WHERE cc.currentcostprice > 0 AND pp.M_Product_ID = ?" + + " AND ce.costingmethod='S'"; + + BigDecimal costPercentageDiff = DB.getSQLValueBD(get_TrxName(), sql, M_Product_ID); + + if (costPercentageDiff == null) + { + throw new AdempiereUserError("Could not retrieve costs"); + } + + if ( (costPercentageDiff.compareTo(new BigDecimal("0.005")))< 0 ) + return true; + + return false; + } + + protected String createLines() throws Exception { + + int created = 0; + isBom(m_production.getM_Product_ID()); + + if (!costsOK(m_production.getM_Product_ID())) + throw new AdempiereUserError("Excessive difference in standard costs"); + + if (!recreate && "true".equalsIgnoreCase(m_production.get_ValueAsString("IsCreated"))) + throw new AdempiereUserError("Production already created."); + + if (newQty != null ) + m_production.setProductionQty(newQty); + + m_production.deleteLines(get_TrxName()); + created = m_production.createLines(mustBeStocked); + if ( created == 0 ) + {return "Failed to create production lines"; } + + + m_production.setIsCreated("Y"); + m_production.save(get_TrxName()); + return created + " production lines were created"; + } + + protected void isBom(int M_Product_ID) throws Exception + { + String bom = DB.getSQLValueString(get_TrxName(), "SELECT isbom FROM M_Product WHERE M_Product_ID = ?", M_Product_ID); + if ("N".compareTo(bom) == 0) + { + throw new AdempiereUserError ("Attempt to create product line for Non Bill Of Materials"); + } + int materials = DB.getSQLValue(get_TrxName(), "SELECT count(M_Product_BOM_ID) FROM M_Product_BOM WHERE M_Product_ID = ?", M_Product_ID); + if (materials == 0) + { + throw new AdempiereUserError ("Attempt to create product line for Bill Of Materials with no BOM Products"); + } + } +} diff --git a/org.adempiere.base.process/src/org/compiere/process/ProductionProcess.java b/org.adempiere.base.process/src/org/compiere/process/ProductionProcess.java new file mode 100644 index 0000000000..322c553caa --- /dev/null +++ b/org.adempiere.base.process/src/org/compiere/process/ProductionProcess.java @@ -0,0 +1,99 @@ +package org.compiere.process; + +import java.sql.Timestamp; +import java.util.logging.Level; + +import org.compiere.model.MProduction; +import org.compiere.model.MProductionLine; +import org.compiere.process.ProcessInfoParameter; +import org.compiere.process.SvrProcess; +import org.compiere.util.AdempiereSystemError; +import org.compiere.util.AdempiereUserError; + + +/** + * + * Process to create production lines based on the plans + * defined for a particular production header + * @author Paul Bowden + * + */ +public class ProductionProcess extends SvrProcess { + + private int p_M_Production_ID=0; + private Timestamp p_MovementDate = null; + private MProduction m_production = null; + private boolean mustBeStocked = false; //not used + private boolean recreate = false; + private boolean issued = false; + //private int p_M_Locator_ID=0; + + + protected void prepare() { + + log.severe("In prepare method"); + ProcessInfoParameter[] para = getParameter(); + for (int i = 0; i < para.length; i++) + { + String name = para[i].getParameterName(); + // log.fine("prepare - " + para[i]); + if (para[i].getParameter() == null) + ; + else if (name.equals("MovementDate")) + p_MovementDate = (Timestamp)para[i].getParameter(); + else + log.log(Level.SEVERE, "Unknown Parameter: " + name); + } + + p_M_Production_ID = getRecord_ID(); + m_production = new MProduction(getCtx(), p_M_Production_ID, get_TrxName()); + + } //prepare + + @Override + protected String doIt() throws Exception { + + + if ( m_production.get_ID() == 0 ) + throw new AdempiereUserError("Could not load production header"); + + if ( m_production.getIsCreated().equals("N") ) + return "Not created"; + + if ( m_production.isProcessed() ) + return "Already processed"; + + + return processLines(); + + } + + protected String processLines() throws Exception { + + int processed = 0; + m_production.setMovementDate(p_MovementDate); + System.err.println(m_production.getMovementDate()); + MProductionLine[] lines = m_production.getLines(); + StringBuffer errors = new StringBuffer(); + for ( int i = 0; i " + p_ReplenishmentCreate); + // + if (p_ReplenishmentCreate.equals("POO")) + createPO(); + else if (p_ReplenishmentCreate.equals("POR")) + createRequisition(); + else if (p_ReplenishmentCreate.equals("MMM")) + createMovements(); + else if (p_ReplenishmentCreate.equals("DOO")) + createDO(); + else if (p_ReplenishmentCreate.equals("PRD")) + createProduction(); + return m_info; + } // doIt + + /** + * Prepare/Check Replenishment Table + */ + private void prepareTable() + { + // Level_Max must be >= Level_Max + String sql = "UPDATE M_Replenish" + + " SET Level_Max = Level_Min " + + "WHERE Level_Max < Level_Min"; + int no = DB.executeUpdate(sql, get_TrxName()); + if (no != 0) + log.fine("Corrected Max_Level=" + no); + + // Minimum Order should be 1 + sql = "UPDATE M_Product_PO" + + " SET Order_Min = 1 " + + "WHERE Order_Min IS NULL OR Order_Min < 1"; + no = DB.executeUpdate(sql, get_TrxName()); + if (no != 0) + log.fine("Corrected Order Min=" + no); + + // Pack should be 1 + sql = "UPDATE M_Product_PO" + + " SET Order_Pack = 1 " + + "WHERE Order_Pack IS NULL OR Order_Pack < 1"; + no = DB.executeUpdate(sql, get_TrxName()); + if (no != 0) + log.fine("Corrected Order Pack=" + no); + + // Set Current Vendor where only one vendor + sql = "UPDATE M_Product_PO p" + + " SET IsCurrentVendor='Y' " + + "WHERE IsCurrentVendor<>'Y'" + + " AND EXISTS (SELECT pp.M_Product_ID FROM M_Product_PO pp " + + "WHERE p.M_Product_ID=pp.M_Product_ID " + + "GROUP BY pp.M_Product_ID " + + "HAVING COUNT(*) = 1)"; + no = DB.executeUpdate(sql, get_TrxName()); + if (no != 0) + log.fine("Corrected CurrentVendor(Y)=" + no); + + // More then one current vendor + sql = "UPDATE M_Product_PO p" + + " SET IsCurrentVendor='N' " + + "WHERE IsCurrentVendor = 'Y'" + + " AND EXISTS (SELECT pp.M_Product_ID FROM M_Product_PO pp " + + "WHERE p.M_Product_ID=pp.M_Product_ID AND pp.IsCurrentVendor='Y' " + + "GROUP BY pp.M_Product_ID " + + "HAVING COUNT(*) > 1)"; + no = DB.executeUpdate(sql, get_TrxName()); + if (no != 0) + log.fine("Corrected CurrentVendor(N)=" + no); + + // Just to be sure + sql = "DELETE T_Replenish WHERE AD_PInstance_ID=" + getAD_PInstance_ID(); + no = DB.executeUpdate(sql, get_TrxName()); + if (no != 0) + log.fine("Delete Existing Temp=" + no); + } // prepareTable + + /** + * Fill Table + * @param wh warehouse + */ + private void fillTable (MWarehouse wh) throws Exception + { + String sql = "INSERT INTO T_Replenish " + + "(AD_PInstance_ID, M_Warehouse_ID, M_Product_ID, AD_Client_ID, AD_Org_ID," + + " ReplenishType, Level_Min, Level_Max," + + " C_BPartner_ID, Order_Min, Order_Pack, QtyToOrder, ReplenishmentCreate) " + + "SELECT " + getAD_PInstance_ID() + + ", r.M_Warehouse_ID, r.M_Product_ID, r.AD_Client_ID, r.AD_Org_ID," + + " r.ReplenishType, r.Level_Min, r.Level_Max," + + " po.C_BPartner_ID, po.Order_Min, po.Order_Pack, 0, "; + if (p_ReplenishmentCreate == null) + sql += "null"; + else + sql += "'" + p_ReplenishmentCreate + "'"; + sql += " FROM M_Replenish r" + + " INNER JOIN M_Product_PO po ON (r.M_Product_ID=po.M_Product_ID) " + + " INNER JOIN M_Product p ON (p.M_Product_ID=po.M_Product_ID) " + + "WHERE po.IsCurrentVendor='Y'" // Only Current Vendor + + " AND r.ReplenishType<>'0'" + + " AND po.IsActive='Y' AND r.IsActive='Y'" + + " AND r.M_Warehouse_ID=" + p_M_Warehouse_ID; + if (p_C_BPartner_ID != 0) + sql += " AND po.C_BPartner_ID=" + p_C_BPartner_ID; + if ( p_M_Product_Category_ID != 0 ) + sql += " AND p.M_Product_Category_ID=" + p_M_Product_Category_ID; + if ( excludeKanban ) + sql += " AND p.IsKanban = 'N' "; + int no = DB.executeUpdate(sql, get_TrxName()); + log.finest(sql); + log.fine("Insert (1) #" + no); + + if (p_C_BPartner_ID == 0) + { + sql = "INSERT INTO T_Replenish " + + "(AD_PInstance_ID, M_Warehouse_ID, M_Product_ID, AD_Client_ID, AD_Org_ID," + + " ReplenishType, Level_Min, Level_Max," + + " C_BPartner_ID, Order_Min, Order_Pack, QtyToOrder, ReplenishmentCreate) " + + "SELECT " + getAD_PInstance_ID() + + ", r.M_Warehouse_ID, r.M_Product_ID, r.AD_Client_ID, r.AD_Org_ID," + + " r.ReplenishType, r.Level_Min, r.Level_Max," + + " 0, 1, 1, 0, "; + if (p_ReplenishmentCreate == null) + sql += "null"; + else + sql += "'" + p_ReplenishmentCreate + "'"; + sql += " FROM M_Replenish r " + + " INNER JOIN M_Product p ON (p.M_Product_ID=r.M_Product_ID) " + + "WHERE r.ReplenishType<>'0' AND r.IsActive='Y'" + + " AND r.M_Warehouse_ID=" + p_M_Warehouse_ID + + " AND NOT EXISTS (SELECT * FROM T_Replenish t " + + "WHERE r.M_Product_ID=t.M_Product_ID" + + " AND AD_PInstance_ID=" + getAD_PInstance_ID() + ")"; + if ( p_M_Product_Category_ID != 0 ) + sql += " AND p.M_Product_Category_ID=" + p_M_Product_Category_ID; + if ( excludeKanban ) + sql += " AND p.IsKanban = 'N' "; + no = DB.executeUpdate(sql, get_TrxName()); + log.fine("Insert (BP) #" + no); + } + + sql = "UPDATE T_Replenish t SET " + + "QtyOnHand = (SELECT COALESCE(SUM(QtyOnHand),0) FROM M_Storage s, M_Locator l WHERE t.M_Product_ID=s.M_Product_ID" + + " AND l.M_Locator_ID=s.M_Locator_ID AND l.M_Warehouse_ID=t.M_Warehouse_ID)," + + "QtyReserved = (SELECT COALESCE(SUM(QtyReserved),0) FROM M_Storage s, M_Locator l WHERE t.M_Product_ID=s.M_Product_ID" + + " AND l.M_Locator_ID=s.M_Locator_ID AND l.M_Warehouse_ID=t.M_Warehouse_ID)," + + "QtyOrdered = (SELECT COALESCE(SUM(QtyOrdered),0) FROM M_Storage s, M_Locator l WHERE t.M_Product_ID=s.M_Product_ID" + + " AND l.M_Locator_ID=s.M_Locator_ID AND l.M_Warehouse_ID=t.M_Warehouse_ID)"; + if (p_C_DocType_ID != 0) + sql += ", C_DocType_ID=" + p_C_DocType_ID; + sql += " WHERE AD_PInstance_ID=" + getAD_PInstance_ID(); + no = DB.executeUpdate(sql, get_TrxName()); + if (no != 0) + log.fine("Update #" + no); + + // add production lines + sql = "UPDATE T_Replenish t SET " + + "QtyReserved = QtyReserved + COALESCE((SELECT COALESCE(SUM(MovementQty),0) FROM M_ProductionLine p, M_Locator l WHERE t.M_Product_ID=p.M_Product_ID" + + " AND l.M_Locator_ID=p.M_Locator_ID AND l.M_Warehouse_ID=t.M_Warehouse_ID AND MovementQty < 0 AND p.Processed = 'N'),0)," + + "QtyOrdered = QtyOrdered + COALESCE((SELECT COALESCE(SUM(MovementQty),0) FROM M_ProductionLine p, M_Locator l WHERE t.M_Product_ID=p.M_Product_ID" + + " AND l.M_Locator_ID=p.M_Locator_ID AND l.M_Warehouse_ID=t.M_Warehouse_ID AND MovementQty > 0 AND p.Processed = 'N'),0)"; + if (p_C_DocType_ID != 0) + sql += ", C_DocType_ID=" + p_C_DocType_ID; + sql += " WHERE AD_PInstance_ID=" + getAD_PInstance_ID(); + no = DB.executeUpdate(sql, get_TrxName()); + if (no != 0) + log.fine("Update #" + no); + + + // Delete inactive products and replenishments + sql = "DELETE T_Replenish r " + + "WHERE (EXISTS (SELECT * FROM M_Product p " + + "WHERE p.M_Product_ID=r.M_Product_ID AND p.IsActive='N')" + + " OR EXISTS (SELECT * FROM M_Replenish rr " + + " WHERE rr.M_Product_ID=r.M_Product_ID AND rr.IsActive='N'" + + " AND rr.M_Warehouse_ID=" + p_M_Warehouse_ID + " ))" + + " AND AD_PInstance_ID=" + getAD_PInstance_ID(); + no = DB.executeUpdate(sql, get_TrxName()); + if (no != 0) + log.fine("Delete Inactive=" + no); + + // Ensure Data consistency + sql = "UPDATE T_Replenish SET QtyOnHand = 0 WHERE QtyOnHand IS NULL"; + no = DB.executeUpdate(sql, get_TrxName()); + sql = "UPDATE T_Replenish SET QtyReserved = 0 WHERE QtyReserved IS NULL"; + no = DB.executeUpdate(sql, get_TrxName()); + sql = "UPDATE T_Replenish SET QtyOrdered = 0 WHERE QtyOrdered IS NULL"; + no = DB.executeUpdate(sql, get_TrxName()); + + // Set Minimum / Maximum Maintain Level + // X_M_Replenish.REPLENISHTYPE_ReorderBelowMinimumLevel + sql = "UPDATE T_Replenish" + + " SET QtyToOrder = CASE WHEN QtyOnHand - QtyReserved + QtyOrdered <= Level_Min " + + " THEN Level_Max - QtyOnHand + QtyReserved - QtyOrdered " + + " ELSE 0 END " + + "WHERE ReplenishType='1'" + + " AND AD_PInstance_ID=" + getAD_PInstance_ID(); + no = DB.executeUpdate(sql, get_TrxName()); + if (no != 0) + log.fine("Update Type-1=" + no); + // + // X_M_Replenish.REPLENISHTYPE_MaintainMaximumLevel + sql = "UPDATE T_Replenish" + + " SET QtyToOrder = Level_Max - QtyOnHand + QtyReserved - QtyOrdered " + + "WHERE ReplenishType='2'" + + " AND AD_PInstance_ID=" + getAD_PInstance_ID(); + no = DB.executeUpdate(sql, get_TrxName()); + if (no != 0) + log.fine("Update Type-2=" + no); + + + // Minimum Order Quantity + sql = "UPDATE T_Replenish" + + " SET QtyToOrder = Order_Min " + + "WHERE QtyToOrder < Order_Min" + + " AND QtyToOrder > 0" + + " AND AD_PInstance_ID=" + getAD_PInstance_ID(); + no = DB.executeUpdate(sql, get_TrxName()); + if (no != 0) + log.fine("Set MinOrderQty=" + no); + + // Even dividable by Pack + sql = "UPDATE T_Replenish" + + " SET QtyToOrder = QtyToOrder - MOD(QtyToOrder, Order_Pack) + Order_Pack " + + "WHERE MOD(QtyToOrder, Order_Pack) <> 0" + + " AND QtyToOrder > 0" + + " AND AD_PInstance_ID=" + getAD_PInstance_ID(); + no = DB.executeUpdate(sql, get_TrxName()); + if (no != 0) + log.fine("Set OrderPackQty=" + no); + + // Source from other warehouse + if (wh.getM_WarehouseSource_ID() != 0) + { + sql = "UPDATE T_Replenish" + + " SET M_WarehouseSource_ID=" + wh.getM_WarehouseSource_ID() + + " WHERE AD_PInstance_ID=" + getAD_PInstance_ID(); + no = DB.executeUpdate(sql, get_TrxName()); + if (no != 0) + log.fine("Set Source Warehouse=" + no); + } + // Check Source Warehouse + sql = "UPDATE T_Replenish" + + " SET M_WarehouseSource_ID = NULL " + + "WHERE M_Warehouse_ID=M_WarehouseSource_ID" + + " AND AD_PInstance_ID=" + getAD_PInstance_ID(); + no = DB.executeUpdate(sql, get_TrxName()); + if (no != 0) + log.fine("Set same Source Warehouse=" + no); + + // Custom Replenishment + String className = wh.getReplenishmentClass(); + if (className != null && className.length() > 0) + { + // Get Replenishment Class + ReplenishInterface custom = null; + try + { + Class clazz = Class.forName(className); + custom = (ReplenishInterface)clazz.newInstance(); + } + catch (Exception e) + { + throw new AdempiereUserError("No custom Replenishment class " + + className + " - " + e.toString()); + } + + X_T_Replenish[] replenishs = getReplenish("ReplenishType='9'"); + for (int i = 0; i < replenishs.length; i++) + { + X_T_Replenish replenish = replenishs[i]; + if (replenish.getReplenishType().equals(X_T_Replenish.REPLENISHTYPE_Custom)) + { + BigDecimal qto = null; + try + { + qto = custom.getQtyToOrder(wh, replenish); + } + catch (Exception e) + { + log.log(Level.SEVERE, custom.toString(), e); + } + if (qto == null) + qto = Env.ZERO; + replenish.setQtyToOrder(qto); + replenish.save(); + } + } + } + // Delete rows where nothing to order + sql = "DELETE T_Replenish " + + "WHERE QtyToOrder < 1" + + " AND AD_PInstance_ID=" + getAD_PInstance_ID(); + no = DB.executeUpdate(sql, get_TrxName()); + if (no != 0) + log.fine("Delete No QtyToOrder=" + no); + + } // fillTable + + /** + * Create PO's + */ + private void createPO() + { + int noOrders = 0; + String info = ""; + // + MOrder order = null; + MWarehouse wh = null; + X_T_Replenish[] replenishs = getReplenish("M_WarehouseSource_ID IS NULL AND C_BPartner_ID > 0"); + for (int i = 0; i < replenishs.length; i++) + { + X_T_Replenish replenish = replenishs[i]; + if (wh == null || wh.getM_Warehouse_ID() != replenish.getM_Warehouse_ID()) + wh = MWarehouse.get(getCtx(), replenish.getM_Warehouse_ID()); + // + if (order == null + || order.getC_BPartner_ID() != replenish.getC_BPartner_ID() + || order.getM_Warehouse_ID() != replenish.getM_Warehouse_ID()) + { + order = new MOrder(getCtx(), 0, get_TrxName()); + order.setIsSOTrx(false); + order.setC_DocTypeTarget_ID(p_C_DocType_ID); + MBPartner bp = new MBPartner(getCtx(), replenish.getC_BPartner_ID(), get_TrxName()); + order.setBPartner(bp); + order.setSalesRep_ID(getAD_User_ID()); + order.setDescription(Msg.getMsg(getCtx(), "Replenishment")); + // Set Org/WH + order.setAD_Org_ID(wh.getAD_Org_ID()); + order.setM_Warehouse_ID(wh.getM_Warehouse_ID()); + if (!order.save()) + return; + log.fine(order.toString()); + noOrders++; + info += " - " + order.getDocumentNo(); + } + MOrderLine line = new MOrderLine (order); + line.setM_Product_ID(replenish.getM_Product_ID()); + line.setQty(replenish.getQtyToOrder()); + line.setPrice(); + line.save(); + } + m_info = "#" + noOrders + info; + log.info(m_info); + } // createPO + + /** + * Create Requisition + */ + private void createRequisition() + { + int noReqs = 0; + String info = ""; + // + MRequisition requisition = null; + MWarehouse wh = null; + X_T_Replenish[] replenishs = getReplenish("M_WarehouseSource_ID IS NULL AND C_BPartner_ID > 0"); + for (int i = 0; i < replenishs.length; i++) + { + X_T_Replenish replenish = replenishs[i]; + if (wh == null || wh.getM_Warehouse_ID() != replenish.getM_Warehouse_ID()) + wh = MWarehouse.get(getCtx(), replenish.getM_Warehouse_ID()); + // + if (requisition == null + || requisition.getM_Warehouse_ID() != replenish.getM_Warehouse_ID()) + { + requisition = new MRequisition (getCtx(), 0, get_TrxName()); + requisition.setAD_User_ID (getAD_User_ID()); + requisition.setC_DocType_ID(p_C_DocType_ID); + requisition.setDescription(Msg.getMsg(getCtx(), "Replenishment")); + // Set Org/WH + requisition.setAD_Org_ID(wh.getAD_Org_ID()); + requisition.setM_Warehouse_ID(wh.getM_Warehouse_ID()); + if (!requisition.save()) + return; + log.fine(requisition.toString()); + noReqs++; + info += " - " + requisition.getDocumentNo(); + } + // + MRequisitionLine line = new MRequisitionLine(requisition); + line.setM_Product_ID(replenish.getM_Product_ID()); + line.setC_BPartner_ID(replenish.getC_BPartner_ID()); + line.setQty(replenish.getQtyToOrder()); + line.setPrice(); + line.save(); + } + m_info = "#" + noReqs + info; + log.info(m_info); + } // createRequisition + + /** + * Create Inventory Movements + */ + private void createMovements() + { + int noMoves = 0; + String info = ""; + // + MClient client = null; + MMovement move = null; + int M_Warehouse_ID = 0; + int M_WarehouseSource_ID = 0; + MWarehouse whSource = null; + MWarehouse wh = null; + X_T_Replenish[] replenishs = getReplenish("M_WarehouseSource_ID IS NOT NULL AND C_BPartner_ID > 0"); + for (int i = 0; i < replenishs.length; i++) + { + X_T_Replenish replenish = replenishs[i]; + if (whSource == null || whSource.getM_WarehouseSource_ID() != replenish.getM_WarehouseSource_ID()) + whSource = MWarehouse.get(getCtx(), replenish.getM_WarehouseSource_ID()); + if (wh == null || wh.getM_Warehouse_ID() != replenish.getM_Warehouse_ID()) + wh = MWarehouse.get(getCtx(), replenish.getM_Warehouse_ID()); + if (client == null || client.getAD_Client_ID() != whSource.getAD_Client_ID()) + client = MClient.get(getCtx(), whSource.getAD_Client_ID()); + // + if (move == null + || M_WarehouseSource_ID != replenish.getM_WarehouseSource_ID() + || M_Warehouse_ID != replenish.getM_Warehouse_ID()) + { + M_WarehouseSource_ID = replenish.getM_WarehouseSource_ID(); + M_Warehouse_ID = replenish.getM_Warehouse_ID(); + + move = new MMovement (getCtx(), 0, get_TrxName()); + move.setC_DocType_ID(p_C_DocType_ID); + move.setDescription(Msg.getMsg(getCtx(), "Replenishment") + + ": " + whSource.getName() + "->" + wh.getName()); + // Set Org + move.setAD_Org_ID(whSource.getAD_Org_ID()); + if (!move.save()) + return; + log.fine(move.toString()); + noMoves++; + info += " - " + move.getDocumentNo(); + } + // To + int M_LocatorTo_ID = wh.getDefaultLocator().getM_Locator_ID(); + // From: Look-up Storage + MProduct product = MProduct.get(getCtx(), replenish.getM_Product_ID()); + String MMPolicy = product.getMMPolicy(); + MStorage[] storages = MStorage.getWarehouse(getCtx(), + whSource.getM_Warehouse_ID(), replenish.getM_Product_ID(), 0, 0, + true, null, + MClient.MMPOLICY_FiFo.equals(MMPolicy), get_TrxName()); + // + BigDecimal target = replenish.getQtyToOrder(); + for (int j = 0; j < storages.length; j++) + { + MStorage storage = storages[j]; + if (storage.getQtyOnHand().signum() <= 0) + continue; + BigDecimal moveQty = target; + if (storage.getQtyOnHand().compareTo(moveQty) < 0) + moveQty = storage.getQtyOnHand(); + // + MMovementLine line = new MMovementLine(move); + line.setM_Product_ID(replenish.getM_Product_ID()); + line.setMovementQty(moveQty); + if (replenish.getQtyToOrder().compareTo(moveQty) != 0) + line.setDescription("Total: " + replenish.getQtyToOrder()); + line.setM_Locator_ID(storage.getM_Locator_ID()); // from + line.setM_AttributeSetInstance_ID(storage.getM_AttributeSetInstance_ID()); + line.setM_LocatorTo_ID(M_LocatorTo_ID); // to + line.setM_AttributeSetInstanceTo_ID(storage.getM_AttributeSetInstance_ID()); + line.save(); + // + target = target.subtract(moveQty); + if (target.signum() == 0) + break; + } + } + if (replenishs.length == 0) + { + m_info = "No Source Warehouse"; + log.warning(m_info); + } + else + { + m_info = "#" + noMoves + info; + log.info(m_info); + } + } // Create Inventory Movements + + /** + * Create Distribution Order + */ + private void createDO() throws Exception + { + int noMoves = 0; + String info = ""; + // + MClient client = null; + MDDOrder order = null; + int M_Warehouse_ID = 0; + int M_WarehouseSource_ID = 0; + MWarehouse whSource = null; + MWarehouse wh = null; + X_T_Replenish[] replenishs = getReplenish("M_WarehouseSource_ID IS NOT NULL"); + for (X_T_Replenish replenish:replenishs) + { + if (whSource == null || whSource.getM_WarehouseSource_ID() != replenish.getM_WarehouseSource_ID()) + whSource = MWarehouse.get(getCtx(), replenish.getM_WarehouseSource_ID()); + if (wh == null || wh.getM_Warehouse_ID() != replenish.getM_Warehouse_ID()) + wh = MWarehouse.get(getCtx(), replenish.getM_Warehouse_ID()); + if (client == null || client.getAD_Client_ID() != whSource.getAD_Client_ID()) + client = MClient.get(getCtx(), whSource.getAD_Client_ID()); + // + if (order == null + || M_WarehouseSource_ID != replenish.getM_WarehouseSource_ID() + || M_Warehouse_ID != replenish.getM_Warehouse_ID()) + { + M_WarehouseSource_ID = replenish.getM_WarehouseSource_ID(); + M_Warehouse_ID = replenish.getM_Warehouse_ID(); + + order = new MDDOrder (getCtx(), 0, get_TrxName()); + order.setC_DocType_ID(p_C_DocType_ID); + order.setDescription(Msg.getMsg(getCtx(), "Replenishment") + + ": " + whSource.getName() + "->" + wh.getName()); + // Set Org + order.setAD_Org_ID(whSource.getAD_Org_ID()); + // Set Org Trx + MOrg orgTrx = MOrg.get(getCtx(), wh.getAD_Org_ID()); + order.setAD_OrgTrx_ID(orgTrx.getAD_Org_ID()); + int C_BPartner_ID = orgTrx.getLinkedC_BPartner_ID(get_TrxName()); + if (C_BPartner_ID==0) + throw new AdempiereUserError(Msg.translate(getCtx(), "C_BPartner_ID")+ " @FillMandatory@ "); + MBPartner bp = new MBPartner(getCtx(),C_BPartner_ID,get_TrxName()); + // Set BPartner Link to Org + order.setBPartner(bp); + order.setDateOrdered(new Timestamp(System.currentTimeMillis())); + //order.setDatePromised(DatePromised); + order.setDeliveryRule(MDDOrder.DELIVERYRULE_Availability); + order.setDeliveryViaRule(MDDOrder.DELIVERYVIARULE_Delivery); + order.setPriorityRule(MDDOrder.PRIORITYRULE_Medium); + order.setIsInDispute(false); + order.setIsApproved(false); + order.setIsDropShip(false); + order.setIsDelivered(false); + order.setIsInTransit(false); + order.setIsPrinted(false); + order.setIsSelected(false); + order.setIsSOTrx(false); + // Warehouse in Transit + MWarehouse[] whsInTransit = MWarehouse.getForOrg(getCtx(), whSource.getAD_Org_ID()); + for (MWarehouse whInTransit:whsInTransit) + { + if(whInTransit.isInTransit()) + order.setM_Warehouse_ID(whInTransit.getM_Warehouse_ID()); + } + if (order.getM_Warehouse_ID()==0) + throw new AdempiereUserError("Warehouse inTransit is @FillMandatory@ "); + + if (!order.save()) + return; + log.fine(order.toString()); + noMoves++; + info += " - " + order.getDocumentNo(); + } + + // To + int M_LocatorTo_ID = wh.getDefaultLocator().getM_Locator_ID(); + int M_Locator_ID = whSource.getDefaultLocator().getM_Locator_ID(); + if(M_LocatorTo_ID == 0 || M_Locator_ID==0) + throw new AdempiereUserError(Msg.translate(getCtx(), "M_Locator_ID")+" @FillMandatory@ "); + + // From: Look-up Storage + /*MProduct product = MProduct.get(getCtx(), replenish.getM_Product_ID()); + MProductCategory pc = MProductCategory.get(getCtx(), product.getM_Product_Category_ID()); + String MMPolicy = pc.getMMPolicy(); + if (MMPolicy == null || MMPolicy.length() == 0) + MMPolicy = client.getMMPolicy(); + // + MStorage[] storages = MStorage.getWarehouse(getCtx(), + whSource.getM_Warehouse_ID(), replenish.getM_Product_ID(), 0, 0, + true, null, + MClient.MMPOLICY_FiFo.equals(MMPolicy), get_TrxName()); + + + BigDecimal target = replenish.getQtyToOrder(); + for (int j = 0; j < storages.length; j++) + { + MStorage storage = storages[j]; + if (storage.getQtyOnHand().signum() <= 0) + continue; + BigDecimal moveQty = target; + if (storage.getQtyOnHand().compareTo(moveQty) < 0) + moveQty = storage.getQtyOnHand(); + // + MDDOrderLine line = new MDDOrderLine(order); + line.setM_Product_ID(replenish.getM_Product_ID()); + line.setQtyEntered(moveQty); + if (replenish.getQtyToOrder().compareTo(moveQty) != 0) + line.setDescription("Total: " + replenish.getQtyToOrder()); + line.setM_Locator_ID(storage.getM_Locator_ID()); // from + line.setM_AttributeSetInstance_ID(storage.getM_AttributeSetInstance_ID()); + line.setM_LocatorTo_ID(M_LocatorTo_ID); // to + line.setM_AttributeSetInstanceTo_ID(storage.getM_AttributeSetInstance_ID()); + line.setIsInvoiced(false); + line.save(); + // + target = target.subtract(moveQty); + if (target.signum() == 0) + break; + }*/ + + MDDOrderLine line = new MDDOrderLine(order); + line.setM_Product_ID(replenish.getM_Product_ID()); + line.setQty(replenish.getQtyToOrder()); + if (replenish.getQtyToOrder().compareTo(replenish.getQtyToOrder()) != 0) + line.setDescription("Total: " + replenish.getQtyToOrder()); + line.setM_Locator_ID(M_Locator_ID); // from + line.setM_AttributeSetInstance_ID(0); + line.setM_LocatorTo_ID(M_LocatorTo_ID); // to + line.setM_AttributeSetInstanceTo_ID(0); + line.setIsInvoiced(false); + line.save(); + + } + if (replenishs.length == 0) + { + m_info = "No Source Warehouse"; + log.warning(m_info); + } + else + { + m_info = "#" + noMoves + info; + log.info(m_info); + } + } // create Distribution Order + /** + * Create Requisition + */ + private void createProduction() + { + int noProds = 0; + String info = ""; + // + MProduction production = null; + MWarehouse wh = null; + X_T_Replenish[] replenishs = getReplenish("M_WarehouseSource_ID IS NULL " + + "AND EXISTS (SELECT * FROM M_Product p WHERE p.M_Product_ID=T_Replenish.M_Product_ID " + + "AND p.IsBOM='Y' AND p.IsManufactured='Y') "); + for (int i = 0; i < replenishs.length; i++) + { + X_T_Replenish replenish = replenishs[i]; + if (wh == null || wh.getM_Warehouse_ID() != replenish.getM_Warehouse_ID()) + wh = MWarehouse.get(getCtx(), replenish.getM_Warehouse_ID()); + production = new MProduction (getCtx(), 0, get_TrxName()); + production.setDescription(Msg.getMsg(getCtx(), "Replenishment")); + // Set Org/WH + production.setAD_Org_ID(wh.getAD_Org_ID()); + production.setM_Locator_ID(wh.getDefaultLocator().get_ID()); + production.setM_Product_ID(replenish.getM_Product_ID()); + production.setProductionQty(replenish.getQtyToOrder()); + production.setMovementDate(Env.getContextAsDate(getCtx(), "#Date")); + production.saveEx(); + + production.createLines(false); + + + production.setIsCreated("Y"); + production.save(get_TrxName()); + log.fine(production.toString()); + noProds++; + info += " - " + production.getDocumentNo(); + + } + m_info = "#" + noProds + info; + log.info(m_info); + } // createRequisition + + /** + * Get Replenish Records + * @return replenish + */ + private X_T_Replenish[] getReplenish (String where) + { + String sql = "SELECT * FROM T_Replenish " + + "WHERE AD_PInstance_ID=? "; + if (where != null && where.length() > 0) + sql += " AND " + where; + sql += " ORDER BY M_Warehouse_ID, M_WarehouseSource_ID, C_BPartner_ID"; + ArrayList list = new ArrayList(); + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement (sql, get_TrxName()); + pstmt.setInt (1, getAD_PInstance_ID()); + ResultSet rs = pstmt.executeQuery (); + while (rs.next ()) + list.add (new X_T_Replenish (getCtx(), rs, get_TrxName())); + rs.close (); + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + log.log(Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + X_T_Replenish[] retValue = new X_T_Replenish[list.size ()]; + list.toArray (retValue); + return retValue; + } // getReplenish + + +} // Replenish diff --git a/org.adempiere.base.process/src/org/compiere/process/RollUpCosts.java b/org.adempiere.base.process/src/org/compiere/process/RollUpCosts.java new file mode 100644 index 0000000000..b809eded29 --- /dev/null +++ b/org.adempiere.base.process/src/org/compiere/process/RollUpCosts.java @@ -0,0 +1,147 @@ +package org.compiere.process; + +import java.math.BigDecimal; +import java.util.HashSet; +import java.util.logging.Level; + +import javax.sql.RowSet; + +import org.compiere.process.ProcessInfoParameter; +import org.compiere.process.SvrProcess; +import org.compiere.util.DB; +import org.compiere.util.Env; + +public class RollUpCosts extends SvrProcess { + + + int category = 0; + int product_id = 0; + int client_id = 0; + int org_id = 0; + int user_id = 0; + int costelement_id = 0; + private HashSet processed; + + protected void prepare() + { + + int chosen_id = 0; + + ProcessInfoParameter[] para = getParameter(); + for (int i = 0; i < para.length; i++) + { + String name = para[i].getParameterName(); + // log.fine("prepare - " + para[i]); + if (para[i].getParameter() == null) + ; + else if (name.equals("M_Product_Category_ID")) + category = para[i].getParameterAsInt(); + else if (name.equals("M_Product_ID")) + chosen_id = para[i].getParameterAsInt(); + else if (name.equals("M_CostElement_ID")) + costelement_id = para[i].getParameterAsInt(); + else + log.log(Level.SEVERE, "Unknown Parameter: " + name); + } + + + product_id = getRecord_ID(); + if (product_id == 0) + { + product_id = chosen_id; + } + + + } + + protected String doIt() throws Exception + { + client_id = Env.getAD_Client_ID(getCtx()); + org_id = Env.getAD_Org_ID(getCtx()); + user_id = Env.getAD_User_ID(getCtx()); + createView(); + String result = rollUp(); + deleteView(); + return result; + } + + + + protected String rollUp() throws Exception { + + + if (product_id != 0) //only for the product + { + rollUpCosts(product_id); + } + else if (category != 0) //roll up for all categories + { + String sql = "SELECT M_PRODUCT_ID FROM M_PRODUCT WHERE M_PRODUCT_CATEGORY_ID = " + + category + " AND AD_CLIENT_ID = " + Env.getAD_Client_ID(getCtx()) + + " AND M_PRODUCT_ID IN (SELECT M_PRODUCT_ID FROM M_PRODUCT_BOM)"; + //System.err.println(sql); + RowSet results = DB.getRowSet(sql); + while (results.next()) + { + rollUpCosts(results.getInt(1)); + } + } + else //do it for all products + { + String sql = "SELECT M_PRODUCT_ID FROM M_PRODUCT WHERE AD_CLIENT_ID = " + Env.getAD_Client_ID(getCtx()) + + " AND M_PRODUCT_ID IN (SELECT M_PRODUCT_ID FROM M_PRODUCT_BOM)"; + //System.err.println(sql); + RowSet results = DB.getRowSet(sql); + while (results.next()) + { + rollUpCosts(results.getInt(1)); + } + } + + return "Roll Up Complete"; + } + + protected void createView() throws Exception + { + + processed = new HashSet(); + + } + + protected void deleteView() + { + } + + protected void rollUpCosts(int p_id) throws Exception + { + String sql = "SELECT M_ProductBOM_ID FROM M_Product_BOM WHERE M_Product_ID = " + + p_id + " AND AD_Client_ID = " + Env.getAD_Client_ID(getCtx()); + //System.err.println(sql); + RowSet results = DB.getRowSet(sql); + + while (results.next()) + { + if ( !processed.contains(p_id)) { + rollUpCosts(results.getInt(1)); + } + } + results.close(); + + //once the subproducts costs are accurate, calculate the costs for this product + String update = "UPDATE M_Cost set CurrentCostPrice = COALESCE((select Sum (b.BOMQty * c.currentcostprice)" + + " FROM M_Product_BOM b INNER JOIN M_Cost c ON (b.M_PRODUCTBOM_ID = c.M_Product_ID) " + + " WHERE b.M_Product_ID = " + p_id + " AND M_CostElement_ID = " + costelement_id + "),0)," + + " FutureCostPrice = COALESCE((select Sum (b.BOMQty * c.futurecostprice) FROM M_Product_BOM b " + + " INNER JOIN M_Cost c ON (b.M_PRODUCTBOM_ID = c.M_Product_ID) " + + " WHERE b.M_Product_ID = " + p_id + " AND M_CostElement_ID = " + costelement_id + "),0)" + + " WHERE M_Product_ID = " + p_id + " AND AD_Client_ID = " + Env.getAD_Client_ID(getCtx()) + + " AND M_CostElement_ID = " + costelement_id + + " AND M_PRODUCT_ID IN (SELECT M_PRODUCT_ID FROM M_PRODUCT_BOM)";; + + //System.err.println(sql); + DB.executeUpdate(update, get_TrxName()); + + processed.add(p_id); + + } +} diff --git a/org.adempiere.base.process/src/org/compiere/process/UniversalSubstitution.java b/org.adempiere.base.process/src/org/compiere/process/UniversalSubstitution.java new file mode 100644 index 0000000000..7c5edc8505 --- /dev/null +++ b/org.adempiere.base.process/src/org/compiere/process/UniversalSubstitution.java @@ -0,0 +1,51 @@ +package org.compiere.process; + +import java.sql.PreparedStatement; +import java.util.logging.Level; + +import org.adempiere.exceptions.AdempiereException; +import org.compiere.process.ProcessInfoParameter; +import org.compiere.process.SvrProcess; +import org.compiere.util.DB; + +public class UniversalSubstitution extends SvrProcess { + + int productId = 0; + int replacementId = 0; + + @Override + protected void prepare() { + ProcessInfoParameter[] para = getParameter(); + for (int i = 0; i < para.length; i++) + { + String name = para[i].getParameterName(); + if (name.equals("M_Product_ID")) + productId = para[i].getParameterAsInt(); + else if (name.equals("Substitute_ID")) + replacementId =para[i].getParameterAsInt(); + else + log.log(Level.SEVERE, "Unknown Parameter: " + name); + } + } + + @Override + protected String doIt() throws Exception { + + if ( productId == 0 || replacementId == 0 ) + throw new AdempiereException("Product and replacement product required"); + + + String update = "UPDATE M_Product_BOM bb " + + "SET M_PRODUCTBOM_ID = ? " + + "WHERE bb.M_PRODUCTBOM_ID = ?"; + + PreparedStatement pstmt = DB.prepareStatement(update, get_TrxName()); + pstmt.setInt(1, replacementId); + pstmt.setInt(2, productId); + + int count = pstmt.executeUpdate(); + + return count + " BOM products updated"; + } + +} diff --git a/org.adempiere.base/src/org/compiere/model/I_M_QualityTest.java b/org.adempiere.base/src/org/compiere/model/I_M_QualityTest.java new file mode 100644 index 0000000000..d46b2300aa --- /dev/null +++ b/org.adempiere.base/src/org/compiere/model/I_M_QualityTest.java @@ -0,0 +1,157 @@ +/****************************************************************************** + * Product: Adempiere ERP & CRM Smart Business Solution * + * Copyright (C) 1999-2007 ComPiere, Inc. All Rights Reserved. * + * This program is free software, you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * + * by the Free Software Foundation. This program is distributed in the hope * + * that it will be useful, but WITHOUT ANY WARRANTY, without even the implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the GNU General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program, if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.model; + +import java.math.BigDecimal; +import java.sql.Timestamp; +import org.compiere.util.KeyNamePair; + +/** Generated Interface for M_QualityTest + * @author Adempiere (generated) + * @version Release 3.6.0LTS + */ +public interface I_M_QualityTest +{ + + /** TableName=M_QualityTest */ + public static final String Table_Name = "M_QualityTest"; + + /** AD_Table_ID=1000004 */ + public static final int Table_ID = MTable.getTable_ID(Table_Name); + + KeyNamePair Model = new KeyNamePair(Table_ID, Table_Name); + + /** AccessLevel = 3 - Client - Org + */ + BigDecimal accessLevel = BigDecimal.valueOf(3); + + /** Load Meta Data */ + + /** Column name AD_Client_ID */ + public static final String COLUMNNAME_AD_Client_ID = "AD_Client_ID"; + + /** Get Client. + * Client/Tenant for this installation. + */ + public int getAD_Client_ID(); + + /** Column name AD_Org_ID */ + public static final String COLUMNNAME_AD_Org_ID = "AD_Org_ID"; + + /** Set Organisation. + * Organisational entity within client + */ + public void setAD_Org_ID (int AD_Org_ID); + + /** Get Organisation. + * Organisational entity within client + */ + public int getAD_Org_ID(); + + /** Column name Created */ + public static final String COLUMNNAME_Created = "Created"; + + /** Get Created. + * Date this record was created + */ + public Timestamp getCreated(); + + /** Column name CreatedBy */ + public static final String COLUMNNAME_CreatedBy = "CreatedBy"; + + /** Get Created By. + * User who created this records + */ + public int getCreatedBy(); + + /** Column name Description */ + public static final String COLUMNNAME_Description = "Description"; + + /** Set Description. + * Optional short description of the record + */ + public void setDescription (String Description); + + /** Get Description. + * Optional short description of the record + */ + public String getDescription(); + + /** Column name Help */ + public static final String COLUMNNAME_Help = "Help"; + + /** Set Comment/Help. + * Comment or Hint + */ + public void setHelp (String Help); + + /** Get Comment/Help. + * Comment or Hint + */ + public String getHelp(); + + /** Column name IsActive */ + public static final String COLUMNNAME_IsActive = "IsActive"; + + /** Set Active. + * The record is active in the system + */ + public void setIsActive (boolean IsActive); + + /** Get Active. + * The record is active in the system + */ + public boolean isActive(); + + /** Column name M_QualityTest_ID */ + public static final String COLUMNNAME_M_QualityTest_ID = "M_QualityTest_ID"; + + /** Set Quality Test */ + public void setM_QualityTest_ID (int M_QualityTest_ID); + + /** Get Quality Test */ + public int getM_QualityTest_ID(); + + /** Column name Name */ + public static final String COLUMNNAME_Name = "Name"; + + /** Set Name. + * Alphanumeric identifier of the entity + */ + public void setName (String Name); + + /** Get Name. + * Alphanumeric identifier of the entity + */ + public String getName(); + + /** Column name Updated */ + public static final String COLUMNNAME_Updated = "Updated"; + + /** Get Updated. + * Date this record was updated + */ + public Timestamp getUpdated(); + + /** Column name UpdatedBy */ + public static final String COLUMNNAME_UpdatedBy = "UpdatedBy"; + + /** Get Updated By. + * User who updated this records + */ + public int getUpdatedBy(); +} diff --git a/org.adempiere.base/src/org/compiere/model/I_M_QualityTestResult.java b/org.adempiere.base/src/org/compiere/model/I_M_QualityTestResult.java new file mode 100644 index 0000000000..6c4beab99f --- /dev/null +++ b/org.adempiere.base/src/org/compiere/model/I_M_QualityTestResult.java @@ -0,0 +1,201 @@ +/****************************************************************************** + * Product: Adempiere ERP & CRM Smart Business Solution * + * Copyright (C) 1999-2007 ComPiere, Inc. All Rights Reserved. * + * This program is free software, you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * + * by the Free Software Foundation. This program is distributed in the hope * + * that it will be useful, but WITHOUT ANY WARRANTY, without even the implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the GNU General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program, if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.model; + +import java.math.BigDecimal; +import java.sql.Timestamp; +import org.compiere.util.KeyNamePair; + +/** Generated Interface for M_QualityTestResult + * @author Adempiere (generated) + * @version Release 3.6.0LTS + */ +public interface I_M_QualityTestResult +{ + + /** TableName=M_QualityTestResult */ + public static final String Table_Name = "M_QualityTestResult"; + + /** AD_Table_ID=1000006 */ + public static final int Table_ID = MTable.getTable_ID(Table_Name); + + KeyNamePair Model = new KeyNamePair(Table_ID, Table_Name); + + /** AccessLevel = 3 - Client - Org + */ + BigDecimal accessLevel = BigDecimal.valueOf(3); + + /** Load Meta Data */ + + /** Column name AD_Client_ID */ + public static final String COLUMNNAME_AD_Client_ID = "AD_Client_ID"; + + /** Get Client. + * Client/Tenant for this installation. + */ + public int getAD_Client_ID(); + + /** Column name AD_Org_ID */ + public static final String COLUMNNAME_AD_Org_ID = "AD_Org_ID"; + + /** Set Organisation. + * Organisational entity within client + */ + public void setAD_Org_ID (int AD_Org_ID); + + /** Get Organisation. + * Organisational entity within client + */ + public int getAD_Org_ID(); + + /** Column name Created */ + public static final String COLUMNNAME_Created = "Created"; + + /** Get Created. + * Date this record was created + */ + public Timestamp getCreated(); + + /** Column name CreatedBy */ + public static final String COLUMNNAME_CreatedBy = "CreatedBy"; + + /** Get Created By. + * User who created this records + */ + public int getCreatedBy(); + + /** Column name Description */ + public static final String COLUMNNAME_Description = "Description"; + + /** Set Description. + * Optional short description of the record + */ + public void setDescription (String Description); + + /** Get Description. + * Optional short description of the record + */ + public String getDescription(); + + /** Column name ExpectedResult */ + public static final String COLUMNNAME_ExpectedResult = "ExpectedResult"; + + /** Set Expected Result */ + public void setExpectedResult (String ExpectedResult); + + /** Get Expected Result */ + public String getExpectedResult(); + + /** Column name IsActive */ + public static final String COLUMNNAME_IsActive = "IsActive"; + + /** Set Active. + * The record is active in the system + */ + public void setIsActive (boolean IsActive); + + /** Get Active. + * The record is active in the system + */ + public boolean isActive(); + + /** Column name IsQCPass */ + public static final String COLUMNNAME_IsQCPass = "IsQCPass"; + + /** Set QC Pass */ + public void setIsQCPass (boolean IsQCPass); + + /** Get QC Pass */ + public boolean isQCPass(); + + /** Column name M_AttributeSetInstance_ID */ + public static final String COLUMNNAME_M_AttributeSetInstance_ID = "M_AttributeSetInstance_ID"; + + /** Set Attribute Set Instance. + * Product Attribute Set Instance + */ + public void setM_AttributeSetInstance_ID (int M_AttributeSetInstance_ID); + + /** Get Attribute Set Instance. + * Product Attribute Set Instance + */ + public int getM_AttributeSetInstance_ID(); + + public I_M_AttributeSetInstance getM_AttributeSetInstance() throws RuntimeException; + + /** Column name M_QualityTest_ID */ + public static final String COLUMNNAME_M_QualityTest_ID = "M_QualityTest_ID"; + + /** Set Quality Test */ + public void setM_QualityTest_ID (int M_QualityTest_ID); + + /** Get Quality Test */ + public int getM_QualityTest_ID(); + + public I_M_QualityTest getM_QualityTest() throws RuntimeException; + + /** Column name M_QualityTestResult_ID */ + public static final String COLUMNNAME_M_QualityTestResult_ID = "M_QualityTestResult_ID"; + + /** Set Quality Test Result */ + public void setM_QualityTestResult_ID (int M_QualityTestResult_ID); + + /** Get Quality Test Result */ + public int getM_QualityTestResult_ID(); + + /** Column name Processed */ + public static final String COLUMNNAME_Processed = "Processed"; + + /** Set Processed. + * The document has been processed + */ + public void setProcessed (boolean Processed); + + /** Get Processed. + * The document has been processed + */ + public boolean isProcessed(); + + /** Column name Result */ + public static final String COLUMNNAME_Result = "Result"; + + /** Set Result. + * Result of the action taken + */ + public void setResult (String Result); + + /** Get Result. + * Result of the action taken + */ + public String getResult(); + + /** Column name Updated */ + public static final String COLUMNNAME_Updated = "Updated"; + + /** Get Updated. + * Date this record was updated + */ + public Timestamp getUpdated(); + + /** Column name UpdatedBy */ + public static final String COLUMNNAME_UpdatedBy = "UpdatedBy"; + + /** Get Updated By. + * User who updated this records + */ + public int getUpdatedBy(); +} diff --git a/org.adempiere.base/src/org/compiere/model/I_T_BOM_Indented.java b/org.adempiere.base/src/org/compiere/model/I_T_BOM_Indented.java new file mode 100644 index 0000000000..1a23e21a92 --- /dev/null +++ b/org.adempiere.base/src/org/compiere/model/I_T_BOM_Indented.java @@ -0,0 +1,318 @@ +/****************************************************************************** + * Product: Adempiere ERP & CRM Smart Business Solution * + * Copyright (C) 1999-2007 ComPiere, Inc. All Rights Reserved. * + * This program is free software, you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * + * by the Free Software Foundation. This program is distributed in the hope * + * that it will be useful, but WITHOUT ANY WARRANTY, without even the implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the GNU General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program, if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.model; + +import java.math.BigDecimal; +import java.sql.Timestamp; +import org.compiere.util.KeyNamePair; + +/** Generated Interface for T_BOM_Indented + * @author Adempiere (generated) + * @version Release 3.6.0LTS + */ +public interface I_T_BOM_Indented +{ + + /** TableName=T_BOM_Indented */ + public static final String Table_Name = "T_BOM_Indented"; + + /** AD_Table_ID=1000008 */ + public static final int Table_ID = MTable.getTable_ID(Table_Name); + + KeyNamePair Model = new KeyNamePair(Table_ID, Table_Name); + + /** AccessLevel = 3 - Client - Org + */ + BigDecimal accessLevel = BigDecimal.valueOf(3); + + /** Load Meta Data */ + + /** Column name AD_Client_ID */ + public static final String COLUMNNAME_AD_Client_ID = "AD_Client_ID"; + + /** Get Client. + * Client/Tenant for this installation. + */ + public int getAD_Client_ID(); + + /** Column name AD_Org_ID */ + public static final String COLUMNNAME_AD_Org_ID = "AD_Org_ID"; + + /** Set Organisation. + * Organisational entity within client + */ + public void setAD_Org_ID (int AD_Org_ID); + + /** Get Organisation. + * Organisational entity within client + */ + public int getAD_Org_ID(); + + /** Column name AD_PInstance_ID */ + public static final String COLUMNNAME_AD_PInstance_ID = "AD_PInstance_ID"; + + /** Set Process Instance. + * Instance of the process + */ + public void setAD_PInstance_ID (int AD_PInstance_ID); + + /** Get Process Instance. + * Instance of the process + */ + public int getAD_PInstance_ID(); + + public I_AD_PInstance getAD_PInstance() throws RuntimeException; + + /** Column name C_AcctSchema_ID */ + public static final String COLUMNNAME_C_AcctSchema_ID = "C_AcctSchema_ID"; + + /** Set Accounting Schema. + * Rules for accounting + */ + public void setC_AcctSchema_ID (int C_AcctSchema_ID); + + /** Get Accounting Schema. + * Rules for accounting + */ + public int getC_AcctSchema_ID(); + + public I_C_AcctSchema getC_AcctSchema() throws RuntimeException; + + /** Column name Cost */ + public static final String COLUMNNAME_Cost = "Cost"; + + /** Set Cost. + * Cost information + */ + public void setCost (BigDecimal Cost); + + /** Get Cost. + * Cost information + */ + public BigDecimal getCost(); + + /** Column name CostFuture */ + public static final String COLUMNNAME_CostFuture = "CostFuture"; + + /** Set Future Cost. + * Cost information + */ + public void setCostFuture (BigDecimal CostFuture); + + /** Get Future Cost. + * Cost information + */ + public BigDecimal getCostFuture(); + + /** Column name Created */ + public static final String COLUMNNAME_Created = "Created"; + + /** Get Created. + * Date this record was created + */ + public Timestamp getCreated(); + + /** Column name CreatedBy */ + public static final String COLUMNNAME_CreatedBy = "CreatedBy"; + + /** Get Created By. + * User who created this records + */ + public int getCreatedBy(); + + /** Column name CurrentCostPrice */ + public static final String COLUMNNAME_CurrentCostPrice = "CurrentCostPrice"; + + /** Set Current Cost Price. + * The currently used cost price + */ + public void setCurrentCostPrice (BigDecimal CurrentCostPrice); + + /** Get Current Cost Price. + * The currently used cost price + */ + public BigDecimal getCurrentCostPrice(); + + /** Column name CurrentCostPriceLL */ + public static final String COLUMNNAME_CurrentCostPriceLL = "CurrentCostPriceLL"; + + /** Set Current Cost Price Lower Level. + * Current Price Lower Level Is the sum of the costs of the components of this product manufactured for this level. + */ + public void setCurrentCostPriceLL (BigDecimal CurrentCostPriceLL); + + /** Get Current Cost Price Lower Level. + * Current Price Lower Level Is the sum of the costs of the components of this product manufactured for this level. + */ + public BigDecimal getCurrentCostPriceLL(); + + /** Column name FutureCostPrice */ + public static final String COLUMNNAME_FutureCostPrice = "FutureCostPrice"; + + /** Set Future Cost Price */ + public void setFutureCostPrice (BigDecimal FutureCostPrice); + + /** Get Future Cost Price */ + public BigDecimal getFutureCostPrice(); + + /** Column name FutureCostPriceLL */ + public static final String COLUMNNAME_FutureCostPriceLL = "FutureCostPriceLL"; + + /** Set Future Cost Price Lower Level */ + public void setFutureCostPriceLL (BigDecimal FutureCostPriceLL); + + /** Get Future Cost Price Lower Level */ + public BigDecimal getFutureCostPriceLL(); + + /** Column name IsActive */ + public static final String COLUMNNAME_IsActive = "IsActive"; + + /** Set Active. + * The record is active in the system + */ + public void setIsActive (boolean IsActive); + + /** Get Active. + * The record is active in the system + */ + public boolean isActive(); + + /** Column name LevelNo */ + public static final String COLUMNNAME_LevelNo = "LevelNo"; + + /** Set Level no */ + public void setLevelNo (int LevelNo); + + /** Get Level no */ + public int getLevelNo(); + + /** Column name Levels */ + public static final String COLUMNNAME_Levels = "Levels"; + + /** Set Levels */ + public void setLevels (String Levels); + + /** Get Levels */ + public String getLevels(); + + /** Column name M_CostElement_ID */ + public static final String COLUMNNAME_M_CostElement_ID = "M_CostElement_ID"; + + /** Set Cost Element. + * Product Cost Element + */ + public void setM_CostElement_ID (int M_CostElement_ID); + + /** Get Cost Element. + * Product Cost Element + */ + public int getM_CostElement_ID(); + + public I_M_CostElement getM_CostElement() throws RuntimeException; + + /** Column name M_Product_ID */ + public static final String COLUMNNAME_M_Product_ID = "M_Product_ID"; + + /** Set Product. + * Product, Service, Item + */ + public void setM_Product_ID (int M_Product_ID); + + /** Get Product. + * Product, Service, Item + */ + public int getM_Product_ID(); + + public I_M_Product getM_Product() throws RuntimeException; + + /** Column name Qty */ + public static final String COLUMNNAME_Qty = "Qty"; + + /** Set Quantity. + * Quantity + */ + public void setQty (BigDecimal Qty); + + /** Get Quantity. + * Quantity + */ + public BigDecimal getQty(); + + /** Column name QtyBOM */ + public static final String COLUMNNAME_QtyBOM = "QtyBOM"; + + /** Set Quantity. + * Indicate the Quantity use in this BOM + */ + public void setQtyBOM (BigDecimal QtyBOM); + + /** Get Quantity. + * Indicate the Quantity use in this BOM + */ + public BigDecimal getQtyBOM(); + + /** Column name Sel_Product_ID */ + public static final String COLUMNNAME_Sel_Product_ID = "Sel_Product_ID"; + + /** Set Selected Product */ + public void setSel_Product_ID (int Sel_Product_ID); + + /** Get Selected Product */ + public int getSel_Product_ID(); + + public I_M_Product getSel_Product() throws RuntimeException; + + /** Column name SeqNo */ + public static final String COLUMNNAME_SeqNo = "SeqNo"; + + /** Set Sequence. + * Method of ordering records; + lowest number comes first + */ + public void setSeqNo (int SeqNo); + + /** Get Sequence. + * Method of ordering records; + lowest number comes first + */ + public int getSeqNo(); + + /** Column name T_BOM_Indented_ID */ + public static final String COLUMNNAME_T_BOM_Indented_ID = "T_BOM_Indented_ID"; + + /** Set Indented BOM Report */ + public void setT_BOM_Indented_ID (int T_BOM_Indented_ID); + + /** Get Indented BOM Report */ + public int getT_BOM_Indented_ID(); + + /** Column name Updated */ + public static final String COLUMNNAME_Updated = "Updated"; + + /** Get Updated. + * Date this record was updated + */ + public Timestamp getUpdated(); + + /** Column name UpdatedBy */ + public static final String COLUMNNAME_UpdatedBy = "UpdatedBy"; + + /** Get Updated By. + * User who updated this records + */ + public int getUpdatedBy(); +} diff --git a/org.adempiere.base/src/org/compiere/model/MProduction.java b/org.adempiere.base/src/org/compiere/model/MProduction.java new file mode 100644 index 0000000000..3ad40d0d18 --- /dev/null +++ b/org.adempiere.base/src/org/compiere/model/MProduction.java @@ -0,0 +1,278 @@ +package org.compiere.model; + +import java.math.BigDecimal; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Properties; +import java.util.logging.Level; + +import org.compiere.model.MAttributeSetInstance; +import org.compiere.model.MOrderLine; +import org.compiere.model.MProduct; +import org.compiere.model.MStorage; +import org.compiere.model.X_M_Production; +import org.compiere.util.AdempiereUserError; +import org.compiere.util.CLogger; +import org.compiere.util.DB; +import org.compiere.util.Env; + +public class MProduction extends X_M_Production { + + /** + * + */ + /** Log */ + private static CLogger m_log = CLogger.getCLogger (MProduction.class); + private static final long serialVersionUID = 1L; + + public MProduction(Properties ctx, int M_Production_ID, String trxName) { + super(ctx, M_Production_ID, trxName); + } + + public MProduction(Properties ctx, ResultSet rs, String trxName) { + super(ctx, rs, trxName); + } + + public MProduction( MOrderLine line ) { + super( line.getCtx(), 0, line.get_TrxName()); + setAD_Client_ID(line.getAD_Client_ID()); + setAD_Org_ID(line.getAD_Org_ID()); + setMovementDate( line.getDatePromised() ); + } + + + + public MProductionLine[] getLines() { + ArrayList list = new ArrayList(); + + String sql = "SELECT pl.M_ProductionLine_ID " + + "FROM M_ProductionLine pl " + + "WHERE pl.M_Production_ID = ?"; + + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement(sql, get_TrxName()); + pstmt.setInt(1, get_ID()); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) + list.add( new MProductionLine( getCtx(), rs.getInt(1), get_TrxName() ) ); + rs.close(); + pstmt.close(); + pstmt = null; + } + catch (SQLException ex) + { + m_log.log(Level.SEVERE, sql, ex); + } + try + { + if (pstmt != null) + pstmt.close(); + } + catch (SQLException ex1) + { + } + pstmt = null; + + MProductionLine[] retValue = new MProductionLine[list.size()]; + list.toArray(retValue); + return retValue; + } + + public void deleteLines(String trxName) { + + for (MProductionLine line : getLines()) + { + line.deleteEx(true); + } + + }// deleteLines + + public int createLines(boolean mustBeStocked) { + + int defaultLocator = 0; + + int lineno = 100; + int count = 0; + // product to be produced + MProduct finishedProduct = new MProduct(getCtx(), getM_Product_ID(), get_TrxName()); + MLocator finishedLocator = MLocator.get(getCtx(), getM_Locator_ID()); + + int M_Warehouse_ID = finishedLocator.getM_Warehouse_ID(); + + int asi = 0; + + MProductionLine line = new MProductionLine( this ); + line.setLine( lineno ); + line.setM_Product_ID( finishedProduct.get_ID() ); + line.setM_Locator_ID( getM_Locator_ID() ); + line.setMovementQty( getProductionQty()); + line.setPlannedQty(getProductionQty()); + + line.save(); + count++; + + // products used in production + String sql = "SELECT M_ProductBom_ID, BOMQty" + " FROM M_Product_BOM" + + " WHERE M_Product_ID=" + getM_Product_ID() + " ORDER BY Line"; + + PreparedStatement pstmt = null; + + try { + pstmt = DB.prepareStatement(sql, get_TrxName()); + + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) { + + lineno = lineno + 10; + int BOMProduct_ID = rs.getInt(1); + BigDecimal BOMQty = rs.getBigDecimal(2); + BigDecimal BOMMovementQty = BOMQty.multiply(getProductionQty()); + + MProduct bomproduct = new MProduct(Env.getCtx(), BOMProduct_ID, get_TrxName()); + + defaultLocator = bomproduct.getM_Locator_ID(); + if ( defaultLocator == 0 ) + defaultLocator = getM_Locator_ID(); + + if (!bomproduct.isStocked()) + { + MProductionLine BOMLine = null; + BOMLine = new MProductionLine( this ); + BOMLine.setLine( lineno ); + BOMLine.setM_Product_ID( BOMProduct_ID ); + BOMLine.setM_Locator_ID( defaultLocator ); + BOMLine.setQtyUsed(BOMMovementQty ); + BOMLine.setPlannedQty( BOMMovementQty ); + BOMLine.save(get_TrxName()); + + lineno = lineno + 10; + count++; + } + else if (BOMMovementQty.signum() == 0) + { + MProductionLine BOMLine = null; + BOMLine = new MProductionLine( this ); + BOMLine.setLine( lineno ); + BOMLine.setM_Product_ID( BOMProduct_ID ); + BOMLine.setM_Locator_ID( defaultLocator ); + BOMLine.setQtyUsed( BOMMovementQty ); + BOMLine.setPlannedQty( BOMMovementQty ); + BOMLine.save(get_TrxName()); + + lineno = lineno + 10; + count++; + } + else + { + + // BOM stock info + MStorage[] storages = null; + MProduct usedProduct = MProduct.get(getCtx(), BOMProduct_ID); + defaultLocator = usedProduct.getM_Locator_ID(); + if ( defaultLocator == 0 ) + defaultLocator = getM_Locator_ID(); + if (usedProduct == null || usedProduct.get_ID() == 0) + return 0; + + MClient client = MClient.get(getCtx()); + MProductCategory pc = MProductCategory.get(getCtx(), + usedProduct.getM_Product_Category_ID()); + String MMPolicy = pc.getMMPolicy(); + if (MMPolicy == null || MMPolicy.length() == 0) + { + MMPolicy = client.getMMPolicy(); + } + + storages = MStorage.getWarehouse(getCtx(), M_Warehouse_ID, BOMProduct_ID, 0, null, + MProductCategory.MMPOLICY_FiFo.equals(MMPolicy), true, 0, get_TrxName()); + + MProductionLine BOMLine = null; + int prevLoc = -1; + int previousAttribSet = -1; + // Create lines from storage until qty is reached + for (int sl = 0; sl < storages.length; sl++) { + + BigDecimal lineQty = storages[sl].getQtyOnHand(); + if (lineQty.signum() != 0) { + if (lineQty.compareTo(BOMMovementQty) > 0) + lineQty = BOMMovementQty; + + + int loc = storages[sl].getM_Locator_ID(); + int slASI = storages[sl].getM_AttributeSetInstance_ID(); + int locAttribSet = new MAttributeSetInstance(getCtx(), asi, + get_TrxName()).getM_AttributeSet_ID(); + + // roll up costing attributes if in the same locator + if (locAttribSet == 0 && previousAttribSet == 0 + && prevLoc == loc) { + BOMLine.setQtyUsed(BOMLine.getQtyUsed() + .add(lineQty)); + BOMLine.setPlannedQty(BOMLine.getQtyUsed()); + BOMLine.save(get_TrxName()); + + } + // otherwise create new line + else { + BOMLine = new MProductionLine( this ); + BOMLine.setLine( lineno ); + BOMLine.setM_Product_ID( BOMProduct_ID ); + BOMLine.setM_Locator_ID( loc ); + BOMLine.setQtyUsed( lineQty); + BOMLine.setPlannedQty( lineQty); + if ( slASI != 0 && locAttribSet != 0 ) // ie non costing attribute + BOMLine.setM_AttributeSetInstance_ID(slASI); + BOMLine.save(get_TrxName()); + + lineno = lineno + 10; + count++; + } + prevLoc = loc; + previousAttribSet = locAttribSet; + // enough ? + BOMMovementQty = BOMMovementQty.subtract(lineQty); + if (BOMMovementQty.signum() == 0) + break; + } + } // for available storages + + // fallback + if (BOMMovementQty.signum() != 0 ) { + if (!mustBeStocked) + { + BOMLine = new MProductionLine( this ); + BOMLine.setLine( lineno ); + BOMLine.setM_Product_ID( BOMProduct_ID ); + BOMLine.setM_Locator_ID( defaultLocator ); + BOMLine.setQtyUsed( BOMMovementQty); + BOMLine.setPlannedQty( BOMMovementQty); + BOMLine.save(get_TrxName()); + + lineno = lineno + 10; + count++; + } + else + { + throw new AdempiereUserError("Not enough stock of " + BOMProduct_ID); + } + } + } + } // for all bom products + } catch (Exception e) { + log.log(Level.SEVERE, "createLines", e); + } + + return count; + } + + @Override + protected boolean beforeDelete() { + deleteLines(get_TrxName()); + return true; + } + +} diff --git a/org.adempiere.base/src/org/compiere/model/MProductionLine.java b/org.adempiere.base/src/org/compiere/model/MProductionLine.java new file mode 100644 index 0000000000..2cb6e37f1e --- /dev/null +++ b/org.adempiere.base/src/org/compiere/model/MProductionLine.java @@ -0,0 +1,330 @@ +package org.compiere.model; + +import java.math.BigDecimal; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.logging.Level; + +import org.compiere.model.MAttributeSet; +import org.compiere.model.MAttributeSetInstance; +import org.compiere.model.MInventoryLineMA; +import org.compiere.model.MLocator; +import org.compiere.model.MProduct; +import org.compiere.model.MStorage; +import org.compiere.model.MTransaction; +import org.compiere.model.X_M_ProductionLine; +import org.compiere.util.DB; +import org.compiere.util.Env; + + +public class MProductionLine extends X_M_ProductionLine { + /** + * + */ + private static final long serialVersionUID = 1L; + private MProduction parent; + + + /** + * Standard Constructor + * @param ctx ctx + * @param M_ProductionLine_ID id + */ + public MProductionLine (Properties ctx, int M_ProductionLine_ID, String trxName) + { + super (ctx, M_ProductionLine_ID, trxName); + if (M_ProductionLine_ID == 0) + { + setLine (0); // @SQL=SELECT NVL(MAX(Line),0)+10 AS DefaultValue FROM M_ProductionLine WHERE M_Production_ID=@M_Production_ID@ + setM_AttributeSetInstance_ID (0); + setM_Locator_ID (0); // @M_Locator_ID@ + setM_Product_ID (0); + setM_ProductionLine_ID (0); + setM_Production_ID (0); + setMovementQty (Env.ZERO); + setProcessed (false); + } + + } // MProductionLine + + public MProductionLine (Properties ctx, ResultSet rs, String trxName) + { + super(ctx, rs, trxName); + } // MProductionLine + + /** + * Parent Constructor + * @param plan + */ + public MProductionLine( MProduction header ) { + super( header.getCtx(), 0, header.get_TrxName() ); + setM_Production_ID( header.get_ID()); + setAD_Client_ID(header.getAD_Client_ID()); + setAD_Org_ID(header.getAD_Org_ID()); + parent = header; + } + + + + /** + * + * @param date + * @return "" for success, error string if failed + */ + public String createTransactions(Timestamp date, boolean mustBeStocked) { + // delete existing ASI records + int deleted = deleteMA(); + log.log(Level.FINE, "Deleted " + deleted + " attribute records "); + + MProduct prod = new MProduct(getCtx(), getM_Product_ID(), get_TrxName()); + log.log(Level.FINE,"Loaded Product " + prod.toString()); + + if ( prod.getProductType().compareTo(MProduct.PRODUCTTYPE_Item ) != 0 ) { + // no need to do any movements + log.log(Level.FINE, "Production Line " + getLine() + " does not require stock movement"); + return ""; + } + StringBuffer errorString = new StringBuffer(); + + MAttributeSetInstance asi = new MAttributeSetInstance(getCtx(), getM_AttributeSetInstance_ID(), get_TrxName()); + String asiString = asi.getDescription(); + if ( asiString == null ) + asiString = ""; + + log.log(Level.WARNING, "asi Description is: " + asiString); + // create transactions for finished goods + if ( getMovementQty().compareTo(Env.ZERO) > 0 ) { + MProductionLineMA lineMA = new MProductionLineMA( this, + asi.get_ID(), getMovementQty()); + if ( !lineMA.save(get_TrxName()) ) { + log.log(Level.SEVERE, "Could not save MA for " + toString()); + errorString.append("Could not save MA for " + toString() + "\n" ); + } + MTransaction matTrx = new MTransaction (getCtx(), getAD_Org_ID(), + "P+", + getM_Locator_ID(), getM_Product_ID(), asi.get_ID(), + getMovementQty(), date, get_TrxName()); + matTrx.setM_ProductionLine_ID(get_ID()); + if ( !matTrx.save(get_TrxName()) ) { + log.log(Level.SEVERE, "Could not save transaction for " + toString()); + errorString.append("Could not save transaction for " + toString() + "\n"); + } + MStorage storage = MStorage.getCreate(getCtx(), getM_Locator_ID(), + getM_Product_ID(), asi.get_ID(), get_TrxName()); + storage.changeQtyOnHand(getMovementQty(), true); + if ( !storage.save(get_TrxName()) ) { + log.log(Level.SEVERE, "Could not update storage for " + toString()); + errorString.append("Could not save transaction for " + toString() + "\n"); + } + log.log(Level.FINE, "Created finished goods line " + getLine()); + + return errorString.toString(); + } + + // create transactions and update stock used in production + MStorage[] storages = MStorage.getAll( getCtx(), getM_Product_ID(), + getM_Locator_ID(), get_TrxName()); + + + + MProductionLineMA lineMA = null; + MTransaction matTrx = null; + BigDecimal qtyToMove = getMovementQty().negate(); + + + for (int sl = 0; sl < storages.length; sl++) { + + BigDecimal lineQty = storages[sl].getQtyOnHand(); + + log.log(Level.FINE, "QtyAvailable " + lineQty ); + if (lineQty.signum() > 0) + { + if (lineQty.compareTo(qtyToMove ) > 0) + lineQty = qtyToMove; + + MAttributeSetInstance slASI = new MAttributeSetInstance(getCtx(), + storages[sl].getM_AttributeSetInstance_ID(),get_TrxName()); + String slASIString = slASI.getDescription(); + if (slASIString == null) + slASIString = ""; + + log.log(Level.WARNING,"slASI-Description =" + slASIString); + + if ( slASIString.compareTo(asiString) == 0 + || asi.getM_AttributeSet_ID() == 0 ) + //storage matches specified ASI or is a costing asi (inc. 0) + // This process will move negative stock on hand quantities + { + lineMA = new MProductionLineMA( this, + storages[sl].getM_AttributeSetInstance_ID(), + lineQty.negate()); + if ( !lineMA.save(get_TrxName()) ) { + log.log(Level.SEVERE, "Could not save MA for " + toString()); + errorString.append("Could not save MA for " + toString() + "\n" ); + } + else + log.log(Level.FINE, "Saved MA for " + toString()); + matTrx = new MTransaction (getCtx(), getAD_Org_ID(), + "P-", + getM_Locator_ID(), getM_Product_ID(), asi.get_ID(), + lineQty.negate(), date, get_TrxName()); + matTrx.setM_ProductionLine_ID(get_ID()); + if ( !matTrx.save(get_TrxName()) ) { + log.log(Level.SEVERE, "Could not save transaction for " + toString()); + errorString.append("Could not save transaction for " + toString() + "\n"); + } + else + log.log(Level.FINE, "Saved transaction for " + toString()); + storages[sl].changeQtyOnHand(lineQty, false); + if ( !storages[sl].save(get_TrxName()) ) { + log.log(Level.SEVERE, "Could not update storage for " + toString()); + errorString.append("Could not update storage for " + toString() + "\n"); + } + qtyToMove = qtyToMove.subtract(lineQty); + System.err.println("Qty Moved = " + lineQty); + log.log(Level.WARNING, "Qty moved = " + lineQty ); + log.log(Level.WARNING, getLine() + " Qty to move: " + qtyToMove ); + } + } + + if ( qtyToMove.signum() == 0 ) + break; + + } // for available storages + + + if ( !( qtyToMove.signum() == 0) ) { + if (mustBeStocked) + { + MLocator loc = new MLocator(getCtx(), getM_Locator_ID(), get_TrxName()); + errorString.append( "Insufficient qty on hand of " + prod.toString() + " at " + + loc.toString() + "\n"); + } + else + { + MProduct product = new MProduct(Env.getCtx(), getM_Product_ID(), get_TrxName()); + int defaultLocator = product.getM_Locator_ID(); + MStorage storage = MStorage.get(Env.getCtx(), defaultLocator, getM_Product_ID(), 0, get_TrxName()); + if (storage == null) + { + storage = new MStorage(Env.getCtx(), 0, get_TrxName()); + storage.setM_Locator_ID(defaultLocator); + storage.setM_Product_ID(getM_Product_ID()); + storage.setM_AttributeSetInstance_ID(0); + storage.save(); + + } + + BigDecimal lineQty = qtyToMove; + MAttributeSetInstance slASI = new MAttributeSetInstance(getCtx(), + storage.getM_AttributeSetInstance_ID(),get_TrxName()); + String slASIString = slASI.getDescription(); + if (slASIString == null) + slASIString = ""; + + log.log(Level.WARNING,"slASI-Description =" + slASIString); + + if ( slASIString.compareTo(asiString) == 0 + || asi.getM_AttributeSet_ID() == 0 ) + //storage matches specified ASI or is a costing asi (inc. 0) + // This process will move negative stock on hand quantities + { + lineMA = new MProductionLineMA( this, + storage.getM_AttributeSetInstance_ID(), + lineQty.negate()); + if ( !lineMA.save(get_TrxName()) ) { + log.log(Level.SEVERE, "Could not save MA for " + toString()); + errorString.append("Could not save MA for " + toString() + "\n" ); + } + else + log.log(Level.FINE, "Saved MA for " + toString()); + matTrx = new MTransaction (getCtx(), getAD_Org_ID(), + "P-", + getM_Locator_ID(), getM_Product_ID(), asi.get_ID(), + lineQty.negate(), date, get_TrxName()); + matTrx.setM_ProductionLine_ID(get_ID()); + if ( !matTrx.save(get_TrxName()) ) { + log.log(Level.SEVERE, "Could not save transaction for " + toString()); + errorString.append("Could not save transaction for " + toString() + "\n"); + } + else + log.log(Level.FINE, "Saved transaction for " + toString()); + storage.changeQtyOnHand(lineQty, false); + if ( !storage.save(get_TrxName()) ) { + log.log(Level.SEVERE, "Could not update storage for " + toString()); + errorString.append("Could not update storage for " + toString() + "\n"); + } + qtyToMove = qtyToMove.subtract(lineQty); + System.err.println("Qty Moved = " + lineQty); + log.log(Level.WARNING, "Qty moved = " + lineQty ); + log.log(Level.WARNING, getLine() + " Qty to move: " + qtyToMove ); + } + + } + + } + + return errorString.toString(); + + } + + private int deleteMA() { + String sql = "DELETE FROM M_ProductionLineMA WHERE M_ProductionLine_ID = " + get_ID(); + int count = DB.executeUpdateEx( sql, get_TrxName() ); + return count; + } + + public String toString() { + if ( getM_Product_ID() == 0 ) + return ("No product defined for production line " + getLine()); + MProduct product = new MProduct(getCtx(),getM_Product_ID(), get_TrxName()); + return ( "Production line:" + getLine() + " -- " + getMovementQty() + " of " + product.getValue()); + } + + @Override + protected boolean beforeSave(boolean newRecord) { + if (parent == null ) + parent = new MProduction(getCtx(), getM_Production_ID(), get_TrxName()); + + if ( parent.getM_Product_ID() == getM_Product_ID() && parent.getProductionQty().signum() == getMovementQty().signum()) + setIsEndProduct(true); + else + setIsEndProduct(false); + + if ( isEndProduct() && getM_AttributeSetInstance_ID() != 0 ) + { + String where = "M_QualityTest_ID IN (SELECT M_QualityTest_ID " + + "FROM M_Product_QualityTest WHERE M_Product_ID=?) " + + "AND M_QualityTest_ID NOT IN (SELECT M_QualityTest_ID " + + "FROM M_QualityTestResult WHERE M_AttributeSetInstance_ID=?)"; + + List tests = new Query(getCtx(), MQualityTest.Table_Name, where, get_TrxName()) + .setOnlyActiveRecords(true).setParameters(getM_Product_ID(), getM_AttributeSetInstance_ID()).list(); + // create quality control results + for (MQualityTest test : tests) + { + test.createResult(getM_AttributeSetInstance_ID()); + } + } + + if ( !isEndProduct() ) + { + setMovementQty(getQtyUsed().negate()); + } + return true; + } + + @Override + protected boolean beforeDelete() { + + deleteMA(); + return true; + } + + + +} diff --git a/org.adempiere.base/src/org/compiere/model/MProductionLineMA.java b/org.adempiere.base/src/org/compiere/model/MProductionLineMA.java new file mode 100644 index 0000000000..3557f4ce1b --- /dev/null +++ b/org.adempiere.base/src/org/compiere/model/MProductionLineMA.java @@ -0,0 +1,44 @@ +package org.compiere.model; + +import java.math.BigDecimal; +import java.sql.ResultSet; +import java.util.Properties; + +import org.compiere.model.X_M_ProductionLineMA; + +public class MProductionLineMA extends X_M_ProductionLineMA { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public MProductionLineMA(Properties ctx, int M_ProductionLineMA_ID, + String trxName) { + super(ctx, M_ProductionLineMA_ID, trxName); + // TODO Auto-generated constructor stub + } + + public MProductionLineMA(Properties ctx, ResultSet rs, String trxName) { + super(ctx, rs, trxName); + // TODO Auto-generated constructor stub + } + + /** + * Parent constructor + * @param parent + * @param asi + * @param qty + * @param ctx + * @param trxName + */ + public MProductionLineMA( MProductionLine parent, int asi, BigDecimal qty) { + + super(parent.getCtx(),0,parent.get_TrxName()); + setM_AttributeSetInstance_ID(asi); + setM_ProductionLine_ID(parent.get_ID()); + setMovementQty(qty); + + } + +} diff --git a/org.adempiere.base/src/org/compiere/model/MQualityTest.java b/org.adempiere.base/src/org/compiere/model/MQualityTest.java new file mode 100644 index 0000000000..f89bf5d679 --- /dev/null +++ b/org.adempiere.base/src/org/compiere/model/MQualityTest.java @@ -0,0 +1,28 @@ +package org.compiere.model; + +import java.sql.ResultSet; +import java.util.Properties; + +public class MQualityTest extends X_M_QualityTest { + + public MQualityTest(Properties ctx, int M_QualityTest_ID, String trxName) { + super(ctx, M_QualityTest_ID, trxName); + } + + public MQualityTest(Properties ctx, ResultSet rs, String trxName) { + super(ctx, rs, trxName); + } + + public MQualityTestResult createResult(int m_attributesetinstance_id) + { + MQualityTestResult result = new MQualityTestResult(getCtx(),0, get_TrxName()); + result.setClientOrg(this); + result.setM_QualityTest_ID(getM_QualityTest_ID()); + result.setM_AttributeSetInstance_ID(m_attributesetinstance_id); + result.setProcessed(false); + result.setIsQCPass(false); + result.saveEx(); + return result; + } + +} diff --git a/org.adempiere.base/src/org/compiere/model/MQualityTestResult.java b/org.adempiere.base/src/org/compiere/model/MQualityTestResult.java new file mode 100644 index 0000000000..9c43c9df41 --- /dev/null +++ b/org.adempiere.base/src/org/compiere/model/MQualityTestResult.java @@ -0,0 +1,12 @@ +package org.compiere.model; + +import java.util.Properties; + +public class MQualityTestResult extends X_M_QualityTestResult { + + public MQualityTestResult(Properties ctx, int M_QualityTestResult_ID, + String trxName) { + super(ctx, M_QualityTestResult_ID, trxName); + } + +} diff --git a/org.adempiere.base/src/org/compiere/model/X_M_QualityTest.java b/org.adempiere.base/src/org/compiere/model/X_M_QualityTest.java new file mode 100644 index 0000000000..f9bf45e0e2 --- /dev/null +++ b/org.adempiere.base/src/org/compiere/model/X_M_QualityTest.java @@ -0,0 +1,152 @@ +/****************************************************************************** + * Product: Adempiere ERP & CRM Smart Business Solution * + * Copyright (C) 1999-2007 ComPiere, Inc. All Rights Reserved. * + * This program is free software, you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * + * by the Free Software Foundation. This program is distributed in the hope * + * that it will be useful, but WITHOUT ANY WARRANTY, without even the implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the GNU General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program, if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +/** Generated Model - DO NOT CHANGE */ +package org.compiere.model; + +import java.sql.ResultSet; +import java.util.Properties; +import org.compiere.util.KeyNamePair; + +/** Generated Model for M_QualityTest + * @author Adempiere (generated) + * @version Release 3.6.0LTS - $Id$ */ +public class X_M_QualityTest extends PO implements I_M_QualityTest, I_Persistent +{ + + /** + * + */ + private static final long serialVersionUID = 20101207L; + + /** Standard Constructor */ + public X_M_QualityTest (Properties ctx, int M_QualityTest_ID, String trxName) + { + super (ctx, M_QualityTest_ID, trxName); + /** if (M_QualityTest_ID == 0) + { + setM_QualityTest_ID (0); + setName (null); + } */ + } + + /** Load Constructor */ + public X_M_QualityTest (Properties ctx, ResultSet rs, String trxName) + { + super (ctx, rs, trxName); + } + + /** AccessLevel + * @return 3 - Client - Org + */ + protected int get_AccessLevel() + { + return accessLevel.intValue(); + } + + /** Load Meta Data */ + protected POInfo initPO (Properties ctx) + { + POInfo poi = POInfo.getPOInfo (ctx, Table_ID, get_TrxName()); + return poi; + } + + public String toString() + { + StringBuffer sb = new StringBuffer ("X_M_QualityTest[") + .append(get_ID()).append("]"); + return sb.toString(); + } + + /** Set Description. + @param Description + Optional short description of the record + */ + public void setDescription (String Description) + { + set_Value (COLUMNNAME_Description, Description); + } + + /** Get Description. + @return Optional short description of the record + */ + public String getDescription () + { + return (String)get_Value(COLUMNNAME_Description); + } + + /** Set Comment/Help. + @param Help + Comment or Hint + */ + public void setHelp (String Help) + { + set_Value (COLUMNNAME_Help, Help); + } + + /** Get Comment/Help. + @return Comment or Hint + */ + public String getHelp () + { + return (String)get_Value(COLUMNNAME_Help); + } + + /** Set Quality Test. + @param M_QualityTest_ID Quality Test */ + public void setM_QualityTest_ID (int M_QualityTest_ID) + { + if (M_QualityTest_ID < 1) + set_ValueNoCheck (COLUMNNAME_M_QualityTest_ID, null); + else + set_ValueNoCheck (COLUMNNAME_M_QualityTest_ID, Integer.valueOf(M_QualityTest_ID)); + } + + /** Get Quality Test. + @return Quality Test */ + public int getM_QualityTest_ID () + { + Integer ii = (Integer)get_Value(COLUMNNAME_M_QualityTest_ID); + if (ii == null) + return 0; + return ii.intValue(); + } + + /** Set Name. + @param Name + Alphanumeric identifier of the entity + */ + public void setName (String Name) + { + set_Value (COLUMNNAME_Name, Name); + } + + /** Get Name. + @return Alphanumeric identifier of the entity + */ + public String getName () + { + return (String)get_Value(COLUMNNAME_Name); + } + + /** Get Record ID/ColumnName + @return ID/ColumnName pair + */ + public KeyNamePair getKeyNamePair() + { + return new KeyNamePair(get_ID(), getName()); + } +} \ No newline at end of file diff --git a/org.adempiere.base/src/org/compiere/model/X_M_QualityTestResult.java b/org.adempiere.base/src/org/compiere/model/X_M_QualityTestResult.java new file mode 100644 index 0000000000..f484b7e39f --- /dev/null +++ b/org.adempiere.base/src/org/compiere/model/X_M_QualityTestResult.java @@ -0,0 +1,239 @@ +/****************************************************************************** + * Product: Adempiere ERP & CRM Smart Business Solution * + * Copyright (C) 1999-2007 ComPiere, Inc. All Rights Reserved. * + * This program is free software, you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * + * by the Free Software Foundation. This program is distributed in the hope * + * that it will be useful, but WITHOUT ANY WARRANTY, without even the implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the GNU General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program, if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +/** Generated Model - DO NOT CHANGE */ +package org.compiere.model; + +import java.sql.ResultSet; +import java.util.Properties; + +/** Generated Model for M_QualityTestResult + * @author Adempiere (generated) + * @version Release 3.6.0LTS - $Id$ */ +public class X_M_QualityTestResult extends PO implements I_M_QualityTestResult, I_Persistent +{ + + /** + * + */ + private static final long serialVersionUID = 20101207L; + + /** Standard Constructor */ + public X_M_QualityTestResult (Properties ctx, int M_QualityTestResult_ID, String trxName) + { + super (ctx, M_QualityTestResult_ID, trxName); + /** if (M_QualityTestResult_ID == 0) + { + setM_AttributeSetInstance_ID (0); + setM_QualityTest_ID (0); + setM_QualityTestResult_ID (0); + setProcessed (false); +// N + } */ + } + + /** Load Constructor */ + public X_M_QualityTestResult (Properties ctx, ResultSet rs, String trxName) + { + super (ctx, rs, trxName); + } + + /** AccessLevel + * @return 3 - Client - Org + */ + protected int get_AccessLevel() + { + return accessLevel.intValue(); + } + + /** Load Meta Data */ + protected POInfo initPO (Properties ctx) + { + POInfo poi = POInfo.getPOInfo (ctx, Table_ID, get_TrxName()); + return poi; + } + + public String toString() + { + StringBuffer sb = new StringBuffer ("X_M_QualityTestResult[") + .append(get_ID()).append("]"); + return sb.toString(); + } + + /** Set Description. + @param Description + Optional short description of the record + */ + public void setDescription (String Description) + { + throw new IllegalArgumentException ("Description is virtual column"); } + + /** Get Description. + @return Optional short description of the record + */ + public String getDescription () + { + return (String)get_Value(COLUMNNAME_Description); + } + + /** Set Expected Result. + @param ExpectedResult Expected Result */ + public void setExpectedResult (String ExpectedResult) + { + throw new IllegalArgumentException ("ExpectedResult is virtual column"); } + + /** Get Expected Result. + @return Expected Result */ + public String getExpectedResult () + { + return (String)get_Value(COLUMNNAME_ExpectedResult); + } + + /** Set QC Pass. + @param IsQCPass QC Pass */ + public void setIsQCPass (boolean IsQCPass) + { + set_Value (COLUMNNAME_IsQCPass, Boolean.valueOf(IsQCPass)); + } + + /** Get QC Pass. + @return QC Pass */ + public boolean isQCPass () + { + Object oo = get_Value(COLUMNNAME_IsQCPass); + if (oo != null) + { + if (oo instanceof Boolean) + return ((Boolean)oo).booleanValue(); + return "Y".equals(oo); + } + return false; + } + + public I_M_AttributeSetInstance getM_AttributeSetInstance() throws RuntimeException + { + return (I_M_AttributeSetInstance)MTable.get(getCtx(), I_M_AttributeSetInstance.Table_Name) + .getPO(getM_AttributeSetInstance_ID(), get_TrxName()); } + + /** Set Attribute Set Instance. + @param M_AttributeSetInstance_ID + Product Attribute Set Instance + */ + public void setM_AttributeSetInstance_ID (int M_AttributeSetInstance_ID) + { + if (M_AttributeSetInstance_ID < 0) + set_ValueNoCheck (COLUMNNAME_M_AttributeSetInstance_ID, null); + else + set_ValueNoCheck (COLUMNNAME_M_AttributeSetInstance_ID, Integer.valueOf(M_AttributeSetInstance_ID)); + } + + /** Get Attribute Set Instance. + @return Product Attribute Set Instance + */ + public int getM_AttributeSetInstance_ID () + { + Integer ii = (Integer)get_Value(COLUMNNAME_M_AttributeSetInstance_ID); + if (ii == null) + return 0; + return ii.intValue(); + } + + public I_M_QualityTest getM_QualityTest() throws RuntimeException + { + return (I_M_QualityTest)MTable.get(getCtx(), I_M_QualityTest.Table_Name) + .getPO(getM_QualityTest_ID(), get_TrxName()); } + + /** Set Quality Test. + @param M_QualityTest_ID Quality Test */ + public void setM_QualityTest_ID (int M_QualityTest_ID) + { + if (M_QualityTest_ID < 1) + set_ValueNoCheck (COLUMNNAME_M_QualityTest_ID, null); + else + set_ValueNoCheck (COLUMNNAME_M_QualityTest_ID, Integer.valueOf(M_QualityTest_ID)); + } + + /** Get Quality Test. + @return Quality Test */ + public int getM_QualityTest_ID () + { + Integer ii = (Integer)get_Value(COLUMNNAME_M_QualityTest_ID); + if (ii == null) + return 0; + return ii.intValue(); + } + + /** Set Quality Test Result. + @param M_QualityTestResult_ID Quality Test Result */ + public void setM_QualityTestResult_ID (int M_QualityTestResult_ID) + { + if (M_QualityTestResult_ID < 1) + set_ValueNoCheck (COLUMNNAME_M_QualityTestResult_ID, null); + else + set_ValueNoCheck (COLUMNNAME_M_QualityTestResult_ID, Integer.valueOf(M_QualityTestResult_ID)); + } + + /** Get Quality Test Result. + @return Quality Test Result */ + public int getM_QualityTestResult_ID () + { + Integer ii = (Integer)get_Value(COLUMNNAME_M_QualityTestResult_ID); + if (ii == null) + return 0; + return ii.intValue(); + } + + /** Set Processed. + @param Processed + The document has been processed + */ + public void setProcessed (boolean Processed) + { + set_Value (COLUMNNAME_Processed, Boolean.valueOf(Processed)); + } + + /** Get Processed. + @return The document has been processed + */ + public boolean isProcessed () + { + Object oo = get_Value(COLUMNNAME_Processed); + if (oo != null) + { + if (oo instanceof Boolean) + return ((Boolean)oo).booleanValue(); + return "Y".equals(oo); + } + return false; + } + + /** Set Result. + @param Result + Result of the action taken + */ + public void setResult (String Result) + { + set_Value (COLUMNNAME_Result, Result); + } + + /** Get Result. + @return Result of the action taken + */ + public String getResult () + { + return (String)get_Value(COLUMNNAME_Result); + } +} \ No newline at end of file diff --git a/org.adempiere.base/src/org/compiere/model/X_T_BOM_Indented.java b/org.adempiere.base/src/org/compiere/model/X_T_BOM_Indented.java new file mode 100644 index 0000000000..290a7a713a --- /dev/null +++ b/org.adempiere.base/src/org/compiere/model/X_T_BOM_Indented.java @@ -0,0 +1,435 @@ +/****************************************************************************** + * Product: Adempiere ERP & CRM Smart Business Solution * + * Copyright (C) 1999-2007 ComPiere, Inc. All Rights Reserved. * + * This program is free software, you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * + * by the Free Software Foundation. This program is distributed in the hope * + * that it will be useful, but WITHOUT ANY WARRANTY, without even the implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the GNU General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program, if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +/** Generated Model - DO NOT CHANGE */ +package org.compiere.model; + +import java.math.BigDecimal; +import java.sql.ResultSet; +import java.util.Properties; +import org.compiere.util.Env; + +/** Generated Model for T_BOM_Indented + * @author Adempiere (generated) + * @version Release 3.6.0LTS - $Id$ */ +public class X_T_BOM_Indented extends PO implements I_T_BOM_Indented, I_Persistent +{ + + /** + * + */ + private static final long serialVersionUID = 20101222L; + + /** Standard Constructor */ + public X_T_BOM_Indented (Properties ctx, int T_BOM_Indented_ID, String trxName) + { + super (ctx, T_BOM_Indented_ID, trxName); + /** if (T_BOM_Indented_ID == 0) + { + setT_BOM_Indented_ID (0); + } */ + } + + /** Load Constructor */ + public X_T_BOM_Indented (Properties ctx, ResultSet rs, String trxName) + { + super (ctx, rs, trxName); + } + + /** AccessLevel + * @return 3 - Client - Org + */ + protected int get_AccessLevel() + { + return accessLevel.intValue(); + } + + /** Load Meta Data */ + protected POInfo initPO (Properties ctx) + { + POInfo poi = POInfo.getPOInfo (ctx, Table_ID, get_TrxName()); + return poi; + } + + public String toString() + { + StringBuffer sb = new StringBuffer ("X_T_BOM_Indented[") + .append(get_ID()).append("]"); + return sb.toString(); + } + + public I_AD_PInstance getAD_PInstance() throws RuntimeException + { + return (I_AD_PInstance)MTable.get(getCtx(), I_AD_PInstance.Table_Name) + .getPO(getAD_PInstance_ID(), get_TrxName()); } + + /** Set Process Instance. + @param AD_PInstance_ID + Instance of the process + */ + public void setAD_PInstance_ID (int AD_PInstance_ID) + { + if (AD_PInstance_ID < 1) + set_Value (COLUMNNAME_AD_PInstance_ID, null); + else + set_Value (COLUMNNAME_AD_PInstance_ID, Integer.valueOf(AD_PInstance_ID)); + } + + /** Get Process Instance. + @return Instance of the process + */ + public int getAD_PInstance_ID () + { + Integer ii = (Integer)get_Value(COLUMNNAME_AD_PInstance_ID); + if (ii == null) + return 0; + return ii.intValue(); + } + + public I_C_AcctSchema getC_AcctSchema() throws RuntimeException + { + return (I_C_AcctSchema)MTable.get(getCtx(), I_C_AcctSchema.Table_Name) + .getPO(getC_AcctSchema_ID(), get_TrxName()); } + + /** Set Accounting Schema. + @param C_AcctSchema_ID + Rules for accounting + */ + public void setC_AcctSchema_ID (int C_AcctSchema_ID) + { + if (C_AcctSchema_ID < 1) + set_Value (COLUMNNAME_C_AcctSchema_ID, null); + else + set_Value (COLUMNNAME_C_AcctSchema_ID, Integer.valueOf(C_AcctSchema_ID)); + } + + /** Get Accounting Schema. + @return Rules for accounting + */ + public int getC_AcctSchema_ID () + { + Integer ii = (Integer)get_Value(COLUMNNAME_C_AcctSchema_ID); + if (ii == null) + return 0; + return ii.intValue(); + } + + /** Set Cost. + @param Cost + Cost information + */ + public void setCost (BigDecimal Cost) + { + set_Value (COLUMNNAME_Cost, Cost); + } + + /** Get Cost. + @return Cost information + */ + public BigDecimal getCost () + { + BigDecimal bd = (BigDecimal)get_Value(COLUMNNAME_Cost); + if (bd == null) + return Env.ZERO; + return bd; + } + + /** Set Future Cost. + @param CostFuture + Cost information + */ + public void setCostFuture (BigDecimal CostFuture) + { + set_Value (COLUMNNAME_CostFuture, CostFuture); + } + + /** Get Future Cost. + @return Cost information + */ + public BigDecimal getCostFuture () + { + BigDecimal bd = (BigDecimal)get_Value(COLUMNNAME_CostFuture); + if (bd == null) + return Env.ZERO; + return bd; + } + + /** Set Current Cost Price. + @param CurrentCostPrice + The currently used cost price + */ + public void setCurrentCostPrice (BigDecimal CurrentCostPrice) + { + set_Value (COLUMNNAME_CurrentCostPrice, CurrentCostPrice); + } + + /** Get Current Cost Price. + @return The currently used cost price + */ + public BigDecimal getCurrentCostPrice () + { + BigDecimal bd = (BigDecimal)get_Value(COLUMNNAME_CurrentCostPrice); + if (bd == null) + return Env.ZERO; + return bd; + } + + /** Set Current Cost Price Lower Level. + @param CurrentCostPriceLL + Current Price Lower Level Is the sum of the costs of the components of this product manufactured for this level. + */ + public void setCurrentCostPriceLL (BigDecimal CurrentCostPriceLL) + { + set_Value (COLUMNNAME_CurrentCostPriceLL, CurrentCostPriceLL); + } + + /** Get Current Cost Price Lower Level. + @return Current Price Lower Level Is the sum of the costs of the components of this product manufactured for this level. + */ + public BigDecimal getCurrentCostPriceLL () + { + BigDecimal bd = (BigDecimal)get_Value(COLUMNNAME_CurrentCostPriceLL); + if (bd == null) + return Env.ZERO; + return bd; + } + + /** Set Future Cost Price. + @param FutureCostPrice Future Cost Price */ + public void setFutureCostPrice (BigDecimal FutureCostPrice) + { + set_Value (COLUMNNAME_FutureCostPrice, FutureCostPrice); + } + + /** Get Future Cost Price. + @return Future Cost Price */ + public BigDecimal getFutureCostPrice () + { + BigDecimal bd = (BigDecimal)get_Value(COLUMNNAME_FutureCostPrice); + if (bd == null) + return Env.ZERO; + return bd; + } + + /** Set Future Cost Price Lower Level. + @param FutureCostPriceLL Future Cost Price Lower Level */ + public void setFutureCostPriceLL (BigDecimal FutureCostPriceLL) + { + set_Value (COLUMNNAME_FutureCostPriceLL, FutureCostPriceLL); + } + + /** Get Future Cost Price Lower Level. + @return Future Cost Price Lower Level */ + public BigDecimal getFutureCostPriceLL () + { + BigDecimal bd = (BigDecimal)get_Value(COLUMNNAME_FutureCostPriceLL); + if (bd == null) + return Env.ZERO; + return bd; + } + + /** Set Level no. + @param LevelNo Level no */ + public void setLevelNo (int LevelNo) + { + set_Value (COLUMNNAME_LevelNo, Integer.valueOf(LevelNo)); + } + + /** Get Level no. + @return Level no */ + public int getLevelNo () + { + Integer ii = (Integer)get_Value(COLUMNNAME_LevelNo); + if (ii == null) + return 0; + return ii.intValue(); + } + + /** Set Levels. + @param Levels Levels */ + public void setLevels (String Levels) + { + set_Value (COLUMNNAME_Levels, Levels); + } + + /** Get Levels. + @return Levels */ + public String getLevels () + { + return (String)get_Value(COLUMNNAME_Levels); + } + + public I_M_CostElement getM_CostElement() throws RuntimeException + { + return (I_M_CostElement)MTable.get(getCtx(), I_M_CostElement.Table_Name) + .getPO(getM_CostElement_ID(), get_TrxName()); } + + /** Set Cost Element. + @param M_CostElement_ID + Product Cost Element + */ + public void setM_CostElement_ID (int M_CostElement_ID) + { + if (M_CostElement_ID < 1) + set_Value (COLUMNNAME_M_CostElement_ID, null); + else + set_Value (COLUMNNAME_M_CostElement_ID, Integer.valueOf(M_CostElement_ID)); + } + + /** Get Cost Element. + @return Product Cost Element + */ + public int getM_CostElement_ID () + { + Integer ii = (Integer)get_Value(COLUMNNAME_M_CostElement_ID); + if (ii == null) + return 0; + return ii.intValue(); + } + + public I_M_Product getM_Product() throws RuntimeException + { + return (I_M_Product)MTable.get(getCtx(), I_M_Product.Table_Name) + .getPO(getM_Product_ID(), get_TrxName()); } + + /** Set Product. + @param M_Product_ID + Product, Service, Item + */ + public void setM_Product_ID (int M_Product_ID) + { + if (M_Product_ID < 1) + set_Value (COLUMNNAME_M_Product_ID, null); + else + set_Value (COLUMNNAME_M_Product_ID, Integer.valueOf(M_Product_ID)); + } + + /** Get Product. + @return Product, Service, Item + */ + public int getM_Product_ID () + { + Integer ii = (Integer)get_Value(COLUMNNAME_M_Product_ID); + if (ii == null) + return 0; + return ii.intValue(); + } + + /** Set Quantity. + @param Qty + Quantity + */ + public void setQty (BigDecimal Qty) + { + set_Value (COLUMNNAME_Qty, Qty); + } + + /** Get Quantity. + @return Quantity + */ + public BigDecimal getQty () + { + BigDecimal bd = (BigDecimal)get_Value(COLUMNNAME_Qty); + if (bd == null) + return Env.ZERO; + return bd; + } + + /** Set Quantity. + @param QtyBOM + Indicate the Quantity use in this BOM + */ + public void setQtyBOM (BigDecimal QtyBOM) + { + set_Value (COLUMNNAME_QtyBOM, QtyBOM); + } + + /** Get Quantity. + @return Indicate the Quantity use in this BOM + */ + public BigDecimal getQtyBOM () + { + BigDecimal bd = (BigDecimal)get_Value(COLUMNNAME_QtyBOM); + if (bd == null) + return Env.ZERO; + return bd; + } + + public I_M_Product getSel_Product() throws RuntimeException + { + return (I_M_Product)MTable.get(getCtx(), I_M_Product.Table_Name) + .getPO(getSel_Product_ID(), get_TrxName()); } + + /** Set Selected Product. + @param Sel_Product_ID Selected Product */ + public void setSel_Product_ID (int Sel_Product_ID) + { + if (Sel_Product_ID < 1) + set_Value (COLUMNNAME_Sel_Product_ID, null); + else + set_Value (COLUMNNAME_Sel_Product_ID, Integer.valueOf(Sel_Product_ID)); + } + + /** Get Selected Product. + @return Selected Product */ + public int getSel_Product_ID () + { + Integer ii = (Integer)get_Value(COLUMNNAME_Sel_Product_ID); + if (ii == null) + return 0; + return ii.intValue(); + } + + /** Set Sequence. + @param SeqNo + Method of ordering records; lowest number comes first + */ + public void setSeqNo (int SeqNo) + { + set_Value (COLUMNNAME_SeqNo, Integer.valueOf(SeqNo)); + } + + /** Get Sequence. + @return Method of ordering records; lowest number comes first + */ + public int getSeqNo () + { + Integer ii = (Integer)get_Value(COLUMNNAME_SeqNo); + if (ii == null) + return 0; + return ii.intValue(); + } + + /** Set Indented BOM Report. + @param T_BOM_Indented_ID Indented BOM Report */ + public void setT_BOM_Indented_ID (int T_BOM_Indented_ID) + { + if (T_BOM_Indented_ID < 1) + set_ValueNoCheck (COLUMNNAME_T_BOM_Indented_ID, null); + else + set_ValueNoCheck (COLUMNNAME_T_BOM_Indented_ID, Integer.valueOf(T_BOM_Indented_ID)); + } + + /** Get Indented BOM Report. + @return Indented BOM Report */ + public int getT_BOM_Indented_ID () + { + Integer ii = (Integer)get_Value(COLUMNNAME_T_BOM_Indented_ID); + if (ii == null) + return 0; + return ii.intValue(); + } +} \ No newline at end of file diff --git a/org.adempiere.ui.swing/src/org/compiere/apps/form/VTreeBOM.java b/org.adempiere.ui.swing/src/org/compiere/apps/form/VTreeBOM.java new file mode 100644 index 0000000000..078f305ada --- /dev/null +++ b/org.adempiere.ui.swing/src/org/compiere/apps/form/VTreeBOM.java @@ -0,0 +1,932 @@ +package org.compiere.apps.form; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.FlowLayout; +//import java.awt.PopupMenu; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.beans.VetoableChangeListener; +import java.lang.reflect.Array; +import java.math.BigDecimal; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; +import java.util.Vector; +import java.util.logging.Level; + +import javax.swing.JCheckBox; +import javax.swing.JPopupMenu; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.JTree; +import javax.swing.SwingUtilities; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.event.TableModelEvent; +import javax.swing.event.TableModelListener; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.table.DefaultTableModel; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeSelectionModel; +import javax.swing.tree.TreePath; + +import org.adempiere.plaf.AdempierePLAF; +import org.compiere.apps.ADialog; +import org.compiere.apps.ConfirmPanel; +import org.compiere.apps.StatusBar; +import org.compiere.apps.form.FormFrame; +import org.compiere.apps.form.FormPanel; +import org.compiere.grid.ed.VLookup; +//import org.compiere.grid.ed.VLookup.VLookup_mouseAdapter; +import org.compiere.minigrid.MiniTable; +import org.compiere.model.MColumn; +import org.compiere.model.MLookup; +import org.compiere.model.MLookupFactory; +import org.compiere.model.MProduct; +import org.compiere.model.MProductBOM; +import org.compiere.model.MTreeNode; +import org.compiere.model.MUOM; +import org.compiere.model.Query; +import org.compiere.swing.CCheckBox; +import org.compiere.swing.CLabel; +import org.compiere.swing.CMenuItem; +import org.compiere.swing.CPanel; +import org.compiere.swing.CTextField; +import org.compiere.util.CLogger; +import org.compiere.util.DisplayType; +import org.compiere.util.Env; +import org.compiere.util.KeyNamePair; +import org.compiere.util.Language; +import org.compiere.util.Msg; +import org.compiere.util.ValueNamePair; + +/** + * BOM Tree Maintenance + * + * @author Victor Perez,Sergio Ramazzinag + * @version $Id: VTreeMaintenance.java,v 1.1 2004/03/20 04:35:51 jjanke Exp $ + * + * 4Layers - MODIFICATIONS -------------------------------------------------------- + * 2005/04/12 Various improvements to the standard form (Sergio Ramazzina) + * 4Layers -------------------------------------------------------------------- end + * + * @author Teo Sarca, SC ARHIPAC SERVICE SRL + * @author Paul Bowden, adaxa modified for manufacturing light + */ +public class VTreeBOM extends CPanel implements FormPanel, ActionListener, + ListSelectionListener, PropertyChangeListener, VetoableChangeListener, + TreeSelectionListener, TableModelListener +{ + + /***************************************************************************** + * Mouse Listener for Popup Menu + */ + final class VTreeBOM_mouseAdapter extends java.awt.event.MouseAdapter + { + /** + * Constructor + * @param adaptee adaptee + */ + VTreeBOM_mouseAdapter(VTreeBOM adaptee) + { + m_adaptee = adaptee; + } // VLookup_mouseAdapter + + private VTreeBOM m_adaptee; + + /** + * Mouse Listener + * @param e MouseEvent + */ + public void mouseClicked(MouseEvent e) + { + // System.out.println("mouseClicked " + e.getID() + " " + e.getSource().getClass().toString()); + // popup menu + if (SwingUtilities.isRightMouseButton(e)) + m_adaptee.popupMenu.show((Component)e.getSource(), e.getX(), e.getY()); + // Hide the popup if not right click - teo_sarca [ 1734802 ] + else + m_adaptee.popupMenu.setVisible(false); + } // mouse Clicked + + } // VTreeBOM_mouseAdapter + + + /** + * Key Pressed + */ + class VTreeBOM_keyAdapter extends java.awt.event.KeyAdapter + { + VTreeBOM m_adaptee; + + /** + * VTreePanel_keyAdapter + * @param adaptee + */ + VTreeBOM_keyAdapter(VTreeBOM adaptee) + { + m_adaptee = adaptee; + } + + /** + * Key Pressed + * @param e + */ + public void keyPressed(KeyEvent e) + { + if (e.getKeyCode() == KeyEvent.VK_ENTER) + m_adaptee.keyPressed(e); + } + } // VTreePanel_keyAdapter + + + + private static final long serialVersionUID = 1L; + + /** + * Tree Maintenance + */ + //public VTreeBOM () +// { +// } // VTreeMaintenance + + /** Window No */ + private int m_WindowNo = 0; + /** FormFrame */ + private FormFrame m_frame; + /** Active Tree */ + private myJTree m_tree; + + private static CLogger log = CLogger.getCLogger(VTreeBOM.class); + + private BorderLayout mainLayout = new BorderLayout (); + private CPanel northPanel = new CPanel (); + + private FlowLayout northLayout = new FlowLayout (); + //private BorderLayout northLayout = new BorderLayout (); + private CPanel southPanel = new CPanel(); + private CPanel southPanel2 = new CPanel (); + private BorderLayout southLayout = new BorderLayout(); + private FlowLayout southLayout2 = new FlowLayout (); + + private CLabel labelProduct = new CLabel (); +// private PopupMenu popMenuTree = new PopupMenu(); + private VLookup fieldProduct; + private CCheckBox implosion = new CCheckBox (); + private CLabel treeInfo = new CLabel (); + private CLabel spacer = new CLabel (); + // + private JSplitPane splitPane = new JSplitPane (); + private JScrollPane dataPane = new JScrollPane(); + private JScrollPane treePane = new JScrollPane(); +// private CPanel southPanel = new CPanel(); +// private BorderLayout southLayout = new BorderLayout(); + private DefaultTreeSelectionModel treeSelect = new DefaultTreeSelectionModel(); + private CCheckBox treeExpand = new CCheckBox(); + private CTextField treeSearch = new CTextField(10); + private CLabel treeSearchLabel = new CLabel(); + private String m_search = ""; + private Enumeration m_nodeEn; + private Enumeration m_childEn; + private DefaultMutableTreeNode m_selectedNode; // the selected model node + private int m_selected_id = 0; + private MouseListener mouseListener = new VTreeBOM_mouseAdapter(this); + private KeyListener keyListener = new VTreeBOM_keyAdapter(this); + /** Property Listener NodeSelected by Left Click */ + public static final String NODE_SELECTION = "NodeSelected"; + private DefaultMutableTreeNode m_root = null; + + private ConfirmPanel confirmPanel = new ConfirmPanel(true); + protected StatusBar statusBar = new StatusBar(); + + private MiniTable tableBOM = new MiniTable(); + private Vector> dataBOM = new Vector>(); + private Vector columnNames; + + private final int DIVIDER_LOCATION = 300; + private boolean reload = false; + private Language language = Language.getLoginLanguage(); // Base Language + + JPopupMenu popupMenu = new JPopupMenu(); + private CMenuItem mBOM; + private CMenuItem mImplosion; + private MLookup m_fieldProduct; + + + public Properties getCtx() { + return Env.getCtx(); + } + + /** + * Initialize Panel + * @param WindowNo window + * @param frame frame + */ + public void init (int WindowNo, FormFrame frame) + { + m_WindowNo = WindowNo; + m_frame = frame; + log.info( "VMerge.init - WinNo=" + m_WindowNo); + try + { + preInit(); + jbInit (); + + frame.getContentPane().add(this, BorderLayout.CENTER); + } + catch (Exception ex) + { + log.log(Level.SEVERE,"VTreeMaintenance.init", ex); + } + } // init + + /** + * Fill Tree Combo + */ + private void preInit() throws Exception + { + m_fieldProduct = MLookupFactory.get(getCtx(), m_WindowNo, + MColumn.getColumn_ID(MProduct.Table_Name, "M_Product_ID"), + DisplayType.Search, language, MProduct.COLUMNNAME_M_Product_ID, 0, false, + " M_Product.IsSummary = 'N'"); + fieldProduct = new VLookup ("M_Product_ID", false, false, true, m_fieldProduct) { + private static final long serialVersionUID = 1L; + public void setValue(Object value) { + super.setValue(value); + action_loadBOM(); + } + }; + + implosion.addActionListener(this); + splitPane.add (dataPane, JSplitPane.RIGHT); + splitPane.add (treePane, JSplitPane.LEFT); + } // preInit + + /** + * Static Init. + *
+	 *  mainPanel
+	 *      northPanel
+	 *      centerPanel
+	 *          xMatched
+	 *          xPanel
+	 *          xMathedTo
+	 *      southPanel
+	 *  
+ * @throws Exception + */ + private void loadTableBOM() + { + // Header Info + columnNames = new Vector(18); + + columnNames.add(Msg.translate(getCtx(), "Select")); // 0 + columnNames.add(Msg.translate(getCtx(), "IsActive")); // 1 + columnNames.add(Msg.translate(getCtx(), "Line")); // 2 + columnNames.add(Msg.translate(getCtx(), "M_Product_ID")); // 3 + columnNames.add(Msg.translate(getCtx(), "C_UOM_ID")); // 4 + columnNames.add(Msg.translate(getCtx(), "QtyBOM")); // 5 + + // Remove previous listeners + tableBOM.getModel().removeTableModelListener(this); + // Remove previous listeners + tableBOM.getModel().removeTableModelListener(this); + // Set Model + DefaultTableModel model = new DefaultTableModel(dataBOM, columnNames); + model.addTableModelListener(this); + tableBOM.setModel(model); + + tableBOM.setColumnClass( 0, Boolean.class, false); // 0 Select + tableBOM.setColumnClass( 1, Boolean.class, false); // 1 IsActive + tableBOM.setColumnClass( 2, Integer.class,false); // 2 Line + tableBOM.setColumnClass( 3, KeyNamePair.class,false); // 3 M_Product_ID + tableBOM.setColumnClass( 4, KeyNamePair.class,false); // 4 C_UOM_ID + tableBOM.setColumnClass( 5, BigDecimal.class,false); // 5 QtyBOM + + tableBOM.setMultiSelection(false); + tableBOM.setColumnVisibility(tableBOM.getColumn(0),false); + tableBOM.autoSize(); + + } // dynInit + + + /** + * Static init + * @throws Exception + */ + private void jbInit () + { + this.setLayout (mainLayout); + + // 4Layers - Set initial window dimension + this.setPreferredSize(new Dimension(640, 480)); + + labelProduct.setText (Msg.getElement(getCtx(), "M_Product_ID")); + implosion.setText (Msg.getElement(getCtx(), "Implosion")); + treeInfo.setText (" "); + spacer.setText (" "); + northPanel.setLayout (northLayout); + northLayout.setAlignment (FlowLayout.LEFT); + + // + this.add (northPanel, BorderLayout.NORTH); + + northPanel.add (labelProduct, null); + northPanel.add (fieldProduct, null); + northPanel.add (implosion, null); + northPanel.add (spacer, null); + northPanel.add (spacer, null); + northPanel.add (treeInfo, null); + + treeExpand.setText(Msg.getMsg(Env.getCtx(), "ExpandTree")); + treeExpand.setActionCommand("Expand"); + treeExpand.addMouseListener(mouseListener); + treeExpand.addActionListener(this); + // + treeSearchLabel.setText(Msg.getMsg(Env.getCtx(), "TreeSearch") + " "); + treeSearchLabel.setLabelFor(treeSearch); + treeSearchLabel.setToolTipText(Msg.getMsg(Env.getCtx(), "TreeSearchText")); + treeSearch.setBackground(AdempierePLAF.getInfoBackground()); + treeSearch.addKeyListener(keyListener); + + this.add(southPanel, BorderLayout.SOUTH); + southPanel.setLayout(southLayout); + confirmPanel.addActionListener(this); + southPanel.add(confirmPanel, BorderLayout.SOUTH); + + southPanel2.setLayout(southLayout2); + southLayout2.setAlignment (FlowLayout.LEFT); + + southPanel.add(southPanel2, BorderLayout.NORTH); + southPanel2.add(treeExpand, null);//BorderLayout.EAST); + southPanel2.add(spacer, null); + southPanel2.add(treeSearchLabel, null);//BorderLayout.WEST); + southPanel2.add(treeSearch, null);//BorderLayout.CENTER); + + + + this.add (splitPane, BorderLayout.CENTER); + + // 4Layers - Set divider location + splitPane.setDividerLocation(DIVIDER_LOCATION); + + mBOM = new CMenuItem(Msg.getMsg(Env.getCtx(), "BOM"), Env.getImageIcon("Detail16.gif")); + mBOM.addActionListener(this); + popupMenu.add(mBOM); + + mImplosion = new CMenuItem(Msg.getMsg(Env.getCtx(), "Implosion"), Env.getImageIcon("Parent16.gif")); + mImplosion.addActionListener(this); + popupMenu.add(mImplosion); + + + + } // jbInit + + /** + * Enter Key + * @param e event + */ + protected void keyPressed(KeyEvent e) + { + + // *** Tree *** + if (e.getSource() instanceof myJTree + || (e.getSource() == treeSearch && e.getModifiers() != 0)) // InputEvent.CTRL_MASK + { + TreePath tp = m_tree.getSelectionPath(); + if (tp == null) + ADialog.beep(); + else + { + DefaultMutableTreeNode tn = (DefaultMutableTreeNode)m_tree.getLastSelectedPathComponent(); + setSelectedNode(tn); + } + } + + // *** treeSearch *** + else if (e.getSource() == treeSearch) + { + String search = treeSearch.getText(); + boolean found = false; + + // at the end - try from top + if (m_nodeEn != null && !m_nodeEn.hasMoreElements()) + m_search = ""; + + // this is the first time + if (!search.equals(m_search)) + { + // get enumeration of all nodes + m_nodeEn = m_root.preorderEnumeration(); + m_search = search; + } + + // search the nodes + while(!found && m_nodeEn != null && m_nodeEn.hasMoreElements()) + { + DefaultMutableTreeNode nd = (DefaultMutableTreeNode)m_nodeEn.nextElement(); + Vector nodeInfo = (Vector )(nd.getUserObject()); + String uoName = ((KeyNamePair)nodeInfo.elementAt(3)).getName() ; + // compare in upper case + if (uoName.toUpperCase().indexOf(search.toUpperCase()) != -1) + { + found = true; + TreePath treePath = new TreePath(nd.getPath()); + m_tree.setSelectionPath(treePath); + m_tree.makeVisible(treePath); // expand it + m_tree.scrollPathToVisible(treePath); + } + } + if (!found) + ADialog.beep(); + } // treeSearch + + } // keyPressed + + + /** + * Set the selected node & initiate all listeners + * @param nd node + */ + private void setSelectedNode (DefaultMutableTreeNode nd) + { + log.config("Node = " + nd); + m_selectedNode = nd; + // + firePropertyChange(NODE_SELECTION, null, nd); + } // setSelectedNode + + + + /** + * Dispose + */ + public void dispose() + { + if (m_frame != null) + m_frame.dispose(); + m_frame = null; + } // dispose + + public void vetoableChange (PropertyChangeEvent e) + { + String name = e.getPropertyName(); + Object value = e.getNewValue(); + log.info( "VAllocation.vetoableChange - " + name + "=" + value); + if (value == null) + return; + + // BPartner + if (name.equals("M_Product_ID")) + { + if (fieldProduct != null) + action_loadBOM(); + } + } // vetoableChange + + /** + * Action Listener + * @param e event + */ + public void actionPerformed (ActionEvent e) + { + if (e.getSource() == mBOM) + { + fieldProduct.setValue(m_selected_id); + if (implosion.isSelected()) + implosion.doClick(); + } + if (e.getSource() == mImplosion) + { + fieldProduct.setValue(m_selected_id); + if (!implosion.isSelected()) + implosion.doClick(); + } + + if (e.getSource() == implosion) + { + action_loadBOM(); + } + if (e.getActionCommand().equals(ConfirmPanel.A_OK)) + { + action_loadBOM(); + } + // 4Layers - Close window when cancel is pressed + if (e.getActionCommand().equals(ConfirmPanel.A_CANCEL)) + { + dispose(); + } + else if (e.getSource() instanceof JCheckBox) + { + if (e.getActionCommand().equals("Expand")) + expandTree(); + } + // 4Layers - End + } // actionPerformed + + /** + * Action: Fill Tree with all nodes + */ + private void action_loadBOM() + { + //m_frame.setBusy(true); + m_frame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + + reload = false; + + int M_Product_ID = getM_Product_ID(); + if (M_Product_ID == 0) + return; + MProduct M_Product = MProduct.get(getCtx(), M_Product_ID); + treeInfo.setText (" Current Selection: "+M_Product.getValue()); + + + Vector line = new Vector(17); + line.add( new Boolean(false)); // 0 Select + line.add( new Boolean(M_Product.isActive())); // 1 IsActive + line.add( new Integer(0)); // 2 Line + KeyNamePair pp = new KeyNamePair(M_Product.getM_Product_ID(),M_Product.getValue().concat("_").concat(M_Product.getName())); + line.add(pp); // 3 M_Product_ID + MUOM u = new MUOM(M_Product.getCtx(), M_Product.getC_UOM_ID(), M_Product.get_TrxName()); + KeyNamePair uom = new KeyNamePair(M_Product.getC_UOM_ID(),u.getUOMSymbol()); + line.add(uom); // 4 C_UOM_ID + line.add(Env.ONE); // 5 QtyBOM + + + DefaultMutableTreeNode parent = new DefaultMutableTreeNode(line); + m_root = (DefaultMutableTreeNode)parent.getRoot(); + + dataBOM.clear(); + + if (isImplosion()) + { + for (MProductBOM bomline : getParentBOMs(M_Product_ID)) + { + addParent(bomline, parent); + } + m_tree = new myJTree(parent); + + m_tree.addMouseListener(mouseListener); + } + else + { + for (MProductBOM bom : getChildBOMs(M_Product_ID, true)) + { + addChild(bom, parent); + } + m_tree = new myJTree(parent); + m_tree.addMouseListener(mouseListener); + } + +/* MouseListener ml = new MouseAdapter() { + public void mousePressed(MouseEvent e) { + int selRow = m_tree.getRowForLocation(e.getX(), e.getY()); + TreePath selPath = m_tree.getPathForLocation(e.getX(), e.getY()); + if(selRow != -1) { + if(e.getClickCount() == 1) { + mySingleClick(selRow, selPath); + } +// else if(e.getClickCount() == 2) { +// myDoubleClick(selRow, selPath); +// } + } + } + + private void mySingleClick(int selRow, TreePath selPath) { + // TODO Auto-generated method stub + + } + }; + m_tree.addMouseListener(ml); +*/ + + m_tree.addTreeSelectionListener(this); + + treePane.getViewport().add (m_tree, null); + + loadTableBOM(); + dataPane.getViewport().add(tableBOM, null); + // 4Layers - Set divider location + splitPane.setDividerLocation(DIVIDER_LOCATION); + // 4Layers - end + + // Popup +// if (m_selected_id != 0) +// { +// } + + + //m_frame.setBusy(false); + m_frame.setCursor(Cursor.getDefaultCursor()); + } // action_fillTree + + private void action_reloadBOM() + { + //m_frame.setBusy(true); + m_frame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + + reload = true; + + //int M_Product_ID = getM_Product_ID(); + int M_Product_ID = m_selected_id; + + if (M_Product_ID == 0) + return; + MProduct M_Product = MProduct.get(getCtx(), M_Product_ID); + treeInfo.setText (" Current Selection: "+M_Product.getValue()); + + + Vector line = new Vector(17); + line.add( new Boolean(false)); // 0 Select + line.add( new Boolean(M_Product.isActive())); // 1 IsActive + line.add( new Integer(0)); // 2 Line + KeyNamePair pp = new KeyNamePair(M_Product.getM_Product_ID(),M_Product.getValue().concat("_").concat(M_Product.getName())); + line.add(pp); // 3 M_Product_ID + MUOM u = new MUOM(M_Product.getCtx(), M_Product.getC_UOM_ID(), M_Product.get_TrxName()); + KeyNamePair uom = new KeyNamePair(M_Product.getC_UOM_ID(),u.getUOMSymbol()); + line.add(uom); // 4 C_UOM_ID + line.add(Env.ONE); // 5 QtyBOM + + + DefaultMutableTreeNode parent = new DefaultMutableTreeNode(line); + + dataBOM.clear(); + + if (isImplosion()) + { + for (MProductBOM bomline : getParentBOMs(M_Product_ID)) + { + addParent(bomline, parent); + } + //m_tree = new myJTree(parent); + } + else + { +/* m_childEn = m_selectedNode.children(); + Vector line = new Vector(17); + while (m_childEn != null && m_childEn.hasMoreElements()) + { + DefaultMutableTreeNode nd = (DefaultMutableTreeNode)m_childEn.nextElement(); + //String[] uo = (String[])nd.getUserObject(); + line.add(nd.getUserObject()); + dataBOM.add( line); + } +*/ + for (MProductBOM bom : getChildBOMs(M_Product_ID, true)) + { + addChild(bom, parent); + } + //m_tree = new myJTree(parent); + } + + //m_tree.addTreeSelectionListener(this); + + //treePane.getViewport().add (m_tree, null); + + loadTableBOM(); + + //m_frame.setBusy(false); + m_frame.setCursor(Cursor.getDefaultCursor()); + } // action_fillTree + + public void addChild(MProductBOM bomline, DefaultMutableTreeNode parent) + { + + //System.out.println("-------------------------Parent:" + bom.getName()); + MProduct M_Product = MProduct.get(getCtx(), bomline.getM_ProductBOM_ID()); + + Vector line = new Vector(17); + line.add( new Boolean(false)); // 0 Select + line.add( new Boolean(bomline.isActive())); // 1 IsActive + line.add( new Integer(bomline.getLine())); // 2 Line + KeyNamePair pp = new KeyNamePair(M_Product.getM_Product_ID(),M_Product.getValue().concat("_").concat(M_Product.getName())); + line.add(pp); // 3 M_Product_ID + MUOM u = new MUOM(M_Product.getCtx(), M_Product.getC_UOM_ID(), M_Product.get_TrxName()); + KeyNamePair uom = new KeyNamePair(M_Product.getC_UOM_ID(),u.getUOMSymbol()); + line.add(uom); // 4 C_UOM_ID + line.add((BigDecimal) ((bomline.getBOMQty()!=null) ? bomline.getBOMQty() : new BigDecimal(0))); // 5 QtyBOM + + DefaultMutableTreeNode child = new DefaultMutableTreeNode(line); + parent.add(child); + + if(m_selected_id == bomline.getM_Product_ID() || getM_Product_ID() == bomline.getM_Product_ID()) + dataBOM.add(line); + + if(reload) return; + + for (MProductBOM bom : getChildBOMs(bomline.getM_ProductBOM_ID(), false)) + { + addChild(bom, child); + } + } + + public void addParent(MProductBOM bom, DefaultMutableTreeNode parent) + { + MProduct M_Product = MProduct.get(getCtx(), bom.getM_Product_ID()); + + Vector line = new Vector(17); + line.add( new Boolean(false)); // 0 Select + line.add( new Boolean(M_Product.isActive())); // 1 IsActive + line.add( new Integer(bom.getLine())); // 2 Line + KeyNamePair pp = new KeyNamePair(M_Product.getM_Product_ID(),M_Product.getValue().concat("_").concat(M_Product.getName())); + line.add(pp); // 3 M_Product_ID + MUOM u = new MUOM(M_Product.getCtx(), M_Product.getC_UOM_ID(), M_Product.get_TrxName()); + KeyNamePair uom = new KeyNamePair(M_Product.getC_UOM_ID(),u.getUOMSymbol()); + line.add(uom); // 6 C_UOM_ID + line.add((BigDecimal) ((bom.getBOMQty()!=null) ? bom.getBOMQty() : new BigDecimal(0))); // 9 QtyBOM + + dataBOM.add(line); + + DefaultMutableTreeNode child = new DefaultMutableTreeNode(line); + parent.add(child); + + if(reload) return; + + for (MProductBOM bomline : getParentBOMs(bom.getM_Product_ID())) + { + addParent(bomline, child); + } + //dataBOM.add(line); + } + + + + public void valueChanged(TreeSelectionEvent event) + { + m_selectedNode = (DefaultMutableTreeNode)m_tree.getLastSelectedPathComponent(); + + /* if nothing is selected */ + if (m_selectedNode == null) return; + + Vector nodeInfo = (Vector )(m_selectedNode.getUserObject()); + + m_selected_id = ((KeyNamePair)nodeInfo.elementAt(3)).getKey() ; + + action_reloadBOM(); + + } + + /** + * List Selection Listener + * @param e event + */ + public void valueChanged (ListSelectionEvent e) + { + if (e.getValueIsAdjusting()) + return; + } // valueChanged + + /** + * Clicked on Expand All + */ + private void expandTree() + { + if (treeExpand.isSelected()) + { + for (int row = 0; row < m_tree.getRowCount(); row++) + m_tree.expandRow(row); + } + else + { +// patch: 1654055 +jgubo Changed direction of collapsing the tree nodes + for (int row = m_tree.getRowCount(); row > 0; row--) + m_tree.collapseRow(row); + } + } // expandTree + + + /** + * VTreePanel Changed + * @param e event + */ + public void propertyChange (PropertyChangeEvent e) + { + } // propertyChange + + public void tableChanged(TableModelEvent e) { + } + + + // action_treeDeleteAll + + /************************************************************************** + * Tree Maintenance List Item + */ + class ListItem + { + public ListItem (int id, String name, String description, boolean isSummary, String imageIndicator) + { + this.id = id; + this.name = name; + this.description = description; + this.isSummary = isSummary; + this.imageIndicator = imageIndicator; + } // ListItem + + public int id; + public String name; + public String description; + public boolean isSummary; + public String imageIndicator; // Menu - Action + + /** + * To String + * @return String Representation + */ + public String toString () + { + String retValue = name; + if (description != null && description.length() > 0) + retValue += " (" + description + ")"; + return retValue; + } // toString + + } // ListItem + +/* private String[] productSummary(MProduct product, boolean isLeaf) { + MUOM muom = MUOM.get(getCtx(), product.getC_UOM_ID()); + String value = product.getValue(); + String name = product.get_Translation(MProduct.COLUMNNAME_Name); + String uom = new StringBuffer(" [") + .append(muom.get_Translation(MUOM.COLUMNNAME_UOMSymbol)).append("]").toString(); + // + if (value != null && value.equals(name)) + name = null; + String[] treeObject = {value,name,uom}; + // + return treeObject; + } +*/ + private boolean isImplosion() { + return implosion.isSelected(); + } + + private int getM_Product_ID() { + Integer Product = (Integer)fieldProduct.getValue(); + if (Product == null) + return 0; + return Product.intValue(); + } + + private List getChildBOMs(int M_Product_ID, boolean onlyActiveRecords) + { + String filter = MProductBOM.COLUMNNAME_M_Product_ID+"=?" + +(onlyActiveRecords ? " AND IsActive='Y'" : ""); + return new Query(getCtx(), MProductBOM.Table_Name, filter, null) + .setParameters(new Object[]{M_Product_ID}) + .list(); + } + + private List getParentBOMs(int M_Product_ID) + { + String filter = MProductBOM.COLUMNNAME_M_ProductBOM_ID+"=?"; + return new Query(getCtx(), MProductBOM.Table_Name, filter, null) + .setParameters(new Object[]{M_Product_ID}) + .list(); + } +} // VTreeMaintenance + + +/************************************************************************** + * Tree convertValueToText + */ +class myJTree extends JTree +{ + + /** + * + */ + private static final long serialVersionUID = -6313465838547930491L; + + public myJTree(DefaultMutableTreeNode parent) { + + super(parent); + } + + //mouseAdapter = new VLookup_mouseAdapter(this); // popup + + @Override + public String convertValueToText(Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { + + DefaultMutableTreeNode nd = (DefaultMutableTreeNode)value; + + Vector userObject = (Vector )nd.getUserObject(); + + StringBuffer sb = new StringBuffer(((KeyNamePair)userObject.elementAt(3)).getName()); + + return sb.toString(); + } +}