[FIX] fixing report headers
[odoo/odoo.git] / addons / account / report / compare_account_balance.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU Affero General Public License as
9 #    published by the Free Software Foundation, either version 3 of the
10 #    License, or (at your option) any later version.
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU Affero General Public License for more details.
16 #
17 #    You should have received a copy of the GNU Affero General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 #
20 ##############################################################################
21
22 import time
23 import locale
24 from report import report_sxw
25
26 #from addons.account.wizard import wizard_account_balance_report
27
28 parents = {
29     'tr':1,
30     'li':1,
31     'story': 0,
32     'section': 0
33 }
34
35 class account_balance(report_sxw.rml_parse):
36     def __init__(self, cr, uid, name, context):
37         super(account_balance, self).__init__(cr, uid, name, context=context)
38         self.flag=1
39         self.dr_total= 0.00
40         self.cr_total= 0.00
41         self.parent_bal=0
42         self.status=0
43         self.done_total=0
44         self.baldiv={}
45         self.empty_parent=0
46         self.result_total = {}
47         self.total_for_perc=[]
48         self.localcontext.update({
49             'time': time,
50             'lines': self.lines,
51             'get_lines':self.get_lines,
52             'linesForTotal': self.linesForTotal,
53             'linesForYear': self.linesForYear,
54             'get_years':self.get_years,
55             'cal_total':self.cal_total,
56             'total_dr':self.total_dr,
57             'total_cr':self.total_cr
58             })
59         self.context = context
60
61     def linesForYear(self, form):
62         temp=0
63         years={}
64
65         global pattern
66         global show
67         global perc
68         global bal_zero
69         global ref_bal
70
71         pattern=form['compare_pattern']
72
73         if form['show_columns']!=1:
74             show=0
75         else:
76             show=form['show_columns']
77
78         if form['format_perc']!=1:
79             perc=0
80         else:
81             perc=form['format_perc']
82
83         if form['account_choice']=='bal_zero':
84             bal_zero=0
85         else:
86             bal_zero=1
87
88         ctx = self.context.copy()
89
90         if perc==1:
91             if form['select_account']!=False:
92                 ref_ac=self.pool.get('account.account').browse(self.cr, self.uid, form['select_account'], ctx.copy())
93                 if ref_ac.balance<>0.00:
94                     ref_bal=ref_ac.balance
95                 else:
96                     ref_bal=1.00
97             else:
98                 ref_bal='nothing'
99         else:
100             ref_bal='nothing'
101
102
103         total_for_perc=[]
104         self.done_total=1
105         self.total_for_perc=self.linesForTotal(form, ids={}, doneAccount={}, level=1)
106         self.done_total=0
107
108         for t1 in range(0,len(form['fiscalyear'])):
109             locale.setlocale(locale.LC_ALL, '')
110             self.result_total["sum_credit" + str(t1)]=locale.format("%.2f", self.result_total["sum_credit" + str(t1)], grouping=True)
111             self.result_total["sum_debit" + str(t1)]=locale.format("%.2f", self.result_total["sum_debit" + str(t1)], grouping=True)
112
113         for temp in range(0,len(form['fiscalyear'])):
114             fy=self.pool.get('account.fiscalyear').name_get(self.cr, self.uid, form['fiscalyear'][temp])
115             years["year"+str(temp)]=fy[0][1][12:16]
116
117         return [years]
118
119
120     def linesForTotal(self, form, ids={}, doneAccount={}, level=1):
121         if self.done_total==1:
122             self.done_total==1
123         else:
124             return [self.result_total]
125         accounts=[]
126         if not ids:
127             ids = self.ids
128         if not ids:
129             return []
130         ctx = self.context.copy()
131         result_total_parent=[]
132
133         for id in form['fiscalyear']:
134             tmp=[]
135
136             ctx['fiscalyear'] = id
137             ctx['periods'] = form['periods']
138             ctx['period_manner'] = form['period_manner']
139             ctx['state'] = form['context'].get('state','all')
140             tmp = self.pool.get('account.account').browse(self.cr, self.uid, ids, ctx.copy())
141
142             if len(tmp):
143                 accounts.append(tmp)
144
145         merged_accounts=zip(*accounts)
146          # used to check for the frst record so all sum_credit and sum_debit r set to 0.00
147         if level==1:
148             doneAccount={}
149         for entry in merged_accounts:
150
151             if entry[0].id in doneAccount:
152                 continue
153             doneAccount[entry[0].id] = 1
154             for k in range(0,len(entry)):
155                 temp_credit=0.00
156                 temp_debit=0.00
157                 if entry[0].type <> 'view':
158                     temp_credit+=entry[k].credit
159                     temp_debit+=entry[k].debit
160
161                 if self.flag==1:
162                     self.result_total["sum_credit" + str(k)]=0.00
163                     self.result_total["sum_debit" + str(k)]=0.00
164                 if form['account_choice']=='bal_zero':
165                     if temp_credit<>temp_debit:
166                         self.result_total["sum_credit" + str(k)]+=temp_credit
167                         self.result_total["sum_debit" + str(k)]+=temp_debit
168                 else:
169                     self.result_total["sum_credit" + str(k)]+=temp_credit
170                     self.result_total["sum_debit" + str(k)]+=temp_debit
171
172             self.flag=2
173
174             if entry[0].child_id:
175                 ids2 = [(x.code,x.id) for x in entry[0].child_id]
176                 ids2.sort()
177
178                 result_total_parent = self.linesForTotal(form, [x[1] for x in ids2], doneAccount, level+1)
179
180         return [self.result_total]
181
182     def lines(self, form, ids={}, done={}, level=1):
183         accounts=[]
184         if not ids:
185             ids = self.ids
186         if not ids:
187             return []
188         result = []
189         ctx = self.context.copy()
190         tmp1=[]
191         for id in form['fiscalyear']:
192
193             ctx['fiscalyear'] = id
194             ctx['periods'] = form['periods']
195             ctx['period_manner']=form['period_manner']
196             ctx['state'] = form['context'].get('state','all')
197             tmp1 = self.pool.get('account.account').browse(self.cr, self.uid, ids, ctx.copy())
198
199             if len(tmp1):
200                 accounts.append(tmp1)
201
202         if level==1:   #if parent is called,done is not empty when called again.
203             done={}
204
205         def cmp_code(x, y):
206             return cmp(x.code, y.code)
207         for n in range(0,len(accounts)):
208             accounts[n].sort(cmp_code)
209         common={}
210         merged_accounts=zip(*accounts)
211
212         for entry in merged_accounts:
213             j=0
214             checked=1
215
216             if form['account_choice']!='all':    #  if checked,include empty a/c;not otherwise
217                 checked=0
218
219             if entry[0].id in done:
220                 continue
221             done[entry[0].id] = 1
222
223             if entry[0].child_id:  # this is for parent account,dont check 0 for it
224                 checked=4
225                 self.status=1 # for displaying it Bold
226             else:
227                 self.status=0
228             if checked==0:
229                 i=0
230                 for i in range(0,len(entry)):
231                     if bal_zero==0:
232                         if entry[i].balance<>0.0:
233                             checked=4
234                             break
235                         else:
236                             checked=3
237                             i=i+1
238                     else:
239                         if entry[i].credit <> 0.0 or entry[i].debit <> 0.0:
240                             checked=4
241                             break
242                         else:
243                             checked=3
244                             i=i+1
245
246             if checked==3:
247                 # this is the point where we skip those accounts which are encountered as empty ones
248                 continue
249                 self.empty_parent=0
250             else:
251                 self.empty_parent=1
252                 res = {
253                     'code': entry[0].code,
254                     'name': entry[0].name,
255                     'level': level,
256                     'status': self.status,
257                     }
258
259                 for j in range(0,len(entry)):
260
261                     locale.setlocale(locale.LC_ALL, '')
262                     res["debit"+str(j)]=locale.format("%.2f", entry[j].debit, grouping=True)
263                     res["credit"+str(j)]=locale.format("%.2f", entry[j].credit, grouping=True)
264                     res["balance"+str(j)]=locale.format("%.2f", entry[j].balance, grouping=True)
265
266
267                     if j==0:
268                         res["bal_cash"+str(j)]="0.00"
269                         res["bal_perc"+str(j)]="0.00%"
270                     else:
271                         temp_cash=entry[j].balance - entry[j-1].balance
272                         res["bal_cash"+str(j)]=locale.format("%.2f", temp_cash, grouping=True)
273                         if entry[j-1].balance<>0.00:
274                             temp_perc=(entry[j].balance - entry[j-1].balance )*100/entry[j-1].balance
275                         else:
276                             temp_perc=(entry[j].balance) *100
277
278                         res["bal_perc"+str(j)]=locale.format("%.2f", temp_perc) + "%"
279
280                     if ref_bal=='nothing':
281                         if level==1:
282                             self.parent_bal=1
283                         else:
284                             self.parent_bal=0
285
286                         if self.parent_bal==1:
287                             res["balance_perc"+str(j)]="/"
288                         else:
289                             if entry[j].balance==0.00:
290                                 if self.baldiv["baldiv"+str(level-1)+str(j)]<>0.00:
291                                     res["balance_perc"+str(j)]="0.00%"
292                                 else:
293                                     res["balance_perc"+str(j)]="/"
294                             else:
295                                 if self.baldiv["baldiv"+str(level-1)+str(j)]<>0.00:
296                                     temp=self.baldiv["baldiv"+str(level-1)+str(j)]
297                                     temp1=(entry[j].balance * 100 )/ float(temp)
298                                     temp1=round(temp1,2)
299                                     res["balance_perc" + str(j)]=str(temp1)+"%"
300                                 else:
301                                     res["balance_perc"+str(j)]="/"
302                     else:
303                         res["balance_perc"+str(j)]=str( (entry[j].balance * 100 )/ float(ref_bal)) + "%"
304
305             result.append(res)
306
307             if entry[0].child_id:
308
309                 for q in range(0,len(form['fiscalyear'])):
310                     self.baldiv["baldiv"+str(level)+str(q)]=entry[q].balance
311
312                 ids2 = [(x.code,x.id) for x in entry[0].child_id]
313                 ids2.sort()
314                 dir=[]
315                 dir += self.lines(form, [x[1] for x in ids2], done, level+1)
316                 if dir==[]:
317                     for w in range(0,len(form['fiscalyear'])):
318                         if entry[w].credit <> 0.0 or entry[w].debit <> 0.0 or entry[w].balance<>0.00:
319                             dont_pop=1
320                             break
321                         else:
322                             dont_pop=0
323                     if dont_pop==1:
324                         result +=dir
325                     else:
326                         result.pop(-1)   # here we pop up the parent having its children as emprty accounts
327                 else:
328                     result +=dir
329
330         return result
331
332     def get_years(self, form):
333         result =[]
334         res={}
335         for temp in range(0,len(form['fiscalyear'])):
336             res={}
337             fy=self.pool.get('account.fiscalyear').name_get(self.cr, self.uid, form['fiscalyear'][temp])
338             res['year']=fy[0][1]
339             res['last_str']=temp
340
341             result.append(res)
342         self.linesForYear(form)
343         return result
344
345     def get_lines(self, year_dict, form):
346         final_result = []
347         line_l =[]
348         res = {}
349         line_l = self.lines(form)
350         self.cal_total(year_dict)
351         if line_l:
352             for l in line_l:
353                 res = {}
354                 res['code'] = l['code']
355                 res['name'] = l['name']
356                 res['level'] = l['level']
357                 for k,v in l.items():
358                     if k.startswith('debit'+str(year_dict['last_str'])):
359                      res['debit'] = v
360                     if k.startswith('credit'+str(year_dict['last_str'])):
361                      res['credit'] = v
362                     if k.startswith('balance'+str(year_dict['last_str'])) and not k.startswith('balance_perc'+str(year_dict['last_str'])):
363                      res['balance'] =v
364                     if k.startswith('balance_perc'+str(year_dict['last_str'])) and not k.startswith('balance'+str(year_dict['last_str'])):
365                      res['balance_perc'] = v
366                     if form['compare_pattern'] == 'bal_perc':
367                         if k.startswith('bal_perc'+str(year_dict['last_str'])):
368                          res['pattern'] = v
369                     elif form['compare_pattern'] == 'bal_cash':
370                         if k.startswith('bal_cash'+str(year_dict['last_str'])):
371                          res['pattern'] = v
372                     else:
373                          res['pattern'] = ''
374                 final_result.append(res)
375         return final_result
376
377     def cal_total(self, year_dict):
378         total_l = self.result_total
379         if total_l:
380             for k,v in total_l.items():
381                 if k.startswith('sum_debit'+str(year_dict['last_str'])):
382                     self.dr_total = v
383                 elif k.startswith('sum_credit'+str(year_dict['last_str'])):
384                     self.cr_total = v
385                 else:
386                     continue
387         return True
388
389     def total_dr(self):
390         return self.dr_total
391
392     def total_cr(self):
393         return self.cr_total
394
395 report_sxw.report_sxw('report.account.balance.account.balance', 'account.account', 'addons/account/report/account_balance.rml', parser=account_balance, header="internal")
396 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
397