-
-
Notifications
You must be signed in to change notification settings - Fork 887
[IMP] report_async 14.0 #611
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,3 +4,4 @@ | |
| from . import report_async | ||
| from . import ir_report | ||
| from . import ir_actions | ||
| from . import queue_job | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| # 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 models | ||
| from odoo import fields, models | ||
|
|
||
| # Define all supported report_type | ||
| REPORT_TYPES = ["qweb-pdf", "qweb-text", "qweb-xml", "csv", "excel", "xlsx"] | ||
|
|
@@ -10,6 +10,18 @@ | |
| class Report(models.Model): | ||
| _inherit = "ir.actions.report" | ||
|
|
||
| async_report = fields.Boolean(default=False) | ||
| async_no_records = fields.Integer( | ||
| string="Min of Records", | ||
| default=100, | ||
| help="Min no of records to use async report functionality; e.g 100+", | ||
| ) | ||
| async_mail_recipient = fields.Char( | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just idea, should this be the many2many TO: filed like in Send Email wizard?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the idea was not to have restrict to system users it can be used with emails where the user is not existing on the system. Also the char field is feed directly on the send_mail values as email_to. This allows comma separated emails, so you can just add a list of emails but separated with comma. e.g
|
||
| string="Mail Recipient", | ||
| help="The email that will receive the async report", | ||
| default=lambda self: self.env.user.email, | ||
| ) | ||
|
|
||
| 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): | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| # Copyright 2022 Sunflower IT (https://sunflowerweb.nl/) | ||
| # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) | ||
|
|
||
| from odoo import api, models | ||
|
|
||
|
|
||
| class QueueJob(models.Model): | ||
| _inherit = "queue.job" | ||
|
|
||
| @api.model | ||
| def create(self, values): | ||
| res = super(QueueJob, self).create(values) | ||
| if ( | ||
| "model_name" in values | ||
| and values["model_name"] == "report.async" | ||
| and "kwargs" in values | ||
| and "to_email" in values["kwargs"] | ||
| ): | ||
| followers = self._find_partner(res, values["kwargs"]["to_email"]) | ||
| if followers: | ||
| res.message_subscribe(partner_ids=followers) | ||
| return res | ||
|
|
||
| def _find_partner(self, record, email): | ||
| partner = self.env["res.partner"].search([("email", "=", email)], limit=1) | ||
| followers = record.message_follower_ids.mapped("partner_id") | ||
| ids = [x for x in partner.ids if x not in followers.ids] | ||
| if partner and ids: | ||
| return ids | ||
| return None |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,11 +2,17 @@ | |
| # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) | ||
|
|
||
| import base64 | ||
| import logging | ||
|
|
||
| import mock | ||
|
|
||
| from odoo import _, api, fields, models | ||
| from odoo.exceptions import UserError | ||
| from odoo.http import request | ||
| from odoo.tools.safe_eval import safe_eval | ||
|
|
||
| _logger = logging.getLogger(__name__) | ||
|
|
||
| # Define all supported report_type | ||
| REPORT_TYPES_FUNC = { | ||
| "qweb-pdf": "_render_qweb_pdf", | ||
|
|
@@ -137,13 +143,56 @@ def view_jobs(self): | |
| return result | ||
|
|
||
| @api.model | ||
| def run_report(self, docids, data, report_id, user_id): | ||
| def print_document_async( | ||
| self, | ||
| record_ids, | ||
| report_name, | ||
| html=None, | ||
| data=None, | ||
| to_email="", | ||
| save_attachment_to_records=False, | ||
| ): | ||
| """Generate a document async, do not return the document file""" | ||
| user_email = to_email or self.env.user.email | ||
| report = self.env["ir.actions.report"]._get_report_from_name(report_name) | ||
| self.with_delay().run_report( | ||
| record_ids, | ||
| data or {}, | ||
| report.id, | ||
| self._uid, | ||
| email_notify=True, | ||
| to_email=user_email, | ||
| session_id=request.session.sid, | ||
| save_attachment_to_records=save_attachment_to_records, | ||
| ) | ||
|
|
||
| @api.model | ||
| def run_report( | ||
| self, | ||
| docids, | ||
| data, | ||
| report_id, | ||
| user_id, | ||
| email_notify=False, | ||
| to_email=None, | ||
| session_id=None, | ||
| save_attachment_to_records=False, | ||
| ): | ||
| report = self.env["ir.actions.report"].browse(report_id) | ||
| func = REPORT_TYPES_FUNC[report.report_type] | ||
| if user_id: | ||
| report = report.with_user(user_id) | ||
| if session_id: | ||
| # necessary for correct CSS headers | ||
| with mock.patch("odoo.http.request.session") as session: | ||
| session.sid = session_id | ||
| out_file, file_ext = getattr(report, func)(docids, data) | ||
| else: | ||
| out_file, file_ext = getattr(report, func)(docids, data) | ||
| # Run report | ||
| out_file, file_ext = getattr(report, func)(docids, data) | ||
| out_file = base64.b64encode(out_file) | ||
| out_name = "{}.{}".format(report.name, file_ext) | ||
| _logger.info("ASYNC GENERATION OF REPORT %s", (out_name,)) | ||
| # Save report to attachment | ||
| attachment = ( | ||
| self.env["ir.attachment"] | ||
|
|
@@ -158,18 +207,47 @@ def run_report(self, docids, data, report_id, user_id): | |
| } | ||
| ) | ||
| ) | ||
| # save attachment to records | ||
| if save_attachment_to_records: | ||
| model = report.model | ||
| records = self.env[model].sudo().browse(docids) | ||
| for record in records: | ||
| attachment = ( | ||
| self.env["ir.attachment"] | ||
| .sudo() | ||
| .create( | ||
| { | ||
| "name": out_name, | ||
| "datas": out_file, | ||
| "type": "binary", | ||
| "res_model": model, | ||
| "res_id": record.id, | ||
| } | ||
| ) | ||
| ) | ||
| if hasattr(record, "message_post"): | ||
| record.message_post(attachment_ids=[attachment.id]) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not 100% sure but I think in some cases this might require a
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @thomaspaulb added the sudo just in case |
||
| self._cr.execute( | ||
| """ | ||
| UPDATE ir_attachment SET create_uid = %s, write_uid = %s | ||
| WHERE id = %s""", | ||
| (self._uid, self._uid, attachment.id), | ||
| ) | ||
| # Send email | ||
| if self.email_notify: | ||
| self._send_email(attachment) | ||
| if email_notify or self.email_notify: | ||
| self._send_email(attachment, to_email=to_email) | ||
|
|
||
| def _send_email(self, attachment): | ||
| def _send_email(self, attachment, to_email=None): | ||
| template = self.env.ref("report_async.async_report_delivery") | ||
| email_values = {} | ||
| if to_email: | ||
| email_values = { | ||
| "recipient_ids": [], | ||
| "email_to": to_email, | ||
| } | ||
| template.send_mail( | ||
| attachment.id, notif_layout="mail.mail_notification_light", force_send=False | ||
| attachment.id, | ||
| notif_layout="mail.mail_notification_light", | ||
| force_send=False, | ||
| email_values=email_values, | ||
| ) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be just ../static/description/sample.gif