Skip to content

Commit 35167df

Browse files
author
Djody
committed
[IMP] sql_export_mail: allow partners as email recipients
Backported from Odoo 18 version into 17.0 branch. - Add mail_partner_ids field to send SQL export reports to partners - Include partner emails in mail template alongside user emails
1 parent ccff2b9 commit 35167df

3 files changed

Lines changed: 112 additions & 11 deletions

File tree

sql_export_mail/models/sql_export.py

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ class SqlExport(models.Model):
1919
help="Add the users who want to receive the report by e-mail. You "
2020
"need to link the sql query with a cron to send mail automatically",
2121
)
22+
mail_partner_ids = fields.Many2many(
23+
"res.partner",
24+
"mail_partner_sqlquery_rel",
25+
"sql_id",
26+
"partner_id",
27+
help="Add the partners who wants to receive the report by e-mail. You "
28+
"need to link the sql query with a cron to send a mail automatically",
29+
)
2230
cron_ids = fields.Many2many(
2331
"ir.cron",
2432
"cron_sqlquery_rel",
@@ -136,13 +144,43 @@ def check_mail_user(self):
136144
if not user.email:
137145
raise UserError(_("The user does not have any e-mail address."))
138146

147+
@api.constrains("mail_partner_ids", "query")
148+
def _check_mail_partner(self):
149+
for export in self:
150+
if export.mail_partner_ids and (
151+
"%(company_id)s" in export.query or "%(user_id)s" in export.query
152+
):
153+
raise UserError(
154+
_(
155+
"A query that uses the company_id or user_id parameter "
156+
"cannot be directly sent to a partner."
157+
)
158+
)
159+
missing_email_partners = export.mail_partner_ids.filtered(
160+
lambda partner: not partner.email
161+
)
162+
if missing_email_partners:
163+
raise UserError(
164+
_(
165+
"Missing email address for partner(s): %(names)s",
166+
names=", ".join(missing_email_partners.mapped("name")),
167+
)
168+
)
169+
139170
def get_email_address_for_template(self):
140171
"""
141-
Called from mail template
172+
Called from mail template.
173+
Collects email addresses from both users and partners.
142174
"""
143175
self.ensure_one()
144176
if self.env.context.get("mail_to"):
145177
mail_users = self.env["res.users"].browse(self.env.context.get("mail_to"))
178+
mail_partners = self.env["res.partner"]
146179
else:
147180
mail_users = self.mail_user_ids
148-
return ",".join([x.email for x in mail_users if x.email])
181+
mail_partners = self.mail_partner_ids
182+
email_addresses = set(
183+
mail_users.mapped("email") + mail_partners.mapped("email")
184+
)
185+
email_addresses.discard(False)
186+
return ",".join(email_addresses)

sql_export_mail/tests/test_sql_query_mail.py

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
44

55
from odoo import SUPERUSER_ID, Command
6+
from odoo.exceptions import UserError
67
from odoo.tests.common import TransactionCase
78

89

@@ -14,16 +15,70 @@ def setUpClass(cls):
1415
cls.sql_report_demo.mail_user_ids = [Command.link(SUPERUSER_ID)]
1516

1617
def test_sql_query_mail(self):
17-
mail_obj = self.env["mail.mail"]
18-
mails = mail_obj.search(
18+
"""Check the general execution"""
19+
self.check_before_change()
20+
self.check_execution()
21+
22+
def test_not_able_add_user(self):
23+
"""if there are field_ids, mail_user_ids can not be set"""
24+
sql_report_demo_with_partner = self.env.ref(
25+
"sql_export.sql_export_partner_with_variables"
26+
)
27+
with self.assertRaises(UserError):
28+
sql_report_demo_with_partner.write(
29+
{"mail_user_ids": [(4, self.env.ref("base.user_demo").id)]}
30+
)
31+
32+
def test_sql_query_mail_company(self):
33+
"""Check the general execution with %(company_id)s"""
34+
self.check_before_change()
35+
self.sql_report_demo.write(
36+
{
37+
"mail_user_ids": [(4, self.env.ref("base.user_demo").id)],
38+
"query": """SELECT name, street
39+
FROM res_partner
40+
where company_id = %(company_id)s""",
41+
}
42+
)
43+
self.check_execution()
44+
45+
def test_sql_query_mail_company_user(self):
46+
"""Check the general execution with %(company_id)s and %(user_id)s)"""
47+
self.check_before_change()
48+
self.sql_report_demo.write(
49+
{
50+
"mail_user_ids": [(4, self.env.ref("base.user_demo").id)],
51+
"query": """SELECT name, street FROM res_partner
52+
where company_id = %(company_id)s and id in (
53+
select partner_id
54+
from res_users where id = %(user_id)s)""",
55+
}
56+
)
57+
self.check_execution()
58+
59+
def test_sql_query_mail_partner(self):
60+
"""Check if emails are sent to partners"""
61+
self.check_before_change()
62+
partner = self.env.ref("base.res_partner_2")
63+
self.sql_report_demo.write({"mail_partner_ids": [(4, partner.id)]})
64+
self.check_execution(partner)
65+
66+
def check_before_change(self):
67+
"""Check if there are no mails before changing the sql report"""
68+
mails = self.env["mail.mail"].search(
1969
[("model", "=", "sql.export"), ("res_id", "=", self.sql_report_demo.id)]
2070
)
2171
self.assertFalse(mails)
72+
73+
def check_execution(self, partner=None):
74+
"""Check if the cron could be created and the mail sending is working"""
2275
self.sql_report_demo.create_cron()
2376
self.assertTrue(self.sql_report_demo.cron_ids)
2477
self.sql_report_demo.cron_ids.method_direct_trigger()
25-
mails = mail_obj.search(
78+
mails = self.env["mail.mail"].search(
2679
[("model", "=", "sql.export"), ("res_id", "=", self.sql_report_demo.id)]
2780
)
2881
self.assertTrue(mails)
2982
self.assertTrue(mails.attachment_ids)
83+
if partner:
84+
self.assertIn(partner.email, mails.mapped("email_to"))

sql_export_mail/views/sql_export_view.xml

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,30 @@
2121
</field>
2222
<page name="page_sql" position="after">
2323
<page name="page_mail" string="Mail">
24-
<group string="Users Notified by e-mail">
25-
<field
24+
<group string="Users Notified by e-mail">
25+
<field
2626
name="mail_user_ids"
2727
nolabel="1"
2828
widget="many2many_tags"
2929
colspan="2"
3030
/>
31-
</group>
32-
<group string="Crons" groups="base.group_system">
33-
<field
31+
</group>
32+
<group string="Partners Notified by e-mail">
33+
<field
34+
name="mail_partner_ids"
35+
nolabel="1"
36+
widget="many2many_tags"
37+
colspan="2"
38+
/>
39+
</group>
40+
<group string="Crons" groups="base.group_system">
41+
<field
3442
name="cron_ids"
3543
nolabel="1"
3644
colspan="2"
3745
domain="[('model_id', '=', 'sql.export')]"
3846
/>
39-
</group>
47+
</group>
4048
</page>
4149
</page>
4250
</field>

0 commit comments

Comments
 (0)