Average Costing & Landed Cost fixes

This commit is contained in:
armenrz 2007-06-19 13:32:45 +00:00
parent fd04f75d8a
commit 7be93edc86
8 changed files with 168 additions and 49 deletions

View File

@ -687,6 +687,28 @@ public class DocLine
return m_productCost;
} // getProductCost
// MZ Goodwill
/**
* Get Total Product Costs from Cost Detail or from Current Cost
* @param as accounting schema
* @param AD_Org_ID trx org
* @param zeroCostsOK zero/no costs are OK
* @param whereClause null are OK
* @return costs
*/
public BigDecimal getProductCosts (MAcctSchema as, int AD_Org_ID, boolean zeroCostsOK, String whereClause)
{
if (whereClause != null)
{
MCostDetail cd = MCostDetail.get (Env.getCtx(), whereClause,
get_ID(), getM_AttributeSetInstance_ID(), p_po.get_TrxName());
if (cd != null)
return cd.getAmt();
}
return getProductCosts(as, AD_Org_ID, zeroCostsOK);
} // getProductCosts
// end MZ
/**
* Get Total Product Costs
* @param as accounting schema

View File

@ -139,7 +139,11 @@ public class Doc_InOut extends Doc
for (int i = 0; i < p_lines.length; i++)
{
DocLine line = p_lines[i];
BigDecimal costs = line.getProductCosts(as, line.getAD_Org_ID(), true);
// MZ Goodwill
// if Shipment CostDetail exist then get Cost from Cost Detail
BigDecimal costs = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_InOutLine_ID=? AND M_AttributeSetInstance_ID=?");
// end MZ
if (costs == null || costs.signum() == 0) // zero costs OK
{
MProduct product = line.getProduct();

View File

@ -134,7 +134,10 @@ public class Doc_Inventory extends Doc
for (int i = 0; i < p_lines.length; i++)
{
DocLine line = p_lines[i];
BigDecimal costs = line.getProductCosts(as, line.getAD_Org_ID(), false);
// MZ Goodwill
// if Physical Inventory CostDetail is exist then get Cost from Cost Detail
BigDecimal costs = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_InventoryLine_ID=? AND M_AttributeSetInstance_ID=?");
// end MZ
if (costs == null || costs.signum() == 0)
{
p_Error = "No Costs for " + line.getProduct().getName();

View File

@ -784,12 +784,6 @@ public class Doc_Invoice extends Doc
if (lcas.length == 0)
return false;
// Delete Old
String sql = "DELETE M_CostDetail WHERE C_InvoiceLine_ID=" + C_InvoiceLine_ID;
int no = DB.executeUpdate(sql, getTrxName());
if (no != 0)
log.config("CostDetail Deleted #" + no);
// Calculate Total Base
double totalBase = 0;
for (int i = 0; i < lcas.length; i++)
@ -802,7 +796,7 @@ public class Doc_Invoice extends Doc
MLandedCostAllocation lca = lcas[i];
if (lca.getBase().signum() == 0)
continue;
double percent = totalBase / lca.getBase().doubleValue();
double percent = lca.getBase().doubleValue() / totalBase;
String desc = il.getDescription();
if (desc == null)
desc = percent + "%";
@ -823,6 +817,7 @@ public class Doc_Invoice extends Doc
FactLine fl = fact.createLine (line, pc.getAccount(ProductCost.ACCTTYPE_P_CostAdjustment, as),
getC_Currency_ID(), drAmt, crAmt);
fl.setDescription(desc);
fl.setM_Product_ID(lca.getM_Product_ID());
// Cost Detail - Convert to AcctCurrency
BigDecimal allocationAmt = lca.getAmt();
@ -835,19 +830,22 @@ public class Doc_Invoice extends Doc
allocationAmt = allocationAmt.setScale(as.getCostingPrecision(), BigDecimal.ROUND_HALF_UP);
if (!dr)
allocationAmt = allocationAmt.negate();
MCostDetail cd = new MCostDetail (as, lca.getAD_Org_ID(),
lca.getM_Product_ID(), lca.getM_AttributeSetInstance_ID(),
lca.getM_CostElement_ID(),
allocationAmt, Env.ZERO, // Qty
desc, getTrxName());
cd.setC_InvoiceLine_ID(C_InvoiceLine_ID);
boolean ok = cd.save();
if (ok && !cd.isProcessed())
{
MClient client = MClient.get(as.getCtx(), as.getAD_Client_ID());
if (client.isCostImmediate())
cd.process();
}
// MZ Goodwill
// set Qty to 1 or -1 instead of 0 and allocation Amt is counted for each product qty
if (lca.getQty().signum() != 0)
allocationAmt = allocationAmt.divide(lca.getQty(), as.getCostingPrecision(), BigDecimal.ROUND_HALF_UP);
// Qty is 1 or -1
BigDecimal qty = Env.ONE;
if (il.getQtyInvoiced().signum() != 0)
qty = il.getQtyInvoiced().divide(il.getQtyInvoiced().abs());
// use createInvoice to create/update non Material Cost Detail
MCostDetail.createInvoice(as, lca.getAD_Org_ID(),
lca.getM_Product_ID(), lca.getM_AttributeSetInstance_ID(),
C_InvoiceLine_ID, lca.getM_CostElement_ID(),
allocationAmt, qty, // Qty
desc, getTrxName());
// end MZ
}
log.config("Created #" + lcas.length);

View File

@ -239,12 +239,52 @@ public class Doc_MatchInv extends Doc
log.fine("IPV=" + ipv + "; Balance=" + fact.getSourceBalance());
// Cost Detail Record - data from Expense/IncClearing (CR) record
// MZ Goodwill
// Create Cost Detail Matched Invoice using Total Amount and Total Qty based on InvoiceLine
MMatchInv[] mInv = MMatchInv.getInvoiceLine(getCtx(), m_invoiceLine.getC_InvoiceLine_ID(), getTrxName());
BigDecimal tQty = Env.ZERO;
BigDecimal tAmt = Env.ZERO;
for (int i = 0 ; i < mInv.length ; i++)
{
if (mInv[i].isPosted() && mInv[i].getM_MatchInv_ID() != get_ID())
{
tQty = tQty.add(mInv[i].getQty());
multiplier = mInv[i].getQty()
.divide(m_invoiceLine.getQtyInvoiced(), 12, BigDecimal.ROUND_HALF_UP)
.abs();
tAmt = tAmt.add(m_invoiceLine.getLineNetAmt().multiply(multiplier));
}
}
tAmt = tAmt.add(cr.getAcctBalance().negate());
// set Qty to negative value when MovementType is Vendor Returns
MInOut receipt = m_receiptLine.getParent();
if (receipt.getMovementType().equals(MInOut.MOVEMENTTYPE_VendorReturns))
tQty = tQty.add(getQty().negate()); // Qty is set to negative value
else
tQty = tQty.add(getQty());
// Different currency
MInvoice invoice = m_invoiceLine.getParent();
if (as.getC_Currency_ID() == invoice.getC_Currency_ID())
{
tAmt = MConversionRate.convert(getCtx(), tAmt,
invoice.getC_Currency_ID(), as.getC_Currency_ID(),
invoice.getDateAcct(), invoice.getC_ConversionType_ID(),
invoice.getAD_Client_ID(), invoice.getAD_Org_ID());
if (tAmt == null)
{
p_Error = "AP Invoice not convertible - " + as.getName();
return null;
}
}
// Set Total Amount and Total Quantity from Matched Invoice
MCostDetail.createInvoice(as, getAD_Org_ID(),
getM_Product_ID(), matchInv.getM_AttributeSetInstance_ID(),
m_invoiceLine.getC_InvoiceLine_ID(), 0, // No cost element
cr.getAcctBalance().negate(), getQty(), // correcting
getDescription(), getTrxName());
getM_Product_ID(), matchInv.getM_AttributeSetInstance_ID(),
m_invoiceLine.getC_InvoiceLine_ID(), 0, // No cost element
tAmt, tQty, getDescription(), getTrxName());
// end MZ
// Update Costing
updateProductInfo(as.getC_AcctSchema_ID(),
MAcctSchema.COSTINGMETHOD_StandardCosting.equals(as.getCostingMethod()));

View File

@ -140,12 +140,49 @@ public class Doc_MatchPO extends Doc
poCost = poCost.setScale(as.getCostingPrecision(), BigDecimal.ROUND_HALF_UP);
}
// Create PO Cost Detail Record firs
// Create PO Cost Detail Record first
// MZ Goodwill
// Create Cost Detail Matched PO using Total Amount and Total Qty based on OrderLine
MMatchPO[] mPO = MMatchPO.getOrderLine(getCtx(), m_oLine.getC_OrderLine_ID(), getTrxName());
BigDecimal tQty = Env.ZERO;
BigDecimal tAmt = Env.ZERO;
BigDecimal priceCost = m_oLine.getPriceCost();
if (priceCost == null || priceCost.signum() == 0)
priceCost = m_oLine.getPriceActual();
for (int i = 0 ; i < mPO.length ; i++)
{
if (mPO[i].isPosted())
{
tQty = tQty.add(mPO[i].getQty());
tAmt = tAmt.add(priceCost.multiply(mPO[i].getQty()));
}
}
// Different currency
if (m_oLine.getC_Currency_ID() != as.getC_Currency_ID())
{
MOrder order = m_oLine.getParent();
BigDecimal rate = MConversionRate.getRate(
order.getC_Currency_ID(), as.getC_Currency_ID(),
order.getDateAcct(), order.getC_ConversionType_ID(),
m_oLine.getAD_Client_ID(), m_oLine.getAD_Org_ID());
if (rate == null)
{
p_Error = "Purchase Order not convertible - " + as.getName();
return null;
}
tAmt = tAmt.multiply(rate);
if (tAmt.scale() > as.getCostingPrecision())
tAmt = tAmt.setScale(as.getCostingPrecision(), BigDecimal.ROUND_HALF_UP);
}
// Set Total Amount and Total Quantity from Matched PO
MCostDetail.createOrder(as, m_oLine.getAD_Org_ID(),
getM_Product_ID(), m_M_AttributeSetInstance_ID,
m_C_OrderLine_ID, 0, // no cost element
poCost, getQty(), // Delivered
m_oLine.getDescription(), getTrxName());
getM_Product_ID(), m_M_AttributeSetInstance_ID,
m_C_OrderLine_ID, 0, // no cost element
tAmt, tQty, // Delivered
m_oLine.getDescription(), getTrxName());
// end MZ
// Calculate PPV for standard costing
String costingMethod = as.getCostingMethod();

View File

@ -120,8 +120,11 @@ public class Doc_Movement extends Doc
for (int i = 0; i < p_lines.length; i++)
{
DocLine line = p_lines[i];
BigDecimal costs = line.getProductCosts(as, line.getAD_Org_ID(), false);
// MZ Goodwill
// if Inventory Move CostDetail exist then get Cost from Cost Detail
BigDecimal costs = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_MovementLine_ID=? AND M_AttributeSetInstance_ID=? AND IsSOTrx='N'");
// end MZ
// ** Inventory DR CR
dr = fact.createLine(line,
line.getAccount(ProductCost.ACCTTYPE_P_Asset, as),

View File

@ -21,6 +21,7 @@ import java.sql.*;
import java.util.*;
import org.compiere.model.*;
import java.util.logging.*;
import org.compiere.util.*;
@ -166,22 +167,33 @@ public class Doc_Production extends Doc
DocLine line = p_lines[i];
// Calculate Costs
BigDecimal costs = null;
if (line.isProductionBOM())
{
// Get BOM Cost - Sum of individual lines
BigDecimal bomCost = Env.ZERO;
for (int ii = 0; ii < p_lines.length; ii++)
{
DocLine line0 = p_lines[ii];
if (line0.getM_ProductionPlan_ID() != line.getM_ProductionPlan_ID())
continue;
if (!line0.isProductionBOM())
bomCost = bomCost.add(line0.getProductCosts(as, line.getAD_Org_ID(), false));
}
costs = bomCost.negate();
}
// MZ Goodwill
// if Production CostDetail exist then get Cost from Cost Detail
MCostDetail cd = MCostDetail.get (as.getCtx(), "M_ProductionLine_ID=? AND M_AttributeSetInstance_ID=?",
line.get_ID(), line.getM_AttributeSetInstance_ID(), getTrxName());
if (cd != null)
costs = cd.getAmt();
else
costs = line.getProductCosts(as, line.getAD_Org_ID(), false);
{
if (line.isProductionBOM())
{
// Get BOM Cost - Sum of individual lines
BigDecimal bomCost = Env.ZERO;
for (int ii = 0; ii < p_lines.length; ii++)
{
DocLine line0 = p_lines[ii];
if (line0.getM_ProductionPlan_ID() != line.getM_ProductionPlan_ID())
continue;
if (!line0.isProductionBOM())
bomCost = bomCost.add(line0.getProductCosts(as, line.getAD_Org_ID(), false));
}
costs = bomCost.negate();
}
else
costs = line.getProductCosts(as, line.getAD_Org_ID(), false);
}
// end MZ
// Inventory DR CR
fl = fact.createLine(line,