Merge lp:~luc-demeyer/openerp-reporting-engines/datetime-fix-report_xls into lp:openerp-reporting-engines

Proposed by Luc De Meyer (Noviat)
Status: Merged
Merged at revision: 3
Proposed branch: lp:~luc-demeyer/openerp-reporting-engines/datetime-fix-report_xls
Merge into: lp:openerp-reporting-engines
Diff against target: 351 lines (+100/-58)
4 files modified
report_xls/__init__.py (+1/-1)
report_xls/__openerp__.py (+48/-12)
report_xls/report_xls.py (+45/-40)
report_xls/utils.py (+6/-5)
To merge this branch: bzr merge lp:~luc-demeyer/openerp-reporting-engines/datetime-fix-report_xls
Reviewer Review Type Date Requested Status
Guewen Baconnier @ Camptocamp Approve
Pedro Manuel Baeza code review Approve
Joël Grand-Guillaume @ camptocamp code review, no tests Approve
Review via email: mp+200604@code.launchpad.net

Description of the change

style & documentation refresh
xls footer datetime fix

To post a comment you must log in.
Revision history for this message
Joël Grand-Guillaume @ camptocamp (jgrandguillaume-c2c) wrote :

Hi,

Thanks for this cleanup, very much appreciated.

LGTM,

Regards,

review: Approve (code review, no tests)
Revision history for this message
Pedro Manuel Baeza (pedro.baeza) wrote :

LGTM

review: Approve (code review)
Revision history for this message
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'report_xls/__init__.py'
2--- report_xls/__init__.py 2013-11-15 15:56:47 +0000
3+++ report_xls/__init__.py 2014-01-06 22:32:08 +0000
4@@ -12,7 +12,7 @@
5 #
6 # This program is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # GNU Affero General Public License for more details.
11 #
12 # You should have received a copy of the GNU Affero General Public License
13
14=== modified file 'report_xls/__openerp__.py'
15--- report_xls/__openerp__.py 2013-11-15 15:56:47 +0000
16+++ report_xls/__openerp__.py 2014-01-06 22:32:08 +0000
17@@ -12,7 +12,7 @@
18 #
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 # GNU Affero General Public License for more details.
24 #
25 # You should have received a copy of the GNU Affero General Public License
26@@ -20,24 +20,60 @@
27 #
28 ##############################################################################
29 {
30- 'name': 'XLS report engine',
31- 'version': '0.3',
32+ 'name': 'Excel report engine',
33+ 'version': '0.4',
34 'license': 'AGPL-3',
35 'author': 'Noviat',
36 'website': 'http://www.noviat.com',
37 'category': 'Reporting',
38- 'description': """
39-
40-This module adds XLS export capabilities to the standard OpenERP reporting engine.
41-
42-In order to generate an XLS export you can define a report of type 'xls' or alternatively pass {'xls_export' : 1) via the context to create method of the report.
43-
44+ 'description': """
45+Excel report engine
46+===================
47+
48+This module adds Excel export capabilities to the standard OpenERP reporting engine.
49+
50+Report development
51+''''''''''''''''''
52+In order to create an Excel report you can\n
53+- define a report of type 'xls'
54+- pass ``{'xls_export': 1}`` via the context to the report create method
55+
56+The ``report_xls`` class contains a number of attributes and methods to facilitate
57+the creation XLS reports in OpenERP.
58+
59+* cell types
60+
61+ Supported cell types : text, number, boolean, date.
62+
63+* cell styles
64+
65+ The predefined cell style definitions result in a consistent
66+ look and feel of the OpenERP Excel reports.
67+
68+* cell formulas
69+
70+ Cell formulas can be easily added with the help of the ``rowcol_to_cell()`` function which
71+ you can import from the ``utils.py`` module.
72+
73+* Excel templates
74+
75+ It is possible to define Excel templates which can be adapted by 'inherited' modules.
76+ Download the ``account_move_line_report_xls`` module from http://apps.openerp.com
77+ as example.
78+
79+* XLS with multiple sheets
80+
81+ Download the ``account_journal_report_xls`` module from http://apps.openerp.com as example.
82+
83+Development assistance
84+''''''''''''''''''''''
85+Contact info@noviat.com for help with the development of Excel reports in OpenERP, .
86+
87 """,
88 'depends': ['base'],
89 'external_dependencies': {'python': ['xlwt']},
90- 'demo_xml': [],
91- 'init_xml': [],
92- 'update_xml' : [],
93+ 'demo': [],
94+ 'data': [],
95 'active': False,
96 'installable': True,
97 }
98
99=== modified file 'report_xls/report_xls.py'
100--- report_xls/report_xls.py 2013-11-15 15:56:47 +0000
101+++ report_xls/report_xls.py 2014-01-06 22:32:08 +0000
102@@ -2,8 +2,8 @@
103 ##############################################################################
104 #
105 # OpenERP, Open Source Management Solution
106-#
107-#Copyright (c) 2013 Noviat nv/sa (www.noviat.com). All rights reserved.
108+#
109+# Copyright (c) 2013 Noviat nv/sa (www.noviat.com). All rights reserved.
110 #
111 # This program is free software: you can redistribute it and/or modify
112 # it under the terms of the GNU Affero General Public License as
113@@ -12,7 +12,7 @@
114 #
115 # This program is distributed in the hope that it will be useful,
116 # but WITHOUT ANY WARRANTY; without even the implied warranty of
117-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
118+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
119 # GNU Affero General Public License for more details.
120 #
121 # You should have received a copy of the GNU Affero General Public License
122@@ -23,7 +23,8 @@
123 import xlwt
124 from xlwt.Style import default_style
125 import cStringIO
126-import datetime, time
127+from datetime import datetime
128+from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
129 import inspect
130 from types import CodeType
131 from openerp.report.report_sxw import *
132@@ -32,13 +33,15 @@
133 import logging
134 _logger = logging.getLogger(__name__)
135
136+
137 class AttrDict(dict):
138 def __init__(self, *args, **kwargs):
139 super(AttrDict, self).__init__(*args, **kwargs)
140 self.__dict__ = self
141
142+
143 class report_xls(report_sxw):
144-
145+
146 xls_types = {
147 'bool': xlwt.Row.set_cell_boolean,
148 'date': xlwt.Row.set_cell_date,
149@@ -53,36 +56,29 @@
150 }
151
152 # TO DO: move parameters infra to configurable data
153-
154+
155 # header/footer
156- DT_FORMAT = '%Y-%m-%d %H:%M:%S'
157+ DT_FORMAT = '%Y-%m-%d %H:%M:%S'
158 hf_params = {
159 'font_size': 8,
160- 'font_style': 'I', # B: Bold, I: Italic, U: Underline
161- }
162- xls_headers = {
163- 'standard': ''
164- }
165- xls_footers = {
166- 'standard': ('&L&%(font_size)s&%(font_style)s' + datetime.now().strftime(DT_FORMAT) +
167- '&R&%(font_size)s&%(font_style)s&P / &N') %hf_params
168- }
169-
170+ 'font_style': 'I', # B: Bold, I: Italic, U: Underline
171+ }
172+
173 # styles
174- _pfc = '26' # default pattern fore_color
175- _bc = '22' # borders color
176+ _pfc = '26' # default pattern fore_color
177+ _bc = '22' # borders color
178 decimal_format = '#,##0.00'
179- date_format = 'YYYY-MM-DD'
180+ date_format = 'YYYY-MM-DD'
181 xls_styles = {
182 'xls_title': 'font: bold true, height 240;',
183 'bold': 'font: bold true;',
184 'underline': 'font: underline true;',
185 'italic': 'font: italic true;',
186- 'fill': 'pattern: pattern solid, fore_color %s;' %_pfc,
187- 'fill_blue' : 'pattern: pattern solid, fore_color 27;',
188- 'fill_grey' : 'pattern: pattern solid, fore_color 22;',
189- 'borders_all': 'borders: left thin, right thin, top thin, bottom thin, ' \
190- 'left_colour %s, right_colour %s, top_colour %s, bottom_colour %s;' %(_bc,_bc,_bc,_bc),
191+ 'fill': 'pattern: pattern solid, fore_color %s;' % _pfc,
192+ 'fill_blue': 'pattern: pattern solid, fore_color 27;',
193+ 'fill_grey': 'pattern: pattern solid, fore_color 22;',
194+ 'borders_all': 'borders: left thin, right thin, top thin, bottom thin, '
195+ 'left_colour %s, right_colour %s, top_colour %s, bottom_colour %s;' % (_bc, _bc, _bc, _bc),
196 'left': 'align: horz left;',
197 'center': 'align: horz center;',
198 'right': 'align: horz right;',
199@@ -91,8 +87,8 @@
200 'bottom': 'align: vert bottom;',
201 }
202 # TO DO: move parameters supra to configurable data
203-
204- def create(self, cr, uid, ids, data, context=None):
205+
206+ def create(self, cr, uid, ids, data, context=None):
207 self.pool = pooler.get_pool(cr.dbname)
208 self.cr = cr
209 self.uid = uid
210@@ -105,11 +101,13 @@
211 if report_xml.report_type == 'xls':
212 return self.create_source_xls(cr, uid, ids, data, context)
213 elif context.get('xls_export'):
214+ self.table = data.get('model') or self.table # use model from 'data' when no ir.actions.report.xml entry
215 return self.create_source_xls(cr, uid, ids, data, context)
216 return super(report_xls, self).create(cr, uid, ids, data, context)
217
218 def create_source_xls(self, cr, uid, ids, data, context=None):
219- if not context: context = {}
220+ if not context:
221+ context = {}
222 parser_instance = self.parser(cr, uid, self.name2, context)
223 self.parser_instance = parser_instance
224 objs = self.getObjects(cr, uid, ids, context)
225@@ -119,15 +117,22 @@
226 wb = xlwt.Workbook(encoding='utf-8')
227 _p = AttrDict(parser_instance.localcontext)
228 _xs = self.xls_styles
229+ self.xls_headers = {
230+ 'standard': '',
231+ }
232+ self.xls_footers = {
233+ 'standard': ('&L&%(font_size)s&%(font_style)s' + datetime.now().strftime(DEFAULT_SERVER_DATETIME_FORMAT) +
234+ '&R&%(font_size)s&%(font_style)s&P / &N') % self.hf_params,
235+ }
236 self.generate_xls_report(_p, _xs, data, objs, wb)
237 wb.save(n)
238 n.seek(0)
239- return (n.read(), 'xls')
240-
241+ return (n.read(), 'xls')
242+
243 def render(self, wanted, col_specs, rowtype, render_space='empty'):
244 """
245- returns 'mako'-rendered col_specs
246-
247+ returns 'evaluated' col_specs
248+
249 Input:
250 - wanted: element from the wanted_list
251 - col_specs : cf. specs[1:] documented in xls_row_template method
252@@ -139,7 +144,7 @@
253 caller_space = inspect.currentframe().f_back.f_back.f_locals
254 localcontext = self.parser_instance.localcontext
255 render_space.update(caller_space)
256- render_space.update(localcontext)
257+ render_space.update(localcontext)
258 row = col_specs[wanted][rowtype][:]
259 for i in range(len(row)):
260 if isinstance(row[i], CodeType):
261@@ -155,9 +160,9 @@
262 def xls_row_template(self, specs, wanted_list):
263 """
264 Returns a row template.
265-
266+
267 Input :
268- - 'wanted_list': list of Columns that will be returned in the row_template
269+ - 'wanted_list': list of Columns that will be returned in the row_template
270 - 'specs': list with Column Characteristics
271 0: Column Name (from wanted_list)
272 1: Column Colspan
273@@ -190,14 +195,14 @@
274 if s_len > 7 and s[7] is not None:
275 c.append(s[7])
276 else:
277- c.append(None)
278+ c.append(None)
279 r.append((col, c[1], c))
280 col += c[1]
281 break
282 if not found:
283 _logger.warn("report_xls.xls_row_template, column '%s' not found in specs", w)
284 return r
285-
286+
287 def xls_write_row(self, ws, row_pos, row_data, row_style=default_style, set_column_size=False):
288 r = ws.row(row_pos)
289 for col, size, spec in row_data:
290@@ -209,9 +214,9 @@
291 data = report_xls.xls_types_default[spec[3]]
292 if size != 1:
293 if formula:
294- ws.write_merge(row_pos, row_pos, col, col+size-1, data, style)
295+ ws.write_merge(row_pos, row_pos, col, col + size - 1, data, style)
296 else:
297- ws.write_merge(row_pos, row_pos, col, col+size-1, data, style)
298+ ws.write_merge(row_pos, row_pos, col, col + size - 1, data, style)
299 else:
300 if formula:
301 ws.write(row_pos, col, formula, style)
302@@ -220,5 +225,5 @@
303 if set_column_size:
304 ws.col(col).width = spec[2] * 256
305 return row_pos + 1
306-
307+
308 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
309
310=== added directory 'report_xls/static'
311=== added directory 'report_xls/static/src'
312=== added directory 'report_xls/static/src/img'
313=== added file 'report_xls/static/src/img/icon.png'
314Binary files report_xls/static/src/img/icon.png 1970-01-01 00:00:00 +0000 and report_xls/static/src/img/icon.png 2014-01-06 22:32:08 +0000 differ
315=== modified file 'report_xls/utils.py'
316--- report_xls/utils.py 2013-11-15 15:56:47 +0000
317+++ report_xls/utils.py 2014-01-06 22:32:08 +0000
318@@ -12,17 +12,18 @@
319 #
320 # This program is distributed in the hope that it will be useful,
321 # but WITHOUT ANY WARRANTY; without even the implied warranty of
322-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
323+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
324 # GNU Affero General Public License for more details.
325 #
326 # You should have received a copy of the GNU Affero General Public License
327 # along with this program. If not, see <http://www.gnu.org/licenses/>.
328 #
329 ##############################################################################
330-#
331+
332
333 def _render(code):
334- return compile(code, '<string>', 'eval')
335+ return compile(code, '<string>', 'eval')
336+
337
338 def rowcol_to_cell(row, col, row_abs=False, col_abs=False):
339 # Code based upon utils from xlwt distribution
340@@ -41,9 +42,9 @@
341 else:
342 col_abs = ''
343 if d > 0:
344- chr1 = chr(ord('A') + d - 1)
345+ chr1 = chr(ord('A') + d - 1)
346 chr2 = chr(ord('A') + m)
347 # Zero index to 1-index
348 return col_abs + chr1 + chr2 + row_abs + str(row + 1)
349-
350+
351 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

Subscribers

People subscribed via source and target branches