Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions report_async/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,15 @@ As normal user, you can run your reports from Report Center
- **Files:** show all files being produced by the job as run by the user.
- **Jobs:** show all jobs triggered by this report as run by the user. Only job queue manager have access to this button.

As additional improvement, you can now generate reports async directly from the form view itself,
and not have to go into the "Report Center" specifically to do it. This can be done by pressing
*Print*, you will get a popup asking you if you want to run it Async, and then to verify the email
address that it should be sent to. See below sample:

.. image:: https://raw.githubusercontent.com/OCA/reporting-engine/14.0/report_async/static/description/sample.gif
Copy link
Copy Markdown
Contributor

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

:width: 800
:alt: How It Works

Bug Tracker
===========

Expand Down Expand Up @@ -97,6 +106,11 @@ Contributors
* Saran Lim. <saranl@ecosoft.co.th>
* Tharathip Chaweewongphan <tharathipc@ecosoft.co.th>

* `Sunflower IT <https://sunflowerweb.nl>`__:

* Tom Blauwendraat <tom@sunflowerweb.nl>
* Kevin Kamau <kevin@sunflowerweb.nl>

Maintainers
~~~~~~~~~~~

Expand Down
3 changes: 3 additions & 0 deletions report_async/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@
"data": [
"security/ir.model.access.csv",
"security/ir_rule.xml",
"views/assets.xml",
"data/mail_template.xml",
"data/queue_job_function_data.xml",
"views/report_async.xml",
"wizard/print_report_wizard.xml",
"views/ir_actions_report.xml",
],
"qweb": ["static/src/xml/report_async.xml"],
"demo": ["demo/report_async_demo.xml"],
"installable": True,
"maintainers": ["kittiu"],
Expand Down
3 changes: 2 additions & 1 deletion report_async/data/mail_template.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@
valign="top"
style="font-size: 13px;"
>
% set base_url = object.env['ir.config_parameter'].sudo().get_param('web.base.url')
% set base_url_async = object.env['ir.config_parameter'].sudo().get_param('web.base.url.async_reports')
% set base_url = base_url_async or 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, )
<div>
Dear ${object.create_uid.partner_id.name or ''},
Expand Down
1 change: 1 addition & 0 deletions report_async/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
from . import report_async
from . import ir_report
from . import ir_actions
from . import queue_job
14 changes: 13 additions & 1 deletion report_async/models/ir_report.py
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"]
Expand All @@ -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(
Copy link
Copy Markdown
Member

@kittiu kittiu Apr 29, 2022

Choose a reason for hiding this comment

The 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?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The 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

oca@oca.com, tom@oca.com, jane@@usarmy.mil

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):
Expand Down
30 changes: 30 additions & 0 deletions report_async/models/queue_job.py
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
90 changes: 84 additions & 6 deletions report_async/models/report_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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"]
Expand All @@ -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])
Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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 sudo, anyway it wouldn't hurt

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The 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,
)
5 changes: 5 additions & 0 deletions report_async/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,8 @@
* Kitti U. <kittiu@ecosoft.co.th>
* Saran Lim. <saranl@ecosoft.co.th>
* Tharathip Chaweewongphan <tharathipc@ecosoft.co.th>

* `Sunflower IT <https://sunflowerweb.nl>`__:

* Tom Blauwendraat <tom@sunflowerweb.nl>
* Kevin Kamau <kevin@sunflowerweb.nl>
9 changes: 9 additions & 0 deletions report_async/readme/USAGE.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,12 @@ As normal user, you can run your reports from Report Center
- **Job Status:** show status of the latest run job. If job fail, exception error will also shown
- **Files:** show all files being produced by the job as run by the user.
- **Jobs:** show all jobs triggered by this report as run by the user. Only job queue manager have access to this button.

As additional improvement, you can now generate reports async directly from the form view itself,
and not have to go into the "Report Center" specifically to do it. This can be done by pressing
*Print*, you will get a popup asking you if you want to run it Async, and then to verify the email
address that it should be sent to. See below sample:

.. image:: ../static/description/sample.gif
:width: 800
:alt: How It Works
12 changes: 11 additions & 1 deletion report_async/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.15.1: http://docutils.sourceforge.net/" />
<meta name="generator" content="Docutils: http://docutils.sourceforge.net/" />
<title>Report Async</title>
<style type="text/css">

Expand Down Expand Up @@ -418,6 +418,11 @@ <h1><a class="toc-backref" href="#id1">Usage</a></h1>
<li><strong>Files:</strong> show all files being produced by the job as run by the user.</li>
<li><strong>Jobs:</strong> show all jobs triggered by this report as run by the user. Only job queue manager have access to this button.</li>
</ul>
<p>As additional improvement, you can now generate reports async directly from the form view itself,
and not have to go into the “Report Center” specifically to do it. This can be done by pressing
<em>Print</em>, you will get a popup asking you if you want to run it Async, and then to verify the email
address that it should be sent to. See below sample:</p><br/>
<img alt="How It Works" src="sample.gif" style="width: 800px;" /></br>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id2">Bug Tracker</a></h1>
Expand All @@ -444,6 +449,11 @@ <h2><a class="toc-backref" href="#id5">Contributors</a></h2>
<li>Tharathip Chaweewongphan &lt;<a class="reference external" href="mailto:tharathipc&#64;ecosoft.co.th">tharathipc&#64;ecosoft.co.th</a>&gt;</li>
</ul>
</li>
<li><a class="reference external" href="https://sunflowerweb.nl">Sunflower IT</a>:<ul>
<li>Tom Blauwendraat &lt;<a class="reference external" href="mailto:tom&#64;sunflowerweb.nl">tom&#64;sunflowerweb.nl</a>&gt;</li>
<li>Kevin Kamau &lt;<a class="reference external" href="mailto:kevin&#64;sunflowerweb.nl">kevin&#64;sunflowerweb.nl</a>&gt;</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="maintainers">
Expand Down
Binary file added report_async/static/description/sample.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading