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()
.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@");
}
}

View File

@ -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
/**

View File

@ -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
/**

View File

@ -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
/**

View File

@ -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()))
{

View File

@ -347,7 +347,7 @@ public class BreadCrumb extends Div implements EventListener<Event>{
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<Event>{
public String getStatusLine() {
return m_statusText;
}
public boolean getStatusError() {
return m_statusError;
}
private void createPopup() {
msgPopupCnt = new Div();