social/mail_composer_cc_bcc/models/mail_template.py

202 lines
8.3 KiB
Python

# Copyright 2023 Camptocamp
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
import itertools
from odoo import fields, models, tools
class MailTemplate(models.Model):
_inherit = "mail.template"
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