📄 doc_matchinv.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 Business Solution
* The Initial Developer of the Original Code is Jorg Janke and ComPiere, Inc.
* Portions created by Jorg Janke are Copyright (C) 1999-2001 Jorg Janke, parts
* created by ComPiere are Copyright (C) ComPiere, Inc.; All Rights Reserved.
* Contributor(s): ______________________________________.
*****************************************************************************/
package org.compiere.acct;
import java.math.*;
import java.util.*;
import java.sql.*;
import org.compiere.util.Env;
import org.compiere.util.DB;
import org.compiere.model.*;
/**
* Post MatchPO Documents.
* <pre>
* Table: M_MatchInv (472)
* Document Types: MXI
* </pre>
* @author Jorg Janke
* @version $Id: Doc_MatchInv.java,v 1.11 2003/03/19 06:47:32 jjanke Exp $
*/
public class Doc_MatchInv extends Doc
{
/**
* Constructor
* @param AD_Client_ID client
*/
protected Doc_MatchInv(int AD_Client_ID)
{
super(AD_Client_ID);
} // Doc_MatchInv
//
private int m_C_InvoiceLine_ID = 0;
private int m_M_InOutLine_ID = 0;
private ProductInfo m_pi;
// Receipt
private int m_M_Locator_ID;
private int m_C_BPartner_Location_ID;
private BigDecimal m_InOutQty = new BigDecimal(1.0);
// Invoice
private BigDecimal m_LineNetAmt = Env.ZERO;
private BigDecimal m_InvoiceQty = new BigDecimal(1.0);
/**
* Return TableName of Document
* @return M_MatchInv
*/
public String getTableName()
{
return "M_MatchInv";
} // getTableName
/**
* Get Table ID
* @return 472
*/
public int getAD_Table_ID()
{
return 472;
} // getAD_Table_ID
/**
* Load Specific Document Details
* @param rs result set
* @return true if loadDocumentType was set
*/
protected boolean loadDocumentDetails (ResultSet rs)
{
p_vo.DocumentType = DocVO.DOCTYPE_MatMatchInv;
try
{
p_vo.DateDoc = rs.getTimestamp("DateTrx");
m_C_InvoiceLine_ID = rs.getInt("C_InvoiceLine_ID");
m_M_InOutLine_ID = rs.getInt("M_InOutLine_ID");
p_vo.M_Product_ID = rs.getInt("M_Product_ID");
p_vo.Qty = rs.getBigDecimal("Qty");
//
m_pi = new ProductInfo (p_vo.M_Product_ID);
m_pi.setQty(p_vo.Qty);
}
catch (SQLException e)
{
log.error ("loadDocumentDetails", e);
}
// Currency
p_vo.C_Currency_ID = Doc.NO_CURRENCY;
return false;
} // loadDocumentDetails
/*************************************************************************/
/**
* Get Source Currency Balance - subtracts line and tax amounts from total - no rounding
* @return Zero (always balanced)
*/
public BigDecimal getBalance()
{
return Env.ZERO;
} // getBalance
/**
* Create Facts (the accounting logic) for
* MXI.
* <pre>
* NotInvoicedReceipts DR
* Expense CR
* InvoicePV DR CR (difference)
* </pre>
* @param as accounting schema
* @return Fact
*/
public Fact createFact (AcctSchema as)
{
// did not find required data
p_vo.Error = loadData();
if (p_vo.Error != null)
{
log.error("createFact - " + p_vo.Error);
return null;
}
// create Fact Header
p_vo.C_Currency_ID = as.getC_Currency_ID();
Fact fact = new Fact(this, as, Fact.POST_Actual);
// Nothing to do if no Product
if (p_vo.M_Product_ID == 0)
return fact;
// NotInvoicedReceipt DR
// From Receipt
FactLine cr = fact.createLine(null,
getAccount(Doc.ACCTTYPE_NotInvoicedReceipts, as),
as.getC_Currency_ID(), m_pi.getProductCosts(as), null);
cr.setM_Locator_ID(m_M_Locator_ID);
cr.setLocationFromBPartner(m_C_BPartner_Location_ID, true); // from Loc
cr.setLocationFromLocator(m_M_Locator_ID, false); // to Loc
BigDecimal temp = cr.getAcctBalance();
cr.updateReverseLine (Doc_InOut.M_InOut_TABLE_ID, m_M_InOutLine_ID,
p_vo.Qty.divide(m_InOutQty, BigDecimal.ROUND_HALF_UP).abs());
log.debug ("crateFact CR - Amt(" + temp + "->" + cr.getAcctBalance() + ") - " + cr.toString());
// Expense CR
// From Invoice
FactLine dr = fact.createLine(null,
m_pi.getAccount(ProductInfo.ACCTTYPE_P_Expense, as),
as.getC_Currency_ID(), null, m_LineNetAmt);
temp = dr.getAcctBalance();
dr.updateReverseLine (Doc_Invoice.C_Invoice_TABLE_ID, m_C_InvoiceLine_ID,
p_vo.Qty.divide(m_InvoiceQty, BigDecimal.ROUND_HALF_UP).abs());
log.debug ("crateFact DR - Amt(" + temp + "->" + dr.getAcctBalance() + ") - " + dr.toString());
// Invoice Price Variance difference
BigDecimal diff = dr.getAcctBalance().add(cr.getAcctBalance()).negate();
fact.createLine(null,
m_pi.getAccount(ProductInfo.ACCTTYPE_P_IPV, as),
as.getC_Currency_ID(), diff);
log.debug ("crateFact Difference=" + diff + "; Balance=" + fact.getSourceBalance());
// Update Costing
updateProductInfo(as.getC_AcctSchema_ID(), as.COSTING_STANDARD.equals(as.getCostingMethod()));
return fact;
} // createFact
/*************************************************************************/
/**
* Load needed Data
* @return Error message or null of OK
*/
private String loadData ()
{
// ** Not Invoiced Receipt Info from Receipt **
String sql = "SELECT i.C_BPartner_ID, i.C_BPartner_Location_ID,"
+ " il.M_Locator_ID, il.C_UOM_ID, il.M_Product_ID, il.MovementQty "
+ "FROM M_InOut i, M_InOutLine il "
+ "WHERE i.M_InOut_ID=il.M_InOut_ID"
+ " AND il.M_InOutLine_ID=?";
int M_Product_ID = -1;
m_InvoiceQty = new BigDecimal(1.0);
try
{
PreparedStatement pstmt = DB.prepareStatement(sql);
pstmt.setInt(1, m_M_InOutLine_ID);
ResultSet rs = pstmt.executeQuery();
if (rs.next())
{
p_vo.C_BPartner_ID = rs.getInt(1);
m_C_BPartner_Location_ID = rs.getInt(2);
m_M_Locator_ID = rs.getInt(3);
m_pi.setQty(p_vo.Qty, rs.getInt(4)); // UOM
m_InOutQty = rs.getBigDecimal(6);
//
M_Product_ID = rs.getInt(5);
}
rs.close();
pstmt.close();
}
catch (SQLException e)
{
log.error ("loadData-1", e);
}
if (M_Product_ID == -1)
return "Not found M_InOutLine_ID=" + m_M_InOutLine_ID;
if (M_Product_ID != p_vo.M_Product_ID)
return "Product not the same InOut/Match - " + M_Product_ID + "/" + p_vo.M_Product_ID;
// ** Expense from Invoice **
sql = "SELECT PriceActual, C_UOM_ID, M_Product_ID, QtyInvoiced "
+ "FROM C_InvoiceLine WHERE C_InvoiceLine_ID=?";
M_Product_ID = -1;
try
{
PreparedStatement pstmt = DB.prepareStatement(sql);
pstmt.setInt(1, m_C_InvoiceLine_ID);
ResultSet rs = pstmt.executeQuery();
if (rs.next())
{
m_LineNetAmt = rs.getBigDecimal(1);
if (m_LineNetAmt != null)
m_LineNetAmt.multiply(p_vo.Qty);
M_Product_ID = rs.getInt(3);
m_InvoiceQty = rs.getBigDecimal(4);
}
rs.close();
pstmt.close();
}
catch (SQLException e)
{
log.error ("loadData-2", e);
}
if (M_Product_ID == -1)
return "Not found C_InvoiceLine_ID=" + m_C_InvoiceLine_ID;
if (M_Product_ID != p_vo.M_Product_ID)
return "Product not the same Invoice/Match - " + M_Product_ID + "/" + p_vo.M_Product_ID;
// UOM Conversion ??
// p_vo.Qty = m_pi.getQty();
return null;
} // loadData
/**
* Update Product Info.
* - Costing (CostStandardCumQty, CostStandardCumAmt, CostAverageCumQty, CostAverageCumAmt)
* @param C_AcctSchema_ID accounting schema
* @param standardCosting true if std costing
*/
private void updateProductInfo (int C_AcctSchema_ID, boolean standardCosting)
{
log.debug ("updateProductInfo - M_MatchInv_ID=" + p_vo.Record_ID);
// update Product Costing Qty/Amt
// requires existence of currency conversion !!
StringBuffer sql = new StringBuffer (
"UPDATE M_Product_Costing pc "
+ "SET (CostStandardCumQty,CostStandardCumAmt, CostAverageCumQty,CostAverageCumAmt) = "
+ "(SELECT CostStandardCumQty + m.Qty,"
+ " CostStandardCumAmt + C_Currency_Convert(il.PriceActual,i.C_Currency_ID,a.C_Currency_ID,i.DateInvoiced,null,i.AD_Client_ID,i.AD_Org_ID)*m.Qty,"
+ " CostAverageCumQty + m.Qty,"
+ " CostAverageCumAmt + C_Currency_Convert(il.PriceActual,i.C_Currency_ID,a.C_Currency_ID,i.DateInvoiced,null,i.AD_Client_ID,i.AD_Org_ID)*m.Qty "
+ "FROM M_MatchInv m, C_Invoice i, C_InvoiceLine il, C_AcctSchema a "
+ "WHERE m.C_InvoiceLine_ID=il.C_InvoiceLine_ID"
+ " AND il.C_Invoice_ID=i.C_Invoice_ID"
+ " AND pc.C_AcctSchema_ID=a.C_AcctSchema_ID"
+ " AND pc.M_Product_ID=il.M_Product_ID"
+ " AND m.M_MatchInv_ID=").append(p_vo.Record_ID).append(") ")
.append("WHERE C_AcctSchema_ID=").append(C_AcctSchema_ID)
.append(" AND M_Product_ID=").append(p_vo.M_Product_ID);
int no = DB.executeUpdate(sql.toString());
log.debug ("updateProductInfo - M_Product_Costing - Qty/Amt Updated #=" + no);
// Update Average Cost
sql = new StringBuffer (
"UPDATE M_Product_Costing "
+ "SET CostAverage = CostAverageCumAmt/DECODE(CostAverageCumQty, 0,1, CostAverageCumQty) "
+ "WHERE C_AcctSchema_ID=").append(C_AcctSchema_ID)
.append(" AND M_Product_ID=").append(p_vo.M_Product_ID);
no = DB.executeUpdate(sql.toString());
log.debug ("updateProductInfo - M_Product_Costing - AvgCost Updated #=" + no);
// Update Current Cost
if (!standardCosting)
{
sql = new StringBuffer (
"UPDATE M_Product_Costing "
+ "SET CurrentCostPrice = CostAverage "
+ "WHERE C_AcctSchema_ID=").append(C_AcctSchema_ID)
.append(" AND M_Product_ID=").append(p_vo.M_Product_ID);
no = DB.executeUpdate(sql.toString());
log.debug ("updateProductInfo - M_Product_Costing - CurrentCost Updated=" + no);
}
} // updateProductInfo
} // Doc_MatchInv
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -