From 678e37b4c3162dc2e15d634fbf5f813c4617752e Mon Sep 17 00:00:00 2001
From: joepsanders <111979167+joepsanders@users.noreply.github.com>
Date: Tue, 18 Feb 2025 15:10:25 +0100
Subject: [PATCH 1/3] [IMP] sql_export_mail, add partner as export email
recipient
---
sql_export_mail/__manifest__.py | 2 +-
sql_export_mail/models/sql_export.py | 37 ++++++++++++++++++-
sql_export_mail/static/description/index.html | 11 ++++--
sql_export_mail/tests/test_sql_query_mail.py | 11 +++++-
sql_export_mail/views/sql_export_view.xml | 8 ++++
5 files changed, 61 insertions(+), 8 deletions(-)
diff --git a/sql_export_mail/__manifest__.py b/sql_export_mail/__manifest__.py
index c81f22f83c..d42b03adf8 100644
--- a/sql_export_mail/__manifest__.py
+++ b/sql_export_mail/__manifest__.py
@@ -1,7 +1,7 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
{
"name": "SQL Export Mail",
- "version": "16.0.2.0.2",
+ "version": "16.0.2.1.0",
"category": "Generic Modules",
"summary": "Send csv file generated by sql query by mail.",
"author": "Akretion,GRAP,Odoo Community Association (OCA)",
diff --git a/sql_export_mail/models/sql_export.py b/sql_export_mail/models/sql_export.py
index 0cdbc2ab9d..25cd76bd66 100644
--- a/sql_export_mail/models/sql_export.py
+++ b/sql_export_mail/models/sql_export.py
@@ -19,6 +19,14 @@ class SqlExport(models.Model):
help="Add the users who want to receive the report by e-mail. You "
"need to link the sql query with a cron to send mail automatically",
)
+ mail_partner_ids = fields.Many2many(
+ "res.partner",
+ "mail_partner_sqlquery_rel",
+ "sql_id",
+ "partner_id",
+ help="Add the partners who wants to receive the report by e-mail. You "
+ "need to link the sql query with a cron to send a mail automatically",
+ )
cron_ids = fields.Many2many(
"ir.cron",
"cron_sqlquery_rel",
@@ -138,13 +146,38 @@ def check_mail_user(self):
if not user.email:
raise UserError(_("The user does not have any e-mail address."))
+ @api.constrains("mail_partner_ids")
+ def _check_mail_partner(self):
+ for export in self:
+ if "%(company_id)s" in export.query or "%(user_id)s" in export.query:
+ raise UserError(
+ _(
+ "A query that uses the company_id or user_id parameter "
+ "cannot be directly sent to a partner."
+ )
+ )
+ missing_email_partners = export.mail_partner_ids.filtered(
+ lambda partner: not partner.email
+ )
+ if missing_email_partners:
+ raise UserError(
+ _(
+ "Missing email address for partner(s): %(names)s",
+ names=", ".join(missing_email_partners.mapped("name")),
+ )
+ )
+
def get_email_address_for_template(self):
"""
- Called from mail template
+ Called from mail template.
+ Collects email addresses from both users and partners.
"""
self.ensure_one()
if self.env.context.get("mail_to"):
mail_users = self.env["res.users"].browse(self.env.context.get("mail_to"))
+ mail_partners = self.env["res.partner"]
else:
mail_users = self.mail_user_ids
- return ",".join([x.email for x in mail_users if x.email])
+ mail_partners = self.mail_partner_ids
+ email_addresses = mail_users.mapped("email") + mail_partners.mapped("email")
+ return ",".join(email_addresses)
diff --git a/sql_export_mail/static/description/index.html b/sql_export_mail/static/description/index.html
index fc6525a371..fecef1061b 100644
--- a/sql_export_mail/static/description/index.html
+++ b/sql_export_mail/static/description/index.html
@@ -8,10 +8,11 @@
/*
:Author: David Goodger (goodger@python.org)
-:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
+:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
+Despite the name, some widely supported CSS2 features are used.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
@@ -274,7 +275,7 @@
margin-left: 2em ;
margin-right: 2em }
-pre.code .ln { color: grey; } /* line numbers */
+pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
@@ -300,7 +301,7 @@
span.pre {
white-space: pre }
-span.problematic {
+span.problematic, pre.problematic {
color: red }
span.section-subtitle {
@@ -421,7 +422,9 @@
This module is maintained by the OCA.
-

+
+
+
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
diff --git a/sql_export_mail/tests/test_sql_query_mail.py b/sql_export_mail/tests/test_sql_query_mail.py
index 973b8a52c8..1f42728f90 100644
--- a/sql_export_mail/tests/test_sql_query_mail.py
+++ b/sql_export_mail/tests/test_sql_query_mail.py
@@ -53,6 +53,13 @@ def test_sql_query_mail_company_user(self):
)
self.check_execution()
+ def test_sql_query_mail_partner(self):
+ """Check if emails are sent to partners"""
+ self.check_before_change()
+ partner = self.env.ref("base.res_partner_2")
+ self.sql_report_demo.write({"mail_partner_ids": [(4, partner.id)]})
+ self.check_execution(partner)
+
def check_before_change(self):
"""Check if there are no mails before changing the sql report"""
mails = self.env["mail.mail"].search(
@@ -60,7 +67,7 @@ def check_before_change(self):
)
self.assertFalse(mails)
- def check_execution(self):
+ def check_execution(self, partner=None):
"""Check if the cron could be created and the mail sending is working"""
self.sql_report_demo.create_cron()
self.assertTrue(self.sql_report_demo.cron_ids)
@@ -70,3 +77,5 @@ def check_execution(self):
)
self.assertTrue(mails)
self.assertTrue(mails.attachment_ids)
+ if partner:
+ self.assertIn(partner.email, mails.mapped("email_to"))
diff --git a/sql_export_mail/views/sql_export_view.xml b/sql_export_mail/views/sql_export_view.xml
index 9a9b7aea9a..cbfdfc9120 100644
--- a/sql_export_mail/views/sql_export_view.xml
+++ b/sql_export_mail/views/sql_export_view.xml
@@ -31,6 +31,14 @@
colspan="2"
/>
+
+
+
Date: Thu, 20 Feb 2025 09:06:53 +0100
Subject: [PATCH 2/3] fixup! [IMP] sql_export_mail, add partner as export email
recipient
---
sql_export_mail/models/sql_export.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/sql_export_mail/models/sql_export.py b/sql_export_mail/models/sql_export.py
index 25cd76bd66..86f3ebda88 100644
--- a/sql_export_mail/models/sql_export.py
+++ b/sql_export_mail/models/sql_export.py
@@ -146,10 +146,12 @@ def check_mail_user(self):
if not user.email:
raise UserError(_("The user does not have any e-mail address."))
- @api.constrains("mail_partner_ids")
+ @api.constrains("mail_partner_ids", "query")
def _check_mail_partner(self):
for export in self:
- if "%(company_id)s" in export.query or "%(user_id)s" in export.query:
+ if export.mail_partner_ids and (
+ "%(company_id)s" in export.query or "%(user_id)s" in export.query
+ ):
raise UserError(
_(
"A query that uses the company_id or user_id parameter "
From 3ba4d18ce122e8822cdd7034469d2e29f9ac6fc7 Mon Sep 17 00:00:00 2001
From: joepsanders <111979167+joepsanders@users.noreply.github.com>
Date: Thu, 20 Feb 2025 10:12:05 +0100
Subject: [PATCH 3/3] fixup! [IMP] sql_export_mail, add partner as export email
recipient
---
sql_export_mail/__manifest__.py | 2 +-
sql_export_mail/models/sql_export.py | 5 ++++-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/sql_export_mail/__manifest__.py b/sql_export_mail/__manifest__.py
index d42b03adf8..c81f22f83c 100644
--- a/sql_export_mail/__manifest__.py
+++ b/sql_export_mail/__manifest__.py
@@ -1,7 +1,7 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
{
"name": "SQL Export Mail",
- "version": "16.0.2.1.0",
+ "version": "16.0.2.0.2",
"category": "Generic Modules",
"summary": "Send csv file generated by sql query by mail.",
"author": "Akretion,GRAP,Odoo Community Association (OCA)",
diff --git a/sql_export_mail/models/sql_export.py b/sql_export_mail/models/sql_export.py
index 86f3ebda88..352274ad29 100644
--- a/sql_export_mail/models/sql_export.py
+++ b/sql_export_mail/models/sql_export.py
@@ -181,5 +181,8 @@ def get_email_address_for_template(self):
else:
mail_users = self.mail_user_ids
mail_partners = self.mail_partner_ids
- email_addresses = mail_users.mapped("email") + mail_partners.mapped("email")
+ email_addresses = set(
+ mail_users.mapped("email") + mail_partners.mapped("email")
+ )
+ email_addresses.discard(False)
return ",".join(email_addresses)