From 14f3e0b0ff85ae68df5c491ec4dc8b25a88d4602 Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Mon, 3 Dec 2012 17:04:23 +0800 Subject: [PATCH] IDEMPIERE-378 Implement Reverse Accrual . Fixed reverse accrual not working for inventory move, payment and physical inventory. --- .../org/compiere/model/MAllocationHdr.java | 2 +- .../src/org/compiere/model/MInventory.java | 6 +- .../src/org/compiere/model/MMovement.java | 52 ++++++++--- .../src/org/compiere/model/MPayment.java | 92 +++++++++++-------- .../adwindow/AbstractADWindowContent.java | 3 +- .../adempiere/webui/adwindow/BreadCrumb.java | 6 +- 6 files changed, 103 insertions(+), 58 deletions(-) diff --git a/org.adempiere.base/src/org/compiere/model/MAllocationHdr.java b/org.adempiere.base/src/org/compiere/model/MAllocationHdr.java index b562053c6f..d8655f2f58 100644 --- a/org.adempiere.base/src/org/compiere/model/MAllocationHdr.java +++ b/org.adempiere.base/src/org/compiere/model/MAllocationHdr.java @@ -419,7 +419,7 @@ public final class MAllocationHdr extends X_C_AllocationHdr implements DocAction .setClient_ID() .setParameters(line.getC_Invoice_ID(), "Y", X_C_Invoice.DOCSTATUS_Voided, X_C_Invoice.DOCSTATUS_Reversed) .match(); - if(InvoiceIsPaid) + if(InvoiceIsPaid && line.getAmount().signum() > 0) throw new AdempiereException("@ValidationError@ @C_Invoice_ID@ @IsPaid@"); } } diff --git a/org.adempiere.base/src/org/compiere/model/MInventory.java b/org.adempiere.base/src/org/compiere/model/MInventory.java index 774d2fb48a..ac72eecfcd 100644 --- a/org.adempiere.base/src/org/compiere/model/MInventory.java +++ b/org.adempiere.base/src/org/compiere/model/MInventory.java @@ -51,6 +51,9 @@ public class MInventory extends X_M_Inventory implements DocAction */ private static final long serialVersionUID = -7137974064086172763L; + /** Reversal Indicator */ + public static String REVERSE_INDICATOR = "^"; + /** * Get Inventory from Cache * @param ctx context @@ -771,6 +774,7 @@ public class MInventory extends X_M_Inventory implements DocAction // Deep Copy MInventory reversal = new MInventory(getCtx(), 0, get_TrxName()); copyValues(this, reversal, getAD_Client_ID(), getAD_Org_ID()); + reversal.setDocumentNo(getDocumentNo() + REVERSE_INDICATOR); // indicate reversals reversal.setMovementDate(reversalDate); reversal.setDocStatus(DOCSTATUS_Drafted); reversal.setDocAction(DOCACTION_Complete); @@ -863,7 +867,7 @@ public class MInventory extends X_M_Inventory implements DocAction m_processMsg = reversal.getDocumentNo(); - return false; + return true; } // reverseAccrualIt /** diff --git a/org.adempiere.base/src/org/compiere/model/MMovement.java b/org.adempiere.base/src/org/compiere/model/MMovement.java index 03236c9fe9..5af524b9e0 100644 --- a/org.adempiere.base/src/org/compiere/model/MMovement.java +++ b/org.adempiere.base/src/org/compiere/model/MMovement.java @@ -691,11 +691,32 @@ public class MMovement extends X_M_Movement implements DocAction if (m_processMsg != null) return false; + MMovement reversal = reverse(false); + if (reversal == null) + return false; + + m_processMsg = reversal.getDocumentNo(); + + // After reverseCorrect + m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSECORRECT); + if (m_processMsg != null) + return false; + + return true; + } // reverseCorrectionIt + + private MMovement reverse(boolean accrual) + { + Timestamp reversalDate = accrual ? Env.getContextAsDate(getCtx(), "#Date") : getMovementDate(); + if (reversalDate == null) { + reversalDate = new Timestamp(System.currentTimeMillis()); + } + MDocType dt = MDocType.get(getCtx(), getC_DocType_ID()); - if (!MPeriod.isOpen(getCtx(), getMovementDate(), dt.getDocBaseType(), getAD_Org_ID())) + if (!MPeriod.isOpen(getCtx(), reversalDate, dt.getDocBaseType(), getAD_Org_ID())) { m_processMsg = "@PeriodClosed@"; - return false; + return null; } // Deep Copy @@ -707,6 +728,7 @@ public class MMovement extends X_M_Movement implements DocAction reversal.setIsInTransit (false); reversal.setPosted(false); reversal.setProcessed(false); + reversal.setMovementDate(reversalDate); reversal.setDocumentNo(getDocumentNo() + REVERSE_INDICATOR); // indicate reversals reversal.addDescription("{->" + getDocumentNo() + ")"); //FR [ 1948157 ] @@ -714,7 +736,7 @@ public class MMovement extends X_M_Movement implements DocAction if (!reversal.save()) { m_processMsg = "Could not create Movement Reversal"; - return false; + return null; } reversal.setReversal(true); // Reverse Line Qty @@ -737,7 +759,7 @@ public class MMovement extends X_M_Movement implements DocAction if (!rLine.save()) { m_processMsg = "Could not create Movement Reversal Line"; - return false; + return null; } //We need to copy MA @@ -759,18 +781,12 @@ public class MMovement extends X_M_Movement implements DocAction if (!reversal.processIt(DocAction.ACTION_Complete)) { m_processMsg = "Reversal ERROR: " + reversal.getProcessMsg(); - return false; + return null; } reversal.closeIt(); reversal.setDocStatus(DOCSTATUS_Reversed); reversal.setDocAction(DOCACTION_None); reversal.saveEx(); - m_processMsg = reversal.getDocumentNo(); - - // After reverseCorrect - m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSECORRECT); - if (m_processMsg != null) - return false; // Update Reversed (this) addDescription("(" + reversal.getDocumentNo() + "<-)"); @@ -779,9 +795,9 @@ public class MMovement extends X_M_Movement implements DocAction setProcessed(true); setDocStatus(DOCSTATUS_Reversed); // may come from void setDocAction(DOCACTION_None); - - return true; - } // reverseCorrectionIt + + return reversal; + } /** * Reverse Accrual - none @@ -795,12 +811,18 @@ public class MMovement extends X_M_Movement implements DocAction if (m_processMsg != null) return false; + MMovement reversal = reverse(true); + if (reversal == null) + return false; + + m_processMsg = reversal.getDocumentNo(); + // After reverseAccrual m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSEACCRUAL); if (m_processMsg != null) return false; - return false; + return true; } // reverseAccrualIt /** diff --git a/org.adempiere.base/src/org/compiere/model/MPayment.java b/org.adempiere.base/src/org/compiere/model/MPayment.java index 053eb8455a..c576eb7de1 100644 --- a/org.adempiere.base/src/org/compiere/model/MPayment.java +++ b/org.adempiere.base/src/org/compiere/model/MPayment.java @@ -2306,8 +2306,9 @@ public final class MPayment extends X_C_Payment /** * De-allocate Payment. * Unkink Invoices and Orders and delete Allocations + * @param accrual */ - private void deAllocate() + private void deAllocate(boolean accrual) { if (getC_Order_ID() != 0) setC_Order_ID(0); @@ -2320,9 +2321,18 @@ public final class MPayment extends X_C_Payment for (int i = 0; i < allocations.length; i++) { allocations[i].set_TrxName(get_TrxName()); - allocations[i].setDocAction(DocAction.ACTION_Reverse_Correct); - if (!allocations[i].processIt(DocAction.ACTION_Reverse_Correct)) - throw new AdempiereException(allocations[i].getProcessMsg()); + if (accrual) + { + allocations[i].setDocAction(DocAction.ACTION_Reverse_Accrual); + if (!allocations[i].processIt(DocAction.ACTION_Reverse_Accrual)) + throw new AdempiereException(allocations[i].getProcessMsg()); + } + else + { + allocations[i].setDocAction(DocAction.ACTION_Reverse_Correct); + if (!allocations[i].processIt(DocAction.ACTION_Reverse_Correct)) + throw new AdempiereException(allocations[i].getProcessMsg()); + } allocations[i].saveEx(); } @@ -2349,7 +2359,8 @@ public final class MPayment extends X_C_Payment } // setC_Invoice_ID(0); - setIsAllocated(false); + if (!accrual) + setIsAllocated(false); } // deallocate /** @@ -2393,7 +2404,7 @@ public final class MPayment extends X_C_Payment setOverUnderAmt(Env.ZERO); setIsAllocated(false); // Unlink & De-Allocate - deAllocate(); + deAllocate(false); } else return reverseCorrectIt(); @@ -2517,7 +2528,7 @@ public final class MPayment extends X_C_Payment reversal.saveEx(get_TrxName()); // Unlink & De-Allocate - deAllocate(); + deAllocate(accrual); setIsReconciled (reconciled); setIsAllocated (true); // the allocation below is overwritten // Set Status @@ -2528,38 +2539,41 @@ public final class MPayment extends X_C_Payment //FR [ 1948157 ] setReversal_ID(reversal.getC_Payment_ID()); - // Create automatic Allocation - MAllocationHdr alloc = new MAllocationHdr (getCtx(), false, - getDateTrx(), getC_Currency_ID(), - Msg.translate(getCtx(), "C_Payment_ID") + ": " + reversal.getDocumentNo(), get_TrxName()); - alloc.setAD_Org_ID(getAD_Org_ID()); - if (!alloc.save()) - log.warning("Automatic allocation - hdr not saved"); - else - { - // Original Allocation - MAllocationLine aLine = new MAllocationLine (alloc, getPayAmt(true), - Env.ZERO, Env.ZERO, Env.ZERO); - aLine.setDocInfo(getC_BPartner_ID(), 0, 0); - aLine.setPaymentInfo(getC_Payment_ID(), 0); - if (!aLine.save(get_TrxName())) - log.warning("Automatic allocation - line not saved"); - // Reversal Allocation - aLine = new MAllocationLine (alloc, reversal.getPayAmt(true), - Env.ZERO, Env.ZERO, Env.ZERO); - aLine.setDocInfo(reversal.getC_BPartner_ID(), 0, 0); - aLine.setPaymentInfo(reversal.getC_Payment_ID(), 0); - if (!aLine.save(get_TrxName())) - log.warning("Automatic allocation - reversal line not saved"); - } - // added AdempiereException by zuhri - if (!alloc.processIt(DocAction.ACTION_Complete)) - throw new AdempiereException("Failed when processing document - " + alloc.getProcessMsg()); - // end added - alloc.saveEx(get_TrxName()); - // StringBuilder info = new StringBuilder(reversal.getDocumentNo()); - info.append(" - @C_AllocationHdr_ID@: ").append(alloc.getDocumentNo()); + if (!accrual) + { + // Create automatic Allocation + MAllocationHdr alloc = new MAllocationHdr (getCtx(), false, + getDateTrx(), getC_Currency_ID(), + Msg.translate(getCtx(), "C_Payment_ID") + ": " + reversal.getDocumentNo(), get_TrxName()); + alloc.setAD_Org_ID(getAD_Org_ID()); + if (!alloc.save()) + log.warning("Automatic allocation - hdr not saved"); + else + { + // Original Allocation + MAllocationLine aLine = new MAllocationLine (alloc, getPayAmt(true), + Env.ZERO, Env.ZERO, Env.ZERO); + aLine.setDocInfo(getC_BPartner_ID(), 0, 0); + aLine.setPaymentInfo(getC_Payment_ID(), 0); + if (!aLine.save(get_TrxName())) + log.warning("Automatic allocation - line not saved"); + // Reversal Allocation + aLine = new MAllocationLine (alloc, reversal.getPayAmt(true), + Env.ZERO, Env.ZERO, Env.ZERO); + aLine.setDocInfo(reversal.getC_BPartner_ID(), 0, 0); + aLine.setPaymentInfo(reversal.getC_Payment_ID(), 0); + if (!aLine.save(get_TrxName())) + log.warning("Automatic allocation - reversal line not saved"); + } + // added AdempiereException by zuhri + if (!alloc.processIt(DocAction.ACTION_Complete)) + throw new AdempiereException("Failed when processing document - " + alloc.getProcessMsg()); + // end added + alloc.saveEx(get_TrxName()); + // + info.append(" - @C_AllocationHdr_ID@: ").append(alloc.getDocumentNo()); + } // Update BPartner if (getC_BPartner_ID() != 0) @@ -2610,7 +2624,7 @@ public final class MPayment extends X_C_Payment return false; m_processMsg = info.toString(); - return false; + return true; } // reverseAccrualIt /** diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java index 4ef8114398..ba9b61b5a6 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java @@ -966,8 +966,9 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements ProcessModalDialog dialog = (ProcessModalDialog) event.getTarget(); onModalClose(dialog.getProcessInfo()); String s = breadCrumb.getStatusLine(); + boolean b = breadCrumb.getStatusError(); onRefresh(true, false); - breadCrumb.setStatusLine(s); + breadCrumb.setStatusLine(s, b); } else if (ADTabpanel.ON_DYNAMIC_DISPLAY_EVENT.equals(event.getName())) { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/BreadCrumb.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/BreadCrumb.java index ec6471b78d..08d5881af3 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/BreadCrumb.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/BreadCrumb.java @@ -347,7 +347,7 @@ public class BreadCrumb extends Div implements EventListener{ if (error) image = new Image(ERROR_INDICATOR_IMAGE); else - image = new Image(INFO_INDICATOR_IMAGE); + image = new Image(INFO_INDICATOR_IMAGE); image.setAttribute("org.zkoss.zul.image.preload", Boolean.TRUE); messageContainer.appendChild(image); @@ -410,6 +410,10 @@ public class BreadCrumb extends Div implements EventListener{ public String getStatusLine() { return m_statusText; } + + public boolean getStatusError() { + return m_statusError; + } private void createPopup() { msgPopupCnt = new Div();