diff --git a/base/src/org/compiere/acct/Doc.java b/base/src/org/compiere/acct/Doc.java
index d4c682576c..62c5bdc9e6 100644
--- a/base/src/org/compiere/acct/Doc.java
+++ b/base/src/org/compiere/acct/Doc.java
@@ -61,6 +61,7 @@ import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.Trx;
import org.eevolution.model.MHRProcess;
+import org.eevolution.model.MPPCostCollector;
/**
* Posting Document Root.
@@ -89,6 +90,9 @@ import org.eevolution.model.MHRProcess;
*
* M_Production: MMP
* Doc_Production 325 - DocType fixed
+ *
+ * M_Production: MMO
+ * Doc_CostCollector 330 - DocType fixed
*
* C_BankStatement: CMB
* Doc_Bank 392 - DocType fixed
@@ -134,7 +138,8 @@ public abstract class Doc
MMatchPO.Table_ID, // M_MatchPO
MProjectIssue.Table_ID, // C_ProjectIssue
MRequisition.Table_ID, // M_Requisition
- MHRProcess.Table_ID // MR_Process
+ MHRProcess.Table_ID, // HR_Process
+ MPPCostCollector.Table_ID // PP_CostCollector
};
/** Table Names of documents */
@@ -154,7 +159,8 @@ public abstract class Doc
MMatchPO.Table_Name, // M_MatchPO
MProjectIssue.Table_Name, // C_ProjectIssue
MRequisition.Table_Name, // M_Requisition
- MHRProcess.Table_Name // HR_Process
+ MHRProcess.Table_Name, // HR_Process
+ MPPCostCollector.Table_Name // PP_CostCollector
};
/**************************************************************************
@@ -218,10 +224,10 @@ public abstract class Doc
/** Purchase Requisition */
public static final String DOCTYPE_PurchaseRequisition = "POR";
/** Process Payroll **/
- public static final String DOCTYPE_Payroll = "HRP";
-
-
-
+ public static final String DOCTYPE_Payroll = "HRP";
+ /** Manufacturing Order */
+ public static final String DOCTYPE_MOrder = "MOO";
+
// Posting Status - AD_Reference_ID=234 //
/** Document Status */
public static final String STATUS_NotPosted = "N";
@@ -340,6 +346,8 @@ public abstract class Doc
doc = new Doc_Requisition (ass, rs, trxName);
else if (AD_Table_ID == MHRProcess.Table_ID)
doc = new Doc_Payroll (ass, rs, trxName);
+ else if (AD_Table_ID == MPPCostCollector.Table_ID)
+ doc = new Doc_Cost_Collector (ass, rs, trxName);
if (doc == null)
s_log.log(Level.SEVERE, "Unknown AD_Table_ID=" + AD_Table_ID);
return doc;
diff --git a/base/src/org/compiere/acct/Doc_Cost_Collector.java b/base/src/org/compiere/acct/Doc_Cost_Collector.java
new file mode 100644
index 0000000000..e9289cb61a
--- /dev/null
+++ b/base/src/org/compiere/acct/Doc_Cost_Collector.java
@@ -0,0 +1,280 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 1999-2006 Adempiere, 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. *
+ * Copyright (C) 2003-2007 e-Evolution,SC. All Rights Reserved. *
+ * Contributor(s): Victor Perez www.e-evolution.com *
+ *****************************************************************************/
+package org.compiere.acct;
+
+import java.math.BigDecimal;
+import java.sql.ResultSet;
+import java.util.ArrayList;
+
+import org.compiere.model.MAccount;
+import org.compiere.model.MAcctSchema;
+import org.compiere.model.MCost;
+import org.compiere.model.MCostElement;
+import org.compiere.model.MProduct;
+import org.compiere.model.ProductCost;
+import org.compiere.model.Query;
+import org.compiere.util.Env;
+import org.compiere.util.Msg;
+import org.compiere.wf.MWFNode;
+import org.eevolution.model.MPPCostCollector;
+import org.eevolution.model.MPPOrderBOMLine;
+import org.eevolution.model.MPPOrderNode;
+
+/**
+ * Post Cost Collector
+ *
+ * Table: PP_Cost_Collector
+ * Document Types: MOP
+ *
+ * @author victor.perez@e-evolution.com http://www.e-evolution.com
+ */
+public class Doc_Cost_Collector extends Doc
+{
+
+
+ /**
+ * Constructor
+ * @param ass accounting schemata
+ * @param rs record
+ * @param trxName trx
+ */
+ protected Doc_Cost_Collector (MAcctSchema[] ass, ResultSet rs, String trxName)
+ {
+ super(ass, MPPCostCollector.class, rs, DOCTYPE_MOrder, trxName);
+ } //Doc Cost Collector
+
+
+ /** Pseudo Line */
+ private DocLine m_line = null;
+
+ /** Collector Cost */
+ private MPPCostCollector m_cc = null;
+
+ /**
+ * Load Document Details
+ * @return error message or null
+ */
+ protected String loadDocumentDetails()
+ {
+ setC_Currency_ID (NO_CURRENCY);
+ m_cc = (MPPCostCollector)getPO();
+ setDateDoc (m_cc.getMovementDate());
+ setDateAcct(m_cc.getMovementDate());
+
+ // Pseudo Line
+ m_line = new DocLine (m_cc, this);
+ m_line.setQty (m_cc.getMovementQty(), false); // sets Trx and Storage Qty
+
+ // Pseudo Line Check
+ if (m_line.getM_Product_ID() == 0)
+ log.warning(m_line.toString() + " - No Product");
+ log.fine(m_line.toString());
+ return null;
+ } // loadDocumentDetails
+
+ /**
+ * Get Balance
+ * @return Zero (always balanced)
+ */
+ public BigDecimal getBalance()
+ {
+ BigDecimal retValue = Env.ZERO;
+ return retValue;
+ } // getBalance
+
+ /**
+ * Create Facts (the accounting logic) for
+ * @param as accounting schema
+ * @return Fact
+ */
+ public ArrayList createFacts (MAcctSchema as)
+ {
+ log.info("Start Create Facts for Cost Collector");
+
+ //TODO: I need write the rule for calculate variances
+ // create Fact Header
+ Fact fact = new Fact(this, as, Fact.POST_Actual);
+ setC_Currency_ID (as.getC_Currency_ID());
+ MProduct product = MProduct.get(getCtx(), m_cc.getM_Product_ID());
+
+ if(m_cc.getCostCollectorType().equals(MPPCostCollector.COSTCOLLECTORTYPE_MaterialReceipt))
+ {
+ //Finish good
+ MAccount debit = m_line.getAccount(ProductCost.ACCTTYPE_P_Asset, as);
+ MAccount credit = m_line.getAccount(ProductCost.ACCTTYPE_P_WorkInProcess, as);
+ BigDecimal cost = Env.ZERO;
+
+ //Material
+ cost = MCost.getCostByCostingMethod(product, as, m_cc.getAD_Org_ID(), m_cc.getM_AttributeSetInstance_ID(),
+ MCostElement.COSTINGMETHOD_StandardCosting, MCostElement.COSTELEMENTTYPE_Material,m_cc.getMovementQty());
+ createLines(MCostElement.COSTELEMENTTYPE_Material, as, fact, product, debit, credit, cost,m_cc.getMovementQty() );
+
+ //Resource (Labor)
+ cost = MCost.getCostByCostingMethod(product, as, m_cc.getAD_Org_ID(), m_cc.getM_AttributeSetInstance_ID(),
+ MCostElement.COSTINGMETHOD_StandardCosting, MCostElement.COSTELEMENTTYPE_Resource,m_cc.getMovementQty());
+ createLines(MCostElement.COSTELEMENTTYPE_Resource, as, fact, product, debit, credit, cost,m_cc.getMovementQty());
+
+ //Burden
+ cost = MCost.getCostByCostingMethod(product, as, m_cc.getAD_Org_ID(), m_cc.getM_AttributeSetInstance_ID(),
+ MCostElement.COSTINGMETHOD_StandardCosting, MCostElement.COSTELEMENTTYPE_BurdenMOverhead,m_cc.getMovementQty());
+ createLines(MCostElement.COSTELEMENTTYPE_BurdenMOverhead, as, fact, product, debit, credit, cost,m_cc.getMovementQty());
+
+ //Outsite Processing
+ cost = MCost.getCostByCostingMethod(product, as, m_cc.getAD_Org_ID(), m_cc.getM_AttributeSetInstance_ID(),
+ MCostElement.COSTINGMETHOD_StandardCosting, MCostElement.COSTELEMENTTYPE_OutsideProcessing,m_cc.getMovementQty());
+ createLines(MCostElement.COSTELEMENTTYPE_OutsideProcessing, as, fact, product, debit, credit, cost, m_cc.getMovementQty());
+
+ //Overhead Applied
+ credit = m_line.getAccount(ProductCost.ACCTTYPE_P_Overhead, as);
+ cost = MCost.getCostByCostingMethod(product, as, m_cc.getAD_Org_ID(), m_cc.getM_AttributeSetInstance_ID(),
+ MCostElement.COSTINGMETHOD_StandardCosting, MCostElement.COSTELEMENTTYPE_Overhead,m_cc.getMovementQty());
+ createLines(MCostElement.COSTELEMENTTYPE_OutsideProcessing, as, fact, product, debit, credit, cost, m_cc.getMovementQty());
+
+ //Account Scrap
+ if(m_cc.getScrappedQty().signum() != 0)
+ {
+ credit = m_line.getAccount(ProductCost.ACCTTYPE_P_WorkInProcess, as);
+ debit = m_line.getAccount(ProductCost.ACCTTYPE_P_Scrap, as);
+ //Material
+ cost = MCost.getCostByCostingMethod(product, as, m_cc.getAD_Org_ID(), m_cc.getM_AttributeSetInstance_ID(),
+ MCostElement.COSTINGMETHOD_StandardCosting, MCostElement.COSTELEMENTTYPE_Material,m_cc.getScrappedQty());
+ createLines(MCostElement.COSTELEMENTTYPE_Material, as, fact, product, debit, credit, cost,m_cc.getScrappedQty());
+
+ //Resource (Labor)
+ cost = MCost.getCostByCostingMethod(product, as, m_cc.getAD_Org_ID(), m_cc.getM_AttributeSetInstance_ID(),
+ MCostElement.COSTINGMETHOD_StandardCosting, MCostElement.COSTELEMENTTYPE_Resource,m_cc.getScrappedQty());
+ createLines(MCostElement.COSTELEMENTTYPE_Resource, as, fact, product, debit, credit, cost, m_cc.getScrappedQty());
+
+ //Burden
+ cost = MCost.getCostByCostingMethod(product, as, m_cc.getAD_Org_ID(), m_cc.getM_AttributeSetInstance_ID(),
+ MCostElement.COSTINGMETHOD_StandardCosting, MCostElement.COSTELEMENTTYPE_BurdenMOverhead,m_cc.getScrappedQty());
+ createLines(MCostElement.COSTELEMENTTYPE_BurdenMOverhead, as, fact, product, debit, credit, cost, m_cc.getScrappedQty());
+
+ //Outsite Processing
+ cost = MCost.getCostByCostingMethod(product, as, m_cc.getAD_Org_ID(), m_cc.getM_AttributeSetInstance_ID(),
+ MCostElement.COSTINGMETHOD_StandardCosting, MCostElement.COSTELEMENTTYPE_OutsideProcessing,m_cc.getScrappedQty());
+ createLines(MCostElement.COSTELEMENTTYPE_OutsideProcessing, as, fact, product, debit, credit, cost, m_cc.getScrappedQty());
+
+ //Overhead Applied
+ credit = m_line.getAccount(ProductCost.ACCTTYPE_P_Overhead, as);
+ cost = MCost.getCostByCostingMethod(product, as, m_cc.getAD_Org_ID(), m_cc.getM_AttributeSetInstance_ID(),
+ MCostElement.COSTINGMETHOD_StandardCosting, MCostElement.COSTELEMENTTYPE_Overhead,m_cc.getScrappedQty());
+ createLines(MCostElement.COSTELEMENTTYPE_OutsideProcessing, as, fact, product, debit, credit, cost, m_cc.getScrappedQty());
+ }
+ }
+ else if (m_cc.getCostCollectorType().equals(MPPCostCollector.COSTCOLLECTORTYPE_ComponentIssue))
+ {
+
+ MAccount debit = m_line.getAccount(ProductCost.ACCTTYPE_P_WorkInProcess, as);
+ MAccount credit = m_line.getAccount(ProductCost.ACCTTYPE_P_Asset, as);
+ final String whereCluase = MPPOrderBOMLine.COLUMNNAME_PP_Order_BOMLine_ID
+ + "= ? AND "
+ + MPPOrderBOMLine.COLUMNNAME_IssueMethod
+ + "= ?";
+
+ boolean isFloorStock = new Query(m_cc.getCtx(),MPPOrderBOMLine.Table_Name,whereCluase, m_cc.get_TableName())
+ .setOnlyActiveRecords(true)
+ .setParameters(new Object[]{m_cc.getPP_Order_BOMLine_ID(),MPPOrderBOMLine.ISSUEMETHOD_FloorStock})
+ .match();
+ if(isFloorStock)
+ {
+ credit = m_line.getAccount(ProductCost.ACCTTYPE_P_FloorStock, as);
+ }
+
+ BigDecimal cost = Env.ZERO;
+ //Material
+ cost = MCost.getCostByCostingMethod(product, as, m_cc.getAD_Org_ID(), m_cc.getM_AttributeSetInstance_ID(),
+ MCostElement.COSTINGMETHOD_StandardCosting, MCostElement.COSTELEMENTTYPE_Material,m_cc.getMovementQty());
+ createLines(MCostElement.COSTELEMENTTYPE_Material, as, fact, product, debit, credit, cost, m_cc.getMovementQty());
+
+ //Resource (Labor)
+ cost = MCost.getCostByCostingMethod(product, as, m_cc.getAD_Org_ID(), m_cc.getM_AttributeSetInstance_ID(),
+ MCostElement.COSTINGMETHOD_StandardCosting, MCostElement.COSTELEMENTTYPE_Resource,m_cc.getMovementQty());
+ createLines(MCostElement.COSTELEMENTTYPE_Resource, as, fact, product, debit, credit, cost, m_cc.getMovementQty());
+
+ //Burden
+ cost = MCost.getCostByCostingMethod(product, as, m_cc.getAD_Org_ID(), m_cc.getM_AttributeSetInstance_ID(),
+ MCostElement.COSTINGMETHOD_StandardCosting, MCostElement.COSTELEMENTTYPE_BurdenMOverhead,m_cc.getMovementQty());
+ createLines(MCostElement.COSTELEMENTTYPE_BurdenMOverhead, as, fact, product, debit, credit, cost, m_cc.getMovementQty());
+
+ //Outsite Processing
+ cost = MCost.getCostByCostingMethod(product, as, m_cc.getAD_Org_ID(), m_cc.getM_AttributeSetInstance_ID(),
+ MCostElement.COSTINGMETHOD_StandardCosting, MCostElement.COSTELEMENTTYPE_OutsideProcessing,m_cc.getMovementQty());
+ createLines(MCostElement.COSTELEMENTTYPE_OutsideProcessing, as, fact, product, debit, credit, cost, m_cc.getMovementQty());
+
+ //Overhead Applied
+ credit = m_line.getAccount(ProductCost.ACCTTYPE_P_Overhead, as);
+ cost = MCost.getCostByCostingMethod(product, as, m_cc.getAD_Org_ID(), m_cc.getM_AttributeSetInstance_ID(),
+ MCostElement.COSTINGMETHOD_StandardCosting, MCostElement.COSTELEMENTTYPE_Overhead,m_cc.getMovementQty());
+ createLines(MCostElement.COSTELEMENTTYPE_OutsideProcessing, as, fact, product, debit, credit, cost, m_cc.getMovementQty());
+
+
+ }
+ else if (m_cc.getCostCollectorType().equals(MPPCostCollector.COSTCOLLECTORTYPE_ActivityControl))
+ {
+ MPPOrderNode activity = (MPPOrderNode) m_cc.getPP_Order_Node();
+ MWFNode node = (MWFNode) activity.getAD_WF_Node();
+ if(activity.getDocAction().equals(MPPOrderNode.DOCSTATUS_Completed))
+ {
+ //Labor Rate
+ MAccount debit = m_line.getAccount(ProductCost.ACCTTYPE_P_WorkInProcess, as);
+ MAccount credit = m_line.getAccount(ProductCost.ACCTTYPE_P_Labor, as);
+ BigDecimal labor = node.getCostForCostElementType(MCostElement.COSTELEMENTTYPE_Resource, as.getC_AcctSchema_ID(), as.getM_CostType_ID(), m_cc.getAD_Org_ID(), m_cc.getSetupTimeReal().intValue(), m_cc.getDurationReal().intValue());
+ createLines(MCostElement.COSTELEMENTTYPE_Resource, as, fact, product, debit, credit, labor, m_cc.getMovementQty());
+ //Burden Rate
+ debit = m_line.getAccount(ProductCost.ACCTTYPE_P_WorkInProcess, as);
+ credit = m_line.getAccount(ProductCost.ACCTTYPE_P_Burden, as);
+ BigDecimal burden = node.getCostForCostElementType(MCostElement.COSTELEMENTTYPE_BurdenMOverhead, as.getC_AcctSchema_ID(), as.getM_CostType_ID(), m_cc.getAD_Org_ID(), m_cc.getSetupTimeReal().intValue(), m_cc.getDurationReal().intValue());
+ createLines(MCostElement.COSTELEMENTTYPE_BurdenMOverhead, as, fact, product, debit, credit, burden, m_cc.getMovementQty());
+ }
+ }
+
+ log.info("End CreateFacts Manufacturing"+fact);
+ //
+ ArrayList facts = new ArrayList();
+ facts.add(fact);
+ return facts;
+ } // createFact
+
+ private void createLines(String CostElementType, MAcctSchema as ,Fact fact , MProduct product,MAccount debit, MAccount credit, BigDecimal cost, BigDecimal qty)
+ {
+ if(cost == null | debit == null | credit == null)
+ return;
+
+ log.info("CostElementType: " +CostElementType + "Product: "+product.getName()+" Debit: " + debit.getDescription() + " Credit: "+ credit.getDescription() + " Cost: " + cost +" Qunatity: "+ qty);
+ // Line pointers
+ FactLine dr = null;
+ FactLine cr = null;
+ if(cost.signum() != 0 & qty != null)
+ {
+ dr = fact.createLine(m_line, debit , as.getC_Currency_ID(), cost, null);
+ dr.setQty(qty);
+ dr.addDescription(Msg.translate(m_cc.getCtx(), CostElementType));
+ dr.setC_Project_ID(m_cc.getC_Project_ID());
+ dr.setC_Activity_ID(m_cc.getC_Activity_ID());
+ dr.setC_Campaign_ID(m_cc.getC_Campaign_ID());
+ dr.setM_Locator_ID(m_cc.getM_Locator_ID());
+
+ cr = fact.createLine(m_line, credit,as.getC_Currency_ID(), null, cost);
+ cr.setQty(qty);
+ cr.addDescription(Msg.translate(m_cc.getCtx(), CostElementType));
+ cr.setC_Project_ID(m_cc.getC_Project_ID());
+ cr.setC_Activity_ID(m_cc.getC_Activity_ID());
+ cr.setC_Campaign_ID(m_cc.getC_Campaign_ID());
+ cr.setM_Locator_ID(m_cc.getM_Locator_ID());
+ }
+ }
+} // Doc Cost Collector
diff --git a/base/src/org/compiere/model/ProductCost.java b/base/src/org/compiere/model/ProductCost.java
index 6c38886257..10ed418ac7 100644
--- a/base/src/org/compiere/model/ProductCost.java
+++ b/base/src/org/compiere/model/ProductCost.java
@@ -150,11 +150,17 @@ public class ProductCost
/** Floor Stock */
public static final int ACCTTYPE_P_FloorStock = 16;
/** Cost Production */
- public static final int ACCTTYPE_P_CostOfProduction = 16;
+ public static final int ACCTTYPE_P_CostOfProduction = 17;
/** Labor */
- public static final int ACCTTYPE_P_Labor = 14;
+ public static final int ACCTTYPE_P_Labor = 18;
/** Burden */
- public static final int ACCTTYPE_P_Burden = 15;
+ public static final int ACCTTYPE_P_Burden = 19;
+ /** Outside Processing */
+ public static final int ACCTTYPE_P_OutsideProcessing = 20;
+ /** Outside Overhead */
+ public static final int ACCTTYPE_P_Overhead = 21;
+ /** Outside Processing */
+ public static final int ACCTTYPE_P_Scrap = 22;
/**
@@ -166,7 +172,7 @@ public class ProductCost
*/
public MAccount getAccount(int AcctType, MAcctSchema as)
{
- if (AcctType < 1 || AcctType > 10)
+ if (AcctType < 1 || AcctType > 22)
return null;
// No Product - get Default from Product Category
@@ -176,7 +182,11 @@ public class ProductCost
String sql = "SELECT P_Revenue_Acct, P_Expense_Acct, P_Asset_Acct, P_Cogs_Acct, " // 1..4
+ "P_PurchasePriceVariance_Acct, P_InvoicePriceVariance_Acct, " // 5..6
+ "P_TradeDiscountRec_Acct, P_TradeDiscountGrant_Acct," // 7..8
- + "P_CostAdjustment_Acct, P_InventoryClearing_Acct " // 9..10
+ + "P_CostAdjustment_Acct, P_InventoryClearing_Acct," // 9..10
+ + "P_WIP_Acct,P_MethodChangeVariance_Acct,P_UsageVariance_Acct," // 11.12.13
+ + "P_RateVariance_Acct,P_MixVariance_Acct,P_FloorStock_Acct," // 14.15.16
+ + "P_CostOfProduction_Acct,P_Labor_Acct,P_Burden_Acct,P_OutsideProcessing_Acct," // 17.18,19,20
+ + "P_Overhead_Acct,P_Scrap_Acct " // 21,22
+ "FROM M_Product_Acct "
+ "WHERE M_Product_ID=? AND C_AcctSchema_ID=?";
//
@@ -214,13 +224,17 @@ public class ProductCost
*/
public MAccount getAccountDefault (int AcctType, MAcctSchema as)
{
- if (AcctType < 1 || AcctType > 10)
+ if (AcctType < 1 || AcctType > 22)
return null;
String sql = "SELECT P_Revenue_Acct, P_Expense_Acct, P_Asset_Acct, P_Cogs_Acct, "
+ "P_PurchasePriceVariance_Acct, P_InvoicePriceVariance_Acct, "
+ "P_TradeDiscountRec_Acct, P_TradeDiscountGrant_Acct, "
- + "P_CostAdjustment_Acct, P_InventoryClearing_Acct "
+ + "P_CostAdjustment_Acct, P_InventoryClearing_Acct, "
+ + "P_WIP_Acct,P_MethodChangeVariance_Acct,P_UsageVariance_Acct," // 11.12.13
+ + "P_RateVariance_Acct,P_MixVariance_Acct,P_FloorStock_Acct," // 14.15.16
+ + "P_CostOfProduction_Acct,P_Labor_Acct,P_Burden_Acct,P_OutsideProcessing_Acct" // 17.18,19,20
+ + "P_Overhead_Acct,P_Scrap_Acct " // 21,22
+ "FROM M_Product_Category pc, M_Product_Category_Acct pca "
+ "WHERE pc.M_Product_Category_ID=pca.M_Product_Category_ID"
+ " AND pca.C_AcctSchema_ID=? "