~openbias/bias-trunk/bias-public-trunk

« back to all changes in this revision

Viewing changes to bias_query/report/query_report.py

  • Committer: Jose Patricio
  • Date: 2011-10-19 03:16:40 UTC
  • Revision ID: josepato@bias.com.mx-20111019031640-05zd7r5lxwx084qu
el push inicial

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
24
 
 
25
from report.interface import report_int
 
26
import reportlab.lib.pagesizes as pagesize
 
27
import pooler
 
28
import tools
 
29
from lxml  import etree
 
30
from report import render
 
31
import csv
 
32
import re
 
33
 
 
34
import time, os
 
35
import mx.DateTime
 
36
import StringIO
 
37
import base64
 
38
import utilRML_std
 
39
 
 
40
class report_printscreen_list(report_int):
 
41
    def __init__(self, name):
 
42
        report_int.__init__(self, name)
 
43
 
 
44
 
 
45
 
 
46
    def unicode_csv_reader(self, utf8_data, dialect=csv.excel, **kwargs):
 
47
        csv_reader = csv.reader(utf8_data, delimiter = ',', quotechar = '"')
 
48
        for row in csv_reader:
 
49
            yield [unicode(cell, 'utf-8') for cell in row]
 
50
 
 
51
 
 
52
 
 
53
    def comma_me(self,amount):
 
54
        if  type(amount) is float :
 
55
            amount = str('%.2f'%amount)
 
56
        else :
 
57
            amount = str(amount)
 
58
        if (amount == '0'):
 
59
            return ' '
 
60
        orig = amount
 
61
        new = re.sub("^(-?\d+)(\d{3})", "\g<1>,\g<2>", amount)
 
62
        if orig == new:
 
63
            return new
 
64
        else:
 
65
            return self.comma_me(new)
 
66
 
 
67
 
 
68
    def get_para_style(self, uid, field):
 
69
        result = {}
 
70
        para = utilRML_std.para()
 
71
        para.setnoClosing()
 
72
        col_options = field.keys()
 
73
        for option in dir(para):
 
74
            if option in col_options:
 
75
                para_str = 'para.%s("%s")'%(option, field[option])
 
76
                if field.has_key('conditioning'):
 
77
                    result['conditioning'] = field['conditioning']
 
78
                if field[option]:
 
79
                    eval(para_str)
 
80
        result['para'] = para
 
81
        return result
 
82
 
 
83
    def evaluate_condition(self, uid, condition_brw, elem):
 
84
        for condition in condition_brw:
 
85
            try:
 
86
                res = eval("%s %s %s"%(elem, condition.name, condition.value))
 
87
            except:
 
88
                res = eval("'%s' %s '%s'"%(elem, condition.name, condition.value))
 
89
            if res:
 
90
                field ={'setfontname':condition.fontname,
 
91
                        'setfontsize':condition.fontsize,
 
92
                        'setalignment':condition.align,
 
93
                        'settextColor':condition.textcolor,
 
94
                        'setbackColor':condition.backcolor,
 
95
                         }
 
96
                para_style = self.get_para_style(uid, field)['para']
 
97
                return para_style
 
98
        return ''
 
99
            
 
100
 
 
101
    def _parse_node(self, root_node):
 
102
        result = []
 
103
        for node in root_node.getchildren():
 
104
            if node.tag == 'field':
 
105
                attrsa = node.attrib
 
106
                attrs = {}
 
107
                if not attrsa is None:
 
108
                   for key,val in attrsa.items():
 
109
                    attrs[key] = val
 
110
                result.append(attrs['name'])
 
111
            else:
 
112
                result.extend(self._parse_node(node))
 
113
        return result
 
114
 
 
115
##    def _parse_string(self, view):
 
116
##        try:
 
117
##            dom = etree.XML(view.encode('utf-8'))
 
118
##        except:
 
119
##            dom = etree.XML(view)   
 
120
##        return self._parse_node(dom)
 
121
 
 
122
    def create(self, cr, uid, ids, datas, context=None):
 
123
        if not context:
 
124
            context={}
 
125
        pool = pooler.get_pool(cr.dbname)
 
126
        model = pool.get(datas['model'])
 
127
        model_id = pool.get('ir.model').search(cr, uid, [('model','=',model._name)])
 
128
        model_brw =  model.browse(cr, uid, datas['id'])
 
129
        datas['ids'] = ids
 
130
        model = pooler.get_pool(cr.dbname).get(datas['model'])
 
131
        lables = model_brw.label_ids
 
132
        fields = {}
 
133
        fields_order = []
 
134
        invisible  = []
 
135
        for label in model_brw.label_ids:
 
136
            if not label.invisible:
 
137
                invisible.append(0)
 
138
                fields_order.append(label.label_new or label.name)
 
139
                fields[label.label_new or label.name] = {
 
140
                    'size':label.size,
 
141
                    'string':label.label_new or label.name,
 
142
                    'type':label.f_type,
 
143
                    'setfontname':label.fontname,
 
144
                    'setfontsize':label.fontsize,
 
145
                    'setalignment':label.align,
 
146
                    'settextColor':label.textcolor,
 
147
                    'setbackColor':label.backcolor,
 
148
                    'sum':label.sum,
 
149
                    }
 
150
                if label.style_ids:
 
151
                    fields[label.label_new or label.name].update({'conditioning':label.style_ids})
 
152
            else:
 
153
                invisible.append(1)
 
154
        rows = datas['form']['file.csv']
 
155
        buf = StringIO.StringIO(rows)
 
156
        report_name = '/tmp/report_%s.csv'%(uid)
 
157
        ss = open(report_name,'w')
 
158
        ss.write(base64.decodestring(buf.getvalue()))
 
159
        ss.close()
 
160
        buf.close()
 
161
        #rows = csv.reader(open(report_name,'rb'), delimiter = ',', quotechar = '"')
 
162
        rows = self.unicode_csv_reader(open(report_name,'rb'))
 
163
        rows_lst = []
 
164
        sniff = []
 
165
        integer = ''
 
166
        header = []
 
167
        if datas['form']['header']:
 
168
            count = 0
 
169
            for rr in rows:
 
170
                if count == 4:
 
171
                    first_row_titles = rows.next()
 
172
                    self.title = header[2]
 
173
                    break
 
174
                header += rr
 
175
                count +=1
 
176
        else:
 
177
            self.title = model_brw.name
 
178
        for row in rows:
 
179
            count = 0
 
180
            new_row = []
 
181
            for rr in row:
 
182
                if not invisible[count]:
 
183
                    new_row.append(rr)
 
184
                count += 1
 
185
            rows_lst.append(new_row)
 
186
        res = self._create_table(uid, model_brw, datas['ids'], fields, fields_order, rows_lst, context, self.title , header)
 
187
        return (self.obj.get(), 'pdf')
 
188
 
 
189
 
 
190
    def add_row_element(self, uid, elem, para_col_tag, count, type=0):
 
191
        if type:
 
192
            if elem:
 
193
                cc = self.comma_me(elem)
 
194
                if para_col_tag[count].has_key('conditioning'):
 
195
                    new_para = self.evaluate_condition(uid, para_col_tag[count]['conditioning'], re.sub(' %','',elem))
 
196
                    if new_para:
 
197
                        return new_para + self.comma_me(elem) +'</para>' or '' 
 
198
                    else:
 
199
                        return para_col_tag[count]['para'] + self.comma_me(elem) +'</para>' or '' 
 
200
                else:
 
201
                    return para_col_tag[count]['para'] + self.comma_me(elem) +'</para>' or '' 
 
202
            else:
 
203
                return ''
 
204
        else:
 
205
            if elem:
 
206
                if para_col_tag[count].has_key('conditioning'):
 
207
                    new_para = self.evaluate_condition(uid, para_col_tag[count]['conditioning'], re.sub(' %','',elem))
 
208
                    if new_para:
 
209
                        return new_para + elem +'</para>' or '' 
 
210
                    else:
 
211
                        return para_col_tag[count]['para'] + elem +'</para>' or '' 
 
212
                else:
 
213
                    return para_col_tag[count]['para'] + elem +'</para>' or '' 
 
214
            else:
 
215
                return ''
 
216
 
 
217
    def _create_table(self, uid, model_brw, ids, fields, fields_order, results, context, title='', header = ''):
 
218
        stylesheet = utilRML_std.stylesheet()
 
219
        style = utilRML_std.getdefaultStyles()
 
220
        stylesheet.addElement(style)
 
221
        story = utilRML_std.story()
 
222
        style_acc = utilRML_std.blockTableStyle('location_heder')
 
223
        style_acc.setblockFont('Helvetica-Bold',{'size':'9'})
 
224
        style_acc.setblockAlignment('LEFT')
 
225
        style_acc.setlineStyle('LINEBELOW', 'black', {'thickness':'2','start':'0,-1', 'stop':'-1,-1'})
 
226
        stylesheet.addElement(style_acc)
 
227
        table_functions = {'page':model_brw.page_size,
 
228
                           'portrait' : model_brw.portrait,}
 
229
        #table_h, style_heder = utilRML_std.getstandarReportHeader(header, table_functions)
 
230
        #stylesheet.addElement(style_heder)
 
231
        pageSize =  'pagesize.%s'%(table_functions['page'])
 
232
        pageSize = eval(pageSize)
 
233
        if table_functions['portrait']:
 
234
            pageSize = (pageSize[1], pageSize[0])
 
235
 
 
236
        l = []
 
237
        t = 0
 
238
        rowcount=0;
 
239
        strmax = (pageSize[0] - 60) 
 
240
        temp = []
 
241
        count = len(fields_order)
 
242
        for i in range(0,count):
 
243
            temp.append(0)
 
244
        if header:
 
245
            table = utilRML_std.blockTable()
 
246
            table.setstyle('header')
 
247
            table.setcolWidths('%s,%s,%s'%(strmax/3 , strmax/3, strmax/3))
 
248
            row = utilRML_std.tr()
 
249
            row.addElement(' ')
 
250
            row.addElement(header[0])
 
251
            r20 = header[1].split(',')[0]
 
252
            row.addElement(r20)
 
253
            row2 = utilRML_std.tr()
 
254
            row2.addElement('')
 
255
            row2.addElement(header[2])
 
256
            r21 = header[1].split(',')[1]
 
257
            row2.addElement(r21)
 
258
            table.addElement(row)
 
259
            table.addElement(row2)
 
260
            count = 0
 
261
            row = utilRML_std.tr()
 
262
            story.addElement(table)
 
263
            #### adds the options
 
264
            table = utilRML_std.blockTable()
 
265
            table.setstyle('header-options')
 
266
            table.setcolWidths('%s'%(strmax))
 
267
            row = utilRML_std.tr()
 
268
            row.addElement('<para>' + header[3] + '</para>')
 
269
            table.addElement(row)
 
270
            story.addElement(table)
 
271
        ince = -1;
 
272
        para_col_tag = []
 
273
        row = utilRML_std.tr()
 
274
        context = {'fontName':'Helvetica-Bold'}
 
275
        for f in fields_order:
 
276
            row.addElement(f, context)
 
277
            s = 0
 
278
            ince += 1
 
279
            if (fields[f]['type'] in ('float','integer')) and not (fields[f]['sum']):
 
280
                temp[ince] = 1
 
281
            elif (fields[f]['type'] in ('float','integer')) and (fields[f]['sum']):
 
282
                temp[ince] = 2
 
283
            elif (fields[f]['type'] == 'pct') and not (fields[f]['sum']):
 
284
                temp[ince] = 3
 
285
            elif (fields[f]['type'] == 'pct') and (fields[f]['sum']):
 
286
                temp[ince] = 4
 
287
            t += fields[f].get('size', 10)# / 28 + 1
 
288
            l.append(s)
 
289
            para_col_tag.append(self.get_para_style( uid, fields[f]))
 
290
        for pos in range(len(l)):
 
291
            if not l[pos]:
 
292
                s = fields[fields_order[pos]].get('size', 10) #/ 28 + 1
 
293
                l[pos] = strmax * s / t
 
294
        nl = ''        
 
295
        for size in map(str,l):
 
296
            nl += size + ' ,'
 
297
        nl = nl.rstrip(',')
 
298
        tsum = []
 
299
        count = len(fields_order)
 
300
        for i in range(0,count):
 
301
            tsum.append(0)
 
302
        table = utilRML_std.blockTable()
 
303
        table.setcolWidths(nl)
 
304
        table.setstyle('products')
 
305
        table.setrepeatRows(1)
 
306
        table.addElement(row)
 
307
        trows = 0
 
308
        for line in results:
 
309
            trows += 1
 
310
            row = utilRML_std.tr()
 
311
            #node_line = etree.Element("row")
 
312
            count = -1
 
313
            for elem in line:
 
314
                if elem == 'None' or elem == 'False':
 
315
                    elem = ''
 
316
                else:
 
317
                    elem = re.sub('&','', elem)
 
318
                count += 1
 
319
                context = {}
 
320
                if temp[count] in (1,2,3,4): ####aqui van los integers y floats y pct
 
321
                    if not elem:
 
322
                        elem = 0
 
323
                    try:
 
324
                        ss = float(elem or 0)
 
325
                    except:
 
326
                        ss = 0
 
327
                    if temp[count] in (2 ,4):
 
328
                        tsum[count] = float(tsum[count])  + ss
 
329
                    if temp[count] in (3 , 4):
 
330
                        elem = str('%.2f'%float(elem)) + ' %'
 
331
                    row.addElement(self.add_row_element( uid, elem, para_col_tag, count, temp[count]))
 
332
                else:
 
333
                    row.addElement(self.add_row_element( uid, elem, para_col_tag, count))
 
334
            table.addElement(row)
 
335
            
 
336
        ####totales
 
337
        row = utilRML_std.tr()
 
338
        total = 0
 
339
        for aa in tsum:
 
340
            total += aa
 
341
        if total:
 
342
            for f in range(0,count+1):
 
343
                context = {}
 
344
                if tsum[f] != None:
 
345
                   if (tsum[f] >= 0.01) and (temp[f] == 2) :
 
346
                       prec = '%.' +  str(2)  + 'f'
 
347
                       total = prec%(tsum[f])
 
348
                       txt = str(total or '')
 
349
                   else:
 
350
                       txt = str(tsum[f] or '')
 
351
                else:
 
352
                    txt = ' '
 
353
                if f == 0:
 
354
                    txt ='Total'
 
355
                if temp[f] == 4:
 
356
                    prec = '%.' +  str(2)  + 'f'
 
357
                    total = prec%(tsum[f]/trows)
 
358
                    txt = str(total or '') + ' %'
 
359
                row.addElement(self.add_row_element( uid, self.comma_me(txt), para_col_tag, f))
 
360
                #row.addElement(self.comma_me(txt) or '', context)
 
361
            table.addElement(row)
 
362
        story.addElement(table)
 
363
 
 
364
        doc = utilRML_std.document()
 
365
        doc.setfilename(self.title)
 
366
        template = utilRML_std.template()
 
367
        template.settitle(self.title)
 
368
        template.setpageSize(model_brw.page_size, model_brw.portrait)
 
369
        template.setrotation(model_brw.rotation)
 
370
        pageTemplate = utilRML_std.pageTemplate()
 
371
        pageTemplate.setid('first')
 
372
        frame = utilRML_std.frame()
 
373
        frame.setx1(model_brw.margin_x)
 
374
        frame.sety1(model_brw.margin_y)
 
375
        frame.setsize(model_brw.page_size, model_brw.portrait)
 
376
        pageGP = utilRML_std.pageGraphics()
 
377
        if model_brw.count_pages:
 
378
            drawString = utilRML_std.drawString()
 
379
            drawString.sety('10')
 
380
            drawString.setx('10')
 
381
            drawString.addElement("Pag.: '<pageNumber/>'")
 
382
            pageGP.addElement(drawString)
 
383
        pageTemplate.addElement(frame)
 
384
        pageTemplate.addElement(pageGP)
 
385
        template.addElement(pageTemplate)
 
386
        #template = utilRML_std.getdefaultTemplate(table_functions['page'], table_functions['portrait'])
 
387
        doc.addElement(template)
 
388
        doc.addElement(stylesheet)
 
389
        doc.setnoClosing()
 
390
        rml2 = `doc` + `story` + '</document>\n'
 
391
        self.obj = render.rml(rml2, title=self.title)
 
392
        self.obj.render()
 
393
        return True
 
394
    
 
395
report_printscreen_list('report.query.print.report')
 
396
 
 
397
 
 
398
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: