IDEMPIERE-378 Implement Reverse Accrual . Fixed reverse accrual not working for inventory move, payment and physical inventory.
This commit is contained in:
parent
78c17bf90f
commit
14f3e0b0ff
|
@ -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@");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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()))
|
||||||
{
|
{
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue