IDEMPIERE-378 Implement Reverse Accrual . Fixed reverse accrual not working for inventory move, payment and physical inventory.

This commit is contained in:
Heng Sin Low 2012-12-03 17:04:23 +08:00
parent 78c17bf90f
commit 14f3e0b0ff
6 changed files with 103 additions and 58 deletions

View File

@ -419,7 +419,7 @@ public final class MAllocationHdr extends X_C_AllocationHdr implements DocAction
.setClient_ID() .setClient_ID()
.setParameters(line.getC_Invoice_ID(), "Y", X_C_Invoice.DOCSTATUS_Voided, X_C_Invoice.DOCSTATUS_Reversed) .setParameters(line.getC_Invoice_ID(), "Y", X_C_Invoice.DOCSTATUS_Voided, X_C_Invoice.DOCSTATUS_Reversed)
.match(); .match();
if(InvoiceIsPaid) if(InvoiceIsPaid && line.getAmount().signum() > 0)
throw new AdempiereException("@ValidationError@ @C_Invoice_ID@ @IsPaid@"); throw new AdempiereException("@ValidationError@ @C_Invoice_ID@ @IsPaid@");
} }
} }

View File

@ -51,6 +51,9 @@ public class MInventory extends X_M_Inventory implements DocAction
*/ */
private static final long serialVersionUID = -7137974064086172763L; private static final long serialVersionUID = -7137974064086172763L;
/** Reversal Indicator */
public static String REVERSE_INDICATOR = "^";
/** /**
* Get Inventory from Cache * Get Inventory from Cache
* @param ctx context * @param ctx context
@ -771,6 +774,7 @@ public class MInventory extends X_M_Inventory implements DocAction
// Deep Copy // Deep Copy
MInventory reversal = new MInventory(getCtx(), 0, get_TrxName()); MInventory reversal = new MInventory(getCtx(), 0, get_TrxName());
copyValues(this, reversal, getAD_Client_ID(), getAD_Org_ID()); copyValues(this, reversal, getAD_Client_ID(), getAD_Org_ID());
reversal.setDocumentNo(getDocumentNo() + REVERSE_INDICATOR); // indicate reversals
reversal.setMovementDate(reversalDate); reversal.setMovementDate(reversalDate);
reversal.setDocStatus(DOCSTATUS_Drafted); reversal.setDocStatus(DOCSTATUS_Drafted);
reversal.setDocAction(DOCACTION_Complete); reversal.setDocAction(DOCACTION_Complete);
@ -863,7 +867,7 @@ public class MInventory extends X_M_Inventory implements DocAction
m_processMsg = reversal.getDocumentNo(); m_processMsg = reversal.getDocumentNo();
return false; return true;
} // reverseAccrualIt } // reverseAccrualIt
/** /**

View File

@ -691,11 +691,32 @@ public class MMovement extends X_M_Movement implements DocAction
if (m_processMsg != null) if (m_processMsg != null)
return false; 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()); 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@"; m_processMsg = "@PeriodClosed@";
return false; return null;
} }
// Deep Copy // Deep Copy
@ -707,6 +728,7 @@ public class MMovement extends X_M_Movement implements DocAction
reversal.setIsInTransit (false); reversal.setIsInTransit (false);
reversal.setPosted(false); reversal.setPosted(false);
reversal.setProcessed(false); reversal.setProcessed(false);
reversal.setMovementDate(reversalDate);
reversal.setDocumentNo(getDocumentNo() + REVERSE_INDICATOR); // indicate reversals reversal.setDocumentNo(getDocumentNo() + REVERSE_INDICATOR); // indicate reversals
reversal.addDescription("{->" + getDocumentNo() + ")"); reversal.addDescription("{->" + getDocumentNo() + ")");
//FR [ 1948157 ] //FR [ 1948157 ]
@ -714,7 +736,7 @@ public class MMovement extends X_M_Movement implements DocAction
if (!reversal.save()) if (!reversal.save())
{ {
m_processMsg = "Could not create Movement Reversal"; m_processMsg = "Could not create Movement Reversal";
return false; return null;
} }
reversal.setReversal(true); reversal.setReversal(true);
// Reverse Line Qty // Reverse Line Qty
@ -737,7 +759,7 @@ public class MMovement extends X_M_Movement implements DocAction
if (!rLine.save()) if (!rLine.save())
{ {
m_processMsg = "Could not create Movement Reversal Line"; m_processMsg = "Could not create Movement Reversal Line";
return false; return null;
} }
//We need to copy MA //We need to copy MA
@ -759,18 +781,12 @@ public class MMovement extends X_M_Movement implements DocAction
if (!reversal.processIt(DocAction.ACTION_Complete)) if (!reversal.processIt(DocAction.ACTION_Complete))
{ {
m_processMsg = "Reversal ERROR: " + reversal.getProcessMsg(); m_processMsg = "Reversal ERROR: " + reversal.getProcessMsg();
return false; return null;
} }
reversal.closeIt(); reversal.closeIt();
reversal.setDocStatus(DOCSTATUS_Reversed); reversal.setDocStatus(DOCSTATUS_Reversed);
reversal.setDocAction(DOCACTION_None); reversal.setDocAction(DOCACTION_None);
reversal.saveEx(); 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) // Update Reversed (this)
addDescription("(" + reversal.getDocumentNo() + "<-)"); addDescription("(" + reversal.getDocumentNo() + "<-)");
@ -779,9 +795,9 @@ public class MMovement extends X_M_Movement implements DocAction
setProcessed(true); setProcessed(true);
setDocStatus(DOCSTATUS_Reversed); // may come from void setDocStatus(DOCSTATUS_Reversed); // may come from void
setDocAction(DOCACTION_None); setDocAction(DOCACTION_None);
return true; return reversal;
} // reverseCorrectionIt }
/** /**
* Reverse Accrual - none * Reverse Accrual - none
@ -795,12 +811,18 @@ public class MMovement extends X_M_Movement implements DocAction
if (m_processMsg != null) if (m_processMsg != null)
return false; return false;
MMovement reversal = reverse(true);
if (reversal == null)
return false;
m_processMsg = reversal.getDocumentNo();
// After reverseAccrual // After reverseAccrual
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSEACCRUAL); m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSEACCRUAL);
if (m_processMsg != null) if (m_processMsg != null)
return false; return false;
return false; return true;
} // reverseAccrualIt } // reverseAccrualIt
/** /**

View File

@ -2306,8 +2306,9 @@ public final class MPayment extends X_C_Payment
/** /**
* De-allocate Payment. * De-allocate Payment.
* Unkink Invoices and Orders and delete Allocations * Unkink Invoices and Orders and delete Allocations
* @param accrual
*/ */
private void deAllocate() private void deAllocate(boolean accrual)
{ {
if (getC_Order_ID() != 0) if (getC_Order_ID() != 0)
setC_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++) for (int i = 0; i < allocations.length; i++)
{ {
allocations[i].set_TrxName(get_TrxName()); allocations[i].set_TrxName(get_TrxName());
allocations[i].setDocAction(DocAction.ACTION_Reverse_Correct); if (accrual)
if (!allocations[i].processIt(DocAction.ACTION_Reverse_Correct)) {
throw new AdempiereException(allocations[i].getProcessMsg()); 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(); allocations[i].saveEx();
} }
@ -2349,7 +2359,8 @@ public final class MPayment extends X_C_Payment
} }
// //
setC_Invoice_ID(0); setC_Invoice_ID(0);
setIsAllocated(false); if (!accrual)
setIsAllocated(false);
} // deallocate } // deallocate
/** /**
@ -2393,7 +2404,7 @@ public final class MPayment extends X_C_Payment
setOverUnderAmt(Env.ZERO); setOverUnderAmt(Env.ZERO);
setIsAllocated(false); setIsAllocated(false);
// Unlink & De-Allocate // Unlink & De-Allocate
deAllocate(); deAllocate(false);
} }
else else
return reverseCorrectIt(); return reverseCorrectIt();
@ -2517,7 +2528,7 @@ public final class MPayment extends X_C_Payment
reversal.saveEx(get_TrxName()); reversal.saveEx(get_TrxName());
// Unlink & De-Allocate // Unlink & De-Allocate
deAllocate(); deAllocate(accrual);
setIsReconciled (reconciled); setIsReconciled (reconciled);
setIsAllocated (true); // the allocation below is overwritten setIsAllocated (true); // the allocation below is overwritten
// Set Status // Set Status
@ -2528,38 +2539,41 @@ public final class MPayment extends X_C_Payment
//FR [ 1948157 ] //FR [ 1948157 ]
setReversal_ID(reversal.getC_Payment_ID()); 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()); 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 // Update BPartner
if (getC_BPartner_ID() != 0) if (getC_BPartner_ID() != 0)
@ -2610,7 +2624,7 @@ public final class MPayment extends X_C_Payment
return false; return false;
m_processMsg = info.toString(); m_processMsg = info.toString();
return false; return true;
} // reverseAccrualIt } // reverseAccrualIt
/** /**

View File

@ -966,8 +966,9 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
ProcessModalDialog dialog = (ProcessModalDialog) event.getTarget(); ProcessModalDialog dialog = (ProcessModalDialog) event.getTarget();
onModalClose(dialog.getProcessInfo()); onModalClose(dialog.getProcessInfo());
String s = breadCrumb.getStatusLine(); String s = breadCrumb.getStatusLine();
boolean b = breadCrumb.getStatusError();
onRefresh(true, false); onRefresh(true, false);
breadCrumb.setStatusLine(s); breadCrumb.setStatusLine(s, b);
} }
else if (ADTabpanel.ON_DYNAMIC_DISPLAY_EVENT.equals(event.getName())) else if (ADTabpanel.ON_DYNAMIC_DISPLAY_EVENT.equals(event.getName()))
{ {

View File

@ -347,7 +347,7 @@ public class BreadCrumb extends Div implements EventListener<Event>{
if (error) if (error)
image = new Image(ERROR_INDICATOR_IMAGE); image = new Image(ERROR_INDICATOR_IMAGE);
else else
image = new Image(INFO_INDICATOR_IMAGE); image = new Image(INFO_INDICATOR_IMAGE);
image.setAttribute("org.zkoss.zul.image.preload", Boolean.TRUE); image.setAttribute("org.zkoss.zul.image.preload", Boolean.TRUE);
messageContainer.appendChild(image); messageContainer.appendChild(image);
@ -410,6 +410,10 @@ public class BreadCrumb extends Div implements EventListener<Event>{
public String getStatusLine() { public String getStatusLine() {
return m_statusText; return m_statusText;
} }
public boolean getStatusError() {
return m_statusError;
}
private void createPopup() { private void createPopup() {
msgPopupCnt = new Div(); msgPopupCnt = new Div();