📄 doc_invoice.java
字号:
/******************************************************************************
* The contents of this file are subject to the Compiere License Version 1.1
* ("License"); You may not use this file except in compliance with the License
* You may obtain a copy of the License at http://www.compiere.org/license.html
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
* The Original Code is Compiere ERP & CRM Smart Business Solution. The Initial
* Developer of the Original Code is Jorg Janke. Portions created by Jorg Janke
* are Copyright (C) 1999-2005 Jorg Janke.
* All parts are Copyright (C) 1999-2005 ComPiere, Inc. All Rights Reserved.
* Contributor(s): ______________________________________.
*****************************************************************************/
package org.compiere.acct;
import java.math.*;
import java.sql.*;
import java.util.*;
import java.util.logging.*;
import org.compiere.model.*;
import org.compiere.util.*;
/**
* Post Invoice Documents.
* <pre>
* Table: C_Invoice (318)
* Document Types: ARI, ARC, ARF, API, APC
* </pre>
* @author Jorg Janke
* @version $Id: Doc_Invoice.java,v 1.28 2006/02/12 02:19:19 jjanke Exp $
*/
public class Doc_Invoice extends Doc
{
/**
* Constructor
* @param ass accounting schemata
* @param rs record
* @parem trxName trx
*/
protected Doc_Invoice(MAcctSchema[] ass, ResultSet rs, String trxName)
{
super (ass, MInvoice.class, rs, null, trxName);
} // Doc_Invoice
/** Contained Optional Tax Lines */
private DocTax[] m_taxes = null;
/** Currency Precision */
private int m_precision = -1;
/** All lines are Service */
private boolean m_allLinesService = true;
/** All lines are product item */
private boolean m_allLinesItem = true;
/**
* Load Specific Document Details
* @return error message or null
*/
protected String loadDocumentDetails ()
{
MInvoice invoice = (MInvoice)getPO();
setDateDoc(invoice.getDateInvoiced());
setIsTaxIncluded(invoice.isTaxIncluded());
// Amounts
setAmount(Doc.AMTTYPE_Gross, invoice.getGrandTotal());
setAmount(Doc.AMTTYPE_Net, invoice.getTotalLines());
setAmount(Doc.AMTTYPE_Charge, invoice.getChargeAmt());
// Contained Objects
m_taxes = loadTaxes();
p_lines = loadLines(invoice);
log.fine("Lines=" + p_lines.length + ", Taxes=" + m_taxes.length);
return null;
} // loadDocumentDetails
/**
* Load Invoice Taxes
* @return DocTax Array
*/
private DocTax[] loadTaxes()
{
ArrayList<DocTax> list = new ArrayList<DocTax>();
String sql = "SELECT it.C_Tax_ID, t.Name, t.Rate, it.TaxBaseAmt, it.TaxAmt, t.IsSalesTax "
+ "FROM C_Tax t, C_InvoiceTax it "
+ "WHERE t.C_Tax_ID=it.C_Tax_ID AND it.C_Invoice_ID=?";
try
{
PreparedStatement pstmt = DB.prepareStatement(sql, getTrxName());
pstmt.setInt(1, get_ID());
ResultSet rs = pstmt.executeQuery();
//
while (rs.next())
{
int C_Tax_ID = rs.getInt(1);
String name = rs.getString(2);
BigDecimal rate = rs.getBigDecimal(3);
BigDecimal taxBaseAmt = rs.getBigDecimal(4);
BigDecimal amount = rs.getBigDecimal(5);
boolean salesTax = "Y".equals(rs.getString(6));
//
DocTax taxLine = new DocTax(C_Tax_ID, name, rate,
taxBaseAmt, amount, salesTax);
log.fine(taxLine.toString());
list.add(taxLine);
}
//
rs.close();
pstmt.close();
}
catch (SQLException e)
{
log.log(Level.SEVERE, sql, e);
return null;
}
// Return Array
DocTax[] tl = new DocTax[list.size()];
list.toArray(tl);
return tl;
} // loadTaxes
/**
* Load Invoice Line
* @return DocLine Array
*/
private DocLine[] loadLines(MInvoice invoice)
{
ArrayList<DocLine> list = new ArrayList<DocLine>();
//
MInvoiceLine[] lines = invoice.getLines(false);
for (int i = 0; i < lines.length; i++)
{
MInvoiceLine line = lines[i];
if (line.isDescription())
continue;
DocLine docLine = new DocLine(line, this);
// Qty
BigDecimal Qty = line.getQtyInvoiced();
boolean cm = getDocumentType().equals(DOCTYPE_ARCredit)
|| getDocumentType().equals(DOCTYPE_APCredit);
docLine.setQty(cm ? Qty.negate() : Qty, invoice.isSOTrx());
//
BigDecimal LineNetAmt = line.getLineNetAmt();
BigDecimal PriceList = line.getPriceList();
int C_Tax_ID = docLine.getC_Tax_ID();
// Correct included Tax
if (isTaxIncluded() && C_Tax_ID != 0)
{
MTax tax = MTax.get(getCtx(), C_Tax_ID);
if (!tax.isZeroTax())
{
BigDecimal LineNetAmtTax = tax.calculateTax(LineNetAmt, true, getStdPercision());
log.fine("LineNetAmt=" + LineNetAmt + " - Tax=" + LineNetAmtTax);
LineNetAmt = LineNetAmt.subtract(LineNetAmtTax);
for (int t = 0; t < m_taxes.length; t++)
{
if (m_taxes[t].getC_Tax_ID() == C_Tax_ID)
{
m_taxes[t].addIncludedTax(LineNetAmtTax);
break;
}
}
BigDecimal PriceListTax = tax.calculateTax(PriceList, true, getStdPercision());
PriceList = PriceList.subtract(PriceListTax);
}
} // correct included Tax
docLine.setAmount (LineNetAmt, PriceList, Qty); // qty for discount calc
if (docLine.isItem())
m_allLinesService = false;
else
m_allLinesItem = false;
//
log.fine(docLine.toString());
list.add(docLine);
}
// Convert to Array
DocLine[] dls = new DocLine[list.size()];
list.toArray(dls);
// Included Tax - make sure that no difference
if (isTaxIncluded())
{
for (int i = 0; i < m_taxes.length; i++)
{
if (m_taxes[i].isIncludedTaxDifference())
{
BigDecimal diff = m_taxes[i].getIncludedTaxDifference();
for (int j = 0; j < dls.length; j++)
{
if (dls[j].getC_Tax_ID() == m_taxes[i].getC_Tax_ID())
{
dls[j].setLineNetAmtDifference(diff);
break;
}
} // for all lines
} // tax difference
} // for all taxes
} // Included Tax difference
// Return Array
return dls;
} // loadLines
/**
* Get Currency Percision
* @return precision
*/
private int getStdPercision()
{
if (m_precision == -1)
m_precision = MCurrency.getStdPrecision(getCtx(), getC_Currency_ID());
return m_precision;
} // getPrecision
/**************************************************************************
* Get Source Currency Balance - subtracts line and tax amounts from total - no rounding
* @return positive amount, if total invoice is bigger than lines
*/
public BigDecimal getBalance()
{
BigDecimal retValue = Env.ZERO;
StringBuffer sb = new StringBuffer (" [");
// Total
retValue = retValue.add(getAmount(Doc.AMTTYPE_Gross));
sb.append(getAmount(Doc.AMTTYPE_Gross));
// - Header Charge
retValue = retValue.subtract(getAmount(Doc.AMTTYPE_Charge));
sb.append("-").append(getAmount(Doc.AMTTYPE_Charge));
// - Tax
for (int i = 0; i < m_taxes.length; i++)
{
retValue = retValue.subtract(m_taxes[i].getAmount());
sb.append("-").append(m_taxes[i].getAmount());
}
// - Lines
for (int i = 0; i < p_lines.length; i++)
{
retValue = retValue.subtract(p_lines[i].getAmtSource());
sb.append("-").append(p_lines[i].getAmtSource());
}
sb.append("]");
//
log.fine(toString() + " Balance=" + retValue + sb.toString());
return retValue;
} // getBalance
/**
* Create Facts (the accounting logic) for
* ARI, ARC, ARF, API, APC.
* <pre>
* ARI, ARF
* Receivables DR
* Charge CR
* TaxDue CR
* Revenue CR
*
* ARC
* Receivables CR
* Charge DR
* TaxDue DR
* Revenue RR
*
* API
* Payables CR
* Charge DR
* TaxCredit DR
* Expense DR
*
* APC
* Payables DR
* Charge CR
* TaxCredit CR
* Expense CR
* </pre>
* @param as accounting schema
* @return Fact
*/
public ArrayList<Fact> createFacts (MAcctSchema as)
{
//
ArrayList<Fact> facts = new ArrayList<Fact>();
// create Fact Header
Fact fact = new Fact(this, as, Fact.POST_Actual);
// Cash based accounting
if (!as.isAccrual())
return facts;
// ** ARI, ARF
if (getDocumentType().equals(DOCTYPE_ARInvoice)
|| getDocumentType().equals(DOCTYPE_ARProForma))
{
BigDecimal grossAmt = getAmount(Doc.AMTTYPE_Gross);
BigDecimal serviceAmt = Env.ZERO;
// Header Charge CR
BigDecimal amt = getAmount(Doc.AMTTYPE_Charge);
if (amt != null && amt.signum() != 0)
fact.createLine(null, getAccount(Doc.ACCTTYPE_Charge, as),
getC_Currency_ID(), null, amt);
// TaxDue CR
for (int i = 0; i < m_taxes.length; i++)
{
amt = m_taxes[i].getAmount();
if (amt != null && amt.signum() != 0)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -