[IMP] account_balance Module : Modified reports.
[odoo/odoo.git] / addons / account_balance / report / account_balance_landscape.py
1 # -*- encoding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution    
5 #    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
6 #    $Id$
7 #
8 #    This program is free software: you can redistribute it and/or modify
9 #    it under the terms of the GNU General Public License as published by
10 #    the Free Software Foundation, either version 3 of the License, or
11 #    (at your option) any later version.
12 #
13 #    This program is distributed in the hope that it will be useful,
14 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
15 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 #    GNU General Public License for more details.
17 #
18 #    You should have received a copy of the GNU General Public License
19 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 #
21 ##############################################################################
22
23 import time
24 import locale
25 from report import report_sxw
26 import rml_parse
27
28 #from addons.account.wizard import wizard_account_balance_report
29
30 parents = {
31     'tr':1,
32     'li':1,
33     'story': 0,
34     'section': 0
35 }
36
37 class account_balance_landscape(rml_parse.rml_parse):
38     def __init__(self, cr, uid, name, context):
39         super(account_balance_landscape, self).__init__(cr, uid, name, context)
40         self.flag=1
41         self.dr_total= 0.00
42         self.cr_total= 0.00
43         self.parent_bal=0
44         self.status=0
45         self.done_total=0
46         self.baldiv={}
47         self.empty_parent=0
48         self.result_total = {}
49         self.total_for_perc=[]
50         self.localcontext.update({
51             'time': time,
52             'lines': self.lines,
53             'get_lines':self.get_lines,
54             'linesForTotal': self.linesForTotal,
55             'linesForYear': self.linesForYear,
56             'get_years':self.get_years,
57             'cal_total':self.cal_total,
58             'total_dr':self.total_dr,
59             'total_cr':self.total_cr
60             })
61         self.context = context
62
63 #    def repeatIn(self, lst, name, nodes_parent=False,td=False,width=[],value=[],type=[]):
64 #        self._node.data = ''
65 #        node = self._find_parent(self._node, nodes_parent or parents)
66 #        ns = node.nextSibling
67 ##start
68 #        if value==['Cash','%']:
69 #            if show==1:
70 #                if perc==1:
71 #                    if pattern=='none':
72 #                        value=['','Cash','%']
73 #                        type=['lable','lable','lable']
74 #                        width=[130,65,65]
75 #                    else:
76 #                        value=[' ','','Cash','%']
77 #                        type=['string','lable','lable','lable']
78 #                        width=[65,130,65,65]
79 #                else:
80 #                    if pattern=='none':
81 #                        value=['']
82 #                        type=['lable']
83 #                        width=[195]
84 #                    else:
85 #                        value=[' ','']
86 #                        type=['string','lable']
87 #                        width=[65,195]
88 #            else:
89 #                if perc==1:
90 #                    if pattern=='none':
91 #                        value=['Cash','%']
92 #                        type=['lable','lable']
93 #                        width=[65,65]
94 #                    else:
95 #                        value=[' ','Cash','%']
96 #                        type=['string','lable','lable']
97 #                        width=[65,65,65]
98 #                else:
99 #                    if pattern=='none':
100 #                        value=['']
101 #                        type=['lable']
102 #                        width=[65]
103 #                    else:
104 #                        value=[' ','']
105 #                        type=['string','lable']
106 #                        width=[65,65]
107 #
108 #
109 #        if value==['year']:
110 #            if show==1:
111 #                if perc==1:
112 #                    if pattern=='none':
113 #                        width=[260]
114 #                    else:
115 #                        value=[' ','year']
116 #                        type=['string','string']
117 #                        width=[65,260]
118 #                else:
119 #                    if pattern=='none':
120 #                        width=[195]
121 #                    else:
122 #                        value=[' ','year']
123 #                        type=['string','string']
124 #                        width=[65,195]
125 #            else:
126 #                if perc==1:
127 #                    if pattern=='none':
128 #                        width=[130]
129 #                    else:
130 #                        value=[' ','year']
131 #                        type=['string','string']
132 #                        width=[65,130]
133 #
134 #                else:
135 #                    if pattern=='none':
136 #                        width=[65]
137 #                    else:
138 #                        value=[' ','year']
139 #                        type=['string','string']
140 #                        width=[65,65]
141 #
142 #        if value==['Debit','Credit','Balance']:
143 #            if show==1:
144 #                if perc==1:
145 #                    if pattern=='none':
146 #                        width=[65,65,130]
147 #                    else:
148 #                        value=[' ','Debit','Credit','Balance']
149 #                        type=['string','lable','lable','lable']
150 #                        width=[65,65,65,130]
151 #                else:
152 #                    if pattern=='none':
153 #                        width=[65,65,65]
154 #                    else:
155 #                        value=[' ','Debit','Credit','Balance']
156 #                        type=['string','lable','lable','lable']
157 #                        width=[65,65,65,65]
158 #
159 #            else:
160 #                if perc==1:
161 #                    if pattern=='none':
162 #                        value=['Balance']
163 #                        type=['lable']
164 #                        width=[130]
165 #                    else:
166 #                        value=[' ','Balance']
167 #                        type=['string','lable']
168 #                        width=[65,130]
169 #                else:
170 #                    if pattern=='none':
171 #                        value=['Balance']
172 #                        type=['lable']
173 #                        width=[65]
174 #                    else:
175 #                        value=[' ','Balance']
176 #                        type=['string','lable']
177 #                        width=[65,65]
178 #
179 #        if value==['debit','credit','balance']:
180 #            if show==1:
181 #                if perc==1:
182 #                    if pattern=='none':
183 #                        value=['debit','credit','balance','balance_perc']
184 #                        type=['string','string','string','string']
185 #                        width=[65,65,65,65]
186 #                    else:
187 #                        value=[pattern,'debit','credit','balance','balance_perc']
188 #                        type=['string','string','string','string','string']
189 #                        width=[65,65,65,65,65]
190 #                else:
191 #                    if pattern=='none':
192 #                        value=['debit','credit','balance']
193 #                        type=['string','string','string']
194 #                        width=[65,65,65]
195 #                    else:
196 #                        value=[pattern,'debit','credit','balance']
197 #                        type=['string','string','string','string']
198 #                        width=[65,65,65,65]
199 #
200 #            else:
201 #                if perc==1:
202 #                    if pattern=='none':
203 #                        value=['balance','balance_perc']
204 #                        type=['string','string']
205 #                        width=[65,65]
206 #                    else:
207 #                        value=[pattern,'balance','balance_perc']
208 #                        type=['string','string','string']
209 #                        width=[65,65,65]
210 #                else:
211 #                    if pattern=='none':
212 #                        value=['balance']
213 #                        type=['string']
214 #                        width=[65]
215 #                    else:
216 #                        value=[pattern,'balance']
217 #                        type=['string','string']
218 #                        width=[65,65]
219 #
220 #        if value==['sum_debit','sum_credit','']:
221 #            if show==1:
222 #                if perc==1:
223 #                    if pattern=='none':
224 #                        width=[65,65,130]
225 #                    else:
226 #                        value=[' ','sum_debit','sum_credit','']
227 #                        type=['string','string','string','lable']
228 #                        width=[65,65,65,130]
229 #                else:
230 #                    if pattern=='none':
231 #                        width=[65,65,65]
232 #                    else:
233 #                        value=[' ','sum_debit','sum_credit','']
234 #                        type=['string','string','string','lable']
235 #                        width=[65,65,65,65]
236 #            else:
237 #                if perc==1:
238 #                    if pattern=='none':
239 #                        value=['']
240 #                        type=['lable']
241 #                        width=[130]
242 #                    else:
243 #                        value=[' ','']
244 #                        type=['string','lable']
245 #                        width=[65,130]
246 #                else:
247 #                    if pattern=='none':
248 #                        value=['']
249 #                        type=['lable']
250 #                        width=[65]
251 #                    else:
252 #                        value=[' ','']
253 #                        type=['string','lable']
254 #                        width=[65,65]
255 #
256 #        if not lst:
257 #            lst.append(1)
258 #        for ns in node.childNodes :
259 #            if ns and ns.nodeName!='#text' and ns.tagName=='blockTable' and td :
260 #                width_str = ns._attrs['colWidths'].nodeValue
261 #                ns.removeAttribute('colWidths')
262 #                total_td = td * len(value)
263 #
264 #                if not width:
265 #                    for v in value:
266 #                        width.append(30)
267 #                check1=0
268 #                for t in range(td):
269 #                    for v in range(len(value)):
270 #                        if type[v] in ('String','STRING','string'):
271 #                            if (value[v]==" " or value[0]==pattern):
272 #                                if check1==0:
273 #                                    check1=1
274 #                                    width_str +=',0.0'
275 #                                else:
276 #                                    width_str +=',%d'%width[v]
277 #                            else:
278 #                                width_str +=',%d'%width[v]
279 #                        else:
280 #                            width_str +=',%d'%width[v]
281 #                ns.setAttribute('colWidths',width_str)
282 #
283 #                child_list =  ns.childNodes
284 #
285 #                check=0
286 #                for child in child_list:
287 #                    if child.nodeName=='tr':
288 #                        lc = child.childNodes[1]
289 #                        for t in range(td):
290 #                            i=0
291 #                            for v in value:
292 #
293 #                                newnode = lc.cloneNode(1)
294 #                                temp2="%s['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-bold'})) ]]"%(name)
295 ##
296 #                                if type[i] in ('String','STRING','string'):
297 #                                    if (v==" " or v==pattern) and i==0 and check==0:
298 #                                        check=1
299 #                                        if newnode.childNodes[1].lastChild:
300 #                                            newnode.childNodes[1].lastChild.data=""
301 #                                    else:
302 #                                        if v==" ":
303 #                                            if newnode.childNodes[1].lastChild:
304 #                                                newnode.childNodes[1].lastChild.data=""
305 #                                        else:
306 #                                            t1= "[[ %s['%s%d'] ]]"%(name,v,t)
307 #                                            if v=="year" or v=="sum_debit" or v=="sum_credit":
308 #                                                if newnode.childNodes[1].lastChild:
309 #                                                    newnode.childNodes[1].lastChild.data = t1
310 #                                            else:
311 #                                                if newnode.childNodes[1].lastChild:
312 #                                                    newnode.childNodes[1].lastChild.data = t1+"[["+temp2
313 ##                                   newnode.childNodes[1].lastChild.data=[[ a['status']==1 and ( setTag('para','para',{'fontName':'Times-bold'})) ]]
314 #                                elif type[i] in ('Lable','LABLE','lable'):
315 #                                    if newnode.childNodes[1].lastChild:
316 #                                        newnode.childNodes[1].lastChild.data= v
317 #
318 #                                child.appendChild(newnode)
319 #
320 #                                newnode=False
321 #                                i+=1
322 #        return super(account_balance_landscape,self).repeatIn(lst, name, nodes_parent=False)
323 #end
324     def linesForYear(self,form):
325         temp=0
326         years={}
327
328         global pattern
329         global show
330         global perc
331         global bal_zero
332         global ref_bal
333
334         pattern=form['compare_pattern']
335
336         if form['show_columns']!=1:
337             show=0
338         else:
339             show=form['show_columns']
340
341         if form['format_perc']!=1:
342             perc=0
343         else:
344             perc=form['format_perc']
345
346         if form['account_choice']=='bal_zero':
347             bal_zero=0
348         else:
349             bal_zero=1
350
351         ctx = self.context.copy()
352
353         if perc==1:
354             if form['select_account']!=False:
355                 ref_ac=self.pool.get('account.account').browse(self.cr, self.uid,form['select_account'],ctx.copy())
356                 if ref_ac.balance<>0.00:
357                     ref_bal=ref_ac.balance
358                 else:
359                     ref_bal=1.00
360             else:
361                 ref_bal='nothing'
362         else:
363             ref_bal='nothing'
364
365
366         total_for_perc=[]
367 #       if perc==1:
368         self.done_total=1
369         self.total_for_perc=self.linesForTotal(form,ids={},doneAccount={},level=1)
370         self.done_total=0
371
372         for t1 in range(0,len(form['fiscalyear'][0][2])):
373             locale.setlocale(locale.LC_ALL, '')
374             self.result_total["sum_credit" + str(t1)]=locale.format("%.2f", self.result_total["sum_credit" + str(t1)], grouping=True)
375             self.result_total["sum_debit" + str(t1)]=locale.format("%.2f", self.result_total["sum_debit" + str(t1)], grouping=True)
376 #           self.flag=1
377 #           self.result_total = {}
378
379         for temp in range(0,len(form['fiscalyear'][0][2])):
380             fy=self.pool.get('account.fiscalyear').name_get(self.cr,self.uid,form['fiscalyear'][0][2][temp])
381             years["year"+str(temp)]=fy[0][1][12:16]
382
383         return [years]
384
385
386     def linesForTotal(self,form,ids={},doneAccount={},level=1):
387         if self.done_total==1:
388             self.done_total==1
389         else:
390             return [self.result_total]
391         accounts=[]
392         if not ids:
393             ids = self.ids
394         if not ids:
395             return []
396
397         ctx = self.context.copy()
398         result_total_parent=[]
399
400         for id in form['fiscalyear'][0][2]:
401             tmp=[]
402
403             ctx['fiscalyear'] = id
404             ctx['periods'] = form['periods'][0][2]
405             ctx['period_manner']=form['period_manner']
406             tmp = self.pool.get('account.account').browse(self.cr, self.uid, ids, ctx.copy())
407
408             if len(tmp):
409                 accounts.append(tmp)
410
411         merged_accounts=zip(*accounts)
412          # used to check for the frst record so all sum_credit and sum_debit r set to 0.00
413         if level==1:
414             doneAccount={}
415         for entry in merged_accounts:
416
417             if entry[0].id in doneAccount:
418                 continue
419             doneAccount[entry[0].id] = 1
420
421             for k in range(0,len(entry)):
422                 temp_credit=0.00
423                 temp_debit=0.00
424
425                 temp_credit+=entry[k].credit
426                 temp_debit+=entry[k].debit
427
428                 if self.flag==1:
429                     self.result_total["sum_credit" + str(k)]=0.00
430                     self.result_total["sum_debit" + str(k)]=0.00
431
432                 if form['account_choice']=='bal_zero':
433                     if temp_credit<>temp_debit:
434                         self.result_total["sum_credit" + str(k)]+=temp_credit
435                         self.result_total["sum_debit" + str(k)]+=temp_debit
436                 else:
437                     self.result_total["sum_credit" + str(k)]+=temp_credit
438                     self.result_total["sum_debit" + str(k)]+=temp_debit
439
440             self.flag=2
441
442             if entry[0].child_id:
443                 ids2 = [(x.code,x.id) for x in entry[0].child_id]
444                 ids2.sort()
445
446                 result_total_parent = self.linesForTotal(form, [x[1] for x in ids2],doneAccount,level+1)
447
448         return [self.result_total]
449
450     def lines(self, form, ids={}, done={}, level=1):
451         accounts=[]
452         if not ids:
453             ids = self.ids
454         if not ids:
455             return []
456         result = []
457         ctx = self.context.copy()
458         tmp1=[]
459         for id in form['fiscalyear'][0][2]:
460
461             ctx['fiscalyear'] = id
462             ctx['periods'] = form['periods'][0][2]
463             ctx['period_manner']=form['period_manner']
464
465             tmp1 = self.pool.get('account.account').browse(self.cr, self.uid, ids,ctx.copy())
466
467             if len(tmp1):
468                 accounts.append(tmp1)
469
470         if level==1:   #if parent is called,done is not empty when called again.
471             done={}
472
473         def cmp_code(x, y):
474             return cmp(x.code, y.code)
475         for n in range(0,len(accounts)):
476             accounts[n].sort(cmp_code)
477         common={}
478         merged_accounts=zip(*accounts)
479
480         for entry in merged_accounts:
481             j=0
482             checked=1
483
484             if form['account_choice']!='all':    #  if checked,include empty a/c;not otherwise
485                 checked=0
486
487             if entry[0].id in done:
488                 continue
489             done[entry[0].id] = 1
490
491             if entry[0].child_id:  # this is for parent account,dont check 0 for it
492                 checked=4
493                 self.status=1 # for displaying it Bold
494             else:
495                 self.status=0
496             if checked==0:
497                 i=0
498                 for i in range(0,len(entry)):
499                     if bal_zero==0:
500                         if entry[i].balance<>0.0:
501                             checked=4
502                             break
503                         else:
504                             checked=3
505                             i=i+1
506                     else:
507                         if entry[i].credit <> 0.0 or entry[i].debit <> 0.0:
508                             checked=4
509                             break
510                         else:
511                             checked=3
512                             i=i+1
513
514             if checked==3:
515                 # this is the point where we skip those accounts which are encountered as empty ones
516                 continue
517                 self.empty_parent=0
518             else:
519                 self.empty_parent=1
520                 res = {
521                     'code': entry[0].code,
522                     'name': entry[0].name,
523                     'level': level,
524                     'status': self.status,
525                     }
526
527                 for j in range(0,len(entry)):
528
529                     locale.setlocale(locale.LC_ALL, '')
530                     res["debit"+str(j)]=locale.format("%.2f", entry[j].debit, grouping=True)
531                     res["credit"+str(j)]=locale.format("%.2f", entry[j].credit, grouping=True)
532                     res["balance"+str(j)]=locale.format("%.2f", entry[j].balance, grouping=True)
533
534
535                     if j==0:
536                         res["bal_cash"+str(j)]="0.00"
537                         res["bal_perc"+str(j)]="0.00%"
538                     else:
539                         temp_cash=entry[j].balance - entry[j-1].balance
540                         res["bal_cash"+str(j)]=locale.format("%.2f", temp_cash, grouping=True)
541                         if entry[j-1].balance<>0.00:
542                             temp_perc=(entry[j].balance - entry[j-1].balance )*100/entry[j-1].balance
543                         else:
544                             temp_perc=(entry[j].balance) *100
545
546                         res["bal_perc"+str(j)]=locale.format("%.2f", temp_perc) + "%"
547
548
549                     if ref_bal=='nothing':
550                         if level==1:
551                             self.parent_bal=1
552                         else:
553                             self.parent_bal=0
554
555                         if self.parent_bal==1:
556                             res["balance_perc"+str(j)]="/"
557                         else:
558                             if entry[j].balance==0.00:
559                                 if self.baldiv["baldiv"+str(level-1)+str(j)]<>0.00:
560                                     res["balance_perc"+str(j)]="0.00%"
561                                 else:
562                                     res["balance_perc"+str(j)]="/"
563                             else:
564                                 if self.baldiv["baldiv"+str(level-1)+str(j)]<>0.00:
565                                     temp=self.baldiv["baldiv"+str(level-1)+str(j)]
566                                     temp1=(entry[j].balance * 100 )/ float(temp)
567                                     temp1=round(temp1,2)
568                                     res["balance_perc" + str(j)]=str(temp1)+"%"
569                                 else:
570                                     res["balance_perc"+str(j)]="/"
571                     else:
572                         res["balance_perc"+str(j)]=str( (entry[j].balance * 100 )/ float(ref_bal)) + "%"
573
574             result.append(res)
575
576             if entry[0].child_id:
577
578                 for q in range(0,len(form['fiscalyear'][0][2])):
579                     self.baldiv["baldiv"+str(level)+str(q)]=entry[q].balance
580
581                 ids2 = [(x.code,x.id) for x in entry[0].child_id]
582                 ids2.sort()
583                 dir=[]
584                 dir += self.lines(form, [x[1] for x in ids2], done, level+1)
585                 if dir==[]:
586                     for w in range(0,len(form['fiscalyear'][0][2])):
587                         if entry[w].credit <> 0.0 or entry[w].debit <> 0.0 or entry[w].balance<>0.00:
588                             dont_pop=1
589                             break
590                         else:
591                             dont_pop=0
592                     if dont_pop==1:
593                         result +=dir
594                     else:
595                         result.pop(-1)   # here we pop up the parent having its children as emprty accounts
596                 else:
597                     result +=dir
598
599         return result
600     
601     def get_years(self,form):
602         result =[]
603         res={}
604         for temp in range(0,len(form['fiscalyear'][0][2])):
605             res={}
606             fy=self.pool.get('account.fiscalyear').name_get(self.cr,self.uid,form['fiscalyear'][0][2][temp])
607             res['year']=fy[0][1][12:16]
608             res['last_str']=temp
609             
610             result.append(res)
611         self.linesForYear(form)
612         return result
613     
614     def get_lines(self,year_dict,form):
615         final_result = []
616         line_l =[]
617         res = {}         
618         line_l = self.lines(form)
619         self.cal_total(year_dict)
620         if line_l:
621             for l in line_l:
622                 res = {}
623                 res['code'] = l['code']
624                 res['name'] = l['name']
625                 res['level'] = l['level']
626                 for k,v in l.items():
627                     if k.startswith('debit'+str(year_dict['last_str'])):
628                      res['debit'] = v  
629                     if k.startswith('credit'+str(year_dict['last_str'])):
630                      res['credit'] = v
631                     if k.startswith('balance'+str(year_dict['last_str'])) and not k.startswith('balance_perc'+str(year_dict['last_str'])):
632                      res['balance'] =v 
633                     if k.startswith('balance_perc'+str(year_dict['last_str'])) and not k.startswith('balance'+str(year_dict['last_str'])):
634                      res['balance_perc'] = v
635                     if form['compare_pattern'] == 'bal_perc':
636                         if k.startswith('bal_perc'+str(year_dict['last_str'])):
637                          res['pattern'] = v
638                     elif form['compare_pattern'] == 'bal_cash':
639                         if k.startswith('bal_cash'+str(year_dict['last_str'])):
640                          res['pattern'] = v
641                     else:
642                          res['pattern'] = ''
643                 final_result.append(res)
644         return final_result
645
646     def cal_total(self,year_dict):
647         total_l = self.result_total
648         if total_l:
649             for k,v in total_l.items():
650                 if k.startswith('sum_debit'+str(year_dict['last_str'])):
651                     self.dr_total = v
652                 elif k.startswith('sum_credit'+str(year_dict['last_str'])):
653                     self.cr_total = v
654                 else:
655                     continue
656         return True
657     
658     def total_dr(self):
659         return self.dr_total
660     
661     def total_cr(self):
662         return self.cr_total
663
664 report_sxw.report_sxw('report.account.account.balance.landscape', 'account.account', 'addons/account_balance/report/account_balance_landscape.rml', parser=account_balance_landscape, header=False)
665 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
666