KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > compiere > acct > Doc_MatchInv


1 /******************************************************************************
2  * The contents of this file are subject to the Compiere License Version 1.1
3  * ("License"); You may not use this file except in compliance with the License
4  * You may obtain a copy of the License at http://www.compiere.org/license.html
5  * Software distributed under the License is distributed on an "AS IS" basis,
6  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
7  * the specific language governing rights and limitations under the License.
8  * The Original Code is Compiere ERP & CRM Business Solution
9  * The Initial Developer of the Original Code is Jorg Janke and ComPiere, Inc.
10  * Portions created by Jorg Janke are Copyright (C) 1999-2001 Jorg Janke, parts
11  * created by ComPiere are Copyright (C) ComPiere, Inc.; All Rights Reserved.
12  * Contributor(s): ______________________________________.
13  *****************************************************************************/

14 package org.compiere.acct;
15
16 import java.math.*;
17 import java.util.*;
18 import java.sql.*;
19
20 import org.compiere.util.Env;
21 import org.compiere.util.DB;
22 import org.compiere.model.*;
23
24 /**
25  * Post MatchPO Documents.
26  * <pre>
27  * Table: M_MatchInv (472)
28  * Document Types: MXI
29  * </pre>
30  * @author Jorg Janke
31  * @version $Id: Doc_MatchInv.java,v 1.13 2003/10/10 01:03:41 jjanke Exp $
32  */

33 public class Doc_MatchInv extends Doc
34 {
35     /**
36      * Constructor
37      * @param AD_Client_ID client
38      */

39     protected Doc_MatchInv(int AD_Client_ID)
40     {
41         super(AD_Client_ID);
42     } // Doc_MatchInv
43

44     //
45
private int m_C_InvoiceLine_ID = 0;
46     private int m_M_InOutLine_ID = 0;
47     private ProductInfo m_pi;
48
49     // Receipt
50
private int m_M_Locator_ID;
51     private int m_C_BPartner_Location_ID;
52     private BigDecimal m_InOutQty = new BigDecimal(1.0);
53     // Invoice
54
private BigDecimal m_LineNetAmt = Env.ZERO;
55     private BigDecimal m_InvoiceQty = new BigDecimal(1.0);
56
57     /**
58      * Return TableName of Document
59      * @return M_MatchInv
60      */

61     public String JavaDoc getTableName()
62     {
63         return "M_MatchInv";
64     } // getTableName
65

66     /**
67      * Get Table ID
68      * @return 472
69      */

70     public int getAD_Table_ID()
71     {
72         return 472;
73     } // getAD_Table_ID
74

75     /**
76      * Load Specific Document Details
77      * @param rs result set
78      * @return true if loadDocumentType was set
79      */

80     protected boolean loadDocumentDetails (ResultSet rs)
81     {
82         p_vo.DocumentType = DocVO.DOCTYPE_MatMatchInv;
83         try
84         {
85             p_vo.DateDoc = rs.getTimestamp("DateTrx");
86             m_C_InvoiceLine_ID = rs.getInt("C_InvoiceLine_ID");
87             m_M_InOutLine_ID = rs.getInt("M_InOutLine_ID");
88             p_vo.M_Product_ID = rs.getInt("M_Product_ID");
89             p_vo.Qty = rs.getBigDecimal("Qty");
90             //
91
m_pi = new ProductInfo (p_vo.M_Product_ID);
92             m_pi.setQty(p_vo.Qty);
93         }
94         catch (SQLException e)
95         {
96             log.error ("loadDocumentDetails", e);
97         }
98         // Currency
99
p_vo.C_Currency_ID = Doc.NO_CURRENCY;
100         return false;
101     } // loadDocumentDetails
102

103     /*************************************************************************/
104
105     /**
106      * Get Source Currency Balance - subtracts line and tax amounts from total - no rounding
107      * @return Zero (always balanced)
108      */

109     public BigDecimal getBalance()
110     {
111         return Env.ZERO;
112     } // getBalance
113

114     /**
115      * Create Facts (the accounting logic) for
116      * MXI.
117      * <pre>
118      * NotInvoicedReceipts DR
119      * Expense CR
120      * InvoicePV DR CR (difference)
121      * </pre>
122      * @param as accounting schema
123      * @return Fact
124      */

125     public Fact createFact (AcctSchema as)
126     {
127         // did not find required data
128
p_vo.Error = loadData();
129         if (p_vo.Error != null)
130         {
131             log.error("createFact - " + p_vo.Error);
132             return null;
133         }
134
135         // create Fact Header
136
p_vo.C_Currency_ID = as.getC_Currency_ID();
137         Fact fact = new Fact(this, as, Fact.POST_Actual);
138         // Nothing to do if no Product
139
if (p_vo.M_Product_ID == 0)
140             return fact;
141
142         // NotInvoicedReceipt DR
143
// From Receipt
144
FactLine cr = fact.createLine(null,
145             getAccount(Doc.ACCTTYPE_NotInvoicedReceipts, as),
146             as.getC_Currency_ID(), m_pi.getProductCosts(as), null);
147         cr.setM_Locator_ID(m_M_Locator_ID);
148         cr.setLocationFromBPartner(m_C_BPartner_Location_ID, true); // from Loc
149
cr.setLocationFromLocator(m_M_Locator_ID, false); // to Loc
150
BigDecimal temp = cr.getAcctBalance();
151         cr.updateReverseLine (Doc_InOut.AD_TABLE_ID, m_M_InOutLine_ID,
152             p_vo.Qty.divide(m_InOutQty, BigDecimal.ROUND_HALF_UP).abs());
153         log.debug ("crateFact CR - Amt(" + temp + "->" + cr.getAcctBalance() + ") - " + cr.toString());
154
155         // Expense CR
156
// From Invoice
157
FactLine dr = fact.createLine(null,
158             m_pi.getAccount(ProductInfo.ACCTTYPE_P_Expense, as),
159             as.getC_Currency_ID(), null, m_LineNetAmt);
160         temp = dr.getAcctBalance();
161         dr.updateReverseLine (Doc_Invoice.C_Invoice_TABLE_ID, m_C_InvoiceLine_ID,
162             p_vo.Qty.divide(m_InvoiceQty, BigDecimal.ROUND_HALF_UP).abs());
163         log.debug ("crateFact DR - Amt(" + temp + "->" + dr.getAcctBalance() + ") - " + dr.toString());
164
165         // Invoice Price Variance difference
166
BigDecimal diff = dr.getAcctBalance().add(cr.getAcctBalance()).negate();
167         fact.createLine(null,
168             m_pi.getAccount(ProductInfo.ACCTTYPE_P_IPV, as),
169             as.getC_Currency_ID(), diff);
170         log.debug ("crateFact Difference=" + diff + "; Balance=" + fact.getSourceBalance());
171
172         // Update Costing
173
updateProductInfo(as.getC_AcctSchema_ID(), AcctSchema.COSTING_STANDARD.equals(as.getCostingMethod()));
174         return fact;
175     } // createFact
176

177     /*************************************************************************/
178
179     /**
180      * Load needed Data
181      * @return Error message or null of OK
182      */

183     private String JavaDoc loadData ()
184     {
185         // ** Not Invoiced Receipt Info from Receipt **
186
String JavaDoc sql = "SELECT i.C_BPartner_ID, i.C_BPartner_Location_ID,"
187             + " il.M_Locator_ID, il.C_UOM_ID, il.M_Product_ID, il.MovementQty "
188             + "FROM M_InOut i, M_InOutLine il "
189             + "WHERE i.M_InOut_ID=il.M_InOut_ID"
190             + " AND il.M_InOutLine_ID=?";
191         int M_Product_ID = -1;
192         m_InvoiceQty = new BigDecimal(1.0);
193         try
194         {
195             PreparedStatement pstmt = DB.prepareStatement(sql);
196             pstmt.setInt(1, m_M_InOutLine_ID);
197             ResultSet rs = pstmt.executeQuery();
198             if (rs.next())
199             {
200                 p_vo.C_BPartner_ID = rs.getInt(1);
201                 m_C_BPartner_Location_ID = rs.getInt(2);
202                 m_M_Locator_ID = rs.getInt(3);
203                 m_pi.setQty(p_vo.Qty, rs.getInt(4)); // UOM
204
m_InOutQty = rs.getBigDecimal(6);
205                 //
206
M_Product_ID = rs.getInt(5);
207             }
208             rs.close();
209             pstmt.close();
210         }
211         catch (SQLException e)
212         {
213             log.error ("loadData-1", e);
214         }
215         if (M_Product_ID == -1)
216             return "Not found M_InOutLine_ID=" + m_M_InOutLine_ID;
217         if (M_Product_ID != p_vo.M_Product_ID)
218             return "Product not the same InOut/Match - " + M_Product_ID + "/" + p_vo.M_Product_ID;
219
220         // ** Expense from Invoice **
221
sql = "SELECT PriceActual, C_UOM_ID, M_Product_ID, QtyInvoiced "
222             + "FROM C_InvoiceLine WHERE C_InvoiceLine_ID=?";
223         M_Product_ID = -1;
224         try
225         {
226             PreparedStatement pstmt = DB.prepareStatement(sql);
227             pstmt.setInt(1, m_C_InvoiceLine_ID);
228             ResultSet rs = pstmt.executeQuery();
229             if (rs.next())
230             {
231                 m_LineNetAmt = rs.getBigDecimal(1);
232                 if (m_LineNetAmt != null)
233                     m_LineNetAmt.multiply(p_vo.Qty);
234                 M_Product_ID = rs.getInt(3);
235                 m_InvoiceQty = rs.getBigDecimal(4);
236             }
237             rs.close();
238             pstmt.close();
239         }
240         catch (SQLException e)
241         {
242             log.error ("loadData-2", e);
243         }
244         if (M_Product_ID == -1)
245             return "Not found C_InvoiceLine_ID=" + m_C_InvoiceLine_ID;
246         if (M_Product_ID != p_vo.M_Product_ID)
247             return "Product not the same Invoice/Match - " + M_Product_ID + "/" + p_vo.M_Product_ID;
248         // UOM Conversion ??
249
// p_vo.Qty = m_pi.getQty();
250
return null;
251     } // loadData
252

253     /**
254      * Update Product Info.
255      * - Costing (CostStandardCumQty, CostStandardCumAmt, CostAverageCumQty, CostAverageCumAmt)
256      * @param C_AcctSchema_ID accounting schema
257      * @param standardCosting true if std costing
258      */

259     private void updateProductInfo (int C_AcctSchema_ID, boolean standardCosting)
260     {
261         log.debug ("updateProductInfo - M_MatchInv_ID=" + p_vo.Record_ID);
262
263         // update Product Costing Qty/Amt
264
// requires existence of currency conversion !!
265
StringBuffer JavaDoc sql = new StringBuffer JavaDoc (
266             "UPDATE M_Product_Costing pc "
267             + "SET (CostStandardCumQty,CostStandardCumAmt, CostAverageCumQty,CostAverageCumAmt) = "
268             + "(SELECT CostStandardCumQty + m.Qty,"
269             + " 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,"
270             + " CostAverageCumQty + m.Qty,"
271             + " 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 "
272             + "FROM M_MatchInv m, C_Invoice i, C_InvoiceLine il, C_AcctSchema a "
273             + "WHERE m.C_InvoiceLine_ID=il.C_InvoiceLine_ID"
274             + " AND il.C_Invoice_ID=i.C_Invoice_ID"
275             + " AND pc.C_AcctSchema_ID=a.C_AcctSchema_ID"
276             + " AND pc.M_Product_ID=il.M_Product_ID"
277             + " AND m.M_MatchInv_ID=").append(p_vo.Record_ID).append(") ")
278             .append("WHERE C_AcctSchema_ID=").append(C_AcctSchema_ID)
279             .append(" AND M_Product_ID=").append(p_vo.M_Product_ID);
280         int no = DB.executeUpdate(sql.toString());
281         log.debug ("updateProductInfo - M_Product_Costing - Qty/Amt Updated #=" + no);
282
283         // Update Average Cost
284
sql = new StringBuffer JavaDoc (
285             "UPDATE M_Product_Costing "
286             + "SET CostAverage = CostAverageCumAmt/DECODE(CostAverageCumQty, 0,1, CostAverageCumQty) "
287             + "WHERE C_AcctSchema_ID=").append(C_AcctSchema_ID)
288             .append(" AND M_Product_ID=").append(p_vo.M_Product_ID);
289         no = DB.executeUpdate(sql.toString());
290         log.debug ("updateProductInfo - M_Product_Costing - AvgCost Updated #=" + no);
291
292         // Update Current Cost
293
if (!standardCosting)
294         {
295             sql = new StringBuffer JavaDoc (
296                 "UPDATE M_Product_Costing "
297                 + "SET CurrentCostPrice = CostAverage "
298                 + "WHERE C_AcctSchema_ID=").append(C_AcctSchema_ID)
299                 .append(" AND M_Product_ID=").append(p_vo.M_Product_ID);
300             no = DB.executeUpdate(sql.toString());
301             log.debug ("updateProductInfo - M_Product_Costing - CurrentCost Updated=" + no);
302         }
303     } // updateProductInfo
304

305 } // Doc_MatchInv
306
Popular Tags