📄 doc_allocation.java
字号:
catch (Exception e)
{
pstmt = null;
}
//
if (getC_BankAccount_ID() <= 0)
{
log.log(Level.SEVERE, "NONE for C_Payment_ID=" + C_Payment_ID);
return null;
}
return getAccount (accountType, as);
} // getPaymentAcct
/**
* Get Cash (Transfer) Acct of CashBook
* @param as accounting schema
* @param C_CashLine_ID
* @return acct
*/
private MAccount getCashAcct (MAcctSchema as, int C_CashLine_ID)
{
String sql = "SELECT c.C_CashBook_ID "
+ "FROM C_Cash c, C_CashLine cl "
+ "WHERE c.C_Cash_ID=cl.C_Cash_ID AND cl.C_CashLine_ID=?";
setC_CashBook_ID(DB.getSQLValue(null, sql, C_CashLine_ID));
if (getC_CashBook_ID() <= 0)
{
log.log(Level.SEVERE, "NONE for C_CashLine_ID=" + C_CashLine_ID);
return null;
}
return getAccount(Doc.ACCTTYPE_CashTransfer, as);
} // getCashAcct
/**************************************************************************
* Create Realized Gain & Loss.
* Compares the Accounted Amount of the Invoice to the
* Accounted Amount of the Allocation
* @param as accounting schema
* @param fact fact
* @param invoice invoice
* @param allocationSource source amt
* @param allocationAccounted acct amt
* @return Error Message or null if OK
*/
private String createRealizedGainLoss (MAcctSchema as, Fact fact, MAccount acct,
MInvoice invoice, BigDecimal allocationSource, BigDecimal allocationAccounted)
{
BigDecimal invoiceSource = null;
BigDecimal invoiceAccounted = null;
//
String sql = "SELECT "
+ (invoice.isSOTrx()
? "SUM(AmtSourceDr), SUM(AmtAcctDr)" // so
: "SUM(AmtSourceCr), SUM(AmtAcctCr)") // po
+ " FROM Fact_Acct "
+ "WHERE AD_Table_ID=318 AND Record_ID=?" // Invoice
+ " AND C_AcctSchema_ID=?"
+ " AND PostingType='A'";
//AND C_Currency_ID=102
PreparedStatement pstmt = null;
try
{
pstmt = DB.prepareStatement(sql, getTrxName());
pstmt.setInt(1, invoice.getC_Invoice_ID());
pstmt.setInt(2, as.getC_AcctSchema_ID());
ResultSet rs = pstmt.executeQuery();
if (rs.next())
{
invoiceSource = rs.getBigDecimal(1);
invoiceAccounted = rs.getBigDecimal(2);
}
rs.close();
pstmt.close();
pstmt = null;
}
catch (Exception e)
{
log.log(Level.SEVERE, sql, e);
}
try
{
if (pstmt != null)
pstmt.close();
pstmt = null;
}
catch (Exception e)
{
pstmt = null;
}
// Requires that Invoice is Posted
if (invoiceSource == null || invoiceAccounted == null)
return "Gain/Loss - Invoice not posted yet";
//
String description = "Invoice=(" + invoice.getC_Currency_ID() + ")" + invoiceSource + "/" + invoiceAccounted
+ " - Allocation=(" + getC_Currency_ID() + ")" + allocationSource + "/" + allocationAccounted;
log.fine(description);
// Allocation not Invoice Currency
if (getC_Currency_ID() != invoice.getC_Currency_ID())
{
BigDecimal allocationSourceNew = MConversionRate.convert(getCtx(),
allocationSource, getC_Currency_ID(),
invoice.getC_Currency_ID(), getDateAcct(),
invoice.getC_ConversionType_ID(), invoice.getAD_Client_ID(), invoice.getAD_Org_ID());
if (allocationSourceNew == null)
return "Gain/Loss - No Conversion from Allocation->Invoice";
String d2 = "Allocation=(" + getC_Currency_ID() + ")" + allocationSource
+ "->(" + invoice.getC_Currency_ID() + ")" + allocationSourceNew;
log.fine(d2);
description += " - " + d2;
allocationSource = allocationSourceNew;
}
BigDecimal acctDifference = null; // gain is negative
// Full Payment in currency
if (allocationSource.compareTo(invoiceSource) == 0)
{
acctDifference = invoiceAccounted.subtract(allocationAccounted); // gain is negative
String d2 = "(full) = " + acctDifference;
log.fine(d2);
description += " - " + d2;
}
else // partial or MC
{
// percent of total payment
double multiplier = allocationSource.doubleValue() / invoiceSource.doubleValue();
// Reduce Orig Invoice Accounted
invoiceAccounted = invoiceAccounted.multiply(new BigDecimal(multiplier));
// Difference based on percentage of Orig Invoice
acctDifference = invoiceAccounted.subtract(allocationAccounted); // gain is negative
// ignore Tolerance
if (acctDifference.abs().compareTo(TOLERANCE) < 0)
acctDifference = Env.ZERO;
// Round
int precision = as.getStdPrecision();
if (acctDifference.scale() > precision)
acctDifference = acctDifference.setScale(precision, BigDecimal.ROUND_HALF_UP);
String d2 = "(partial) = " + acctDifference + " - Multiplier=" + multiplier;
log.fine(d2);
description += " - " + d2;
}
if (acctDifference.signum() == 0)
{
log.fine("No Difference");
return null;
}
MAccount gain = MAccount.get (as.getCtx(), as.getAcctSchemaDefault().getRealizedGain_Acct());
MAccount loss = MAccount.get (as.getCtx(), as.getAcctSchemaDefault().getRealizedLoss_Acct());
//
if (invoice.isSOTrx())
{
FactLine fl = fact.createLine (null, loss, gain,
as.getC_Currency_ID(), acctDifference);
fl.setDescription(description);
fact.createLine (null, acct,
as.getC_Currency_ID(), acctDifference.negate());
fl.setDescription(description);
}
else
{
fact.createLine (null, acct,
as.getC_Currency_ID(), acctDifference);
FactLine fl = fact.createLine (null, loss, gain,
as.getC_Currency_ID(), acctDifference.negate());
}
return null;
} // createRealizedGainLoss
/**************************************************************************
* Create Tax Correction.
* Requirement: Adjust the tax amount, if you did not receive the full
* amount of the invoice (payment discount, write-off).
* Applies to many countries with VAT.
* Example:
* Invoice: Net $100 + Tax1 $15 + Tax2 $5 = Total $120
* Payment: $115 (i.e. $5 underpayment)
* Tax Adjustment = Tax1 = 0.63 (15/120*5) Tax2 = 0.21 (5/120/5)
*
* @param as accounting schema
* @param fact fact
* @param DiscountAccount discount acct
* @param WriteOffAccoint write off acct
* @return true if created
*/
private boolean createTaxCorrection (MAcctSchema as, Fact fact,
DocLine_Allocation line,
MAccount DiscountAccount, MAccount WriteOffAccoint)
{
log.info ("createTaxCorrection - " + line);
Doc_AllocationTax tax = new Doc_AllocationTax (
DiscountAccount, line.getDiscountAmt(),
WriteOffAccoint, line.getWriteOffAmt());
// Get Source Amounts with account
String sql = "SELECT * "
+ "FROM Fact_Acct "
+ "WHERE AD_Table_ID=318 AND Record_ID=?" // Invoice
+ " AND C_AcctSchema_ID=?"
+ " AND Line_ID IS NULL"; // header lines like tax or total
PreparedStatement pstmt = null;
try
{
pstmt = DB.prepareStatement(sql, getTrxName());
pstmt.setInt(1, line.getC_Invoice_ID());
pstmt.setInt(2, as.getC_AcctSchema_ID());
ResultSet rs = pstmt.executeQuery();
while (rs.next())
tax.addInvoiceFact (new MFactAcct(getCtx(), rs, fact.get_TrxName()));
rs.close();
pstmt.close();
pstmt = null;
}
catch (Exception e)
{
log.log(Level.SEVERE, sql, e);
}
try
{
if (pstmt != null)
pstmt.close();
pstmt = null;
}
catch (Exception e)
{
pstmt = null;
}
// Invoice Not posted
if (tax.getLineCount() == 0)
{
log.warning ("Invoice not posted yet - " + line);
return false;
}
// size = 1 if no tax
if (tax.getLineCount() < 2)
return true;
return tax.createEntries (as, fact, line);
} // createTaxCorrection
} // Doc_Allocation
/**
* Allocation Document Tax Handing
*
* @author Jorg Janke
* @version $Id: Doc_Allocation.java,v 1.17 2005/10/28 01:00:53 jjanke Exp $
*/
class Doc_AllocationTax
{
/**
* Allocation Tax Adjustment
* @param DiscountAccount discount acct
* @param DiscountAmt discount amt
* @param WriteOffAccount write off acct
* @param WriteOffAmt write off amt
*/
public Doc_AllocationTax (MAccount DiscountAccount, BigDecimal DiscountAmt,
MAccount WriteOffAccount, BigDecimal WriteOffAmt)
{
m_DiscountAccount = DiscountAccount;
m_DiscountAmt = DiscountAmt;
m_WriteOffAccount = WriteOffAccount;
m_WriteOffAmt = WriteOffAmt;
} // Doc_AllocationTax
private CLogger log = CLogger.getCLogger(getClass());
private MAccount m_DiscountAccount;
private BigDecimal m_DiscountAmt;
private MAccount m_WriteOffAccount;
private BigDecimal m_WriteOffAmt;
private ArrayList<MFactAcct> m_facts = new ArrayList<MFactAcct>();
private int m_totalIndex = 0;
/**
* Add Invoice Fact Line
* @param fact fact line
*/
public void addInvoiceFact (MFactAcct fact)
{
m_facts.add(fact);
} // addInvoiceLine
/**
* Get Line Count
* @return number of lines
*/
public int getLineCount()
{
return m_facts.size();
} // getLineCount
/**
* Create Accounting Entries
* @param as account schema
* @param fact fact to add lines
* @return true if created
*/
public boolean createEntries (MAcctSchema as, Fact fact, DocLine line)
{
// get total index (the Receivables/Liabilities line)
BigDecimal total = Env.ZERO;
for (int i = 0; i < m_facts.size(); i++)
{
MFactAcct factAcct = (MFactAcct)m_facts.get(i);
if (factAcct.getAmtSourceDr().compareTo(total) > 0)
{
total = factAcct.getAmtSourceDr();
m_totalIndex = i;
}
if (factAcct.getAmtSourceCr().compareTo(total) > 0)
{
total = factAcct.getAmtSourceCr();
m_totalIndex = i;
}
}
MFactAcct factAcct = (MFactAcct)m_facts.get(m_totalIndex);
log.info ("createEntries - Total Invoice = " + total + " - " + factAcct);
int precision = as.getStdPrecision();
for (int i = 0; i < m_facts.size(); i++)
{
// No Tax Line
if (i == m_totalIndex)
continue;
factAcct = (MFactAcct)m_facts.get(i);
log.info (i + ": " + factAcct);
// Create Tax Account
MAccount taxAcct = factAcct.getMAccount();
if (taxAcct == null || taxAcct.get_ID() == 0)
{
log.severe ("Tax Account not found/created");
return false;
}
// Discount Amount
if (Env.ZERO.compareTo(m_DiscountAmt) != 0)
{
// Original Tax is DR - need to correct it CR
if (Env.ZERO.compareTo(factAcct.getAmtSourceDr()) != 0)
{
BigDecimal amount = calcAmount(factAcct.getAmtSourceDr(),
total, m_DiscountAmt, precision);
if (amount.signum() != 0)
{
fact.createLine (line, m_DiscountAccount,
as.getC_Currency_ID(), amount, null);
fact.createLine (line, taxAcct,
as.getC_Currency_ID(), null, amount);
}
}
// Original Tax is CR - need to correct it DR
else
{
BigDecimal amount = calcAmount(factAcct.getAmtSourceCr(),
total, m_DiscountAmt, precision);
if (amount.signum() != 0)
{
fact.createLine (line, taxAcct,
as.getC_Currency_ID(), amount, null);
fact.createLine (line, m_DiscountAccount,
as.getC_Currency_ID(), null, amount);
}
}
} // Discount
// WriteOff Amount
if (Env.ZERO.compareTo(m_WriteOffAmt) != 0)
{
// Original Tax is DR - need to correct it CR
if (Env.ZERO.compareTo(factAcct.getAmtSourceDr()) != 0)
{
BigDecimal amount = calcAmount(factAcct.getAmtSourceDr(),
total, m_WriteOffAmt, precision);
if (amount.signum() != 0)
{
fact.createLine (line, m_WriteOffAccount,
as.getC_Currency_ID(), amount, null);
fact.createLine (line, taxAcct,
as.getC_Currency_ID(), null, amount);
}
}
// Original Tax is CR - need to correct it DR
else
{
BigDecimal amount = calcAmount(factAcct.getAmtSourceCr(),
total, m_WriteOffAmt, precision);
if (amount.signum() != 0)
{
fact.createLine (line, taxAcct,
as.getC_Currency_ID(), amount, null);
fact.createLine (line, m_WriteOffAccount,
as.getC_Currency_ID(), null, amount);
}
}
} // WriteOff
} // for all lines
return true;
} // createEntries
/**
* Calc Amount tax / total * amt
* @param tax tax
* @param total total
* @param amt reduction amt
* @param precision precision
* @return tax / total * amt
*/
private BigDecimal calcAmount (BigDecimal tax, BigDecimal total, BigDecimal amt, int precision)
{
log.fine("Tax=" + tax + " / Total=" + total + " * Amt=" + amt);
if (tax.signum() == 0
|| total.signum() == 0
|| amt.signum() == 0)
return Env.ZERO;
/**
BigDecimal percentage = tax.divide(total, 10, BigDecimal.ROUND_HALF_UP);
BigDecimal retValue = percentage.multiply(amt);
if (retValue.scale() > precision)
retValue = retValue.setScale(precision, BigDecimal.ROUND_HALF_UP);
log.fine("calcAmount - Percentage=" + percentage + ", Result=" + retValue);
**/
BigDecimal retValue = tax.multiply(amt).divide(total, precision, BigDecimal.ROUND_HALF_UP);
log.fine("Result=" + retValue);
return retValue;
} // calcAmount
} // Doc_AllocationTax
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -