📄 vallocation.java
字号:
BigDecimal totalInv = new BigDecimal(0.0);
rows = invoice.getRowCount();
m_noInvoices = 0;
for (int i = 0; i < rows; i++)
{
if (((Boolean)invoice.getValueAt(i, 0)).booleanValue())
{
Timestamp ts = (Timestamp)invoice.getValueAt(i, 1);
allocDate = TimeUtil.max(allocDate, ts);
BigDecimal bd = (BigDecimal)invoice.getValueAt(i, i_applied);
totalInv = totalInv.add(bd); // Applied Inv
m_noInvoices++;
log.fine("Invoice_" + i + " = " + bd + " - Total=" + totalPay);
}
}
invoiceInfo.setText(String.valueOf(m_noInvoices) + " - "
+ Msg.getMsg(Env.getCtx(), "Sum") + " " + format.format(totalInv) + " ");
// Set AllocationDate
if (allocDate != null)
dateField.setValue(allocDate);
// Set Allocation Currency
allocCurrencyLabel.setText(currencyPick.getDisplay());
// Difference
BigDecimal difference = totalPay.subtract(totalInv);
differenceField.setText(format.format(difference));
if (difference.compareTo(new BigDecimal(0.0)) == 0)
allocateButton.setEnabled(true);
else
allocateButton.setEnabled(false);
} // calculate
/**
* Vetoable Change Listener.
* - Business Partner
* - Currency
* - Date
* @param e event
*/
public void vetoableChange (PropertyChangeEvent e)
{
String name = e.getPropertyName();
Object value = e.getNewValue();
log.config(name + "=" + value);
if (value == null)
return;
// BPartner
if (name.equals("C_BPartner_ID"))
{
bpartnerSearch.setValue(value);
m_C_BPartner_ID = ((Integer)value).intValue();
loadBPartner();
}
// Currency
else if (name.equals("C_Currency_ID"))
{
m_C_Currency_ID = ((Integer)value).intValue();
loadBPartner();
}
// Date for Multi-Currency
else if (name.equals("Date") && multiCurrency.isSelected())
loadBPartner();
} // vetoableChange
/**************************************************************************
* Save Data
*/
private void saveData()
{
if (m_noInvoices + m_noPayments == 0)
return;
// fixed fields
int AD_Client_ID = Env.getContextAsInt(Env.getCtx(), m_WindowNo, "AD_Client_ID");
int AD_Org_ID = Env.getContextAsInt(Env.getCtx(), m_WindowNo, "AD_Org_ID");
int C_BPartner_ID = m_C_BPartner_ID;
int C_Order_ID = 0;
int C_CashLine_ID = 0;
Timestamp DateTrx = (Timestamp)dateField.getValue();
int C_Currency_ID = m_C_Currency_ID; // the allocation currency
//
if (AD_Org_ID == 0)
{
ADialog.error(m_WindowNo, this, "Org0NotAllowed", null);
return;
}
//
log.config("Client=" + AD_Client_ID + ", Org=" + AD_Org_ID
+ ", BPartner=" + C_BPartner_ID + ", Date=" + DateTrx);
Trx trx = Trx.get(Trx.createTrxName("AL"), true);
/**
* Generation of allocations: amount/discount/writeOff
* - if there is one payment -- one line per invoice is generated
* with both the Invoice and Payment reference
* Pay=80 Inv=100 Disc=10 WOff=10 => 80/10/10 Pay#1 Inv#1
* or
* Pay=160 Inv=100 Disc=10 WOff=10 => 80/10/10 Pay#1 Inv#1
* Pay=160 Inv=100 Disc=10 WOff=10 => 80/10/10 Pay#1 Inv#2
*
* - if there are multiple payment lines -- the amounts are allocated
* starting with the first payment and payment
* Pay=60 Inv=100 Disc=10 WOff=10 => 60/10/10 Pay#1 Inv#1
* Pay=100 Inv=100 Disc=10 WOff=10 => 20/0/0 Pay#2 Inv#1
* Pay=100 Inv=100 Disc=10 WOff=10 => 80/10/10 Pay#2 Inv#2
*
* - if you apply a credit memo to an invoice
* Inv=10 Disc=0 WOff=0 => 10/0/0 Inv#1
* Inv=-10 Disc=0 WOff=0 => -10/0/0 Inv#2
*
* - if you want to write off a (partial) invoice without applying,
* enter zero in applied
* Inv=10 Disc=1 WOff=9 => 0/1/9 Inv#1
* Issues
* - you cannot write-off a payment
*/
// Payment - Loop and add them to paymentList/amountList
int pRows = paymentTable.getRowCount();
TableModel payment = paymentTable.getModel();
ArrayList<Integer> paymentList = new ArrayList<Integer>(pRows);
ArrayList<BigDecimal> amountList = new ArrayList<BigDecimal>(pRows);
BigDecimal paymentAppliedAmt = Env.ZERO;
for (int i = 0; i < pRows; i++)
{
// Payment line is selected
if (((Boolean)payment.getValueAt(i, 0)).booleanValue())
{
KeyNamePair pp = (KeyNamePair)payment.getValueAt(i, 2); // Value
// Payment variables
int C_Payment_ID = pp.getKey();
paymentList.add(new Integer(C_Payment_ID));
//
BigDecimal PaymentAmt = (BigDecimal)payment.getValueAt(i, i_payment); // Applied Payment
amountList.add(PaymentAmt);
//
paymentAppliedAmt = paymentAppliedAmt.add(PaymentAmt);
//
log.fine("C_Payment_ID=" + C_Payment_ID
+ " - PaymentAmt=" + PaymentAmt); // + " * " + Multiplier + " = " + PaymentAmtAbs);
}
}
log.config("Number of Payments=" + paymentList.size() + " - Total=" + paymentAppliedAmt);
// Invoices - Loop and generate alloctions
int iRows = invoiceTable.getRowCount();
TableModel invoice = invoiceTable.getModel();
BigDecimal totalAppliedAmt = Env.ZERO;
// Create Allocation - but don't save yet
MAllocationHdr alloc = new MAllocationHdr (Env.getCtx(), true, // manual
DateTrx, C_Currency_ID, Env.getContext(Env.getCtx(), "#AD_User_Name"), trx.getTrxName());
alloc.setAD_Org_ID(AD_Org_ID);
// For all invoices
int invoiceLines = 0;
for (int i = 0; i < iRows; i++)
{
// Invoice line is selected
if (((Boolean)invoice.getValueAt(i, 0)).booleanValue())
{
invoiceLines++;
KeyNamePair pp = (KeyNamePair)invoice.getValueAt(i, 2); // Value
// Invoice variables
int C_Invoice_ID = pp.getKey();
BigDecimal AppliedAmt = (BigDecimal)invoice.getValueAt(i, i_applied);
// semi-fixed fields (reset after first invoice)
BigDecimal DiscountAmt = (BigDecimal)invoice.getValueAt(i, i_discount);
BigDecimal WriteOffAmt = (BigDecimal)invoice.getValueAt(i, i_writeOff);
// OverUnderAmt needs to be in Allocation Currency
BigDecimal OverUnderAmt = ((BigDecimal)invoice.getValueAt(i, i_open))
.subtract(AppliedAmt).subtract(DiscountAmt).subtract(WriteOffAmt);
log.config("Invoice #" + i + " - AppliedAmt=" + AppliedAmt);// + " -> " + AppliedAbs);
// loop through all payments until invoice applied
int noPayments = 0;
for (int j = 0; j < paymentList.size() && AppliedAmt.signum() != 0; j++)
{
int C_Payment_ID = ((Integer)paymentList.get(j)).intValue();
BigDecimal PaymentAmt = (BigDecimal)amountList.get(j);
if (PaymentAmt.signum() != 0)
{
log.config(".. with payment #" + j + ", Amt=" + PaymentAmt);
noPayments++;
// use Invoice Applied Amt
BigDecimal amount = AppliedAmt;
log.fine("C_Payment_ID=" + C_Payment_ID + ", C_Invoice_ID=" + C_Invoice_ID
+ ", Amount=" + amount + ", Discount=" + DiscountAmt + ", WriteOff=" + WriteOffAmt);
// Allocation Header
if (alloc.get_ID() == 0 && !alloc.save())
{
log.log(Level.SEVERE, "Allocation not created");
return;
}
// Allocation Line
MAllocationLine aLine = new MAllocationLine (alloc, amount,
DiscountAmt, WriteOffAmt, OverUnderAmt);
aLine.setDocInfo(C_BPartner_ID, C_Order_ID, C_Invoice_ID);
aLine.setPaymentInfo(C_Payment_ID, C_CashLine_ID);
if (!aLine.save())
log.log(Level.SEVERE, "Allocation Line not written - Invoice=" + C_Invoice_ID);
// Apply Discounts and WriteOff only first time
DiscountAmt = Env.ZERO;
WriteOffAmt = Env.ZERO;
// subtract amount from Payment/Invoice
AppliedAmt = AppliedAmt.subtract(amount);
PaymentAmt = PaymentAmt.subtract(amount);
log.fine("Allocation Amount=" + amount + " - Remaining Applied=" + AppliedAmt + ", Payment=" + PaymentAmt);
amountList.set(j, PaymentAmt); // update
} // for all applied amounts
} // noop through payments for invoice
// No Payments allocated and none existing (e.g. Inv/CM)
if (noPayments == 0 && paymentList.size() == 0)
{
int C_Payment_ID = 0;
log.config(" ... no payment - TotalApplied=" + totalAppliedAmt);
// Create Allocation
log.fine("C_Payment_ID=" + C_Payment_ID + ", C_Invoice_ID=" + C_Invoice_ID
+ ", Amount=" + AppliedAmt + ", Discount=" + DiscountAmt + ", WriteOff=" + WriteOffAmt);
// Allocation Header
if (alloc.get_ID() == 0 && !alloc.save())
{
log.log(Level.SEVERE, "Allocation not created");
return;
}
// Allocation Line
MAllocationLine aLine = new MAllocationLine (alloc, AppliedAmt,
DiscountAmt, WriteOffAmt, OverUnderAmt);
aLine.setDocInfo(C_BPartner_ID, C_Order_ID, C_Invoice_ID);
aLine.setPaymentInfo(C_Payment_ID, C_CashLine_ID);
if (!aLine.save(trx.getTrxName()))
log.log(Level.SEVERE, "Allocation Line not written - Invoice=" + C_Invoice_ID);
log.fine("Allocation Amount=" + AppliedAmt);
}
totalAppliedAmt = totalAppliedAmt.add(AppliedAmt);
log.config("TotalRemaining=" + totalAppliedAmt);
} // invoice selected
} // invoice loop
// Only Payments and total of 0 (e.g. Payment/Reversal)
if (invoiceLines == 0 && paymentList.size() > 0
&& paymentAppliedAmt.signum() == 0)
{
for (int i = 0; i < paymentList.size(); i++)
{
int C_Payment_ID = ((Integer)paymentList.get(i)).intValue();
BigDecimal PaymentAmt = (BigDecimal)amountList.get(i);
// BigDecimal PaymentMultiplier = (BigDecimal)multiplierList.get(i);
// BigDecimal PaymentAbs = PaymentAmt.multiply(PaymentMultiplier);
log.fine("Payment=" + C_Payment_ID
+ ", Amount=" + PaymentAmt);// + ", Abs=" + PaymentAbs);
// Allocation Header
if (alloc.get_ID() == 0 && !alloc.save())
{
log.log(Level.SEVERE, "Allocation not created");
return;
}
// Allocation Line
MAllocationLine aLine = new MAllocationLine (alloc, PaymentAmt,
Env.ZERO, Env.ZERO, Env.ZERO);
aLine.setDocInfo(C_BPartner_ID, 0, 0);
aLine.setPaymentInfo(C_Payment_ID, 0);
if (!aLine.save(trx.getTrxName()))
log.log(Level.SEVERE, "Allocation Line not saved - Payment=" + C_Payment_ID);
}
} // onlyPayments
if (totalAppliedAmt.signum() != 0)
log.log(Level.SEVERE, "Remaining TotalAppliedAmt=" + totalAppliedAmt);
// Should start WF
if (alloc.get_ID() != 0)
{
alloc.processIt(DocAction.ACTION_Complete);
alloc.save();
}
// Test/Set IsPaid for Invoice - requires that allocation is posted
for (int i = 0; i < iRows; i++)
{
// Invoice line is selected
if (((Boolean)invoice.getValueAt(i, 0)).booleanValue())
{
KeyNamePair pp = (KeyNamePair)invoice.getValueAt(i, 2); // Value
// Invoice variables
int C_Invoice_ID = pp.getKey();
String sql = "SELECT invoiceOpen(C_Invoice_ID, 0) "
+ "FROM C_Invoice WHERE C_Invoice_ID=?";
BigDecimal open = DB.getSQLValueBD(trx.getTrxName(), sql, C_Invoice_ID);
if (open != null && open.signum() == 0)
{
sql = "UPDATE C_Invoice SET IsPaid='Y' "
+ "WHERE C_Invoice_ID=" + C_Invoice_ID;
int no = DB.executeUpdate(sql, trx.getTrxName());
log.config("Invoice #" + i + " is paid");
}
else
log.config("Invoice #" + i + " is not paid - " + open);
}
}
// Test/Set Payment is fully allocated
for (int i = 0; i < paymentList.size(); i++)
{
int C_Payment_ID = ((Integer)paymentList.get(i)).intValue();
MPayment pay = new MPayment (Env.getCtx(), C_Payment_ID, trx.getTrxName());
if (pay.testAllocation())
pay.save();
log.config("Payment #" + i + (pay.isAllocated() ? " not" : " is")
+ " fully allocated");
}
paymentList.clear();
amountList.clear();
trx.commit();
trx.close();
} // saveData
} // VAllocation
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -