diff --git a/oca_dependencies.txt b/oca_dependencies.txt index 9c8c9172c..755a720cb 100644 --- a/oca_dependencies.txt +++ b/oca_dependencies.txt @@ -1 +1,2 @@ server-tools +queue diff --git a/report_async/README.rst b/report_async/README.rst index 43ce15a6b..075627f87 100644 --- a/report_async/README.rst +++ b/report_async/README.rst @@ -14,13 +14,13 @@ Report Async :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Freporting--engine-lightgray.png?logo=github - :target: https://github.com/OCA/reporting-engine/tree/12.0/report_async + :target: https://github.com/OCA/reporting-engine/tree/13.0/report_async :alt: OCA/reporting-engine .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/reporting-engine-12-0/reporting-engine-12-0-report_async + :target: https://translation.odoo-community.org/projects/reporting-engine-13-0/reporting-engine-13-0-report_async :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/143/12.0 + :target: https://runbot.odoo-community.org/runbot/143/13.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -76,7 +76,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -92,6 +92,7 @@ Contributors ~~~~~~~~~~~~ * Kitti U. +* Saran Lim. Maintainers ~~~~~~~~~~~ @@ -114,6 +115,6 @@ Current `maintainer `__: |maintainer-kittiu| -This module is part of the `OCA/reporting-engine `_ project on GitHub. +This module is part of the `OCA/reporting-engine `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/report_async/__manifest__.py b/report_async/__manifest__.py index 74a9be855..e861171a1 100644 --- a/report_async/__manifest__.py +++ b/report_async/__manifest__.py @@ -1,27 +1,23 @@ # Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) { - 'name': 'Report Async', - 'summary': 'Central place to run reports live or async', - 'version': '12.0.1.0.1', - 'author': 'Ecosoft, Odoo Community Association (OCA)', - 'license': 'AGPL-3', - 'website': 'https://github.com/OCA/reporting-engine', - 'category': 'Generic Modules', - 'depends': [ - 'queue_job', + "name": "Report Async", + "summary": "Central place to run reports live or async", + "version": "14.0.1.0.0", + "author": "Ecosoft, Odoo Community Association (OCA)", + "license": "AGPL-3", + "website": "https://github.com/OCA/reporting-engine", + "category": "Generic Modules", + "depends": ["queue_job"], + "data": [ + "security/ir.model.access.csv", + "security/ir_rule.xml", + "data/mail_template.xml", + "views/report_async.xml", + "wizard/print_report_wizard.xml", ], - 'data': [ - 'security/ir.model.access.csv', - 'security/ir_rule.xml', - 'data/mail_template.xml', - 'views/report_async.xml', - 'wizard/print_report_wizard.xml', - ], - 'demo': [ - 'demo/report_async_demo.xml', - ], - 'installable': True, - 'maintainers': ['kittiu'], - 'development_status': 'Beta', + "demo": ["demo/report_async_demo.xml"], + "installable": True, + "maintainers": ["kittiu"], + "development_status": "Beta", } diff --git a/report_async/data/mail_template.xml b/report_async/data/mail_template.xml index 409677e05..77411dc14 100644 --- a/report_async/data/mail_template.xml +++ b/report_async/data/mail_template.xml @@ -1,46 +1,73 @@ - + Report Async: New Report Available - + Your report is available, ${object.name} - ${object.company_id.partner_id.email_formatted|safe} + ${object.company_id.partner_id.email_formatted|safe} ${user.partner_id.id} - - -
- - +
- - -
- - - - -
+ + + + + + +
+ + + - + +
% set base_url = object.env['ir.config_parameter'].sudo().get_param('web.base.url') % set download_url = '%s/web/content/ir.attachment/%s/datas/%s?download=true' % (base_url, object.id, object.name, )
Dear ${object.create_uid.partner_id.name or ''}, -

- Your requested report, ${object.name}, is available for download. -

+

+ Your requested report, ${object.name}, is available for + download + . +

Have a nice day!
- --
${object.company_id.name} + --
${object.company_id.name}
+
-
+
- - + +
diff --git a/report_async/demo/report_async_demo.xml b/report_async/demo/report_async_demo.xml index 13e4b602b..1a60a3874 100644 --- a/report_async/demo/report_async_demo.xml +++ b/report_async/demo/report_async_demo.xml @@ -1,9 +1,7 @@ - - - + + - diff --git a/report_async/i18n/pt.po b/report_async/i18n/pt.po deleted file mode 100644 index 3af6e5c73..000000000 --- a/report_async/i18n/pt.po +++ /dev/null @@ -1,378 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * report_async -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 12.0\n" -"Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2021-03-13 20:45+0000\n" -"Last-Translator: Pedro Castro Silva \n" -"Language-Team: none\n" -"Language: pt\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.3.2\n" - -#. module: report_async -#: model:mail.template,body_html:report_async.async_report_delivery -msgid "\n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" % set base_url = object.env['ir.config_parameter'].sudo().get_param('web.base.url')\n" -" % set download_url = '%s/web/content/ir.attachment/%s/datas/%s?download=true' % (base_url, object.id, object.name, )\n" -"
\n" -" Dear ${object.create_uid.partner_id.name or ''},\n" -"

\n" -" Your requested report, ${object.name}, is available for download.\n" -"

\n" -" Have a nice day!
\n" -" --
${object.company_id.name}\n" -"
\n" -"
\n" -"
\n" -"
\n" -" " -msgstr "" -"\n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" % set base_url = object.env['ir." -"config_parameter'].sudo().get_param('web.base.url')\n" -" % set download_url = '%s/web/content/" -"ir.attachment/%s/datas/%s?download=true' % (base_url, object.id, " -"object.name, )\n" -"
\n" -" Caro ${" -"object.create_uid.partner_id.name or ''},\n" -"

\n" -" O seu relatório solicitado, " -"${object.name}, está disponível para download.\n" -"

\n" -" Tenha um bom dia!
\n" -" --
${object.company_id.name}" -"\n" -"
\n" -"
\n" -"
\n" -"
\n" -" " - -#. module: report_async -#: model:ir.model.fields,field_description:report_async.field_report_async__allow_async -msgid "Allow Async" -msgstr "Permitir Assincronia" - -#. module: report_async -#: code:addons/report_async/models/report_async.py:108 -#, python-format -msgid "Background process not allowed." -msgstr "Processo background não permitido." - -#. module: report_async -#: model_terms:ir.ui.view,arch_db:report_async.print_report_wizard -msgid "Cancel" -msgstr "Cancelar" - -#. module: report_async -#: model:ir.model.fields,field_description:report_async.field_print_report_wizard__create_uid -#: model:ir.model.fields,field_description:report_async.field_report_async__create_uid -msgid "Created by" -msgstr "Criado por" - -#. module: report_async -#: model:ir.model.fields,field_description:report_async.field_print_report_wizard__create_date -#: model:ir.model.fields,field_description:report_async.field_report_async__create_date -msgid "Created on" -msgstr "Criado em" - -#. module: report_async -#: model:ir.model.fields,field_description:report_async.field_print_report_wizard__display_name -#: model:ir.model.fields,field_description:report_async.field_report_async__display_name -msgid "Display Name" -msgstr "Nome a Exibir" - -#. module: report_async -#: model:ir.model.fields,field_description:report_async.field_print_report_wizard__reference -msgid "Document" -msgstr "Documento" - -#. module: report_async -#: selection:report.async,job_status:0 -msgid "Done" -msgstr "Concluído" - -#. module: report_async -#: model:ir.model.fields,field_description:report_async.field_report_async__email_notify -msgid "Email Notification" -msgstr "Notificação de Email" - -#. module: report_async -#: selection:report.async,job_status:0 -msgid "Enqueued" -msgstr "Enfileirado" - -#. module: report_async -#: model_terms:ir.ui.view,arch_db:report_async.print_report_wizard -msgid "Execute" -msgstr "Executar" - -#. module: report_async -#: selection:report.async,job_status:0 -msgid "Failed" -msgstr "Falhou" - -#. module: report_async -#: model:ir.model.fields,field_description:report_async.field_report_async__file_ids -msgid "File" -msgstr "Ficheiro" - -#. module: report_async -#: model_terms:ir.ui.view,arch_db:report_async.view_report_async_form -#: model_terms:ir.ui.view,arch_db:report_async.view_report_async_tree -msgid "Files" -msgstr "Ficheiros" - -#. module: report_async -#: model:ir.model.fields,field_description:report_async.field_report_async__group_ids -msgid "Groups" -msgstr "Grupos" - -#. module: report_async -#: model:ir.model.fields,field_description:report_async.field_print_report_wizard__id -#: model:ir.model.fields,field_description:report_async.field_report_async__id -msgid "ID" -msgstr "ID" - -#. module: report_async -#: model:ir.model.fields,field_description:report_async.field_report_async__job_ids -msgid "Job" -msgstr "Trabalho" - -#. module: report_async -#: model:ir.model.fields,field_description:report_async.field_report_async__job_info -msgid "Job Info" -msgstr "Informações do Trabalho" - -#. module: report_async -#: model:ir.model.fields,field_description:report_async.field_report_async__job_status -msgid "Job Status" -msgstr "Estado do Trabalho" - -#. module: report_async -#: model_terms:ir.ui.view,arch_db:report_async.view_report_async_form -msgid "Jobs" -msgstr "Jobs" - -#. module: report_async -#: model:ir.model.fields,field_description:report_async.field_print_report_wizard____last_update -#: model:ir.model.fields,field_description:report_async.field_report_async____last_update -msgid "Last Modified on" -msgstr "Última Modificação em" - -#. module: report_async -#: model_terms:ir.ui.view,arch_db:report_async.view_report_async_form -msgid "Last Run Job Error" -msgstr "Erro na última execução do trabalho" - -#. module: report_async -#: model:ir.model.fields,field_description:report_async.field_print_report_wizard__write_uid -#: model:ir.model.fields,field_description:report_async.field_report_async__write_uid -msgid "Last Updated by" -msgstr "Última Atualização por" - -#. module: report_async -#: model:ir.model.fields,field_description:report_async.field_print_report_wizard__write_date -#: model:ir.model.fields,field_description:report_async.field_report_async__write_date -msgid "Last Updated on" -msgstr "Última Atualização em" - -#. module: report_async -#: model:ir.model.fields,help:report_async.field_report_async__job_info -msgid "Latest Job Error Message" -msgstr "Mensagem de Erro do Trabalho Mais Recente" - -#. module: report_async -#: model:ir.model.fields,help:report_async.field_report_async__job_status -msgid "Latest Job Status" -msgstr "Estado do Trabalho Mais Recente" - -#. module: report_async -#: model:ir.model.fields,help:report_async.field_report_async__file_ids -msgid "List all files created by this report background process" -msgstr "" -"Listar todos os arquivos criados por este processo de relatório em background" - -#. module: report_async -#: model:ir.model.fields,help:report_async.field_report_async__job_ids -msgid "List all jobs related to this running report" -msgstr "Listar todos os trabalhos relacionados a este relatório em curso" - -#. module: report_async -#: model:ir.model.fields,field_description:report_async.field_report_async__name -msgid "Name" -msgstr "Nome" - -#. module: report_async -#: model_terms:ir.actions.act_window,help:report_async.action_view_files -msgid "No files found" -msgstr "Nenhum arquivo encontrado" - -#. module: report_async -#: model:ir.model.fields,help:report_async.field_report_async__group_ids -msgid "Only user in selected groups can use this report.If left blank, everyone can use" -msgstr "" -"Apenas utilizadores em grupos selecionados podem usar este relatório. Se " -"deixado vazio, qualquer um o pode usar" - -#. module: report_async -#: selection:report.async,job_status:0 -msgid "Pending" -msgstr "Pendente" - -#. module: report_async -#: model:ir.actions.act_window,name:report_async.action_print_report_wizard -msgid "Print Document" -msgstr "Imprimir Documento" - -#. module: report_async -#: model:ir.model,name:report_async.model_print_report_wizard -msgid "Print Report Wizard" -msgstr "Assistente de Impressão de Relatório" - -#. module: report_async -#: model:ir.model,name:report_async.model_ir_actions_report -msgid "Report Action" -msgstr "Ação de Relatório" - -#. module: report_async -#: model:ir.model,name:report_async.model_report_async -msgid "Report Async" -msgstr "Relatório Async" - -#. module: report_async -#: model:ir.actions.act_window,name:report_async.action_report_async -#: model:ir.ui.menu,name:report_async.menu_report_async -#: model_terms:ir.ui.view,arch_db:report_async.view_report_async_search -#: model_terms:ir.ui.view,arch_db:report_async.view_report_async_tree -msgid "Report Center" -msgstr "Centro de Relatórios" - -#. module: report_async -#: model:ir.actions.act_window,name:report_async.action_view_files -msgid "Report Files" -msgstr "Ficheiros de Relatórios" - -#. module: report_async -#: model:ir.model.fields,field_description:report_async.field_print_report_wizard__action_report_id -msgid "Report Template" -msgstr "Modelo de Relatório" - -#. module: report_async -#: model:ir.model.fields,field_description:report_async.field_report_async__action_id -msgid "Reports" -msgstr "Relatórios" - -#. module: report_async -#: model_terms:ir.ui.view,arch_db:report_async.view_report_async_form -#: model_terms:ir.ui.view,arch_db:report_async.view_report_async_tree -msgid "Run Background" -msgstr "Executar Background" - -#. module: report_async -#: model_terms:ir.ui.view,arch_db:report_async.view_report_async_form -#: model_terms:ir.ui.view,arch_db:report_async.view_report_async_tree -msgid "Run Now" -msgstr "Executar Agora" - -#. module: report_async -#: model_terms:ir.actions.act_window,help:report_async.action_report_async -msgid "Run reports asyncronously" -msgstr "Executar relatórios de forma assíncrona" - -#. module: report_async -#: model:ir.model.fields,help:report_async.field_report_async__email_notify -msgid "Send email with link to report, when it is ready" -msgstr "Enviar e-mail com link para o relatório quando este estiver pronto" - -#. module: report_async -#: selection:report.async,job_status:0 -msgid "Started" -msgstr "Iniciado" - -#. module: report_async -#: model_terms:ir.ui.view,arch_db:report_async.view_report_async_form -msgid "The last running job was failed.\n" -" Please contact your system administrator." -msgstr "" -"O último trabalho em curso falhou. Por " -"favor, contacte o administrador do sistema." - -#. module: report_async -#: model_terms:ir.ui.view,arch_db:report_async.view_report_async_form -msgid "The last running job was succeed.\n" -" You can check the result in Files" -msgstr "" -"O último trabalho em curso foi bem sucedido." -"\n" -" Pode verificar o resultado em Ficheiros" - -#. module: report_async -#: model_terms:ir.ui.view,arch_db:report_async.view_report_async_form -msgid "The report will be running by \n" -" job, and will be available at\n" -" Files" -msgstr "" -"O relatório será executado por trabalho e " -"estará disponível em Arquivos" - -#. module: report_async -#: model:ir.model.fields,help:report_async.field_report_async__allow_async -msgid "This is not automatic field, please check if you want to allow this report in background process" -msgstr "" -"Este campo não é automático. Por favor, verifique se deseja permitir este " -"relatório em processo background" - -#. module: report_async -#: model:mail.template,subject:report_async.async_report_delivery -msgid "Your report is available, ${object.name}" -msgstr "Seu relatório está disponível, ${object.name}" diff --git a/report_async/models/ir_report.py b/report_async/models/ir_report.py index e70988bdd..03a122cda 100644 --- a/report_async/models/ir_report.py +++ b/report_async/models/ir_report.py @@ -1,28 +1,23 @@ # Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) -from odoo import api, models - +from odoo import models # Define all supported report_type -REPORT_TYPES = ['qweb-pdf', 'qweb-text', - 'qweb-xml', 'csv', - 'excel', 'xlsx'] +REPORT_TYPES = ["qweb-pdf", "qweb-text", "qweb-xml", "csv", "excel", "xlsx"] class Report(models.Model): - _inherit = 'ir.actions.report' + _inherit = "ir.actions.report" - @api.noguess def report_action(self, docids, data=None, config=True): - res = super(Report, self).report_action(docids, data=data, - config=config) - if res['context'].get('async_process', False): - rpt_async_id = res['context']['active_id'] - report_async = self.env['report.async'].browse(rpt_async_id) - if res['report_type'] in REPORT_TYPES: + res = super(Report, self).report_action(docids, data=data, config=config) + if res["context"].get("async_process", False): + rpt_async_id = res["context"]["active_id"] + report_async = self.env["report.async"].browse(rpt_async_id) + if res["report_type"] in REPORT_TYPES: report_async.with_delay().run_report( - res['context'].get('active_ids', []), data, - self.id, self._uid) + res["context"].get("active_ids", []), data, self.id, self._uid + ) return {} return res diff --git a/report_async/models/report_async.py b/report_async/models/report_async.py index 376acc71c..ad362a166 100644 --- a/report_async/models/report_async.py +++ b/report_async/models/report_async.py @@ -2,93 +2,104 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) import base64 -from odoo import api, fields, models, _ -from odoo.tools.safe_eval import safe_eval + +from odoo import _, api, fields, models from odoo.exceptions import UserError +from odoo.tools.safe_eval import safe_eval + from odoo.addons.queue_job.job import job - # Define all supported report_type -REPORT_TYPES_FUNC = {'qweb-pdf': 'render_qweb_pdf', - 'qweb-text': 'render_qweb_text', - 'qweb-xml': 'render_qweb_xml', - 'csv': 'render_csv', - 'excel': 'render_excel', - 'xlsx': 'render_xlsx', } +REPORT_TYPES_FUNC = { + "qweb-pdf": "render_qweb_pdf", + "qweb-text": "render_qweb_text", + "qweb-xml": "render_qweb_xml", + "csv": "render_csv", + "excel": "render_excel", + "xlsx": "render_xlsx", +} class ReportAsync(models.Model): - _name = 'report.async' - _description = 'Report Async' + _name = "report.async" + _description = "Report Async" action_id = fields.Many2one( - comodel_name='ir.actions.act_window', - string='Reports', + comodel_name="ir.actions.act_window", + string="Reports", required=True, ) allow_async = fields.Boolean( - string='Allow Async', + string="Allow Async", default=False, help="This is not automatic field, please check if you want to allow " "this report in background process", ) name = fields.Char( - string='Name', - related='action_id.display_name', + string="Name", + related="action_id.display_name", ) email_notify = fields.Boolean( - string='Email Notification', + string="Email Notification", help="Send email with link to report, when it is ready", ) group_ids = fields.Many2many( - string='Groups', - comodel_name='res.groups', + string="Groups", + comodel_name="res.groups", help="Only user in selected groups can use this report." "If left blank, everyone can use", ) job_ids = fields.Many2many( - comodel_name='queue.job', - compute='_compute_job', + comodel_name="queue.job", + compute="_compute_job", help="List all jobs related to this running report", ) job_status = fields.Selection( - selection=[('pending', 'Pending'), - ('enqueued', 'Enqueued'), - ('started', 'Started'), - ('done', 'Done'), - ('failed', 'Failed')], - compute='_compute_job', + selection=[ + ("pending", "Pending"), + ("enqueued", "Enqueued"), + ("started", "Started"), + ("done", "Done"), + ("failed", "Failed"), + ], + compute="_compute_job", help="Latest Job Status", ) job_info = fields.Text( - compute='_compute_job', + compute="_compute_job", help="Latest Job Error Message", ) file_ids = fields.Many2many( - comodel_name='ir.attachment', - compute='_compute_file', + comodel_name="ir.attachment", + compute="_compute_file", help="List all files created by this report background process", ) - @api.multi def _compute_job(self): for rec in self: - rec.job_ids = self.sudo().env['queue.job'].search( - [('func_string', 'like', 'report.async(%s,)' % rec.id), - ('user_id', '=', self._uid)], - order='id desc') - rec.job_status = (rec.job_ids[0].sudo().state - if rec.job_ids else False) - rec.job_info = (rec.job_ids[0].sudo().exc_info - if rec.job_ids else False) + rec.job_ids = ( + self.sudo() + .env["queue.job"] + .search( + [ + ("func_string", "like", "report.async(%s,)" % rec.id), + ("user_id", "=", self._uid), + ], + order="id desc", + ) + ) + rec.job_status = rec.job_ids[0].sudo().state if rec.job_ids else False + rec.job_info = rec.job_ids[0].sudo().exc_info if rec.job_ids else False - @api.multi def _compute_file(self): - files = self.env['ir.attachment'].search( - [('res_model', '=', 'report.async'), - ('res_id', 'in', self.ids), - ('create_uid', '=', self._uid)], - order='id desc') + files = self.env["ir.attachment"].search( + [ + ("res_model", "=", "report.async"), + ("res_id", "in", self.ids), + ("create_uid", "=", self._uid), + ], + order="id desc", + ) for rec in self: rec.file_ids = files.filtered(lambda l: l.res_id == rec.id) @@ -96,67 +107,72 @@ class ReportAsync(models.Model): self.ensure_one() action = self.env.ref(self.action_id.xml_id) result = action.read()[0] - ctx = safe_eval(result.get('context', {})) - ctx.update({'async_process': False}) - result['context'] = ctx + ctx = safe_eval(result.get("context", {})) + ctx.update({"async_process": False}) + result["context"] = ctx return result - @api.multi def run_async(self): self.ensure_one() if not self.allow_async: - raise UserError(_('Background process not allowed.')) + raise UserError(_("Background process not allowed.")) action = self.env.ref(self.action_id.xml_id) result = action.read()[0] - ctx = safe_eval(result.get('context', {})) - ctx.update({'async_process': True}) - result['context'] = ctx + ctx = safe_eval(result.get("context", {})) + ctx.update({"async_process": True}) + result["context"] = ctx return result - @api.multi def view_files(self): self.ensure_one() - action = self.env.ref('report_async.action_view_files') + action = self.env.ref("report_async.action_view_files") result = action.read()[0] - result['domain'] = [('id', 'in', self.file_ids.ids)] + result["domain"] = [("id", "in", self.file_ids.ids)] return result - @api.multi def view_jobs(self): self.ensure_one() - action = self.env.ref('queue_job.action_queue_job') + action = self.env.ref("queue_job.action_queue_job") result = action.read()[0] - result['domain'] = [('id', 'in', self.job_ids.ids)] - result['context'] = {} + result["domain"] = [("id", "in", self.job_ids.ids)] + result["context"] = {} return result @api.model @job def run_report(self, docids, data, report_id, user_id): - report = self.env['ir.actions.report'].browse(report_id) + report = self.env["ir.actions.report"].browse(report_id) func = REPORT_TYPES_FUNC[report.report_type] # Run report out_file, file_ext = getattr(report, func)(docids, data) out_file = base64.b64encode(out_file) - out_name = '%s.%s' % (report.name, file_ext) + out_name = "{}.{}".format(report.name, file_ext) # Save report to attachment - attachment = self.env['ir.attachment'].sudo().create({ - 'name': out_name, - 'datas': out_file, - 'datas_fname': out_name, - 'type': 'binary', - 'res_model': 'report.async', - 'res_id': self.id, - }) - self._cr.execute(""" + attachment = ( + self.env["ir.attachment"] + .sudo() + .create( + { + "name": out_name, + "datas": out_file, + "type": "binary", + "res_model": "report.async", + "res_id": self.id, + } + ) + ) + self._cr.execute( + """ UPDATE ir_attachment SET create_uid = %s, write_uid = %s - WHERE id = %s""", (self._uid, self._uid, attachment.id)) + WHERE id = %s""", + (self._uid, self._uid, attachment.id), + ) # Send email if self.email_notify: self._send_email(attachment) def _send_email(self, attachment): - template = self.env.ref('report_async.async_report_delivery') - template.send_mail(attachment.id, - notif_layout='mail.mail_notification_light', - force_send=False) + template = self.env.ref("report_async.async_report_delivery") + template.send_mail( + attachment.id, notif_layout="mail.mail_notification_light", force_send=False + ) diff --git a/report_async/readme/CONTRIBUTORS.rst b/report_async/readme/CONTRIBUTORS.rst index 6ce956d96..b8832b9e7 100644 --- a/report_async/readme/CONTRIBUTORS.rst +++ b/report_async/readme/CONTRIBUTORS.rst @@ -1 +1,2 @@ * Kitti U. +* Saran Lim. diff --git a/report_async/security/ir_rule.xml b/report_async/security/ir_rule.xml index a1430189c..b551c92cb 100644 --- a/report_async/security/ir_rule.xml +++ b/report_async/security/ir_rule.xml @@ -1,23 +1,25 @@ - + Report Async by Groups - - - - - - - ['|', ('group_ids', '=', False), ('group_ids', 'in', [g.id for g in user.groups_id])] + + + + + + + ['|', ('group_ids', '=', False), ('group_ids', 'in', [g.id for g in user.groups_id])] Report Async by Groups - - - - - - + + + + + + [(1,'=', 1)] diff --git a/report_async/static/description/index.html b/report_async/static/description/index.html index 2a72761e6..f31d1515c 100644 --- a/report_async/static/description/index.html +++ b/report_async/static/description/index.html @@ -367,7 +367,7 @@ ul.auto-toc { !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/reporting-engine Translate me on Weblate Try me on Runbot

+

Beta License: AGPL-3 OCA/reporting-engine Translate me on Weblate Try me on Runbot

The new menu “Report Center” is the central place to host your reports in one place. From here, there are 2 ways to launch the report,

    @@ -424,7 +424,7 @@ report will be sent.

    Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -feedback.

    +feedback.

    Do not contact contributors directly about support or help with technical issues.

    @@ -439,6 +439,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome

    Contributors

    @@ -450,7 +451,7 @@ mission is to support the collaborative development of Odoo features and promote its widespread use.

    Current maintainer:

    kittiu

    -

    This module is part of the OCA/reporting-engine project on GitHub.

    +

    This module is part of the OCA/reporting-engine project on GitHub.

    You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

    diff --git a/report_async/tests/test_report_async.py b/report_async/tests/test_report_async.py index b921534a2..a1f1e8bd0 100644 --- a/report_async/tests/test_report_async.py +++ b/report_async/tests/test_report_async.py @@ -1,26 +1,26 @@ # Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) +from odoo.exceptions import UserError from odoo.tests import common from odoo.tests.common import Form -from odoo.exceptions import UserError class TestJobChannel(common.TransactionCase): - def setUp(self): super(TestJobChannel, self).setUp() - self.print_doc = self.env.ref('report_async.' - 'report_async_print_document') - self.test_rec = self.env.ref('base.module_mail') - self.test_rpt = self.env.ref('base.ir_module_reference_print') + self.print_doc = self.env.ref("report_async." "report_async_print_document") + self.test_rec = self.env.ref("base.module_mail") + self.test_rpt = self.env.ref("base.ir_module_reference_print") def _print_wizard(self, res): - obj = self.env[res['res_model']] - ctx = {'active_model': self.print_doc._name, - 'active_id': self.print_doc.id, } - ctx.update(res['context']) + obj = self.env[res["res_model"]] + ctx = { + "active_model": self.print_doc._name, + "active_id": self.print_doc.id, + } + ctx.update(res["context"]) with Form(obj.with_context(ctx)) as form: - form.reference = '%s,%s' % (self.test_rec._name, self.test_rec.id) + form.reference = "{},{}".format(self.test_rec._name, self.test_rec.id) form.action_report_id = self.test_rpt print_wizard = form.save() return print_wizard @@ -29,19 +29,18 @@ class TestJobChannel(common.TransactionCase): """Run now will return report action as normal""" res = self.print_doc.run_now() report_action = self._print_wizard(res).print_report() - self.assertEquals(report_action['type'], 'ir.actions.report') + self.assertEquals(report_action["type"], "ir.actions.report") def test_2_run_async(self): """Run background will return nothing, job started""" with self.assertRaises(UserError): self.print_doc.run_async() - self.print_doc.write({'allow_async': True, - 'email_notify': True}) + self.print_doc.write({"allow_async": True, "email_notify": True}) res = self.print_doc.run_async() print_wizard = self._print_wizard(res) report_action = print_wizard.print_report() self.assertEquals(report_action, {}) # Do not run report yet - self.assertEquals(self.print_doc.job_status, 'pending') # Job started + self.assertEquals(self.print_doc.job_status, "pending") # Job started # Test produce file (as queue will not run in test mode) docids = [print_wizard.reference.id] data = None diff --git a/report_async/views/report_async.xml b/report_async/views/report_async.xml index f6d5f58f1..5b833029f 100644 --- a/report_async/views/report_async.xml +++ b/report_async/views/report_async.xml @@ -1,133 +1,177 @@ - + - report.async.tree report.async - -