From b27e82ec94b0bc787f21ac72d1a54a5af238c96b Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Tue, 2 Jul 2013 17:24:55 +0800 Subject: [PATCH] IDEMPIERE-150 Vendor RMA - M_cost Table is not updated. --- .../src/org/compiere/acct/DocLine.java | 5 + .../src/org/compiere/acct/Doc_InOut.java | 93 ++++++++++++++++ .../src/org/compiere/model/MCostDetail.java | 105 ++++++++++++------ 3 files changed, 169 insertions(+), 34 deletions(-) diff --git a/org.adempiere.base/src/org/compiere/acct/DocLine.java b/org.adempiere.base/src/org/compiere/acct/DocLine.java index ac1cce333b..cc793ed1bd 100644 --- a/org.adempiere.base/src/org/compiere/acct/DocLine.java +++ b/org.adempiere.base/src/org/compiere/acct/DocLine.java @@ -1143,6 +1143,11 @@ public class DocLine } // getReversalLine_ID //end AZ Goodwill + public PO getPO() + { + return p_po; + } + /** * String representation * @return String diff --git a/org.adempiere.base/src/org/compiere/acct/Doc_InOut.java b/org.adempiere.base/src/org/compiere/acct/Doc_InOut.java index 436a7712c4..3bad3a11e0 100644 --- a/org.adempiere.base/src/org/compiere/acct/Doc_InOut.java +++ b/org.adempiere.base/src/org/compiere/acct/Doc_InOut.java @@ -18,9 +18,14 @@ package org.compiere.acct; import java.math.BigDecimal; import java.sql.ResultSet; +import java.sql.Timestamp; import java.util.ArrayList; import java.util.logging.Level; +import org.compiere.model.I_M_InOutLine; +import org.compiere.model.I_M_RMA; +import org.compiere.model.I_M_RMALine; +import org.compiere.model.MConversionRate; import org.compiere.model.MTax; import org.compiere.model.MCurrency; import org.compiere.model.MAccount; @@ -33,6 +38,7 @@ import org.compiere.model.MProduct; import org.compiere.model.ProductCost; import org.compiere.util.DB; import org.compiere.util.Env; +import org.compiere.util.Util; /** * Post Shipment/Receipt Documents. @@ -597,6 +603,13 @@ public class Doc_InOut extends Doc } } } + + String costingError = createVendorRMACostDetail(as); + if (!Util.isEmpty(costingError)) + { + p_Error = costingError; + return null; + } } // Purchasing Return else { @@ -613,4 +626,84 @@ public class Doc_InOut extends Doc return m_Reversal_ID !=0 && line.getReversalLine_ID() != 0; } + private String createVendorRMACostDetail(MAcctSchema as) + { + MOrderLine origianlOrderLine = null; + + MInOut inOut = (MInOut) getPO(); + + for (int i = 0; i < p_lines.length; i++) + { + DocLine line = p_lines[i]; + MInOutLine ioLine = (MInOutLine) line.getPO(); + I_M_RMALine rmaLine = ioLine.getM_RMALine(); + + BigDecimal poCost = rmaLine != null ? rmaLine.getAmt() : BigDecimal.ZERO; + I_M_InOutLine originalInOutLine = rmaLine != null ? rmaLine.getM_InOutLine() : null; + if (originalInOutLine != null && originalInOutLine.getC_OrderLine_ID() > 0) + { + origianlOrderLine = (MOrderLine) originalInOutLine.getC_OrderLine(); + // Goodwill: Correct included Tax + int C_Tax_ID = origianlOrderLine.getC_Tax_ID(); + if (origianlOrderLine.isTaxIncluded() && C_Tax_ID != 0) + { + MTax tax = MTax.get(getCtx(), C_Tax_ID); + if (!tax.isZeroTax()) + { + int stdPrecision = MCurrency.getStdPrecision(getCtx(), origianlOrderLine.getC_Currency_ID()); + BigDecimal costTax = tax.calculateTax(poCost, true, stdPrecision); + if (log.isLoggable(Level.FINE)) log.fine("Costs=" + poCost + " - Tax=" + costTax); + poCost = poCost.subtract(costTax); + } + } // correct included Tax + poCost = poCost.multiply(line.getQty()); // Returned so far + BigDecimal tAmt = poCost; + BigDecimal tQty = line.getQty(); + + I_M_RMA rma = rmaLine.getM_RMA(); + if (rma.getC_Currency_ID() != as.getC_Currency_ID()) + { + Timestamp dateAcct = inOut.getDateAcct(); + // + BigDecimal rate = MConversionRate.getRate( + rma.getC_Currency_ID(), as.getC_Currency_ID(), + dateAcct, 0, + rmaLine.getAD_Client_ID(), rmaLine.getAD_Org_ID()); + if (rate == null) + { + return "Vendor RMA not convertible - " + as.getName(); + } + poCost = poCost.multiply(rate); + if (poCost.scale() > as.getCostingPrecision()) + poCost = poCost.setScale(as.getCostingPrecision(), BigDecimal.ROUND_HALF_UP); + 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 rma line + if (!MCostDetail.createShipment(as, line.getAD_Org_ID(), line.getM_Product_ID(), + line.getM_AttributeSetInstance_ID(), line.get_ID(), 0, tAmt, tQty, + line.getDescription(), false, getTrxName())) + { + return "SaveError"; + } + } + else + { + //no rma line linkage, fallback to current cost + poCost = line.getProductCosts(as, line.getAD_Org_ID(), false); + BigDecimal tAmt = poCost.negate(); + BigDecimal tQty = line.getQty(); + if (!MCostDetail.createShipment(as, line.getAD_Org_ID(), line.getM_Product_ID(), + line.getM_AttributeSetInstance_ID(), line.get_ID(), 0, tAmt, tQty, + line.getDescription(), false, getTrxName())) + { + return "SaveError"; + } + } + } + // end MZ + return ""; + } } // Doc_InOut diff --git a/org.adempiere.base/src/org/compiere/model/MCostDetail.java b/org.adempiere.base/src/org/compiere/model/MCostDetail.java index caa83f3bd8..735e4d46c4 100644 --- a/org.adempiere.base/src/org/compiere/model/MCostDetail.java +++ b/org.adempiere.base/src/org/compiere/model/MCostDetail.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Properties; import java.util.logging.Level; +import org.compiere.acct.Doc; import org.compiere.model.X_M_CostHistory; import org.compiere.util.CLogger; import org.compiere.util.DB; @@ -51,6 +52,12 @@ public class MCostDetail extends X_M_CostDetail */ private static final long serialVersionUID = -448632684360931078L; + private static final String INOUTLINE_DOCBASETYPE_SQL = + "SELECT c.DocBaseType From M_InOut io " + + "INNER JOIN M_InOutLine iol ON io.M_InOut_ID=iol.M_InOut_ID " + + "INNER JOIN C_DocType c ON io.C_DocType_ID=c.C_DocType_ID " + + "WHERE iol.M_InOutLine_ID=?"; + /** * Create New Order Cost Detail for Purchase Orders. * Called from Doc_MatchPO @@ -677,6 +684,20 @@ public class MCostDetail extends X_M_CostDetail return isSOTrx() && getM_InOutLine_ID() != 0; } // isShipment + /** + * @return true if return to vendor + */ + public boolean isVendorRMA() + { + if (!isSOTrx() && getM_InOutLine_ID() > 0) + { + String docBaseType = DB.getSQLValueString((String)null, + INOUTLINE_DOCBASETYPE_SQL, getM_InOutLine_ID()); + return Doc.DOCTYPE_MatShipment.equals(docBaseType); + } + return false; + } + /** * Is this a Delta Record (previously processed)? * @return true if delta is not null @@ -1036,22 +1057,26 @@ public class MCostDetail extends X_M_CostDetail || getPP_Cost_Collector_ID() != 0) { boolean addition = qty.signum() > 0; + boolean isVendorRMA = isVendorRMA(); // if (ce.isAverageInvoice()) { - if (addition) + if (!isVendorRMA) { - cost.setWeightedAverage(amt, qty); - //shouldn't accumulate reversal of customer shipment qty and amt - if (isShipment()) + if (addition) { - cost.setCumulatedQty(history.getOldCQty()); - cost.setCumulatedAmt(history.getOldCAmt()); + cost.setWeightedAverage(amt, qty); + //shouldn't accumulate reversal of customer shipment qty and amt + if (isShipment()) + { + cost.setCumulatedQty(history.getOldCQty()); + cost.setCumulatedAmt(history.getOldCAmt()); + } } + else + cost.setCurrentQty(cost.getCurrentQty().add(qty)); + if (log.isLoggable(Level.FINER)) log.finer("QtyAdjust - AverageInv - " + cost); } - else - cost.setCurrentQty(cost.getCurrentQty().add(qty)); - if (log.isLoggable(Level.FINER)) log.finer("QtyAdjust - AverageInv - " + cost); } else if (ce.isAveragePO()) { @@ -1059,51 +1084,63 @@ public class MCostDetail extends X_M_CostDetail { cost.setWeightedAverage(amt, qty); //shouldn't accumulate reversal of customer shipment qty and amt - if (isShipment()) + if (isShipment() && !isVendorRMA()) { cost.setCumulatedQty(history.getOldCQty()); cost.setCumulatedAmt(history.getOldCAmt()); } } else - cost.setCurrentQty(cost.getCurrentQty().add(qty)); + { + if (isVendorRMA) + { + cost.setWeightedAverage(amt, qty); + } + else + { + cost.setCurrentQty(cost.getCurrentQty().add(qty)); + } + } if (log.isLoggable(Level.FINER)) log.finer("QtyAdjust - AveragePO - " + cost); } else if (ce.isFifo() || ce.isLifo()) { - if (addition) + if (!isVendorRMA) { - // Real ASI - costing level Org - MCostQueue cq = MCostQueue.get(product, getM_AttributeSetInstance_ID(), - as, Org_ID, ce.getM_CostElement_ID(), get_TrxName()); - cq.setCosts(amt, qty, precision); - cq.saveEx(); + if (addition) + { + // Real ASI - costing level Org + MCostQueue cq = MCostQueue.get(product, getM_AttributeSetInstance_ID(), + as, Org_ID, ce.getM_CostElement_ID(), get_TrxName()); + cq.setCosts(amt, qty, precision); + cq.saveEx(); + } + else + { + // Adjust Queue - costing level Org/ASI + MCostQueue.adjustQty(product, M_ASI_ID, + as, Org_ID, ce, qty.negate(), get_TrxName()); + } + // Get Costs - costing level Org/ASI + MCostQueue[] cQueue = MCostQueue.getQueue(product, M_ASI_ID, + as, Org_ID, ce, get_TrxName()); + if (cQueue != null && cQueue.length > 0) + cost.setCurrentCostPrice(cQueue[0].getCurrentCostPrice()); + cost.setCurrentQty(cost.getCurrentQty().add(qty)); + if (log.isLoggable(Level.FINER)) log.finer("QtyAdjust - FiFo/Lifo - " + cost); } - else - { - // Adjust Queue - costing level Org/ASI - MCostQueue.adjustQty(product, M_ASI_ID, - as, Org_ID, ce, qty.negate(), get_TrxName()); - } - // Get Costs - costing level Org/ASI - MCostQueue[] cQueue = MCostQueue.getQueue(product, M_ASI_ID, - as, Org_ID, ce, get_TrxName()); - if (cQueue != null && cQueue.length > 0) - cost.setCurrentCostPrice(cQueue[0].getCurrentCostPrice()); - cost.setCurrentQty(cost.getCurrentQty().add(qty)); - if (log.isLoggable(Level.FINER)) log.finer("QtyAdjust - FiFo/Lifo - " + cost); } - else if (ce.isLastInvoice()) + else if (ce.isLastInvoice() && !isVendorRMA) { cost.setCurrentQty(cost.getCurrentQty().add(qty)); if (log.isLoggable(Level.FINER)) log.finer("QtyAdjust - LastInv - " + cost); } - else if (ce.isLastPOPrice()) + else if (ce.isLastPOPrice() && !isVendorRMA) { cost.setCurrentQty(cost.getCurrentQty().add(qty)); if (log.isLoggable(Level.FINER)) log.finer("QtyAdjust - LastPO - " + cost); } - else if (ce.isStandardCosting()) + else if (ce.isStandardCosting() && !isVendorRMA) { if (addition) { @@ -1123,7 +1160,7 @@ public class MCostDetail extends X_M_CostDetail } if (log.isLoggable(Level.FINER)) log.finer("QtyAdjust - Standard - " + cost); } - else if (ce.isUserDefined()) + else if (ce.isUserDefined() && !isVendorRMA) { // Interface if (addition)