~openerp-community/openobject-addons/taktik

« back to all changes in this revision

Viewing changes to account/report/report_xls.py

  • Committer: Fabien Lydoire
  • Date: 2010-06-18 09:43:14 UTC
  • Revision ID: fl@taktik.be-20100618094314-rsei1ysqf6uwz6nf
added account reports in xls

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- encoding: utf-8 -*-
 
2
##############################################################################
 
3
#
 
4
# Copyright (c) 2010 AJM Technologies S.A. (http://www.ajm.lu)
 
5
#
 
6
# WARNING: This program as such is intended to be used by professional
 
7
# programmers who take the whole responsability of assessing all potential
 
8
# consequences resulting from its eventual inadequacies and bugs
 
9
# End users who are looking for a ready-to-use solution with commercial
 
10
# garantees and support are strongly adviced to contract a Free Software
 
11
# Service Company
 
12
#
 
13
# This program is Free Software; you can redistribute it and/or
 
14
# modify it under the terms of the GNU General Public License
 
15
# as published by the Free Software Foundation; either version 3
 
16
# of the License, or (at your option) any later version.
 
17
#
 
18
# This program is distributed in the hope that it will be useful,
 
19
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
20
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
21
# GNU General Public License for more details.
 
22
#
 
23
# You should have received a copy of the GNU General Public License
 
24
# along with this program; if not, write to the Free Software
 
25
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
26
#
 
27
##############################################################################
 
28
 
 
29
from report import report_sxw
 
30
import tools
 
31
import xlwt
 
32
import cStringIO
 
33
import time
 
34
import datetime
 
35
import pooler
 
36
 
 
37
class report_xls(report_sxw.report_sxw):
 
38
 
 
39
    xls_types = {
 
40
        'bool': xlwt.Row.set_cell_boolean,
 
41
        'date': xlwt.Row.set_cell_date,
 
42
        'text': xlwt.Row.set_cell_text,
 
43
        'number': xlwt.Row.set_cell_number,
 
44
    }
 
45
    xls_types_default = {
 
46
        'bool': False,
 
47
        'date': None,
 
48
        'text': '',
 
49
        'number': 0,
 
50
    }
 
51
 
 
52
    # Override create to force it to "XLS" mode
 
53
    def create(self, cr, uid, ids, data, context=None):
 
54
        pool = pooler.get_pool(cr.dbname)
 
55
        ir_obj = pool.get('ir.actions.report.xml')
 
56
        report_xml_ids = ir_obj.search(cr, uid,
 
57
                [('report_name', '=', self.name[7:])], context=context)
 
58
        if report_xml_ids:
 
59
            report_xml = ir_obj.browse(cr, uid, report_xml_ids[0], context=context)
 
60
        else:
 
61
            title = ''
 
62
            rml = tools.file_open(self.tmpl, subdir=None).read()
 
63
            report_type= data.get('report_type', 'pdf')
 
64
            class a(object):
 
65
                def __init__(self, *args, **argv):
 
66
                    for key,arg in argv.items():
 
67
                        setattr(self, key, arg)
 
68
            report_xml = a(title=title, report_type=report_type, report_rml_content=rml, name=title, attachment=False, header=self.header)
 
69
        report_type = report_xml.report_type
 
70
        ## ajm override :: begin
 
71
        report_type = 'xls'
 
72
        ## ajm override :: end
 
73
        if report_type in ['sxw','odt']:
 
74
            fnct = self.create_source_odt
 
75
        elif report_type in ['pdf','raw','html']:
 
76
            fnct = self.create_source_pdf
 
77
        elif report_type=='html2html':
 
78
            fnct = self.create_source_html2html
 
79
        ## ajm override :: begin
 
80
        elif report_type == 'xls':
 
81
            fnct = self.create_source_xls
 
82
        ## ajm override :: end
 
83
        else:
 
84
            raise 'Unknown Report Type'
 
85
        fnct_ret = fnct(cr, uid, ids, data, report_xml, context)
 
86
        if not fnct_ret:
 
87
            return (False,False)
 
88
        return fnct_ret
 
89
 
 
90
    def create_source_xls(self, cr, uid, ids, data, report_xml, context=None):
 
91
        #print("START: "+time.strftime("%Y-%m-%d %H:%M:%S"))
 
92
 
 
93
        if not context:
 
94
            context = {}
 
95
        context = context.copy()
 
96
        rml_parser = self.parser(cr, uid, self.name2, context=context)
 
97
        objs = self.getObjects(cr, uid, ids, context=context)
 
98
        rml_parser.set_context(objs, data, ids, 'xls')
 
99
 
 
100
        n = cStringIO.StringIO()
 
101
        wb = xlwt.Workbook(encoding='utf-8')
 
102
        for i, a in enumerate(rml_parser.localcontext['objects']):
 
103
            self.generate_xls_report(rml_parser, data, a, wb)
 
104
        wb.save(n)
 
105
        n.seek(0)
 
106
 
 
107
        #print("END: "+time.strftime("%Y-%m-%d %H:%M:%S"))
 
108
 
 
109
        return (n.read(), 'xls')
 
110
 
 
111
    def generate_xls_report(self, parser, data, obj, wb):
 
112
        """Generate Report
 
113
        this function has to be overriden by each new report
 
114
        """
 
115
        raise NotImplementedError()
 
116
 
 
117
    def dt_to_datetime(self, date_str):
 
118
        return datetime.datetime.fromtimestamp(time.mktime(time.strptime(date_str, '%Y-%m-%d %H:%M:%S')))
 
119
 
 
120
    def d_to_datetime(self, date_str):
 
121
        return datetime.datetime.fromtimestamp(time.mktime(time.strptime(date_str, '%Y-%m-%d')))
 
122
 
 
123
    def xls_row_template(self, specs, wanted_list):
 
124
        """Return a row template
 
125
        @specs: contains column specifications:
 
126
            0: Column Name
 
127
            1: Column Colspan
 
128
            2: Column Size
 
129
            3: Column Type (from report_xls.xls_types)
 
130
            4: Column data_get_function(x, d, p)
 
131
            5: Column write_cell_func
 
132
            6: Column Style
 
133
        @wanted_list: wanted columns name list in the desired order
 
134
        """
 
135
        r = []
 
136
        col = 0
 
137
        for w in wanted_list:
 
138
            for s in specs:
 
139
                if s[0] == w:
 
140
                    c = list(s[:])
 
141
                    c.append(report_xls.xls_types[c[3]])
 
142
 
 
143
                    # Set custom cell style
 
144
                    if len(s) > 5 and s[5] is not None:
 
145
                        c.append(s[5])
 
146
                    else:
 
147
                        c.append(None)
 
148
 
 
149
                    r.append((col, c[1], c))
 
150
                    col += c[1]
 
151
                    break
 
152
        return r
 
153
    def xls_write_row(self, ws, x, d, p, row_count, row_template, row_style):
 
154
        """Write a row to a WorkSheet
 
155
        @ws: xlwt.Worksheet instance
 
156
        @x: current object
 
157
        @d: wizard form data
 
158
        @p: report_sxw.rml_parse instance
 
159
        @row_count: the row on which we're going to write
 
160
        @row_template: the row template we will use
 
161
        @row_style: the row style to be used for this row
 
162
        """
 
163
        r = ws.row(row_count)
 
164
        for col, size, spec in row_template:
 
165
            data = spec[4](x, d, p)
 
166
            style = spec[6] and spec[6] or row_style
 
167
            if not data:
 
168
                # if no data, use default values
 
169
                data = report_xls.xls_types_default[spec[3]]
 
170
            if size != 1:
 
171
                ws.write_merge(row_count, row_count,
 
172
                               col, col+size-1,
 
173
                               data, style)
 
174
            else:
 
175
                spec[5](r, col, data, style)
 
176
 
 
177
    def xls_write_row_header(self, ws, row_count, row_template, row_style=None, set_column_size=False):
 
178
        """Write a row header
 
179
        @ws: xlwt.Worksheet instance
 
180
        @row_count: the row on which we're going to write
 
181
        @row_template: the row template we will use
 
182
        @row_style: the row style to be used for this row
 
183
        @set_column_size: set column size based on this template
 
184
        """
 
185
        r = ws.row(row_count)
 
186
        for col, size, spec in row_template:
 
187
            data = spec[0]
 
188
            if size != 1:
 
189
                ws.write_merge(row_count, row_count,
 
190
                               col, col+size-1,
 
191
                               data, row_style)
 
192
            else:
 
193
                r.set_cell_text(col, data, row_style)
 
194
            if set_column_size:
 
195
                ws.col(col).width = spec[2] * 54
 
196
 
 
197
 
 
198
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: