IDEMPIERE-5723 NPE when allocate has both AR and AP invoice (#1842)
* IDEMPIERE-5723 NPE when allocate has both AR and AP invoice base on patch from gauravsontakke * IDEMPIERE-5723 NPE when allocate has both AR and AP invoice (fix code review) https://github.com/idempiere/idempiere/pull/1842#pullrequestreview-1429618616 * IDEMPIERE-5723 NPE when allocate has both AR and AP invoice (check Accrual) createInvoiceGainLoss isn't yet test for non accrual so at check for accrual to consistent with above code
This commit is contained in:
parent
116b5b4db1
commit
dfe2fff6cd
|
@ -21,8 +21,9 @@ import java.math.RoundingMode;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Hashtable;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import org.compiere.model.MAccount;
|
import org.compiere.model.MAccount;
|
||||||
|
@ -190,6 +191,8 @@ public class Doc_AllocationHdr extends Doc
|
||||||
Fact factForRGL = new Fact(this, as, Fact.POST_Actual); // dummy fact (not posted) to calculate Realized Gain & Loss
|
Fact factForRGL = new Fact(this, as, Fact.POST_Actual); // dummy fact (not posted) to calculate Realized Gain & Loss
|
||||||
boolean isInterOrg = isInterOrg(as);
|
boolean isInterOrg = isInterOrg(as);
|
||||||
MAccount bpAcct = null; // Liability/Receivables
|
MAccount bpAcct = null; // Liability/Receivables
|
||||||
|
MAccount bpAcctAr = null;
|
||||||
|
MAccount bpAcctAp = null;
|
||||||
|
|
||||||
for (int i = 0; i < p_lines.length; i++)
|
for (int i = 0; i < p_lines.length; i++)
|
||||||
{
|
{
|
||||||
|
@ -324,7 +327,9 @@ public class Doc_AllocationHdr extends Doc
|
||||||
// AR Invoice Amount CR
|
// AR Invoice Amount CR
|
||||||
if (as.isAccrual())
|
if (as.isAccrual())
|
||||||
{
|
{
|
||||||
bpAcct = getAccount(Doc.ACCTTYPE_C_Receivable, as);
|
if (bpAcctAr == null)
|
||||||
|
bpAcctAr = getAccount(Doc.ACCTTYPE_C_Receivable, as);
|
||||||
|
bpAcct = bpAcctAr;
|
||||||
fl = fact.createLine (line, bpAcct,
|
fl = fact.createLine (line, bpAcct,
|
||||||
getC_Currency_ID(), null, allocationSource); // payment currency
|
getC_Currency_ID(), null, allocationSource); // payment currency
|
||||||
if (fl != null)
|
if (fl != null)
|
||||||
|
@ -377,7 +382,9 @@ public class Doc_AllocationHdr extends Doc
|
||||||
// AP Invoice Amount DR
|
// AP Invoice Amount DR
|
||||||
if (as.isAccrual())
|
if (as.isAccrual())
|
||||||
{
|
{
|
||||||
bpAcct = getAccount(Doc.ACCTTYPE_V_Liability, as);
|
if (bpAcctAp == null)
|
||||||
|
bpAcctAp = getAccount(Doc.ACCTTYPE_V_Liability, as);
|
||||||
|
bpAcct = bpAcctAp;
|
||||||
fl = fact.createLine (line, bpAcct,
|
fl = fact.createLine (line, bpAcct,
|
||||||
getC_Currency_ID(), allocationSource, null); // payment currency
|
getC_Currency_ID(), allocationSource, null); // payment currency
|
||||||
if (fl != null)
|
if (fl != null)
|
||||||
|
@ -456,7 +463,7 @@ public class Doc_AllocationHdr extends Doc
|
||||||
}
|
}
|
||||||
|
|
||||||
// Realized Gain & Loss
|
// Realized Gain & Loss
|
||||||
if (invoice != null
|
if (invoice != null && as.isAccrual()
|
||||||
&& (getC_Currency_ID() != as.getC_Currency_ID() // payment allocation in foreign currency
|
&& (getC_Currency_ID() != as.getC_Currency_ID() // payment allocation in foreign currency
|
||||||
|| getC_Currency_ID() != line.getInvoiceC_Currency_ID())) // allocation <> invoice currency
|
|| getC_Currency_ID() != line.getInvoiceC_Currency_ID())) // allocation <> invoice currency
|
||||||
{
|
{
|
||||||
|
@ -479,7 +486,7 @@ public class Doc_AllocationHdr extends Doc
|
||||||
// rounding adjustment
|
// rounding adjustment
|
||||||
if (getC_Currency_ID() != as.getC_Currency_ID())
|
if (getC_Currency_ID() != as.getC_Currency_ID())
|
||||||
{
|
{
|
||||||
p_Error = createInvoiceRoundingCorrection (as, fact, bpAcct);
|
p_Error = createInvoiceRoundingCorrection (as, fact, bpAcctAr, bpAcctAp);
|
||||||
if (p_Error != null)
|
if (p_Error != null)
|
||||||
return null;
|
return null;
|
||||||
p_Error = createPaymentRoundingCorrection (as, fact);
|
p_Error = createPaymentRoundingCorrection (as, fact);
|
||||||
|
@ -1065,26 +1072,30 @@ public class Doc_AllocationHdr extends Doc
|
||||||
* @param acct account
|
* @param acct account
|
||||||
* @return Error Message or null if OK
|
* @return Error Message or null if OK
|
||||||
*/
|
*/
|
||||||
private String createInvoiceRoundingCorrection (MAcctSchema as, Fact fact, MAccount acct)
|
private String createInvoiceRoundingCorrection (MAcctSchema as, Fact fact, MAccount acctAr, MAccount acctAp)
|
||||||
{
|
{
|
||||||
ArrayList<MInvoice> invList = new ArrayList<MInvoice>();
|
Map<Integer, MInvoice> invList = new HashMap<>();
|
||||||
Hashtable<Integer, Integer> htInvAllocLine = new Hashtable<Integer, Integer>();
|
Map<Integer, Integer> htInvAllocLine = new HashMap<>();
|
||||||
for (int i = 0; i < p_lines.length; i++)
|
for (int i = 0; i < p_lines.length; i++)
|
||||||
{
|
{
|
||||||
MInvoice invoice = null;
|
MInvoice invoice = null;
|
||||||
DocLine_Allocation line = (DocLine_Allocation)p_lines[i];
|
DocLine_Allocation line = (DocLine_Allocation)p_lines[i];
|
||||||
if (line.getC_Invoice_ID() != 0)
|
|
||||||
{
|
if (line.getC_Invoice_ID() == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (invList.containsKey(line.getC_Invoice_ID())){
|
||||||
|
log.severe(line.getC_Invoice_ID() + ":same invoice included in more than one allocation line");
|
||||||
|
}else {
|
||||||
invoice = new MInvoice (getCtx(), line.getC_Invoice_ID(), getTrxName());
|
invoice = new MInvoice (getCtx(), line.getC_Invoice_ID(), getTrxName());
|
||||||
if (!invList.contains(invoice))
|
invList.put(invoice.getC_Invoice_ID(), invoice);
|
||||||
invList.add(invoice);
|
|
||||||
htInvAllocLine.put(invoice.getC_Invoice_ID(), line.get_ID());
|
htInvAllocLine.put(invoice.getC_Invoice_ID(), line.get_ID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Hashtable<Integer, BigDecimal> htInvSource = new Hashtable<Integer, BigDecimal>();
|
Map<Integer, BigDecimal> htInvSource = new HashMap<>();
|
||||||
Hashtable<Integer, BigDecimal> htInvAccounted = new Hashtable<Integer, BigDecimal>();
|
Map<Integer, BigDecimal> htInvAccounted = new HashMap<>();
|
||||||
for (MInvoice invoice : invList)
|
for (MInvoice invoice : invList.values())
|
||||||
{
|
{
|
||||||
StringBuilder sql = new StringBuilder()
|
StringBuilder sql = new StringBuilder()
|
||||||
.append("SELECT SUM(AmtSourceDr), SUM(AmtAcctDr), SUM(AmtSourceCr), SUM(AmtAcctCr)")
|
.append("SELECT SUM(AmtSourceDr), SUM(AmtAcctDr), SUM(AmtSourceCr), SUM(AmtAcctCr)")
|
||||||
|
@ -1093,7 +1104,7 @@ public class Doc_AllocationHdr extends Doc
|
||||||
.append(" AND C_AcctSchema_ID=?")
|
.append(" AND C_AcctSchema_ID=?")
|
||||||
.append(" AND Account_ID=?")
|
.append(" AND Account_ID=?")
|
||||||
.append(" AND PostingType='A'");
|
.append(" AND PostingType='A'");
|
||||||
|
MAccount acct = invoice.isSOTrx() ? acctAr : acctAp;
|
||||||
// For Invoice
|
// For Invoice
|
||||||
List<Object> valuesInv = DB.getSQLValueObjectsEx(getTrxName(), sql.toString(),
|
List<Object> valuesInv = DB.getSQLValueObjectsEx(getTrxName(), sql.toString(),
|
||||||
MInvoice.Table_ID, invoice.getC_Invoice_ID(), as.getC_AcctSchema_ID(), acct.getAccount_ID());
|
MInvoice.Table_ID, invoice.getC_Invoice_ID(), as.getC_AcctSchema_ID(), acct.getAccount_ID());
|
||||||
|
@ -1128,10 +1139,10 @@ public class Doc_AllocationHdr extends Doc
|
||||||
MAccount gain = MAccount.get (as.getCtx(), as.getAcctSchemaDefault().getRealizedGain_Acct());
|
MAccount gain = MAccount.get (as.getCtx(), as.getAcctSchemaDefault().getRealizedGain_Acct());
|
||||||
MAccount loss = MAccount.get (as.getCtx(), as.getAcctSchemaDefault().getRealizedLoss_Acct());
|
MAccount loss = MAccount.get (as.getCtx(), as.getAcctSchemaDefault().getRealizedLoss_Acct());
|
||||||
|
|
||||||
Hashtable<Integer, BigDecimal> htTotalAmtSourceDr = new Hashtable<Integer, BigDecimal>();
|
Map<Integer, BigDecimal> htTotalAmtSourceDr = new HashMap<>();
|
||||||
Hashtable<Integer, BigDecimal> htTotalAmtAcctDr = new Hashtable<Integer, BigDecimal>();
|
Map<Integer, BigDecimal> htTotalAmtAcctDr = new HashMap<>();
|
||||||
Hashtable<Integer, BigDecimal> htTotalAmtSourceCr = new Hashtable<Integer, BigDecimal>();
|
Map<Integer, BigDecimal> htTotalAmtSourceCr = new HashMap<>();
|
||||||
Hashtable<Integer, BigDecimal> htTotalAmtAcctCr = new Hashtable<Integer, BigDecimal>();
|
Map<Integer, BigDecimal> htTotalAmtAcctCr = new HashMap<>();
|
||||||
FactLine[] factlines = fact.getLines();
|
FactLine[] factlines = fact.getLines();
|
||||||
for (FactLine factLine : factlines)
|
for (FactLine factLine : factlines)
|
||||||
{
|
{
|
||||||
|
@ -1140,6 +1151,8 @@ public class Doc_AllocationHdr extends Doc
|
||||||
MAllocationLine allocationLine = new MAllocationLine(getCtx(), factLine.getLine_ID(), getTrxName());
|
MAllocationLine allocationLine = new MAllocationLine(getCtx(), factLine.getLine_ID(), getTrxName());
|
||||||
if (allocationLine.getC_Invoice_ID() > 0)
|
if (allocationLine.getC_Invoice_ID() > 0)
|
||||||
{
|
{
|
||||||
|
MInvoice invoice = invList.get(allocationLine.getC_Invoice_ID());
|
||||||
|
MAccount acct = invoice.isSOTrx() ? acctAr : acctAp;
|
||||||
if (factLine.getAccount_ID() == acct.getAccount_ID())
|
if (factLine.getAccount_ID() == acct.getAccount_ID())
|
||||||
{
|
{
|
||||||
BigDecimal totalAmtSourceDr = htTotalAmtSourceDr.get(allocationLine.getC_Invoice_ID());
|
BigDecimal totalAmtSourceDr = htTotalAmtSourceDr.get(allocationLine.getC_Invoice_ID());
|
||||||
|
@ -1187,9 +1200,9 @@ public class Doc_AllocationHdr extends Doc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Hashtable<Integer, BigDecimal> htAllocInvSource = new Hashtable<Integer, BigDecimal>();
|
Map<Integer, BigDecimal> htAllocInvSource = new HashMap<>();
|
||||||
Hashtable<Integer, BigDecimal> htAllocInvAccounted = new Hashtable<Integer, BigDecimal>();
|
Map<Integer, BigDecimal> htAllocInvAccounted = new HashMap<>();
|
||||||
for (MInvoice invoice : invList)
|
for (MInvoice invoice : invList.values())
|
||||||
{
|
{
|
||||||
BigDecimal allocateSource = Env.ZERO;
|
BigDecimal allocateSource = Env.ZERO;
|
||||||
BigDecimal allocateAccounted = Env.ZERO;
|
BigDecimal allocateAccounted = Env.ZERO;
|
||||||
|
@ -1247,6 +1260,7 @@ public class Doc_AllocationHdr extends Doc
|
||||||
.append(" AND Account_ID=?")
|
.append(" AND Account_ID=?")
|
||||||
.append(" AND Line_ID IN (SELECT C_AllocationLine_ID FROM C_AllocationLine WHERE C_AllocationHdr_ID=? AND C_Invoice_ID=?)");
|
.append(" AND Line_ID IN (SELECT C_AllocationLine_ID FROM C_AllocationLine WHERE C_AllocationHdr_ID=? AND C_Invoice_ID=?)");
|
||||||
|
|
||||||
|
MAccount acct = invoice.isSOTrx() ? acctAr : acctAp;
|
||||||
// For Allocation
|
// For Allocation
|
||||||
List<Object> valuesAlloc = DB.getSQLValueObjectsEx(getTrxName(), sql.toString(),
|
List<Object> valuesAlloc = DB.getSQLValueObjectsEx(getTrxName(), sql.toString(),
|
||||||
MAllocationHdr.Table_ID, alloc.get_ID(), as.getC_AcctSchema_ID(), acct.getAccount_ID(), alloc.get_ID(), invoice.getC_Invoice_ID());
|
MAllocationHdr.Table_ID, alloc.get_ID(), as.getC_AcctSchema_ID(), acct.getAccount_ID(), alloc.get_ID(), invoice.getC_Invoice_ID());
|
||||||
|
@ -1328,8 +1342,9 @@ public class Doc_AllocationHdr extends Doc
|
||||||
htAllocInvAccounted.put(invoice.getC_Invoice_ID(), allocateAccounted);
|
htAllocInvAccounted.put(invoice.getC_Invoice_ID(), allocateAccounted);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (MInvoice invoice : invList)
|
for (MInvoice invoice : invList.values())
|
||||||
{
|
{
|
||||||
|
MAccount acct = invoice.isSOTrx() ? acctAr : acctAp;
|
||||||
BigDecimal invSource = htInvSource.get(invoice.getC_Invoice_ID());
|
BigDecimal invSource = htInvSource.get(invoice.getC_Invoice_ID());
|
||||||
if (invSource == null)
|
if (invSource == null)
|
||||||
invSource = Env.ZERO;
|
invSource = Env.ZERO;
|
||||||
|
@ -1444,8 +1459,8 @@ public class Doc_AllocationHdr extends Doc
|
||||||
*/
|
*/
|
||||||
private String createPaymentRoundingCorrection (MAcctSchema as, Fact fact)
|
private String createPaymentRoundingCorrection (MAcctSchema as, Fact fact)
|
||||||
{
|
{
|
||||||
ArrayList<MPayment> payList = new ArrayList<MPayment>();
|
List<MPayment> payList = new ArrayList<MPayment>();
|
||||||
Hashtable<Integer, Integer> htPayAllocLine = new Hashtable<Integer, Integer>();
|
Map<Integer, Integer> htPayAllocLine = new HashMap<>();
|
||||||
for (int i = 0; i < p_lines.length; i++)
|
for (int i = 0; i < p_lines.length; i++)
|
||||||
{
|
{
|
||||||
MPayment payment = null;
|
MPayment payment = null;
|
||||||
|
@ -1459,9 +1474,9 @@ public class Doc_AllocationHdr extends Doc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Hashtable<Integer, MAccount> htPayAcct = new Hashtable<Integer, MAccount>();
|
Map<Integer, MAccount> htPayAcct = new HashMap<>();
|
||||||
Hashtable<Integer, BigDecimal> htPaySource = new Hashtable<Integer, BigDecimal>();
|
Map<Integer, BigDecimal> htPaySource = new HashMap<>();
|
||||||
Hashtable<Integer, BigDecimal> htPayAccounted = new Hashtable<Integer, BigDecimal>();
|
Map<Integer, BigDecimal> htPayAccounted = new HashMap<>();
|
||||||
for (MPayment payment : payList)
|
for (MPayment payment : payList)
|
||||||
{
|
{
|
||||||
htPayAcct.put(payment.getC_Payment_ID(), getPaymentAcct(as, payment.getC_Payment_ID()));
|
htPayAcct.put(payment.getC_Payment_ID(), getPaymentAcct(as, payment.getC_Payment_ID()));
|
||||||
|
@ -1494,10 +1509,10 @@ public class Doc_AllocationHdr extends Doc
|
||||||
MAccount gain = MAccount.get (as.getCtx(), as.getAcctSchemaDefault().getRealizedGain_Acct());
|
MAccount gain = MAccount.get (as.getCtx(), as.getAcctSchemaDefault().getRealizedGain_Acct());
|
||||||
MAccount loss = MAccount.get (as.getCtx(), as.getAcctSchemaDefault().getRealizedLoss_Acct());
|
MAccount loss = MAccount.get (as.getCtx(), as.getAcctSchemaDefault().getRealizedLoss_Acct());
|
||||||
|
|
||||||
Hashtable<Integer, BigDecimal> htTotalAmtSourceDr = new Hashtable<Integer, BigDecimal>();
|
Map<Integer, BigDecimal> htTotalAmtSourceDr = new HashMap<>();
|
||||||
Hashtable<Integer, BigDecimal> htTotalAmtAcctDr = new Hashtable<Integer, BigDecimal>();
|
Map<Integer, BigDecimal> htTotalAmtAcctDr = new HashMap<>();
|
||||||
Hashtable<Integer, BigDecimal> htTotalAmtSourceCr = new Hashtable<Integer, BigDecimal>();
|
Map<Integer, BigDecimal> htTotalAmtSourceCr = new HashMap<>();
|
||||||
Hashtable<Integer, BigDecimal> htTotalAmtAcctCr = new Hashtable<Integer, BigDecimal>();
|
Map<Integer, BigDecimal> htTotalAmtAcctCr = new HashMap<>();
|
||||||
FactLine[] factlines = fact.getLines();
|
FactLine[] factlines = fact.getLines();
|
||||||
for (FactLine factLine : factlines)
|
for (FactLine factLine : factlines)
|
||||||
{
|
{
|
||||||
|
@ -1553,8 +1568,8 @@ public class Doc_AllocationHdr extends Doc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Hashtable<Integer, BigDecimal> htAllocPaySource = new Hashtable<Integer, BigDecimal>();
|
Map<Integer, BigDecimal> htAllocPaySource = new HashMap<>();
|
||||||
Hashtable<Integer, BigDecimal> htAllocPayAccounted = new Hashtable<Integer, BigDecimal>();
|
Map<Integer, BigDecimal> htAllocPayAccounted = new HashMap<>();
|
||||||
for (MPayment payment : payList)
|
for (MPayment payment : payList)
|
||||||
{
|
{
|
||||||
BigDecimal allocateSource = Env.ZERO;
|
BigDecimal allocateSource = Env.ZERO;
|
||||||
|
|
|
@ -170,6 +170,58 @@ public class AllocationTest extends AbstractTestCase {
|
||||||
rollback();
|
rollback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
/**
|
||||||
|
* https://idempiere.atlassian.net/browse/IDEMPIERE-5723
|
||||||
|
*/
|
||||||
|
public void testAllocateInvoiceArAp() {
|
||||||
|
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.JOE_BLOCK.id);
|
||||||
|
|
||||||
|
Timestamp date = TimeUtil.getDay(null);
|
||||||
|
MCurrency usd = MCurrency.get(DictionaryIDs.C_Currency.USD.id); // USD
|
||||||
|
|
||||||
|
int payterm = DictionaryIDs.C_PaymentTerm.TWO_PERCENT_10_NET_30.id; //(2%10 Net 30)
|
||||||
|
int taxid = DictionaryIDs.C_Tax.CT_SALES.id; // (CT Sales, Rate 6)
|
||||||
|
|
||||||
|
MInvoice invoiceAr = createInvoice(true, false, date, date,
|
||||||
|
bpartner.getC_BPartner_ID(), payterm, taxid, Env.ONEHUNDRED);
|
||||||
|
assertEquals(invoiceAr.getTotalLines().setScale(2, RoundingMode.HALF_UP), new BigDecimal("100.00"));
|
||||||
|
assertEquals(invoiceAr.getGrandTotal().setScale(2, RoundingMode.HALF_UP), new BigDecimal("106.00"));
|
||||||
|
|
||||||
|
completeDocument(invoiceAr);
|
||||||
|
postDocument(invoiceAr);
|
||||||
|
|
||||||
|
MInvoice invoiceAp = createInvoice(false, false, date, date,
|
||||||
|
bpartner.getC_BPartner_ID(), payterm, taxid, Env.ONEHUNDRED);
|
||||||
|
|
||||||
|
completeDocument(invoiceAp);
|
||||||
|
postDocument(invoiceAp);
|
||||||
|
|
||||||
|
|
||||||
|
MAllocationHdr alloc = new MAllocationHdr(Env.getCtx(), true, date, usd.getC_Currency_ID(), Env.getContext(Env.getCtx(), "#AD_User_Name"), getTrxName());
|
||||||
|
alloc.setAD_Org_ID(invoiceAr.getAD_Org_ID());
|
||||||
|
int doctypeAlloc = MDocType.getDocType(MDocType.DOCBASETYPE_PaymentAllocation);
|
||||||
|
alloc.setC_DocType_ID(doctypeAlloc);
|
||||||
|
//alloc.setDescription(alloc.getDescriptionForManualAllocation(payment.getC_BPartner_ID(), getTrxName()));
|
||||||
|
alloc.saveEx();
|
||||||
|
|
||||||
|
MAllocationLine aLine1 = new MAllocationLine(alloc, invoiceAp.getOpenAmt(), Env.ZERO, Env.ZERO, Env.ZERO);
|
||||||
|
aLine1.setDocInfo(invoiceAp.getC_BPartner_ID(), 0, invoiceAp.getC_Invoice_ID());
|
||||||
|
aLine1.saveEx();
|
||||||
|
|
||||||
|
MAllocationLine aLine2 = new MAllocationLine(alloc, invoiceAr.getOpenAmt(), Env.ZERO, Env.ZERO, Env.ZERO);
|
||||||
|
aLine2.setDocInfo(invoiceAr.getC_BPartner_ID(), 0, invoiceAr.getC_Invoice_ID());
|
||||||
|
aLine2.saveEx();
|
||||||
|
|
||||||
|
completeDocument(alloc);
|
||||||
|
postDocument(alloc);
|
||||||
|
|
||||||
|
alloc.load(getTrxName());
|
||||||
|
|
||||||
|
assertTrue(alloc.isPosted(), "Allocation not posted");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAllocateCustomerInvoice() {
|
public void testAllocateCustomerInvoice() {
|
||||||
int severeCount = 0;
|
int severeCount = 0;
|
||||||
|
|
Loading…
Reference in New Issue