Average Costing & Landed Cost fixes
This commit is contained in:
parent
fd04f75d8a
commit
7be93edc86
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()));
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue