diff options
Diffstat (limited to 'addons/web/controllers')
| -rw-r--r-- | addons/web/controllers/__init__.py | 2 | ||||
| -rw-r--r-- | addons/web/controllers/list_controller.py | 98 | ||||
| -rw-r--r-- | addons/web/controllers/main.py | 9 |
3 files changed, 105 insertions, 4 deletions
diff --git a/addons/web/controllers/__init__.py b/addons/web/controllers/__init__.py index 48cc37266c6..2113dfa39c9 100644 --- a/addons/web/controllers/__init__.py +++ b/addons/web/controllers/__init__.py @@ -1,4 +1,4 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from . import main, pivot +from . import main, pivot, list_controller diff --git a/addons/web/controllers/list_controller.py b/addons/web/controllers/list_controller.py new file mode 100644 index 00000000000..7ac98b79220 --- /dev/null +++ b/addons/web/controllers/list_controller.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import json +from datetime import datetime + +from odoo import http +from odoo.http import request +from odoo.tools.misc import xlwt + + +HEADER_BOLD = xlwt.easyxf("font: bold on; pattern: pattern solid, fore_colour gray25;") + +class TableListExporter(http.Controller): + + def _write_group_header(self, worksheet, x, y, group, columns, group_depth=0): + aggregates = group.get('aggregateValues', {}) + title = group.get('value') + + if group.get('hideHeader'): + return x, y + + title = '%s%s (%s)' % ('>' * group_depth, title, group.get('count', 0)) + worksheet.write(x, y, title, HEADER_BOLD) + for column in columns[1:]: # No aggregates allowed in the first column + y += 1 + worksheet.write(x, y, aggregates.get(column['field'], ''), HEADER_BOLD) + return x + 1, 0 + + def _write_record(self, worksheet, x, y, record, columns): + for column in columns: + worksheet.write(x, y, record[column['field']]) + y += 1 + return x + 1, 0 + + def _write_groups(self, worksheet, x, y, groups, columns, group_depth=0): + """ + Write groups to the xls worksheet. Recursive if groups are nested (chained groupby) + :param worksheet: + :param x: start position where to write the group (vertical axis, pointing downward) + :param y: start position where to write the group (horizontal axis, pointing to the right) + :param groups: list of groups. Each group is a dict containing either records' data + or sub-groups. A group has the following structure: + 'data': list of records or list of sub-groups + 'isGrouped': True if data contains sub-groups + 'value': title of the group + 'count': number of records in the group + 'aggregateValues': dict container aggregated values of fields {field: aggregatedValue, ...} + 'hideHeader': self explanatory, used when the records are not grouped at all. + :param columns: list of displayed columns. Each column is a dict with the following keys: + 'field': field name + 'aggregateValue': aggregate for all records + 'string': + """ + for group in groups: + x, y = self._write_group_header(worksheet, x, y, group, columns, group_depth) + if group['isGrouped']: + # Recursively write sub-groups + x, y = self._write_groups(worksheet, x, y, group['data'], columns, group_depth + 1) + else: + for record in group['data']: + x, y = self._write_record(worksheet, x, y, record, columns) + return x, y + + def _write_worksheet(self, worksheet, data): + bold = xlwt.easyxf("font: bold on;") + + columns = data['columns'] + groups = data['groups'] + + # Write main header + for y, field in enumerate(columns): + worksheet.write(0, y, field['string'], bold) + + # Write data + x, y = 1, 0 + x, y = self._write_groups(worksheet, x, y, groups, columns) + + # Write column aggregates + for y, field in enumerate(columns): + worksheet.write(x, y, field.get('aggregateValue', ''), bold) + + @http.route('/web/list/export_xls', type='http', auth="user") + def export_xls(self, data, token): + data = json.loads(data) + title = data.get('title', 'export') + workbook = xlwt.Workbook() + worksheet = workbook.add_sheet(title) + + self._write_worksheet(worksheet, data) + + response = request.make_response(None, + headers=[('Content-Type', 'application/vnd.ms-excel'), + ('Content-Disposition', 'attachment; filename="%s - %s.xls"' % (title, datetime.now()))], + cookies={'fileToken': token}) + workbook.save(response.stream) + + return response diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index b2132850d08..cb8d4d82ecc 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -1190,7 +1190,7 @@ class Binary(http.Controller): '/web/partner_image/<int:rec_id>', '/web/partner_image/<int:rec_id>/<string:field>', '/web/partner_image/<int:rec_id>/<string:field>/<string:model>/'], type='http', auth="public") - def content_image_partner(self, rec_id, field='image_64', model='res.partner', **kwargs): + def content_image_partner(self, rec_id, field='image_128', model='res.partner', **kwargs): # other kwargs are ignored on purpose return self._content_image(id=rec_id, model='res.partner', field=field, placeholder='user_placeholder.jpg') @@ -1833,8 +1833,11 @@ class ReportController(http.Controller): response = self.report_routes(reportname, docids=docids, converter=converter, context=context) else: # Particular report: - data = url_decode(url.split('?')[1]).items() # decoding the args represented in JSON - response = self.report_routes(reportname, converter=converter, context=context, **dict(data)) + data = dict(url_decode(url.split('?')[1]).items()) # decoding the args represented in JSON + if 'context' in data: + context, data_context = json.loads(context or '{}'), json.loads(data.pop('context')) + context = json.dumps({**context, **data_context}) + response = self.report_routes(reportname, converter=converter, context=context, **data) report = request.env['ir.actions.report']._get_report_from_name(reportname) filename = "%s.%s" % (report.name, extension) |
