Odoo18-Base/extra-addons/web_cohort/controllers/main.py

104 lines
4.2 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import io
import json
from odoo import http, _
from odoo.http import content_disposition, request
from odoo.tools import osutil
from odoo.tools.misc import xlsxwriter
class WebCohort(http.Controller):
@http.route('/web/cohort/export', type='http', auth='user')
def export_xls(self, data, **kw):
result = json.loads(data)
output = io.BytesIO()
workbook = xlsxwriter.Workbook(output, {'in_memory': True})
worksheet = workbook.add_worksheet(result['title'])
style_highlight = workbook.add_format({'bold': True, 'pattern': 1, 'bg_color': '#E0E0E0', 'align': 'center'})
style_normal = workbook.add_format({'align': 'center'})
row = 0
def write_data(report, row, col):
# Headers
columns_length = len(result[report]['rows'][0]['columns'])
if result['timeline'] == 'backward':
header_sign = ''
col_range = range(-(columns_length - 1), 1)
else:
header_sign = '+'
col_range = range(columns_length)
worksheet.merge_range(row, col + 2, row, columns_length + 1,
_('%(date_stop)s - By %(interval)s', date_stop=result['date_stop_string'], interval=result['interval_string']), style_highlight)
row += 1
worksheet.write(row, col, result['date_start_string'], style_highlight)
# set minimum width to date_start_string cell to 15 which is around 83px
worksheet.set_column(col, col, 15)
col += 1
worksheet.write(col, col, result['measure_string'], style_highlight)
# set minimum width to measure_string cell to 15 which is around 83px
worksheet.set_column(col, col, 15)
col += 1
for n in col_range:
worksheet.write(row, col, '%s%s' % (header_sign, n), style_highlight)
col += 1
# Rows
row += 1
for res in result[report]['rows']:
col = 0
worksheet.write(row, col, res['date'], style_normal)
col += 1
worksheet.write(row, col, res['value'], style_normal)
col += 1
for i in res['columns']:
worksheet.write(row, col, i['percentage'] == '-' and i['percentage'] or str(i['percentage']) + '%', style_normal)
col += 1
row += 1
# Total
col = 0
worksheet.write(row, col, _('Average'), style_highlight)
col += 1
worksheet.write(row, col, '%.1f' % result[report]['avg']['avg_value'], style_highlight)
col += 1
total = result[report]['avg']['columns_avg']
for n in range(columns_length):
if total[str(n)]['count']:
worksheet.write(row, col, '%.1f' % float(total[str(n)]['percentage'] / total[str(n)]['count']) + '%', style_highlight)
else:
worksheet.write(row, col, '-', style_highlight)
col += 1
return row
report_length = len(result['report']['rows'])
comparison_report = result.get('comparisonReport', False)
if comparison_report:
comparison_report_length = len(comparison_report['rows'])
if comparison_report:
if report_length:
row = write_data('report', row, 0)
if comparison_report_length:
write_data('comparisonReport', row + 2, 0)
elif comparison_report_length:
write_data('comparisonReport', row, 0)
else:
row = write_data('report', row, 0)
workbook.close()
xlsx_data = output.getvalue()
filename = osutil.clean_filename(_("Cohort %(title)s (%(model_name)s)", title=result['title'], model_name=result['model']))
response = request.make_response(
xlsx_data,
headers=[('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'),
('Content-Disposition', content_disposition(filename + '.xlsx'))],
)
return response