diff --git a/base/src/org/compiere/acct/Doc_MatchInv.java b/base/src/org/compiere/acct/Doc_MatchInv.java index d0a51c7021..858d038cbc 100644 --- a/base/src/org/compiere/acct/Doc_MatchInv.java +++ b/base/src/org/compiere/acct/Doc_MatchInv.java @@ -291,6 +291,7 @@ public class Doc_MatchInv extends Doc tAmt = tAmt.add(m_invoiceLine.getLineNetAmt().multiply(multiplier)); } } + tAmt = tAmt.add(cr.getAcctBalance().negate()); //Invoice Price // Different currency MInvoice invoice = m_invoiceLine.getParent(); @@ -307,7 +308,6 @@ public class Doc_MatchInv extends Doc } } - tAmt = tAmt.add(cr.getAcctBalance().negate()); //Invoice Price // set Qty to negative value when MovementType is Vendor Returns MInOut receipt = m_receiptLine.getParent(); if (receipt.getMovementType().equals(MInOut.MOVEMENTTYPE_VendorReturns)) diff --git a/base/src/org/compiere/model/MInvoice.java b/base/src/org/compiere/model/MInvoice.java index ae260077bb..2dd29d3b7d 100644 --- a/base/src/org/compiere/model/MInvoice.java +++ b/base/src/org/compiere/model/MInvoice.java @@ -1790,12 +1790,7 @@ public class MInvoice extends X_C_Invoice implements DocAction return DocAction.STATUS_Invalid; } else - matchInv++; - - // Elaine 2008/6/20 - String err = createMatchInvCostDetail(inv, line, receiptLine); - if(err != null && err.length() > 0) return err; - // + matchInv++; } } // for all lines if (matchInv > 0) @@ -1922,92 +1917,7 @@ public class MInvoice extends X_C_Invoice implements DocAction setProcessed(true); setDocAction(DOCACTION_Close); return DocAction.STATUS_Completed; - } // completeIt - - // Elaine 2008/6/20 - private String createMatchInvCostDetail(MMatchInv inv, MInvoiceLine m_invoiceLine, MInOutLine m_receiptLine) - { - // Get Account Schemas to create MCostDetail - MAcctSchema[] acctschemas = MAcctSchema.getClientAcctSchema(getCtx(), getAD_Client_ID()); - for(int asn = 0; asn < acctschemas.length; asn++) - { - MAcctSchema as = acctschemas[asn]; - - boolean skip = false; - if (as.getAD_OrgOnly_ID() != 0) - { - if (as.getOnlyOrgs() == null) - as.setOnlyOrgs(MReportTree.getChildIDs(getCtx(), - 0, MAcctSchemaElement.ELEMENTTYPE_Organization, - as.getAD_OrgOnly_ID())); - - // Header Level Org - skip = as.isSkipOrg(getAD_Org_ID()); - // Line Level Org - skip = as.isSkipOrg(m_invoiceLine.getAD_Org_ID()); - } - if (skip) - continue; - - BigDecimal LineNetAmt = m_invoiceLine.getLineNetAmt(); - BigDecimal multiplier = inv.getQty() - .divide(m_invoiceLine.getQtyInvoiced(), 12, BigDecimal.ROUND_HALF_UP) - .abs(); - if (multiplier.compareTo(Env.ONE) != 0) - LineNetAmt = LineNetAmt.multiply(multiplier); - - // Source from Doc_MatchInv.createFacts(MAcctSchema) - // 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(), inv.get_TrxName()); - 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)); - } - } - - // 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) - { - return "AP Invoice not convertible - " + as.getName(); - } - } - - tAmt = tAmt.add(LineNetAmt); //Invoice Price - // 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(inv.getQty().negate()); // Qty is set to negative value - else - tQty = tQty.add(inv.getQty()); - - // Set Total Amount and Total Quantity from Matched Invoice - MCostDetail.createInvoice(as, getAD_Org_ID(), - inv.getM_Product_ID(), inv.getM_AttributeSetInstance_ID(), - m_invoiceLine.getC_InvoiceLine_ID(), 0, // No cost element - tAmt, tQty, getDescription(), inv.get_TrxName()); - // end MZ - // end - } - - return ""; - } - // + } // completeIt /** * Set the definite document number after completed diff --git a/base/src/org/compiere/model/MMatchInv.java b/base/src/org/compiere/model/MMatchInv.java index 76e9f8fb46..e1e2e56191 100644 --- a/base/src/org/compiere/model/MMatchInv.java +++ b/base/src/org/compiere/model/MMatchInv.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.Properties; import java.util.logging.Level; +import org.compiere.report.MReportTree; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; @@ -294,6 +295,29 @@ public class MMatchInv extends X_M_MatchInv return true; } // beforeSave + /** + * After Save. + * Set Order Qty Delivered/Invoiced + * @param newRecord new + * @param success success + * @return success + */ + protected boolean afterSave (boolean newRecord, boolean success) + { + if (newRecord && success) + { + // Elaine 2008/6/20 + String err = createMatchInvCostDetail(); + if(err != null && err.length() > 0) + { + s_log.warning(err); + return false; + } + } + // + return success; + } // afterSave + /** * Get the later Date Acct from invoice or shipment * @return date or null @@ -347,37 +371,9 @@ public class MMatchInv extends X_M_MatchInv { if (success) { - // MZ Goodwill - // update/delete Cost Detail and recalculate Current Cost - MCostDetail cd = MCostDetail.get (getCtx(), "C_InvoiceLine_ID=? AND M_AttributeSetInstance_ID=?", - getC_InvoiceLine_ID(), getM_AttributeSetInstance_ID(), get_TrxName()); - if (cd != null) - { - MInOut receipt = (new MInOutLine(getCtx(),getM_InOutLine_ID(),get_TrxName())).getParent(); - BigDecimal qty = getQty(); - if (receipt.getMovementType().equals(MInOut.MOVEMENTTYPE_VendorReturns)) - qty = getQty().negate(); - // - BigDecimal price = cd.getAmt().divide(cd.getQty(),12,BigDecimal.ROUND_HALF_UP); - cd.setDeltaAmt(price.multiply(qty.negate())); - cd.setDeltaQty(qty.negate()); - cd.setProcessed(false); - // - cd.setAmt(price.multiply(cd.getQty().subtract(qty))); - cd.setQty(cd.getQty().subtract(qty)); - if (!cd.isProcessed()) - { - MClient client = MClient.get(getCtx(), getAD_Client_ID()); - if (client.isCostImmediate()) - cd.process(); - } - if (cd.getQty().compareTo(Env.ZERO) == 0) - { - cd.setProcessed(false); - cd.delete(true); - } - } - // end MZ + // AZ Goodwill + deleteMatchInvCostDetail(); + // end AZ // Get Order and decrease invoices MInvoiceLine iLine = new MInvoiceLine (getCtx(), getC_InvoiceLine_ID(), get_TrxName()); @@ -407,4 +403,142 @@ public class MMatchInv extends X_M_MatchInv return success; } // afterDelete + + // Elaine 2008/6/20 + private String createMatchInvCostDetail() + { + MInvoiceLine invoiceLine = new MInvoiceLine (getCtx(), getC_InvoiceLine_ID(), get_TrxName()); + + // Get Account Schemas to create MCostDetail + MAcctSchema[] acctschemas = MAcctSchema.getClientAcctSchema(getCtx(), getAD_Client_ID()); + for(int asn = 0; asn < acctschemas.length; asn++) + { + MAcctSchema as = acctschemas[asn]; + + boolean skip = false; + if (as.getAD_OrgOnly_ID() != 0) + { + if (as.getOnlyOrgs() == null) + as.setOnlyOrgs(MReportTree.getChildIDs(getCtx(), + 0, MAcctSchemaElement.ELEMENTTYPE_Organization, + as.getAD_OrgOnly_ID())); + skip = as.isSkipOrg(getAD_Org_ID()); + } + if (skip) + continue; + + BigDecimal LineNetAmt = invoiceLine.getLineNetAmt(); + BigDecimal multiplier = getQty() + .divide(invoiceLine.getQtyInvoiced(), 12, BigDecimal.ROUND_HALF_UP) + .abs(); + if (multiplier.compareTo(Env.ONE) != 0) + LineNetAmt = LineNetAmt.multiply(multiplier); + + // Source from Doc_MatchInv.createFacts(MAcctSchema) + // 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(), invoiceLine.getC_InvoiceLine_ID(), get_TrxName()); + 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(invoiceLine.getQtyInvoiced(), 12, BigDecimal.ROUND_HALF_UP).abs(); + tAmt = tAmt.add(invoiceLine.getLineNetAmt().multiply(multiplier)); + } + } + tAmt = tAmt.add(LineNetAmt); //Invoice Price + + // Different currency + MInvoice invoice = 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) + { + return "AP Invoice not convertible - " + as.getName(); + } + } + + // set Qty to negative value when MovementType is Vendor Returns + MInOutLine receiptLine = new MInOutLine (getCtx(),getM_InOutLine_ID(), get_TrxName()); + MInOut receipt = 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()); + + // Set Total Amount and Total Quantity from Matched Invoice + MCostDetail.createInvoice(as, getAD_Org_ID(), + getM_Product_ID(), getM_AttributeSetInstance_ID(), + invoiceLine.getC_InvoiceLine_ID(), 0, // No cost element + tAmt, tQty, getDescription(), get_TrxName()); + // end MZ + } + + return ""; + } + // + //AZ Goodwill + private String deleteMatchInvCostDetail() + { + // Get Account Schemas to delete MCostDetail + MAcctSchema[] acctschemas = MAcctSchema.getClientAcctSchema(getCtx(), getAD_Client_ID()); + for(int asn = 0; asn < acctschemas.length; asn++) + { + MAcctSchema as = acctschemas[asn]; + + boolean skip = false; + if (as.getAD_OrgOnly_ID() != 0) + { + if (as.getOnlyOrgs() == null) + as.setOnlyOrgs(MReportTree.getChildIDs(getCtx(), + 0, MAcctSchemaElement.ELEMENTTYPE_Organization, + as.getAD_OrgOnly_ID())); + skip = as.isSkipOrg(getAD_Org_ID()); + } + if (skip) + continue; + + // update/delete Cost Detail and recalculate Current Cost + MCostDetail cd = MCostDetail.get (getCtx(), "C_InvoiceLine_ID=? AND M_AttributeSetInstance_ID=?", + getC_InvoiceLine_ID(), getM_AttributeSetInstance_ID(), get_TrxName()); + if (cd != null) + { + MInOut receipt = (new MInOutLine(getCtx(),getM_InOutLine_ID(),get_TrxName())).getParent(); + BigDecimal qty = getQty(); + if (receipt.getMovementType().equals(MInOut.MOVEMENTTYPE_VendorReturns)) + qty = getQty().negate(); + // + BigDecimal price = cd.getAmt().divide(cd.getQty(),12,BigDecimal.ROUND_HALF_UP); + cd.setDeltaAmt(price.multiply(qty.negate())); + cd.setDeltaQty(qty.negate()); + cd.setProcessed(false); + // + cd.setAmt(price.multiply(cd.getQty().subtract(qty))); + cd.setQty(cd.getQty().subtract(qty)); + if (!cd.isProcessed()) + { + MClient client = MClient.get(getCtx(), getAD_Client_ID()); + if (client.isCostImmediate()) + cd.process(); + } + if (cd.getQty().compareTo(Env.ZERO) == 0) + { + cd.setProcessed(false); + cd.delete(true); + } + } + } + + return ""; + } + } // MMatchInv diff --git a/base/src/org/compiere/model/MMatchPO.java b/base/src/org/compiere/model/MMatchPO.java index 49e5a09761..de5d299138 100644 --- a/base/src/org/compiere/model/MMatchPO.java +++ b/base/src/org/compiere/model/MMatchPO.java @@ -582,7 +582,7 @@ public class MMatchPO extends X_M_MatchPO if (newRecord && success) { // Elaine 2008/6/20 - String err = createMatchPOCostDetail(this, getOrderLine()); + String err = createMatchPOCostDetail(); if(err != null && err.length() > 0) { s_log.warning(err); @@ -693,32 +693,9 @@ public class MMatchPO extends X_M_MatchPO // (Reserved in VMatch and MInOut.completeIt) if (success && getC_OrderLine_ID() != 0) { - // MZ Goodwill - // update/delete Cost Detail and recalculate Current Cost - MCostDetail cd = MCostDetail.get (getCtx(), "C_OrderLine_ID=? AND M_AttributeSetInstance_ID=?", - getC_OrderLine_ID(), getM_AttributeSetInstance_ID(), get_TrxName()); - if (cd != null) - { - BigDecimal price = cd.getAmt().divide(cd.getQty(),12,BigDecimal.ROUND_HALF_UP); - cd.setDeltaAmt(price.multiply(getQty().negate())); - cd.setDeltaQty(getQty().negate()); - cd.setProcessed(false); - // - cd.setAmt(price.multiply(cd.getQty().subtract(getQty()))); - cd.setQty(cd.getQty().subtract(getQty())); - if (!cd.isProcessed()) - { - MClient client = MClient.get(getCtx(), getAD_Client_ID()); - if (client.isCostImmediate()) - cd.process(); - } - if (cd.getQty().compareTo(Env.ZERO) == 0) - { - cd.setProcessed(false); - cd.delete(true); - } - } - // end MZ + // AZ Goodwill + deleteMatchPOCostDetail(); + // end AZ MOrderLine orderLine = new MOrderLine (getCtx(), getC_OrderLine_ID(), get_TrxName()); if (getM_InOutLine_ID() != 0) @@ -821,8 +798,10 @@ public class MMatchPO extends X_M_MatchPO } // consolidate // Elaine 2008/6/20 - private String createMatchPOCostDetail(MMatchPO po, MOrderLine m_oLine) + private String createMatchPOCostDetail() { + MOrderLine oLine = getOrderLine(); + // Get Account Schemas to create MCostDetail MAcctSchema[] acctschemas = MAcctSchema.getClientAcctSchema(getCtx(), getAD_Client_ID()); for(int asn = 0; asn < acctschemas.length; asn++) @@ -836,35 +815,31 @@ public class MMatchPO extends X_M_MatchPO as.setOnlyOrgs(MReportTree.getChildIDs(getCtx(), 0, MAcctSchemaElement.ELEMENTTYPE_Organization, as.getAD_OrgOnly_ID())); - - // Header Level Org skip = as.isSkipOrg(getAD_Org_ID()); - // Line Level Org - skip = as.isSkipOrg(m_oLine.getAD_Org_ID()); } if (skip) continue; // Purchase Order Line - BigDecimal poCost = m_oLine.getPriceCost(); + BigDecimal poCost = oLine.getPriceCost(); if (poCost == null || poCost.signum() == 0) - poCost = m_oLine.getPriceActual(); + poCost = oLine.getPriceActual(); // Source from Doc_MatchPO.createFacts(MAcctSchema) - MInOutLine receiptLine = new MInOutLine (getCtx(), po.getM_InOutLine_ID(), po.get_TrxName()); + MInOutLine receiptLine = new MInOutLine (getCtx(), getM_InOutLine_ID(), get_TrxName()); MInOut inOut = receiptLine.getParent(); boolean isReturnTrx = inOut.getMovementType().equals(X_M_InOut.MOVEMENTTYPE_VendorReturns); // 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(), po.get_TrxName()); + MMatchPO[] mPO = MMatchPO.getOrderLine(getCtx(), oLine.getC_OrderLine_ID(), get_TrxName()); BigDecimal tQty = Env.ZERO; BigDecimal tAmt = Env.ZERO; for (int i = 0 ; i < mPO.length ; i++) { if (mPO[i].isPosted() - && mPO[i].getM_AttributeSetInstance_ID() == po.getM_AttributeSetInstance_ID() + && mPO[i].getM_AttributeSetInstance_ID() == getM_AttributeSetInstance_ID() && mPO[i].getM_MatchPO_ID() != get_ID()) { BigDecimal qty = (isReturnTrx ? mPO[i].getQty().negate() : mPO[i].getQty()); @@ -873,23 +848,23 @@ public class MMatchPO extends X_M_MatchPO } } - poCost = poCost.multiply(po.getQty()); // Delivered so far + poCost = poCost.multiply(getQty()); // Delivered so far tAmt = tAmt.add(isReturnTrx ? poCost.negate() : poCost); - tQty = tQty.add(isReturnTrx ? po.getQty().negate() : po.getQty()); + tQty = tQty.add(isReturnTrx ? getQty().negate() : getQty()); // Different currency String costingMethod = as.getCostingMethod(); - if (m_oLine.getC_Currency_ID() != as.getC_Currency_ID()) + if (oLine.getC_Currency_ID() != as.getC_Currency_ID()) { - MOrder order = m_oLine.getParent(); + MOrder order = oLine.getParent(); Timestamp dateAcct = order.getDateAcct(); if (MAcctSchema.COSTINGMETHOD_AveragePO.equals(costingMethod) || MAcctSchema.COSTINGMETHOD_LastPOPrice.equals(costingMethod) ) - dateAcct = po.getDateAcct(); //Movement Date + dateAcct = inOut.getDateAcct(); //Movement Date BigDecimal rate = MConversionRate.getRate( order.getC_Currency_ID(), as.getC_Currency_ID(), dateAcct, order.getC_ConversionType_ID(), - m_oLine.getAD_Client_ID(), m_oLine.getAD_Org_ID()); + oLine.getAD_Client_ID(), oLine.getAD_Org_ID()); if (rate == null) { return "Purchase Order not convertible - " + as.getName(); @@ -903,17 +878,65 @@ public class MMatchPO extends X_M_MatchPO } // Set Total Amount and Total Quantity from Matched PO - MCostDetail.createOrder(as, m_oLine.getAD_Org_ID(), - po.getM_Product_ID(), po.getM_AttributeSetInstance_ID(), - m_oLine.getC_OrderLine_ID(), 0, // no cost element + MCostDetail.createOrder(as, oLine.getAD_Org_ID(), + getM_Product_ID(), getM_AttributeSetInstance_ID(), + oLine.getC_OrderLine_ID(), 0, // no cost element tAmt, tQty, // Delivered - m_oLine.getDescription(), po.get_TrxName()); + oLine.getDescription(), get_TrxName()); // end MZ - // end } return ""; } - // + + //AZ Goodwill + private String deleteMatchPOCostDetail() + { + // Get Account Schemas to delete MCostDetail + MAcctSchema[] acctschemas = MAcctSchema.getClientAcctSchema(getCtx(), getAD_Client_ID()); + for(int asn = 0; asn < acctschemas.length; asn++) + { + MAcctSchema as = acctschemas[asn]; + + boolean skip = false; + if (as.getAD_OrgOnly_ID() != 0) + { + if (as.getOnlyOrgs() == null) + as.setOnlyOrgs(MReportTree.getChildIDs(getCtx(), + 0, MAcctSchemaElement.ELEMENTTYPE_Organization, + as.getAD_OrgOnly_ID())); + skip = as.isSkipOrg(getAD_Org_ID()); + } + if (skip) + continue; + + // update/delete Cost Detail and recalculate Current Cost + MCostDetail cd = MCostDetail.get (getCtx(), "C_OrderLine_ID=? AND M_AttributeSetInstance_ID=?", + getC_OrderLine_ID(), getM_AttributeSetInstance_ID(), get_TrxName()); + if (cd != null) + { + BigDecimal price = cd.getAmt().divide(cd.getQty(),12,BigDecimal.ROUND_HALF_UP); + cd.setDeltaAmt(price.multiply(getQty().negate())); + cd.setDeltaQty(getQty().negate()); + cd.setProcessed(false); + // + cd.setAmt(price.multiply(cd.getQty().subtract(getQty()))); + cd.setQty(cd.getQty().subtract(getQty())); + if (!cd.isProcessed()) + { + MClient client = MClient.get(getCtx(), getAD_Client_ID()); + if (client.isCostImmediate()) + cd.process(); + } + if (cd.getQty().compareTo(Env.ZERO) == 0) + { + cd.setProcessed(false); + cd.delete(true); + } + } + } + + return ""; + } } // MMatchPO