📄 doc_order.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 Order Documents.
* <pre>
* Table: C_Order (259)
* Document Types: SOO, POO
* </pre>
* @author Jorg Janke
* @version $Id: Doc_Order.java,v 1.14 2006/02/12 02:19:20 jjanke Exp $
*/
public class Doc_Order extends Doc
{
/**
* Constructor
* @param ass accounting schemata
* @param rs record
* @parem trxName trx
*/
protected Doc_Order (MAcctSchema[] ass, ResultSet rs, String trxName)
{
super (ass, MOrder.class, rs, null, trxName);
} // Doc_Order
/** Contained Optional Tax Lines */
private DocTax[] m_taxes = null;
/** Requisitions */
private DocLine[] m_requisitions = null;
/** Order Currency Precision */
private int m_precision = -1;
/**
* Load Specific Document Details
* @return error message or null
*/
protected String loadDocumentDetails ()
{
MOrder order = (MOrder)getPO();
setDateDoc(order.getDateOrdered());
setIsTaxIncluded(order.isTaxIncluded());
// Amounts
setAmount(AMTTYPE_Gross, order.getGrandTotal());
setAmount(AMTTYPE_Net, order.getTotalLines());
setAmount(AMTTYPE_Charge, order.getChargeAmt());
// Contained Objects
m_taxes = loadTaxes();
p_lines = loadLines(order);
// log.fine( "Lines=" + p_lines.length + ", Taxes=" + m_taxes.length);
return null;
} // loadDocumentDetails
/**
* Load Invoice Line
* @return DocLine Array
*/
private DocLine[] loadLines(MOrder order)
{
ArrayList<DocLine> list = new ArrayList<DocLine>();
MOrderLine[] lines = order.getLines();
for (int i = 0; i < lines.length; i++)
{
MOrderLine line = lines[i];
DocLine docLine = new DocLine (line, this);
BigDecimal Qty = line.getQtyOrdered();
docLine.setQty(Qty, order.isSOTrx());
//
BigDecimal PriceActual = line.getPriceActual();
BigDecimal PriceCost = null;
if (getDocumentType().equals(DOCTYPE_POrder)) // PO
PriceCost = line.getPriceCost();
BigDecimal LineNetAmt = null;
if (PriceCost != null && PriceCost.signum() != 0)
LineNetAmt = Qty.multiply(PriceCost);
else
LineNetAmt = line.getLineNetAmt();
docLine.setAmount (LineNetAmt); // DR
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, getStdPrecision());
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, getStdPrecision());
PriceList = PriceList.subtract(PriceListTax);
}
} // correct included Tax
docLine.setAmount (LineNetAmt, PriceList, Qty);
list.add(docLine);
}
// Return Array
DocLine[] dl = new DocLine[list.size()];
list.toArray(dl);
return dl;
} // loadLines
/**
* Load Requisitions
* @return requisition lines of Order
*/
private DocLine[] loadRequisitions ()
{
MOrder order = (MOrder)getPO();
MOrderLine[] oLines = order.getLines();
HashMap<Integer,BigDecimal> qtys = new HashMap<Integer,BigDecimal>();
for (int i = 0; i < oLines.length; i++)
{
MOrderLine line = oLines[i];
qtys.put(new Integer(line.getC_OrderLine_ID()), line.getQtyOrdered());
}
//
ArrayList<DocLine> list = new ArrayList<DocLine>();
String sql = "SELECT * FROM M_RequisitionLine rl "
+ "WHERE EXISTS (SELECT * FROM C_Order o "
+ " INNER JOIN C_OrderLine ol ON (o.C_Order_ID=ol.C_Order_ID) "
+ "WHERE ol.C_OrderLine_ID=rl.C_OrderLine_ID"
+ " AND o.C_Order_ID=?) "
+ "ORDER BY rl.C_OrderLine_ID";
PreparedStatement pstmt = null;
try
{
pstmt = DB.prepareStatement (sql, null);
pstmt.setInt (1, order.getC_Order_ID());
ResultSet rs = pstmt.executeQuery ();
while (rs.next ())
{
MRequisitionLine line = new MRequisitionLine (getCtx(), rs, null);
DocLine docLine = new DocLine (line, this);
// Quantity - not more then OrderLine
// Issue: Split of Requisition to multiple POs & different price
Integer key = new Integer(line.getC_OrderLine_ID());
BigDecimal maxQty = qtys.get(key);
BigDecimal Qty = line.getQty().max(maxQty);
if (Qty.signum() == 0)
continue;
docLine.setQty (Qty, false);
qtys.put(key, maxQty.subtract(Qty));
//
BigDecimal PriceActual = line.getPriceActual();
BigDecimal LineNetAmt = line.getLineNetAmt();
if (line.getQty().compareTo(Qty) != 0)
LineNetAmt = PriceActual.multiply(Qty);
docLine.setAmount (LineNetAmt); // DR
list.add (docLine);
}
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;
}
// Return Array
DocLine[] dls = new DocLine[list.size ()];
list.toArray (dls);
return dls;
} // loadRequisitions
/**
* Get Currency Precision
* @return precision
*/
private int getStdPrecision()
{
if (m_precision == -1)
m_precision = MCurrency.getStdPrecision(getCtx(), getC_Currency_ID());
return m_precision;
} // getPrecision
/**
* 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_OrderTax it "
+ "WHERE t.C_Tax_ID=it.C_Tax_ID AND it.C_Order_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);
list.add(taxLine);
}
//
rs.close();
pstmt.close();
}
catch (SQLException e)
{
log.log(Level.SEVERE, sql, e);
}
// Return Array
DocTax[] tl = new DocTax[list.size()];
list.toArray(tl);
return tl;
} // loadTaxes
/**************************************************************************
* 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 = new BigDecimal(0.0);
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
if (m_taxes != null)
{
for (int i = 0; i < m_taxes.length; i++)
{
retValue = retValue.subtract(m_taxes[i].getAmount());
sb.append("-").append(m_taxes[i].getAmount());
}
}
// - Lines
if (p_lines != null)
{
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("]");
}
//
if (retValue.signum() != 0 // Sum of Cost(vs. Price) in lines may not add up
&& getDocumentType().equals(DOCTYPE_POrder)) // PO
{
log.fine(toString() + " Balance=" + retValue + sb.toString() + " (ignored)");
retValue = Env.ZERO;
}
else
log.fine(toString() + " Balance=" + retValue + sb.toString());
return retValue;
} // getBalance
/*************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -