📄 doc_order.java
字号:
* Create Facts (the accounting logic) for
* SOO, POO.
* <pre>
* Reservation (release)
* Expense DR
* Offset CR
* Commitment
* (to be released by Invoice Matching)
* Expense CR
* Offset DR
* </pre>
* @param as accounting schema
* @return Fact
*/
public ArrayList<Fact> createFacts (MAcctSchema as)
{
ArrayList<Fact> facts = new ArrayList<Fact>();
// Purchase Order
if (getDocumentType().equals(DOCTYPE_POrder))
{
updateProductPO(as);
updateProductInfo(as.getC_AcctSchema_ID());
BigDecimal grossAmt = getAmount(Doc.AMTTYPE_Gross);
// Commitment
if (as.isCreateCommitment())
{
Fact fact = new Fact(this, as, Fact.POST_Commitment);
BigDecimal total = Env.ZERO;
for (int i = 0; i < p_lines.length; i++)
{
DocLine line = p_lines[i];
BigDecimal cost = line.getAmtSource();
total = total.add(cost);
// Account
MAccount expense = line.getAccount(ProductCost.ACCTTYPE_P_Expense, as);
FactLine fl = fact.createLine (line, expense,
getC_Currency_ID(), cost, null);
}
// Offset
MAccount offset = getAccount(ACCTTYPE_CommitmentOffset, as);
if (offset == null)
{
p_Error = "@NotFound@ @CommitmentOffset_Acct@";
log.log(Level.SEVERE, p_Error);
return null;
}
fact.createLine (null, offset,
getC_Currency_ID(), null, total);
//
facts.add(fact);
}
// Reverse Reservation
if (as.isCreateReservation())
{
Fact fact = new Fact(this, as, Fact.POST_Reservation);
BigDecimal total = Env.ZERO;
if (m_requisitions == null)
m_requisitions = loadRequisitions();
for (int i = 0; i < m_requisitions.length; i++)
{
DocLine line = m_requisitions[i];
BigDecimal cost = line.getAmtSource();
total = total.add(cost);
// Account
MAccount expense = line.getAccount(ProductCost.ACCTTYPE_P_Expense, as);
FactLine fl = fact.createLine (line, expense,
getC_Currency_ID(), null, cost);
}
// Offset
MAccount offset = getAccount(ACCTTYPE_CommitmentOffset, as);
if (offset == null)
{
p_Error = "@NotFound@ @CommitmentOffset_Acct@";
log.log(Level.SEVERE, p_Error);
return null;
}
fact.createLine (null, offset,
getC_Currency_ID(), total, null);
//
facts.add(fact);
} // reservations
}
// SO
return facts;
} // createFact
/**
* Update ProductPO PriceLastPO
* @param as accounting schema
*/
private void updateProductPO(MAcctSchema as)
{
MClientInfo ci = MClientInfo.get(getCtx(), as.getAD_Client_ID());
if (ci.getC_AcctSchema1_ID() != as.getC_AcctSchema_ID())
return;
StringBuffer sql = new StringBuffer (
"UPDATE M_Product_PO po "
+ "SET PriceLastPO = (SELECT currencyConvert(ol.PriceActual,ol.C_Currency_ID,po.C_Currency_ID,o.DateOrdered,o.C_ConversionType_ID,o.AD_Client_ID,o.AD_Org_ID) "
+ "FROM C_Order o, C_OrderLine ol "
+ "WHERE o.C_Order_ID=ol.C_Order_ID"
+ " AND po.M_Product_ID=ol.M_Product_ID AND po.C_BPartner_ID=o.C_BPartner_ID"
+ " AND ROWNUM=1 AND o.C_Order_ID=").append(get_ID()).append(") ")
.append("WHERE EXISTS (SELECT * "
+ "FROM C_Order o, C_OrderLine ol "
+ "WHERE o.C_Order_ID=ol.C_Order_ID"
+ " AND po.M_Product_ID=ol.M_Product_ID AND po.C_BPartner_ID=o.C_BPartner_ID"
+ " AND o.C_Order_ID=").append(get_ID()).append(")");
int no = DB.executeUpdate(sql.toString(), getTrxName());
log.fine("Updated=" + no);
} // updateProductPO
/**
* Get Commitments
* @param doc document
* @param maxQty Qty invoiced/matched
* @param C_InvoiceLine_ID invoice line
* @return commitments (order lines)
*/
protected static DocLine[] getCommitments(Doc doc, BigDecimal maxQty, int C_InvoiceLine_ID)
{
int precision = -1;
//
ArrayList<DocLine> list = new ArrayList<DocLine>();
String sql = "SELECT * FROM C_OrderLine ol "
+ "WHERE EXISTS "
+ "(SELECT * FROM C_InvoiceLine il "
+ "WHERE il.C_OrderLine_ID=ol.C_OrderLine_ID"
+ " AND il.C_InvoiceLine_ID=?)"
+ " OR EXISTS "
+ "(SELECT * FROM M_MatchPO po "
+ "WHERE po.C_OrderLine_ID=ol.C_OrderLine_ID"
+ " AND po.C_InvoiceLine_ID=?)";
PreparedStatement pstmt = null;
try
{
pstmt = DB.prepareStatement (sql, null);
pstmt.setInt (1, C_InvoiceLine_ID);
pstmt.setInt (2, C_InvoiceLine_ID);
ResultSet rs = pstmt.executeQuery ();
while (rs.next ())
{
if (maxQty.signum() == 0)
continue;
MOrderLine line = new MOrderLine (doc.getCtx(), rs, null);
DocLine docLine = new DocLine (line, doc);
// Currency
if (precision == -1)
{
doc.setC_Currency_ID(docLine.getC_Currency_ID());
precision = MCurrency.getStdPrecision(doc.getCtx(), docLine.getC_Currency_ID());
}
// Qty
BigDecimal Qty = line.getQtyOrdered().max(maxQty);
docLine.setQty(Qty, false);
//
BigDecimal PriceActual = line.getPriceActual();
BigDecimal PriceCost = line.getPriceCost();
BigDecimal LineNetAmt = null;
if (PriceCost != null && PriceCost.signum() != 0)
LineNetAmt = Qty.multiply(PriceCost);
else if (Qty.equals(maxQty))
LineNetAmt = line.getLineNetAmt();
else
LineNetAmt = Qty.multiply(PriceActual);
maxQty = maxQty.subtract(Qty);
docLine.setAmount (LineNetAmt); // DR
BigDecimal PriceList = line.getPriceList();
int C_Tax_ID = docLine.getC_Tax_ID();
// Correct included Tax
if (C_Tax_ID != 0 && line.getParent().isTaxIncluded())
{
MTax tax = MTax.get(doc.getCtx(), C_Tax_ID);
if (!tax.isZeroTax())
{
BigDecimal LineNetAmtTax = tax.calculateTax(LineNetAmt, true, precision);
s_log.fine("LineNetAmt=" + LineNetAmt + " - Tax=" + LineNetAmtTax);
LineNetAmt = LineNetAmt.subtract(LineNetAmtTax);
BigDecimal PriceListTax = tax.calculateTax(PriceList, true, precision);
PriceList = PriceList.subtract(PriceListTax);
}
} // correct included Tax
docLine.setAmount (LineNetAmt, PriceList, Qty);
list.add(docLine);
}
rs.close ();
pstmt.close ();
pstmt = null;
}
catch (Exception e)
{
s_log.log (Level.SEVERE, sql, e);
}
try
{
if (pstmt != null)
pstmt.close ();
pstmt = null;
}
catch (Exception e)
{
pstmt = null;
}
// Return Array
DocLine[] dl = new DocLine[list.size()];
list.toArray(dl);
return dl;
} // getCommitments
/**
* Get Commitment Release.
* Called from MatchInv for accrual and Allocation for Cash Based
* @param as accounting schema
* @param doc doc
* @param Qty qty invoiced/matched
* @param C_InvoiceLine_ID line
* @param multiplier 1 for accrual
* @return Fact
*/
protected static Fact getCommitmentRelease(MAcctSchema as, Doc doc,
BigDecimal Qty, int C_InvoiceLine_ID, BigDecimal multiplier)
{
Fact fact = new Fact(doc, as, Fact.POST_Commitment);
DocLine[] commitments = Doc_Order.getCommitments(doc, Qty,
C_InvoiceLine_ID);
BigDecimal total = Env.ZERO;
int C_Currency_ID = -1;
for (int i = 0; i < commitments.length; i++)
{
DocLine line = commitments[i];
if (C_Currency_ID == -1)
C_Currency_ID = line.getC_Currency_ID();
else if (C_Currency_ID != line.getC_Currency_ID())
{
doc.p_Error = "Different Currencies of Order Lines";
s_log.log(Level.SEVERE, doc.p_Error);
return null;
}
BigDecimal cost = line.getAmtSource().multiply(multiplier);
total = total.add(cost);
// Account
MAccount expense = line.getAccount(ProductCost.ACCTTYPE_P_Expense, as);
FactLine fl = fact.createLine (line, expense,
C_Currency_ID, null, cost);
}
// Offset
MAccount offset = doc.getAccount(ACCTTYPE_CommitmentOffset, as);
if (offset == null)
{
doc.p_Error = "@NotFound@ @CommitmentOffset_Acct@";
s_log.log(Level.SEVERE, doc.p_Error);
return null;
}
fact.createLine (null, offset,
C_Currency_ID, total, null);
return fact;
} // getCommitmentRelease
/**************************************************************************
* Update Product Info (old)
* - Costing (PriceLastPO)
* - PO (PriceLastPO)
* @param C_AcctSchema_ID accounting schema
* @deprecated old costing
*/
private void updateProductInfo (int C_AcctSchema_ID)
{
log.fine("C_Order_ID=" + get_ID());
/** @todo Last.. would need to compare document/last updated date
* would need to maintain LastPriceUpdateDate on _PO and _Costing */
// update Product Costing
// requires existence of currency conversion !!
// if there are multiple lines of the same product last price uses first
StringBuffer sql = new StringBuffer (
"UPDATE M_Product_Costing pc "
+ "SET PriceLastPO = "
+ "(SELECT currencyConvert(ol.PriceActual,ol.C_Currency_ID,a.C_Currency_ID,o.DateOrdered,o.C_ConversionType_ID,o.AD_Client_ID,o.AD_Org_ID) "
+ "FROM C_Order o, C_OrderLine ol, C_AcctSchema a "
+ "WHERE o.C_Order_ID=ol.C_Order_ID"
+ " AND pc.M_Product_ID=ol.M_Product_ID AND pc.C_AcctSchema_ID=a.C_AcctSchema_ID"
+ " AND ROWNUM=1"
+ " AND pc.C_AcctSchema_ID=").append(C_AcctSchema_ID).append(" AND o.C_Order_ID=")
.append(get_ID()).append(") ")
.append("WHERE EXISTS (SELECT * "
+ "FROM C_Order o, C_OrderLine ol, C_AcctSchema a "
+ "WHERE o.C_Order_ID=ol.C_Order_ID"
+ " AND pc.M_Product_ID=ol.M_Product_ID AND pc.C_AcctSchema_ID=a.C_AcctSchema_ID"
+ " AND pc.C_AcctSchema_ID=").append(C_AcctSchema_ID).append(" AND o.C_Order_ID=")
.append(get_ID()).append(")");
int no = DB.executeUpdate(sql.toString(), getTrxName());
log.fine("M_Product_Costing - Updated=" + no);
} // updateProductInfo
} // Doc_Order
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -