From 3b652200d9041389231b97e2e964076a8f84a310 Mon Sep 17 00:00:00 2001 From: trisdoan Date: Mon, 28 Oct 2024 12:14:22 +0700 Subject: [PATCH] [IMP] mail_composer_cc_bcc: refactor _generate_template_recipients --- mail_composer_cc_bcc/__manifest__.py | 1 + mail_composer_cc_bcc/models/mail_template.py | 190 +----------------- .../tests/test_mail_cc_bcc.py | 12 -- mail_composer_cc_bcc/wizards/__init__.py | 1 + .../wizards/mail_compose_message.py | 48 ++--- .../wizards/mail_template_preview.py | 18 ++ .../wizards/mail_template_preview_view.xml | 12 ++ 7 files changed, 58 insertions(+), 224 deletions(-) create mode 100644 mail_composer_cc_bcc/wizards/mail_template_preview.py create mode 100644 mail_composer_cc_bcc/wizards/mail_template_preview_view.xml diff --git a/mail_composer_cc_bcc/__manifest__.py b/mail_composer_cc_bcc/__manifest__.py index 099e43e5..44344d92 100644 --- a/mail_composer_cc_bcc/__manifest__.py +++ b/mail_composer_cc_bcc/__manifest__.py @@ -22,5 +22,6 @@ "views/mail_message_views.xml", "views/mail_template_views.xml", "wizards/mail_compose_message_view.xml", + "wizards/mail_template_preview_view.xml", ], } diff --git a/mail_composer_cc_bcc/models/mail_template.py b/mail_composer_cc_bcc/models/mail_template.py index 5ac5c76e..fb128abb 100644 --- a/mail_composer_cc_bcc/models/mail_template.py +++ b/mail_composer_cc_bcc/models/mail_template.py @@ -2,9 +2,7 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -import itertools - -from odoo import fields, models, tools +from odoo import fields, models class MailTemplate(models.Model): @@ -13,189 +11,3 @@ class MailTemplate(models.Model): email_bcc = fields.Char( "Bcc", help="Blind cc recipients (placeholders may be used here)" ) - - # ------------------------------------------------------------ - # MESSAGE/EMAIL VALUES GENERATION - # ------------------------------------------------------------ - - def _generate_template_recipients( # noqa:C901 - self, res_ids, render_fields, find_or_create_partners=False, render_results=None - ): - self.ensure_one() - if render_results is None: - render_results = {} - ModelSudo = self.env[self.model].with_prefetch(res_ids).sudo() - - # if using default recipients -> ``_message_get_default_recipients`` gives - # values for email_to, email_cc and partner_ids - if self.use_default_to and self.model: - default_recipients = ModelSudo.browse( - res_ids - )._message_get_default_recipients() - for res_id, recipients in default_recipients.items(): - render_results.setdefault(res_id, {}).update(recipients) - # render fields dynamically which generates recipients - else: - for field in set(render_fields) & { - "email_cc", - "email_to", - "partner_to", - "email_bcc", - }: - generated_field_values = self._render_field(field, res_ids) - for res_id in res_ids: - render_results.setdefault(res_id, {})[field] = ( - generated_field_values[res_id] - ) - - # create partners from emails if asked to - if find_or_create_partners: - res_id_to_company = {} - if self.model and "company_id" in ModelSudo._fields: - for read_record in ModelSudo.browse(res_ids).read(["company_id"]): - company_id = ( - read_record["company_id"][0] - if read_record["company_id"] - else False - ) - res_id_to_company[read_record["id"]] = company_id - - all_emails = [] - email_to_res_ids = {} - email_to_company = {} - for res_id in res_ids: - record_values = render_results.setdefault(res_id, {}) - # DIFFERENT FROM ODOO NATIVE: - if record_values.get("email_cc"): - continue - mails = tools.email_split(record_values.pop("email_to", "")) - all_emails += mails - record_company = res_id_to_company.get(res_id) - for mail in mails: - email_to_res_ids.setdefault(mail, []).append(res_id) - if record_company: - email_to_company[mail] = record_company - - if all_emails: - customers_information = ModelSudo.browse( - res_ids - )._get_customer_information() - partners = self.env["res.partner"]._find_or_create_from_emails( - all_emails, - additional_values={ - email: { - "company_id": email_to_company.get(email), - **customers_information.get(email, {}), - } - for email in itertools.chain(all_emails, [False]) - }, - ) - for original_email, partner in zip(all_emails, partners): # noqa: B905 - if not partner: - continue - for res_id in email_to_res_ids[original_email]: - render_results[res_id].setdefault("partner_ids", []).append( - partner.id - ) - - # update 'partner_to' rendered value to 'partner_ids' - all_partner_to = { - pid - for record_values in render_results.values() - for pid in self._parse_partner_to(record_values.get("partner_to", "")) - } - existing_pids = set() - if all_partner_to: - existing_pids = set( - self.env["res.partner"].sudo().browse(list(all_partner_to)).exists().ids - ) - for res_id, record_values in render_results.items(): # noqa: B007 - partner_to = record_values.pop("partner_to", "") - if partner_to: - tpl_partner_ids = ( - set(self._parse_partner_to(partner_to)) & existing_pids - ) - record_values.setdefault("partner_ids", []).extend(tpl_partner_ids) - - # DIFFERENT FROM ODOO NATIVE: - # update 'email_cc' rendered value to 'partner_bcc_ids' - all_cc_emails = [] - if record_values.get("email_cc", ""): - mails = tools.email_split(record_values.pop("email_cc", "")) - all_cc_emails += mails - record_company = res_id_to_company.get(res_id) - for mail in mails: - email_to_res_ids.setdefault(mail, []).append(res_id) - if record_company: - email_to_company[mail] = record_company - # DIFFERENT FROM ODOO NATIVE: - if all_cc_emails: - customers_information = ModelSudo.browse( - res_ids - )._get_customer_information() - partners = self.env["res.partner"]._find_or_create_from_emails( - all_cc_emails, - additional_values={ - email: { - "company_id": email_to_company.get(email), - **customers_information.get(email, {}), - } - for email in itertools.chain(all_cc_emails, [False]) - }, - ) - for original_email, partner in zip(all_cc_emails, partners): # noqa: B905 - if not partner: - continue - for res_id in email_to_res_ids[original_email]: - render_results[res_id].setdefault("partner_cc_ids", []).append( - partner.id - ) - # DIFFERENT FROM ODOO NATIVE: - # update 'email_bcc' rendered value to 'partner_bcc_ids' - all_bcc_emails = [] - if record_values.get("email_bcc", ""): - mails = tools.email_split(record_values.pop("email_bcc", "")) - all_bcc_emails += mails - record_company = res_id_to_company.get(res_id) - for mail in mails: - email_to_res_ids.setdefault(mail, []).append(res_id) - if record_company: - email_to_company[mail] = record_company - # DIFFERENT FROM ODOO NATIVE: - if all_bcc_emails: - customers_information = ModelSudo.browse( - res_ids - )._get_customer_information() - partners = self.env["res.partner"]._find_or_create_from_emails( - all_bcc_emails, - additional_values={ - email: { - "company_id": email_to_company.get(email), - **customers_information.get(email, {}), - } - for email in itertools.chain(all_bcc_emails, [False]) - }, - ) - for original_email, partner in zip(all_bcc_emails, partners): # noqa: B905 - if not partner: - continue - for res_id in email_to_res_ids[original_email]: - render_results[res_id].setdefault("partner_bcc_ids", []).append( - partner.id - ) - return render_results - - def _generate_template(self, res_ids, render_fields, find_or_create_partners=False): - res = super()._generate_template( - res_ids, render_fields, find_or_create_partners=find_or_create_partners - ) - - for _, (template, template_res_ids) in self._classify_per_lang(res_ids).items(): - if "email_bcc" in render_fields: - template._generate_template_recipients( - template_res_ids, - set("email_bcc"), - render_results=res, - find_or_create_partners=find_or_create_partners, - ) - return res diff --git a/mail_composer_cc_bcc/tests/test_mail_cc_bcc.py b/mail_composer_cc_bcc/tests/test_mail_cc_bcc.py index a592d24c..f0d76b98 100644 --- a/mail_composer_cc_bcc/tests/test_mail_cc_bcc.py +++ b/mail_composer_cc_bcc/tests/test_mail_cc_bcc.py @@ -7,7 +7,6 @@ from odoo.tests import Form, tagged from odoo.tests.common import TransactionCase -from odoo.addons.mail.models.mail_template import MailTemplate as MailTemplate_upstream from odoo.addons.mail.tests.common import MailCase from odoo.addons.mail.tests.test_mail_composer import TestMailComposerForm from odoo.addons.mail.wizard.mail_compose_message import ( @@ -15,7 +14,6 @@ ) VALID_HASHES = { - "mail.template:_generate_template_recipients": ["73b0e20a018984841e454a57a86ee08d"], "mail.composer:_compute_partner_ids": ["813ef112e3948fe625b9a89428f2518d"], } @@ -45,16 +43,6 @@ def open_mail_composer_form(self): form.body = "

Hello

" return form - def test_MailTemplate_upstream_file_hash(self): - """Test that copied upstream function hasn't received fixes""" - func = inspect.getsource( - MailTemplate_upstream._generate_template_recipients - ).encode() - func_hash = hashlib.md5(func).hexdigest() - self.assertIn( - func_hash, VALID_HASHES.get("mail.template:_generate_template_recipients") - ) - def test_MailComposer_upstream_file_hash(self): """Test that copied upstream function hasn't received fixes""" _compute_partner_ids = inspect.getsource( diff --git a/mail_composer_cc_bcc/wizards/__init__.py b/mail_composer_cc_bcc/wizards/__init__.py index b528d997..2a2ad24b 100644 --- a/mail_composer_cc_bcc/wizards/__init__.py +++ b/mail_composer_cc_bcc/wizards/__init__.py @@ -1 +1,2 @@ from . import mail_compose_message +from . import mail_template_preview diff --git a/mail_composer_cc_bcc/wizards/mail_compose_message.py b/mail_composer_cc_bcc/wizards/mail_compose_message.py index ce1cfb91..741f06c8 100644 --- a/mail_composer_cc_bcc/wizards/mail_compose_message.py +++ b/mail_composer_cc_bcc/wizards/mail_compose_message.py @@ -1,7 +1,8 @@ # Copyright 2023 Camptocamp # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +import itertools -from odoo import Command, api, fields, models +from odoo import Command, api, fields, models, tools class MailComposeMessage(models.TransientModel): @@ -44,7 +45,6 @@ def default_get(self, fields_list): res["partner_bcc_ids"] = [Command.set(partner_bcc.ids)] return res - # TODO: reduce repeated code @api.depends( "composition_mode", "model", "parent_id", "res_domain", "res_ids", "template_id" ) @@ -55,27 +55,12 @@ def _compute_partner_cc_bcc_ids(self): and composer.composition_mode == "comment" and not composer.composition_batch ): - res_ids = composer._evaluate_res_ids() or [0] - rendered_values = composer._generate_template_for_composer( - res_ids, - {"email_cc", "email_bcc"}, - find_or_create_partners=True, - )[res_ids[0]] - - if rendered_values.get("partner_cc_ids"): - partner_cc_ids = rendered_values.get("partner_cc_ids") - if not isinstance(partner_cc_ids, list): - partner_cc_ids = [partner_cc_ids] - for partner_cc_id in partner_cc_ids: - composer.partner_cc_ids = [(4, partner_cc_id)] - - if rendered_values.get("partner_bcc_ids"): - partner_bcc_ids = rendered_values.get("partner_bcc_ids") - if not isinstance(partner_bcc_ids, list): - partner_bcc_ids = [partner_bcc_ids] - for partner_bcc_id in partner_bcc_ids: - composer.partner_bcc_ids = [(4, partner_bcc_id)] - + composer._set_partner_ids_from_mails( + composer.template_id.email_cc, "partner_cc_ids" + ) + composer._set_partner_ids_from_mails( + composer.template_id.email_bcc, "partner_bcc_ids" + ) elif composer.parent_id and composer.composition_mode == "comment": composer.partner_cc_ids = composer.parent_id.partner_cc_ids composer.partner_bcc_ids = composer.parent_id.partner_bcc_ids @@ -112,6 +97,23 @@ def _compute_partner_ids(self): elif not composer.template_id: composer.partner_ids = False + def _set_partner_ids_from_mails(self, email_field, partner_field): + if email_field: + mails = tools.email_split(email_field) + partner_ids = self.env["res.partner"]._find_or_create_from_emails( + mails, + additional_values={ + email: { + "company_id": self.record_company_id.id, + } + for email in itertools.chain(mails, [False]) + }, + ) + if not isinstance(partner_ids, list): + partner_ids = [partner_ids] + for partner_id in partner_ids: + setattr(self, partner_field, [(4, partner_id.id)]) + # ------------------------------------------------------------ # RENDERING / VALUES GENERATION # ------------------------------------------------------------ diff --git a/mail_composer_cc_bcc/wizards/mail_template_preview.py b/mail_composer_cc_bcc/wizards/mail_template_preview.py new file mode 100644 index 00000000..9d8d1a64 --- /dev/null +++ b/mail_composer_cc_bcc/wizards/mail_template_preview.py @@ -0,0 +1,18 @@ +# Copyright 2024 Camptocamp +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + +from odoo.addons.mail.wizard.mail_template_preview import MailTemplatePreview + + +class MailTemplatePreview(models.TransientModel): + _inherit = "mail.template.preview" + + _MAIL_TEMPLATE_FIELDS = MailTemplatePreview._MAIL_TEMPLATE_FIELDS + ["email_bcc"] + + email_bcc = fields.Char( + "Bcc", + compute="_compute_mail_template_fields", + help="Blind Carbon copy recipients", + ) diff --git a/mail_composer_cc_bcc/wizards/mail_template_preview_view.xml b/mail_composer_cc_bcc/wizards/mail_template_preview_view.xml new file mode 100644 index 00000000..6935e31a --- /dev/null +++ b/mail_composer_cc_bcc/wizards/mail_template_preview_view.xml @@ -0,0 +1,12 @@ + + + + mail.template.preview + + + + + + + +