KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openbravo > erpCommon > ad_forms > Fact


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

17 package org.openbravo.erpCommon.ad_forms;
18
19 import org.openbravo.base.secureApp.VariablesSecureApp;
20 import java.math.*;
21 import java.util.*;
22 import javax.servlet.*;
23 import org.apache.log4j.Logger ;
24 // imports for transactions
25
import org.openbravo.database.ConnectionProvider;
26 import java.sql.Connection JavaDoc;
27
28
29
30 public class Fact {
31   static Logger log4jFact = Logger.getLogger(Fact.class);
32     
33     /** Document */
34     private AcctServer m_doc = null;
35
36     /** Accounting Schema */
37     private AcctSchema m_acctSchema = null;
38
39     /** Posting Type */
40     private String JavaDoc m_postingType = null;
41
42
43     public final BigDecimal ZERO = new BigDecimal("0");
44
45
46     /** Actual Balance Type */
47     public static final String JavaDoc POST_Actual = "A";
48     /** Budget Balance Type */
49     public static final String JavaDoc POST_Budget = "B";
50     /** Encumbrance Posting */
51     public static final String JavaDoc POST_Commitment = "C";
52
53     /** Lines */
54     private ArrayList<Object JavaDoc> m_lines = new ArrayList<Object JavaDoc>();
55
56
57
58     /**
59      * Constructor
60      * @param document pointer to document
61      * @param acctSchema Account Schema to create accounts
62      * @param defaultPostingType the default Posting type (actual,..) for this posting
63      */

64     public Fact (AcctServer document, AcctSchema acctSchema, String JavaDoc defaultPostingType) {
65         m_doc = document;
66         m_acctSchema = acctSchema;
67         m_postingType = defaultPostingType;
68         //
69
log4jFact.debug ("Fact[" + m_doc.DocumentNo + "," + "AcctSchema[" + m_acctSchema.m_C_AcctSchema_ID + "-" + m_acctSchema.m_Name
70             + ",PostType=" + m_postingType + "]");
71     } // Fact
72

73     /**
74      * Dispose
75      */

76     public void dispose(){
77         for (int i = 0; i < m_lines.size(); i++)
78             ((FactLine)m_lines.get(i)).dispose();
79         m_lines.clear();
80         m_lines = null;
81     } // dispose
82

83     /**
84      * Create and convert Fact Line.
85      * Used to create a DR and/or CR entry
86      *
87      * @param docLine the document line or null
88      * @param account if null, line is not created
89      * @param C_Currency_ID the currency
90      * @param debitAmt debit amount, can be null
91      * @param creditAmt credit amount, can be null
92      * @return Fact Line
93      */

94     public FactLine createLine (DocLine docLine, Account account,
95         String JavaDoc C_Currency_ID, String JavaDoc debitAmt, String JavaDoc creditAmt, String JavaDoc Fact_Acct_Group_ID, String JavaDoc SeqNo, String JavaDoc DocBaseType,ConnectionProvider conn){
96         log4jFact.debug ("createLine - " + account + " - Dr=" + debitAmt + ", Cr=" + creditAmt);
97         log4jFact.debug("Starting createline");
98         // Data Check
99
if (account == null){
100             log4jFact.debug("end of create line");
101             return null;
102         }
103         //
104
log4jFact.debug("createLine - Fact_Acct_Group_ID = " + Fact_Acct_Group_ID);
105         FactLine line = new FactLine (m_doc.AD_Table_ID, m_doc.Record_ID,
106             docLine == null ? "" : docLine.m_TrxLine_ID, Fact_Acct_Group_ID, SeqNo, DocBaseType);
107         log4jFact.debug("createLine - line.m_Fact_Acct_Group_ID = " + line.m_Fact_Acct_Group_ID);
108         log4jFact.debug("Object created");
109         line.setDocumentInfo(m_doc, docLine);
110         line.setAD_Org_ID(m_doc.AD_Org_ID);
111         //if (docLine!=null) line.setAD_Org_ID(docLine.m_AD_Org_ID);
112
log4jFact.debug("document info set");
113         line.setAccount(m_acctSchema, account);
114         log4jFact.debug("account set");
115
116         log4jFact.debug("C_Currency_ID: " + C_Currency_ID + " - debitAmt: " + debitAmt + " - creditAmt: " + creditAmt);
117         // Amounts - one needs to be both not zero
118
if (!line.setAmtSource(C_Currency_ID, debitAmt, creditAmt))
119             return null;
120         log4jFact.debug("C_Currency_ID: " + m_acctSchema.getC_Currency_ID() + " - DateAcct: " + m_doc.DateAcct + " - CurrencyRateType: " + m_acctSchema.getCurrencyRateType());
121         // Convert
122
line.convert(m_acctSchema.getC_Currency_ID(), m_doc.DateAcct, m_acctSchema.getCurrencyRateType(),conn);
123         // Optionally overwrite Acct Amount
124
if (docLine != null && !docLine.m_AmtAcctDr.equals("") && !docLine.m_AmtAcctCr.equals(""))
125             line.setAmtAcct(docLine.m_AmtAcctDr, docLine.m_AmtAcctCr);
126         // Info
127
line.setJournalInfo(m_doc.GL_Budget_ID, m_doc.GL_Category_ID);
128         line.setPostingType(m_postingType);
129         // Set Info
130
line.setDocumentInfo(m_doc, docLine);
131         //
132
log4jFact.debug ("createLine - " + m_doc.DocumentNo);
133         log4jFact.debug("********************* Fact - createLine - DocumentNo - " + m_doc.DocumentNo + " - m_lines.size() - " + m_lines.size());
134         m_lines.add(line);
135         return line;
136     } // createLine
137

138
139     /**
140      * Add Fact Line
141      * @param line fact line
142      */

143     void add (FactLine line){
144         m_lines.add(line);
145     } // add
146

147     /**
148      * Create and convert Fact Line.
149      * Used to create either a DR or CR entry
150      *
151      * @param docLine Document Line or null
152      * @param accountDr Account to be used if Amt is DR balance
153      * @param accountCr Account to be used if Amt is CR balance
154      * @param C_Currency_ID Currency
155      * @param Amt if negative Cr else Dr
156      * @return FactLine
157      */

158     public FactLine createLine (DocLine docLine, Account accountDr, Account accountCr,String JavaDoc C_Currency_ID, String JavaDoc Amt, String JavaDoc Fact_Acct_Group_ID, String JavaDoc SeqNo, String JavaDoc DocBaseType, ConnectionProvider conn){
159         BigDecimal m_Amt = ZERO;
160         try {
161             if(!Amt.equals("")) m_Amt = new BigDecimal(Amt);
162         } catch (Exception JavaDoc ex) {
163             ex.printStackTrace();
164             //System.out.println("******************** Amount: " + ((Amt!=null)?Amt:"null"));
165
}
166         if (m_Amt.compareTo(ZERO) < 0)
167             return createLine (docLine, accountCr, C_Currency_ID, "", m_Amt.abs().toString(), Fact_Acct_Group_ID, SeqNo, DocBaseType,conn);
168         else
169             return createLine (docLine, accountDr, C_Currency_ID, m_Amt.toString(), "", Fact_Acct_Group_ID, SeqNo, DocBaseType,conn);
170     } // createLine
171

172     /**
173      * Create and convert Fact Line.
174      * Used to create either a DR or CR entry
175      *
176      * @param docLine Document line or null
177      * @param account Account to be used
178      * @param C_Currency_ID Currency
179      * @param Amt if negative Cr else Dr
180      * @return FactLine
181      */

182     public FactLine createLine (DocLine docLine, Account account,String JavaDoc C_Currency_ID, String JavaDoc Amt, String JavaDoc Fact_Acct_Group_ID, String JavaDoc SeqNo, String JavaDoc DocBaseType, ConnectionProvider conn){
183         BigDecimal m_Amt = ZERO;
184         try {
185             if(!Amt.equals("")) m_Amt = new BigDecimal(Amt);
186         } catch (Exception JavaDoc ex) {
187             ex.printStackTrace();
188             //System.out.println("******************** Amount: " + ((Amt!=null)?Amt:"null"));
189
}
190         if (m_Amt.compareTo(ZERO) < 0)
191             return createLine (docLine, account, C_Currency_ID, "", m_Amt.abs().toString(), Fact_Acct_Group_ID, SeqNo, DocBaseType,conn);
192         else
193             return createLine (docLine, account, C_Currency_ID, Amt.toString(), "", Fact_Acct_Group_ID, SeqNo, DocBaseType,conn);
194     } // createLine
195

196     /**
197      * Are the lines Source Balanced
198      * @return true if source lines balanced
199      */

200     public boolean isSourceBalanced(){
201         log4jFact.debug ("Starting isSourceBalanced");
202         // No lines -> balanded
203
if (m_lines == null || m_lines.size() == 0)
204             return true;
205         BigDecimal balance = getSourceBalance();
206         boolean retValue = balance.compareTo(ZERO) == 0;
207         if (retValue)
208             log4jFact.debug ("isSourceBalanced - ");
209         else
210             log4jFact.warn ("isSourceBalanced NO - Balance=" + balance);
211         return retValue;
212     } // isSourceBalanced
213

214     /**
215      * Return Source Balance
216      * @return source balance
217      */

218     protected BigDecimal getSourceBalance(){
219         BigDecimal result = new BigDecimal("0");
220         for (int i = 0; i < m_lines.size(); i++){
221             FactLine line = (FactLine)m_lines.get(i);
222             result = result.add (line.getSourceBalance());
223         }
224     // log.debug ("getSourceBalance - " + result.toString());
225
return result;
226     } // getSourceBalance
227

228     /**
229      * Create Source Line for Suspense Balancing.
230      * Only if Suspense Balancing is enabled and not a multi-currency document
231      * (double check as otherwise the rule should not have fired)
232      * If not balanced create balancing entry in currency of the document
233      * @return FactLine
234      */

235     public FactLine balanceSource(ConnectionProvider conn){
236         if (!m_acctSchema.isSuspenseBalancing() || m_doc.MultiCurrency)
237             return null;
238         if (m_lines.size()==0) {
239           log4jFact.error("balanceSouce failed.");
240           return null;
241         }
242         FactLine fl = (FactLine)m_lines.get(0);
243         BigDecimal diff = getSourceBalance();
244         log4jFact.debug ("balanceSource = " + diff);
245         // new line
246
FactLine line = new FactLine (m_doc.AD_Table_ID, m_doc.Record_ID, "", fl.m_Fact_Acct_Group_ID, fl.m_SeqNo, fl.m_DocBaseType);//antes "0".
247
line.setDocumentInfo(m_doc, null);
248         line.setJournalInfo(m_doc.GL_Budget_ID, m_doc.GL_Category_ID);
249         line.setPostingType(m_postingType);
250         // Amount
251
if (diff.compareTo(ZERO) < 0) // negative balance => DR
252
line.setAmtSource(m_doc.C_Currency_ID, diff.abs().toString(), ZERO.toString());
253         else // positive balance => CR
254
line.setAmtSource(m_doc.C_Currency_ID, ZERO.toString(), diff.toString());
255         // Convert
256
line.convert(m_acctSchema.getC_Currency_ID(), m_doc.DateAcct, m_acctSchema.getCurrencyRateType(),conn);
257         line.setAccount(m_acctSchema, m_acctSchema.getSuspenseBalancing_Acct());
258         //
259
log4jFact.debug ("balanceSource - ");
260         log4jFact.debug("****************** fact - balancesource - m_lines.size() - " + m_lines.size());
261         m_lines.add(line);
262         return line;
263     } // balancingSource
264

265
266
267     /**
268      * Get Lines
269      * @return FactLine Array
270      */

271     public FactLine[] getLines(){
272         FactLine[] temp = new FactLine[m_lines.size()];
273         m_lines.toArray(temp);
274         return temp;
275     } // getLines
276

277     /**
278      * Save Fact
279      * @param con connection
280      * @return true if all lines were saved
281      */

282     public boolean save (Connection JavaDoc con,ConnectionProvider conn,VariablesSecureApp vars)throws ServletException{
283         // save Lines
284
log4jFact.debug(" Fact - save() - m_lines.size - " + m_lines.size());
285         if(m_lines.size()==0) return true;
286         for (int i = 0; i < m_lines.size(); i++){
287             FactLine fl = (FactLine)m_lines.get(i);
288             if (!fl.save(con, conn, vars)){ // abort on first error
289
log4jFact.warn("Save (fact): aborted. i=" + i);
290                 return false;
291             }
292         }
293         return true;
294     } // commit
295

296     /**
297      * Are all segments balanced
298      * @return true if segments are balanced
299      */

300     public boolean isSegmentBalanced(ConnectionProvider conn){
301         if (m_lines.size() == 0)
302             return true;
303
304         ArrayList<Object JavaDoc> elementList = m_acctSchema.m_elementList;
305         int size = elementList.size();
306         // check all balancing segments
307
for (int i = 0; i < size; i++){
308             AcctSchemaElement ase = (AcctSchemaElement)elementList.get(i);
309             if (ase.m_balanced.equals("Y") && !isSegmentBalanced (ase.m_segmentType, conn))
310                 return false;
311         }
312         return true;
313     } // isSegmentBalanced
314

315     /**
316      * Is Source Segment balanced.
317      * @param segmentType - see AcctSchemaElement.SEGMENT_*
318      * Implemented only for Org
319      * Other sensible candidates are Project, User1/2
320      * @return true if segments are balanced
321      */

322     public boolean isSegmentBalanced (String JavaDoc segmentType, ConnectionProvider conn){
323         if (segmentType.equals(AcctSchemaElement.SEGMENT_Org)){
324             log4jFact.debug("Starting isSegmentBalanced");
325             HashMap<Integer JavaDoc, BigDecimal> map = new HashMap<Integer JavaDoc, BigDecimal>();
326             // Add up values by key
327
for (int i = 0; i < m_lines.size(); i++){
328                 FactLine line = (FactLine)m_lines.get(i);
329                 Integer JavaDoc key = new Integer JavaDoc(line.getAD_Org_ID(conn));
330                 BigDecimal bal = line.getSourceBalance();
331                 BigDecimal oldBal = map.get(key);
332                 if (oldBal != null)
333                     bal = bal.add(oldBal);
334                 map.put(key, bal);
335             // log4jFact.debug("Add Key=" + key + ", Bal=" + bal + " <- " + line);
336
}
337             // check if all keys are zero
338
Iterator values = map.values().iterator();
339             while (values.hasNext()){
340                 BigDecimal bal = (BigDecimal)values.next();
341                 if (bal.compareTo(ZERO) != 0){
342                     map.clear();
343                     log4jFact.warn ("isSegmentBalanced (" + segmentType + ") NO - " + toString() + ", Balance=" + bal);
344                     return false;
345                 }
346             }
347             map.clear();
348             log4jFact.debug ("isSegmentBalanced (" + segmentType + ") - " + toString());
349             return true;
350         }
351         log4jFact.debug ("isSegmentBalanced (" + segmentType + ") (not checked) - " + toString());
352         return true;
353     } // isSegmentBalanced
354

355     /**
356      * Balance all segments.
357      * - For all balancing segments
358      * - For all segment values
359      * - If balance <> 0 create dueTo/dueFrom line
360      * overwriting the segment value
361      */

362     public void balanceSegments(ConnectionProvider conn){
363         log4jFact.debug("balanceSegments");
364         //
365
ArrayList<Object JavaDoc> elementList = m_acctSchema.m_elementList;
366         int size = elementList.size();
367         // check all balancing segments
368
for (int i = 0; i < size; i++){
369             AcctSchemaElement ase = (AcctSchemaElement)elementList.get(i);
370             if (ase.m_balanced.equals("Y")) balanceSegment (ase.m_segmentType, conn);
371         }
372     } // balanceSegments
373

374     /**
375      * Balance Source Segment
376      * @param segmentType segment type
377      */

378     private void balanceSegment (String JavaDoc segmentType, ConnectionProvider conn){
379         // no lines -> balanced
380
if (m_lines.size() == 0) return;
381         log4jFact.debug ("balanceSegment (" + segmentType + ") - ");
382         // Org
383
if (segmentType.equals(AcctSchemaElement.SEGMENT_Org)){
384             HashMap<Integer JavaDoc, BigDecimal> map = new HashMap<Integer JavaDoc, BigDecimal>();
385             // Add up values by key
386
for (int i = 0; i < m_lines.size(); i++){
387                 FactLine line = (FactLine)m_lines.get(i);
388                 Integer JavaDoc key = new Integer JavaDoc(line.getAD_Org_ID(conn));
389                 BigDecimal bal = line.getSourceBalance();
390                 BigDecimal oldBal = map.get(key);
391                 if (oldBal != null)
392                     bal = bal.add(oldBal);
393                 map.put(key, bal);
394             }
395             // Create entry for non-zero element
396
Iterator keys = map.keySet().iterator();
397             while (keys.hasNext()){
398                 Integer JavaDoc key = (Integer JavaDoc)keys.next();
399                 BigDecimal diff = map.get(key);
400                 //
401
if (diff.compareTo(ZERO) != 0){
402                     // Create Balancing Entry
403
if (m_lines.size()==0) {
404                       log4jFact.error("balanceSegment failed.");
405                       return;
406                     }
407                     FactLine fl = (FactLine)m_lines.get(0);
408                     FactLine line = new FactLine (m_doc.AD_Table_ID, m_doc.Record_ID, "", fl.m_Fact_Acct_Group_ID, fl.m_SeqNo, fl.m_DocBaseType);
409                     line.setDocumentInfo(m_doc, null);
410                     line.setJournalInfo(m_doc.GL_Budget_ID, m_doc.GL_Category_ID);
411                     line.setPostingType(m_postingType);
412                     // Amount & Account
413
if (diff.compareTo(ZERO) < 0){
414                         line.setAmtSource(m_doc.C_Currency_ID, diff.abs().toString(), ZERO.toString());
415                         line.setAccount(m_acctSchema, m_acctSchema.m_DueFrom_Acct);
416                     }else {
417                         line.setAmtSource(m_doc.C_Currency_ID, ZERO.toString(), diff.abs().toString());
418                         line.setAccount(m_acctSchema, m_acctSchema.m_DueTo_Acct);
419                     }
420                     line.convert(m_acctSchema.getC_Currency_ID(), m_doc.DateAcct, m_acctSchema.getCurrencyRateType(),conn);
421                     line.setAD_Org_ID(key.toString());
422                     log4jFact .debug ("balanceSegment (" + segmentType + ") - ");
423                     log4jFact.debug("************* fact - balanceSegment - m_lines.size() - " + m_lines.size() + " - line.ad_org_id - " + line.getAD_Org_ID(conn));
424                     m_lines.add(line);
425                 }
426             }
427             map.clear();
428         }
429     } // balanceSegment
430

431     /**
432      * Are the lines Accounting Balanced
433      * @return true if accounting lines are balanced
434      */

435     public boolean isAcctBalanced(){
436         // no lines -> balanced
437
if (m_lines == null || m_lines.size() == 0)
438             return true;
439         BigDecimal balance = getAcctBalance();
440         boolean retValue = balance.compareTo(ZERO) == 0;
441         if (retValue)
442             log4jFact.debug("isAcctBalanced - ");
443         else
444             log4jFact.warn("isAcctBalanced NO - Balance=" + balance);
445         return retValue;
446     } // isAcctBalanced
447

448     /**
449      * Return Accounting Balance
450      * @return true if accounting lines are balanced
451      */

452     protected BigDecimal getAcctBalance(){
453         BigDecimal result = ZERO;
454         for (int i = 0; i < m_lines.size(); i++){
455             FactLine line = (FactLine)m_lines.get(i);
456             BigDecimal balance = new BigDecimal(line.getAcctBalance());
457             result = result.add(balance);
458         }
459         return result;
460     } // getAcctBalance
461

462     /**
463      * Balance Accounting Currency.
464      * If the accounting currency is not balanced,
465      * if Currency balancing is enabled
466      * create a new line using the currency balancing account with zero source balance
467      * or
468      * adjust the line with the largest balance sheet account
469      * or if no balance sheet account exist, the line with the largest amount
470      * @return FactLine
471      */

472     public FactLine balanceAccounting(ConnectionProvider conn){
473         BigDecimal diff = getAcctBalance();
474         log4jFact.debug ("balanceAccounting - Balance=" + diff);
475         FactLine line = null;
476         // Create Currency Entry
477
if (m_acctSchema.isCurrencyBalancing()){
478             if (m_lines.size()==0) {
479               log4jFact.error("balanceAccounting failed.");
480               return null;
481             }
482             FactLine fl = (FactLine)m_lines.get(0);
483             line = new FactLine (m_doc.AD_Table_ID, m_doc.Record_ID, "", fl.m_Fact_Acct_Group_ID, fl.m_SeqNo, fl.m_DocBaseType);
484             line.setDocumentInfo(m_doc, null);
485             line.setJournalInfo(m_doc.GL_Budget_ID, m_doc.GL_Category_ID);
486             line.setPostingType(m_postingType);
487
488             // Amount
489
line.setAmtSource(m_doc.C_Currency_ID, ZERO.toString(), ZERO.toString());
490             line.convert(m_acctSchema.getC_Currency_ID(), m_doc.DateAcct, m_acctSchema.getCurrencyRateType(),conn);
491             if (diff.compareTo(ZERO) < 0) line.setAmtAcct(diff.abs().toString(), ZERO.toString());
492             else line.setAmtAcct(ZERO.toString(), diff.abs().toString());
493             line.setAccount(m_acctSchema, m_acctSchema.getCurrencyBalancing_Acct());
494             log4jFact.debug ("balanceAccounting - " + line.toString());
495             log4jFact.debug("************* fact - balanceAccounting - m_lines.size() - " + m_lines.size());
496             m_lines.add(line);
497         }
498         else{ // Adjust biggest (Balance Sheet) line amount
499
BigDecimal BSamount = ZERO;
500             FactLine BSline = null;
501             BigDecimal PLamount = ZERO;
502             FactLine PLline = null;
503
504             // Find line
505
for (int i = 0; i < m_lines.size(); i++){
506                 FactLine l = (FactLine)m_lines.get(i);
507                 BigDecimal amt = new BigDecimal(l.getAcctBalance());
508                 amt = amt.abs();
509                 if (l.isBalanceSheet() && amt.compareTo(BSamount) > 0){
510                     BSamount = amt;
511                     BSline = l;
512                 }else if (!l.isBalanceSheet() && amt.compareTo(PLamount) > 0){
513                     PLamount = amt;
514                     PLline = l;
515                 }
516             }
517             if (BSline != null) line = BSline;
518             else line = PLline;
519
520             if (line == null) log4jFact.error ("balanceAccounting - No Line found");
521             else{
522                 log4jFact.debug ("Adjusting Amt=" + diff.toString() + "; Line=" + line.toString());
523                 line.currencyCorrect(diff);
524                 log4jFact.debug ("balanceAccounting - " + line.toString());
525             }
526         } // correct biggest amount
527

528         // Debug info only
529
this.isAcctBalanced();
530
531         return line;
532     } // balanceAccounting
533

534
535 }
536
Popular Tags