From b8c2ed4b2b68b65f92e4ad10b50b5d2c23f2c4db Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Mon, 19 May 2014 14:40:07 +0800 Subject: [PATCH] 1003754 Landed cost issue -- related to IDEMPIERE-1285. Fix rounding issue with current product cost for average costing. --- .../src/org/compiere/acct/Doc_Invoice.java | 24 ++++++++++++++++--- .../src/org/compiere/model/MCost.java | 14 +++++++---- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/org.adempiere.base/src/org/compiere/acct/Doc_Invoice.java b/org.adempiere.base/src/org/compiere/acct/Doc_Invoice.java index 1f0c6368c5..61f3dd94f6 100644 --- a/org.adempiere.base/src/org/compiere/acct/Doc_Invoice.java +++ b/org.adempiere.base/src/org/compiere/acct/Doc_Invoice.java @@ -22,6 +22,8 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Savepoint; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; import java.util.logging.Level; import org.adempiere.exceptions.AverageCostingZeroQtyException; @@ -826,6 +828,8 @@ public class Doc_Invoice extends Doc for (int i = 0; i < lcas.length; i++) totalBase += lcas[i].getBase().doubleValue(); + Map costDetailAmtMap = new HashMap(); + // Create New MInvoiceLine il = new MInvoiceLine (getCtx(), C_InvoiceLine_ID, getTrxName()); for (int i = 0; i < lcas.length; i++) @@ -878,11 +882,11 @@ public class Doc_Invoice extends Doc if (estimatedAmt.scale() > as.getCostingPrecision()) { - estimatedAmt.setScale(as.getCostingPrecision(), BigDecimal.ROUND_HALF_UP); + estimatedAmt = estimatedAmt.setScale(as.getCostingPrecision(), BigDecimal.ROUND_HALF_UP); } BigDecimal costAdjustmentAmt = allocationAmt; if (estimatedAmt.signum() > 0) - { + { //get other allocation amt StringBuilder sql = new StringBuilder("SELECT Sum(Amt) FROM C_LandedCostAllocation WHERE M_InOutLine_ID=? ") .append("AND C_LandedCostAllocation_ID<>? ") @@ -900,7 +904,7 @@ public class Doc_Invoice extends Doc } } if (estimatedAmt.signum() > 0) - { + { if (allocationAmt.signum() > 0) costAdjustmentAmt = allocationAmt.subtract(estimatedAmt); else if (allocationAmt.signum() < 0) @@ -928,6 +932,12 @@ public class Doc_Invoice extends Doc if (costDetailAmt.scale() > as.getCostingPrecision()) costDetailAmt = costDetailAmt.setScale(as.getCostingPrecision(), BigDecimal.ROUND_HALF_UP); + String key = lca.getM_Product_ID()+"_"+lca.getM_AttributeSetInstance_ID(); + BigDecimal prevAmt = costDetailAmtMap.remove(key); + if (prevAmt != null) { + costDetailAmt = costDetailAmt.add(prevAmt); + } + costDetailAmtMap.put(key, costDetailAmt); if (!MCostDetail.createInvoice(as, lca.getAD_Org_ID(), lca.getM_Product_ID(), lca.getM_AttributeSetInstance_ID(), C_InvoiceLine_ID, lca.getM_CostElement_ID(), @@ -963,6 +973,14 @@ public class Doc_Invoice extends Doc if (allocationAmt.signum() > 0) { + if (allocationAmt.scale() > as.getStdPrecision()) + { + allocationAmt = allocationAmt.setScale(as.getStdPrecision(), BigDecimal.ROUND_HALF_UP); + } + if (estimatedAmt.scale() > as.getStdPrecision()) + { + estimatedAmt = estimatedAmt.setScale(as.getStdPrecision(), BigDecimal.ROUND_HALF_UP); + } int compare = allocationAmt.compareTo(estimatedAmt); if (compare > 0) { diff --git a/org.adempiere.base/src/org/compiere/model/MCost.java b/org.adempiere.base/src/org/compiere/model/MCost.java index b67fcbe2b0..b9dd42fe44 100644 --- a/org.adempiere.base/src/org/compiere/model/MCost.java +++ b/org.adempiere.base/src/org/compiere/model/MCost.java @@ -1500,14 +1500,18 @@ public class MCost extends X_M_Cost throw new AverageCostingNegativeQtyException("Product(ID)="+getM_Product_ID()+", Current Qty="+getCurrentQty()+", Trx Qty="+qty +", CostElement="+getM_CostElement().getName()+", Schema="+getC_AcctSchema().getName()); } - - BigDecimal oldSum = getCurrentCostPrice().multiply(getCurrentQty()); - BigDecimal newSum = amt; // is total already - BigDecimal sumAmt = oldSum.add(newSum); + BigDecimal sumQty = getCurrentQty().add(qty); if (sumQty.signum() != 0) { - BigDecimal cost = sumAmt.divide(sumQty, getPrecision(), BigDecimal.ROUND_HALF_UP); + BigDecimal oldSum = getCurrentCostPrice().multiply(getCurrentQty()); + BigDecimal oldCost = oldSum.divide(sumQty, 12, BigDecimal.ROUND_HALF_UP); + BigDecimal newCost = amt.divide(sumQty, 12, BigDecimal.ROUND_HALF_UP); //amt is total already + BigDecimal cost = oldCost.add(newCost); + if (cost.scale() > (getPrecision()*2)) + { + cost = cost.setScale((getPrecision()*2), BigDecimal.ROUND_HALF_UP); + } setCurrentCostPrice(cost); } //