From 16d909879299cd25aa4d945efbe6405d0cee4d2e Mon Sep 17 00:00:00 2001
From: Ronald Portier
Date: Tue, 6 May 2025 11:34:34 +0200
Subject: [PATCH 1/3] [ADD] mail_visible_email: new module
This module will show actual to, cc and bcc headers used on
incoming and outgoing mails.
---
mail_visible_email/README.rst | 123 +++++
mail_visible_email/__init__.py | 3 +
mail_visible_email/__manifest__.py | 23 +
mail_visible_email/models/__init__.py | 5 +
mail_visible_email/models/mail_mail.py | 54 ++
mail_visible_email/models/mail_message.py | 24 +
mail_visible_email/models/mail_thread.py | 21 +
mail_visible_email/readme/CONFIGURE.rst | 1 +
mail_visible_email/readme/CONTRIBUTORS.rst | 3 +
mail_visible_email/readme/DESCRIPTION.rst | 28 ++
.../static/description/icon.png | Bin 0 -> 9455 bytes
.../static/description/index.html | 462 ++++++++++++++++++
mail_visible_email/tests/__init__.py | 4 +
mail_visible_email/tests/test_mail_receive.py | 61 +++
mail_visible_email/tests/test_mail_send.py | 69 +++
.../views/mail_message_views.xml | 15 +
16 files changed, 896 insertions(+)
create mode 100644 mail_visible_email/README.rst
create mode 100644 mail_visible_email/__init__.py
create mode 100644 mail_visible_email/__manifest__.py
create mode 100644 mail_visible_email/models/__init__.py
create mode 100644 mail_visible_email/models/mail_mail.py
create mode 100644 mail_visible_email/models/mail_message.py
create mode 100644 mail_visible_email/models/mail_thread.py
create mode 100644 mail_visible_email/readme/CONFIGURE.rst
create mode 100644 mail_visible_email/readme/CONTRIBUTORS.rst
create mode 100644 mail_visible_email/readme/DESCRIPTION.rst
create mode 100644 mail_visible_email/static/description/icon.png
create mode 100644 mail_visible_email/static/description/index.html
create mode 100644 mail_visible_email/tests/__init__.py
create mode 100644 mail_visible_email/tests/test_mail_receive.py
create mode 100644 mail_visible_email/tests/test_mail_send.py
create mode 100644 mail_visible_email/views/mail_message_views.xml
diff --git a/mail_visible_email/README.rst b/mail_visible_email/README.rst
new file mode 100644
index 000000000..2921be17e
--- /dev/null
+++ b/mail_visible_email/README.rst
@@ -0,0 +1,123 @@
+======================================
+Make emails for to, cc and bcc visible
+======================================
+
+..
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ !! This file is generated by oca-gen-addon-readme !!
+ !! changes will be overwritten. !!
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ !! source digest: sha256:53373ba10ebe61d982a5d796725296eee83924dc9d4d6aa7e54e0ec9839f59a5
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png
+ :target: https://odoo-community.org/page/development-status
+ :alt: Alpha
+.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
+ :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
+ :alt: License: AGPL-3
+.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsocial-lightgray.png?logo=github
+ :target: https://github.com/OCA/social/tree/16.0/mail_visible_email
+ :alt: OCA/social
+.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
+ :target: https://translation.odoo-community.org/projects/social-16-0/social-16-0-mail_visible_email
+ :alt: Translate me on Weblate
+.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
+ :target: https://runboat.odoo-community.org/builds?repo=OCA/social&target_branch=16.0
+ :alt: Try me on Runboat
+
+|badge1| |badge2| |badge3| |badge4| |badge5|
+
+In Odoo mails it is often unclear who where the other recipients of mails
+received, or what the actual mail addresses where of mails sent.
+
+This module adds the following fields to mail_message:
+- email_to
+- email_cc
+- email_bcc
+
+For both incoming and outgoing mails, the actual to and cc headers
+from the mails will be stored here. For outgoing mails also the bcc
+header.
+
+In case we receive a mail because we received it on an address that was
+in the bcc of the email sent, the address will actually be shown on the
+email_to field. This is because there is no bcc header in an incoming mail,
+we will have the address in the Delivered-To header.
+
+Note that we will only store the unadorned email (without partner name),
+as this will be the relevant part, and the partner names are visible on
+other fields.
+
+For technical reasons this module depends on mail_composer_cc_bcc:
+
+* We need the email_bcc field on mail.mail;
+* The module mail_composer_bcc fundamentally changes the workings of the _send()
+ method on mail.mail. In order not to have to support both methods depending
+ on whether mail_composer_bcc is installed or not, it is easier to just make sure
+ it is installed.
+
+.. IMPORTANT::
+ This is an alpha version, the data model and design can change at any time without warning.
+ Only for development or testing purpose, do not use in production.
+ `More details on development status `_
+
+**Table of contents**
+
+.. contents::
+ :local:
+
+Configuration
+=============
+
+This module has no separate configuration options.
+
+Bug Tracker
+===========
+
+Bugs are tracked on `GitHub Issues `_.
+In case of trouble, please check there if your issue has already been reported.
+If you spotted it first, help us to smash it by providing a detailed and welcomed
+`feedback `_.
+
+Do not contact contributors directly about support or help with technical issues.
+
+Credits
+=======
+
+Authors
+~~~~~~~
+
+* Therp BV
+
+Contributors
+~~~~~~~~~~~~
+
+* `Therp BV `_:
+
+ * Ronald Portier
+
+Maintainers
+~~~~~~~~~~~
+
+This module is maintained by the OCA.
+
+.. image:: https://odoo-community.org/logo.png
+ :alt: Odoo Community Association
+ :target: https://odoo-community.org
+
+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.
+
+.. |maintainer-NL66278| image:: https://github.com/NL66278.png?size=40px
+ :target: https://github.com/NL66278
+ :alt: NL66278
+
+Current `maintainer `__:
+
+|maintainer-NL66278|
+
+This module is part of the `OCA/social `_ project on GitHub.
+
+You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/mail_visible_email/__init__.py b/mail_visible_email/__init__.py
new file mode 100644
index 000000000..31660d6a9
--- /dev/null
+++ b/mail_visible_email/__init__.py
@@ -0,0 +1,3 @@
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+from . import models
diff --git a/mail_visible_email/__manifest__.py b/mail_visible_email/__manifest__.py
new file mode 100644
index 000000000..808a6d3bd
--- /dev/null
+++ b/mail_visible_email/__manifest__.py
@@ -0,0 +1,23 @@
+# Copyright 2025 Therp BV .
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+{
+ "name": "Make emails for to, cc and bcc visible",
+ "summary": "Save and show the actual email addresses used in mail.message.",
+ "version": "16.0.1.0.0",
+ "development_status": "Alpha",
+ "category": "Social",
+ "website": "https://github.com/OCA/social",
+ "author": "Therp BV, Odoo Community Association (OCA)",
+ "maintainers": ["NL66278"],
+ "license": "AGPL-3",
+ "application": False,
+ "installable": True,
+ "depends": [
+ "mail",
+ "test_mail",
+ "mail_composer_cc_bcc",
+ ],
+ "data": [
+ "views/mail_message_views.xml",
+ ],
+}
diff --git a/mail_visible_email/models/__init__.py b/mail_visible_email/models/__init__.py
new file mode 100644
index 000000000..c54733443
--- /dev/null
+++ b/mail_visible_email/models/__init__.py
@@ -0,0 +1,5 @@
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+from . import mail_thread
+from . import mail_message
+from . import mail_mail
diff --git a/mail_visible_email/models/mail_mail.py b/mail_visible_email/models/mail_mail.py
new file mode 100644
index 000000000..73d713f4a
--- /dev/null
+++ b/mail_visible_email/models/mail_mail.py
@@ -0,0 +1,54 @@
+# Copyright 2025 Therp BV .
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+from odoo import models, tools
+
+
+def list_emails(partners):
+ return [
+ p.email and tools.mail._normalize_email(p.email) for p in partners if p.email
+ ]
+
+
+class MailMail(models.Model):
+ _inherit = "mail.mail"
+
+ def _send(self, auto_commit=False, raise_exception=False, smtp_session=None):
+ """Store email_to, email_cc, email_bcc also in mail.message."""
+ for this in self.filtered(lambda r: r.state == "outgoing"):
+ message_vals = {}
+ email_values = this._get_email_values()
+ for fieldname in ["email_to", "email_cc", "email_bcc"]:
+ emails = email_values.get(fieldname, [])
+ if not emails and not this[fieldname]:
+ continue
+ message_vals[fieldname] = this._append_email(fieldname, emails)
+ if message_vals:
+ this.mail_message_id.write(message_vals)
+ return super()._send(
+ auto_commit=auto_commit,
+ raise_exception=raise_exception,
+ smtp_session=smtp_session,
+ )
+
+ def _get_email_values(self):
+ self.ensure_one()
+ partners_to = (
+ self.recipient_ids - self.recipient_cc_ids - self.recipient_bcc_ids
+ )
+ return {
+ "email_to": list_emails(partners_to),
+ "email_cc": list_emails(self.recipient_cc_ids),
+ "email_bcc": list_emails(self.recipient_bcc_ids),
+ }
+
+ def _append_email(self, fieldname, emails):
+ """Do not override existing emails."""
+ self.ensure_one()
+ message = self.mail_message_id
+ preset_emails = self[fieldname]
+ if preset_emails:
+ emails += tools.email_normalize_all(preset_emails)
+ existing = message[fieldname]
+ if existing:
+ emails += existing.split(",")
+ return ",".join(list(set(emails)))
diff --git a/mail_visible_email/models/mail_message.py b/mail_visible_email/models/mail_message.py
new file mode 100644
index 000000000..5fc183716
--- /dev/null
+++ b/mail_visible_email/models/mail_message.py
@@ -0,0 +1,24 @@
+# Copyright 2025 Therp BV .
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+from odoo import fields, models
+
+
+class MailMessage(models.Model):
+ _inherit = "mail.message"
+
+ email_to = fields.Char(
+ string="To",
+ readonly=True,
+ help="original email addresses in 'to' header",
+ )
+ email_cc = fields.Char(
+ string="Cc",
+ readonly=True,
+ help="original email addresses in 'cc' header",
+ )
+ email_bcc = fields.Char(
+ string="Bcc",
+ readonly=True,
+ help="original email addresses in 'bcc' header",
+ )
diff --git a/mail_visible_email/models/mail_thread.py b/mail_visible_email/models/mail_thread.py
new file mode 100644
index 000000000..aa1238124
--- /dev/null
+++ b/mail_visible_email/models/mail_thread.py
@@ -0,0 +1,21 @@
+# Copyright 2025 Therp BV .
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+from odoo import api, models
+
+
+class MailThread(models.AbstractModel):
+ _inherit = "mail.thread"
+
+ @api.model
+ def _message_route_process(self, message, message_dict, routes):
+ """Intercept message_dict to write 'to' and 'cc' to mail.message.
+
+ Smtp does not deliver messages with a bcc header. If a message is
+ received from a bcc address, this address will be in the raw
+ Delivered-To header, which message_parse adds to the 'to' key
+ of message_dict.
+ """
+ message_dict["email_to"] = message_dict.get("to", False)
+ message_dict["email_cc"] = message_dict.get("cc", False)
+ return super()._message_route_process(message, message_dict, routes)
diff --git a/mail_visible_email/readme/CONFIGURE.rst b/mail_visible_email/readme/CONFIGURE.rst
new file mode 100644
index 000000000..7d2c7b671
--- /dev/null
+++ b/mail_visible_email/readme/CONFIGURE.rst
@@ -0,0 +1 @@
+This module has no separate configuration options.
diff --git a/mail_visible_email/readme/CONTRIBUTORS.rst b/mail_visible_email/readme/CONTRIBUTORS.rst
new file mode 100644
index 000000000..1659ed220
--- /dev/null
+++ b/mail_visible_email/readme/CONTRIBUTORS.rst
@@ -0,0 +1,3 @@
+* `Therp BV `_:
+
+ * Ronald Portier
diff --git a/mail_visible_email/readme/DESCRIPTION.rst b/mail_visible_email/readme/DESCRIPTION.rst
new file mode 100644
index 000000000..e2ec870b3
--- /dev/null
+++ b/mail_visible_email/readme/DESCRIPTION.rst
@@ -0,0 +1,28 @@
+In Odoo mails it is often unclear who where the other recipients of mails
+received, or what the actual mail addresses where of mails sent.
+
+This module adds the following fields to mail_message:
+- email_to
+- email_cc
+- email_bcc
+
+For both incoming and outgoing mails, the actual to and cc headers
+from the mails will be stored here. For outgoing mails also the bcc
+header.
+
+In case we receive a mail because we received it on an address that was
+in the bcc of the email sent, the address will actually be shown on the
+email_to field. This is because there is no bcc header in an incoming mail,
+we will have the address in the Delivered-To header.
+
+Note that we will only store the unadorned email (without partner name),
+as this will be the relevant part, and the partner names are visible on
+other fields.
+
+For technical reasons this module depends on mail_composer_cc_bcc:
+
+* We need the email_bcc field on mail.mail;
+* The module mail_composer_bcc fundamentally changes the workings of the _send()
+ method on mail.mail. In order not to have to support both methods depending
+ on whether mail_composer_bcc is installed or not, it is easier to just make sure
+ it is installed.
diff --git a/mail_visible_email/static/description/icon.png b/mail_visible_email/static/description/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d
GIT binary patch
literal 9455
zcmW++2RxMjAAjx~&dlBk9S+%}OXg)AGE&Cb*&}d0jUxM@u(PQx^-s)697TX`ehR4?GS^qbkof1cslKgkU)h65qZ9Oc=ml_0temigYLJfnz{IDzUf>bGs4N!v3=Z3jMq&A#7%rM5eQ#dc?k~!
zVpnB`o+K7|Al`Q_U;eD$B
zfJtP*jH`siUq~{KE)`jP2|#TUEFGRryE2`i0**z#*^6~AI|YzIWy$Cu#CSLW3q=GA
z6`?GZymC;dCPk~rBS%eCb`5OLr;RUZ;D`}um=H)BfVIq%7VhiMr)_#G0N#zrNH|__
zc+blN2UAB0=617@>_u;MPHN;P;N#YoE=)R#i$k_`UAA>WWCcEVMh~L_
zj--gtp&|K1#58Yz*AHCTMziU1Jzt_jG0I@qAOHsk$2}yTmVkBp_eHuY$A9)>P6o~I
z%aQ?!(GqeQ-Y+b0I(m9pwgi(IIZZzsbMv+9w{PFtd_<_(LA~0H(xz{=FhLB@(1&qHA5EJw1>>=%q2f&^X>IQ{!GJ4e9U
z&KlB)z(84HmNgm2hg2C0>WM{E(DdPr+EeU_N@57;PC2&DmGFW_9kP&%?X4}+xWi)(
z;)z%wI5>D4a*5XwD)P--sPkoY(a~WBw;E~AW`Yue4kFa^LM3X`8x|}ZUeMnqr}>kH
zG%WWW>3ml$Yez?i%)2pbKPI7?5o?hydokgQyZsNEr{a|mLdt;X2TX(#B1j35xPnPW
z*bMSSOauW>o;*=kO8ojw91VX!qoOQb)zHJ!odWB}d+*K?#sY_jqPdg{Sm2HdYzdEx
zOGVPhVRTGPtv0o}RfVP;Nd(|CB)I;*t&QO8h
zFfekr30S!-LHmV_Su-W+rEwYXJ^;6&3|L$mMC8*bQptyOo9;>Qb9Q9`ySe3%V$A*9
zeKEe+b0{#KWGp$F+tga)0RtI)nhMa-K@JS}2krK~n8vJ=Ngm?R!9G<~RyuU0d?nz#
z-5EK$o(!F?hmX*2Yt6+coY`6jGbb7tF#6nHA
zuKk=GGJ;ZwON1iAfG$E#Y7MnZVmrY|j0eVI(DN_MNFJmyZ|;w4tf@=CCDZ#5N_0K=
z$;R~bbk?}TpfDjfB&aiQ$VA}s?P}xPERJG{kxk5~R`iRS(SK5d+Xs9swCozZISbnS
zk!)I0>t=A<-^z(cmSFz3=jZ23u13X><0b)P)^1T_))Kr`e!-pb#q&J*Q`p+B6la%C
zuVl&0duN<;uOsB3%T9Fp8t{ED108)`y_~Hnd9AUX7h-H?jVuU|}My+C=TjH(jKz
zqMVr0re3S$H@t{zI95qa)+Crz*5Zj}Ao%4Z><+W(nOZd?gDnfNBC3>M8WE61$So|P
zVvqH0SNtDTcsUdzaMDpT=Ty0pDHHNL@Z0w$Y`XO
z2M-_r1S+GaH%pz#Uy0*w$Vdl=X=rQXEzO}d6J^R6zjM1u&c9vYLvLp?W7w(?np9x1
zE_0JSAJCPB%i7p*Wvg)pn5T`8k3-uR?*NT|J`eS#_#54p>!p(mLDvmc-3o0mX*mp_
zN*AeS<>#^-{S%W<*mz^!X$w_2dHWpcJ6^j64qFBft-o}o_Vx80o0>}Du;>kLts;$8
zC`7q$QI(dKYG`Wa8#wl@V4jVWBRGQ@1dr-hstpQL)Tl+aqVpGpbSfN>5i&QMXfiZ>
zaA?T1VGe?rpQ@;+pkrVdd{klI&jVS@I5_iz!=UMpTsa~mBga?1r}aRBm1WS;TT*s0f0lY=JBl66Upy)-k4J}lh=P^8(SXk~0xW=T9v*B|gzIhN
z>qsO7dFd~mgxAy4V?&)=5ieYq?zi?ZEoj)&2o)RLy=@hbCRcfT5jigwtQGE{L*8<@Yd{zg;CsL5mvzfDY}P-wos_6PfprFVaeqNE%h
zKZhLtcQld;ZD+>=nqN~>GvROfueSzJD&BE*}XfU|H&(FssBqY=hPCt`d
zH?@s2>I(|;fcW&YM6#V#!kUIP8$Nkdh0A(bEVj``-AAyYgwY~jB
zT|I7Bf@%;7aL7Wf4dZ%VqF$eiaC38OV6oy3Z#TER2G+fOCd9Iaoy6aLYbPTN{XRPz
z;U!V|vBf%H!}52L2gH_+j;`bTcQRXB+y9onc^wLm5wi3-Be}U>k_u>2Eg$=k!(l@I
zcCg+flakT2Nej3i0yn+g+}%NYb?ta;R?(g5SnwsQ49U8Wng8d|{B+lyRcEDvR3+`O{zfmrmvFrL6acVP%yG98X
zo&+VBg@px@i)%o?dG(`T;n*$S5*rnyiR#=wW}}GsAcfyQpE|>a{=$Hjg=-*_K;UtD
z#z-)AXwSRY?OPefw^iI+
z)AXz#PfEjlwTes|_{sB?4(O@fg0AJ^g8gP}ex9Ucf*@_^J(s_5jJV}c)s$`Myn|Kd
z$6>}#q^n{4vN@+Os$m7KV+`}c%4)4pv@06af4-x5#wj!KKb%caK{A&Y#Rfs
z-po?Dcb1({W=6FKIUirH&(yg=*6aLCekcKwyfK^JN5{wcA3nhO(o}SK#!CINhI`-I
z1)6&n7O&ZmyFMuNwvEic#IiOAwNkR=u5it{B9n2sAJV5pNhar=j5`*N!Na;c7g!l$
z3aYBqUkqqTJ=Re-;)s!EOeij=7SQZ3Hq}ZRds%IM*PtM$wV
z@;rlc*NRK7i3y5BETSKuumEN`Xu_8GP1Ri=OKQ$@I^ko8>H6)4rjiG5{VBM>B|%`&&s^)jS|-_95&yc=GqjNo{zFkw%%HHhS~e=s
zD#sfS+-?*t|J!+ozP6KvtOl!R)@@-z24}`9{QaVLD^9VCSR2b`b!KC#o;Ki<+wXB6
zx3&O0LOWcg4&rv4QG0)4yb}7BFSEg~=IR5#ZRj8kg}dS7_V&^%#Do==#`u
zpy6{ox?jWuR(;pg+f@mT>#HGWHAJRRDDDv~@(IDw&R>9643kK#HN`!1vBJHnC+RM&yIh8{gG2q
zA%e*U3|N0XSRa~oX-3EAneep)@{h2vvd3Xvy$7og(sayr@95+e6~Xvi1tUqnIxoIH
zVWo*OwYElb#uyW{Imam6f2rGbjR!Y3`#gPqkv57dB6K^wRGxc9B(t|aYDGS=m$&S!NmCtrMMaUg(c
zc2qC=2Z`EEFMW-me5B)24AqF*bV5Dr-M5ig(l-WPS%CgaPzs6p_gnCIvTJ=Y<6!gT
zVt@AfYCzjjsMEGi=rDQHo0yc;HqoRNnNFeWZgcm?f;cp(6CNylj36DoL(?TS7eU#+
z7&mfr#y))+CJOXQKUMZ7QIdS9@#-}7y2K1{8)cCt0~-X0O!O?Qx#E4Og+;A2SjalQ
zs7r?qn0H044=sDN$SRG$arw~n=+T_DNdSrarmu)V6@|?1-ZB#hRn`uilTGPJ@fqEy
zGt(f0B+^JDP&f=r{#Y_wi#AVDf-y!RIXU^0jXsFpf>=Ji*TeqSY!H~AMbJdCGLhC)
zn7Rx+sXw6uYj;WRYrLd^5IZq@6JI1C^YkgnedZEYy<&4(z%Q$5yv#Boo{AH8n$a
zhb4Y3PWdr269&?V%uI$xMcUrMzl=;w<_nm*qr=c3Rl@i5wWB;e-`t7D&c-mcQl7x!
zZWB`UGcw=Y2=}~wzrfLx=uet<;m3~=8I~ZRuzvMQUQdr+yTV|ATf1Uuomr__nDf=X
zZ3WYJtHp_ri(}SQAPjv+Y+0=fH4krOP@S&=zZ-t1jW1o@}z;xk8
z(Nz1co&El^HK^NrhVHa-_;&88vTU>_J33=%{if;BEY*J#1n59=07jrGQ#IP>@u#3A
z;!q+E1Rj3ZJ+!4bq9F8PXJ@yMgZL;>&gYA0%_Kbi8?S=XGM~dnQZQ!yBSgcZhY96H
zrWnU;k)qy`rX&&xlDyA%(a1Hhi5CWkmg(`Gb%m(HKi-7Z!LKGRP_B8@`7&hdDy5n=
z`OIxqxiVfX@OX1p(mQu>0Ai*v_cTMiw4qRt3~NBvr9oBy0)r>w3p~V0SCm=An6@3n)>@z!|o-$HvDK
z|3D2ZMJkLE5loMKl6R^ez@Zz%S$&mbeoqH5`Bb){Ei21q&VP)hWS2tjShfFtGE+$z
zzCR$P#uktu+#!w)cX!lWN1XU%K-r=s{|j?)Akf@q#3b#{6cZCuJ~gCxuMXRmI$nGtnH+-h
z+GEi!*X=AP<|fG`1>MBdTb?28JYc=fGvAi2I<$B(rs$;eoJCyR6_bc~p!XR@O-+sD
z=eH`-ye})I5ic1eL~TDmtfJ|8`0VJ*Yr=hNCd)G1p2MMz4C3^Mj?7;!w|Ly%JqmuW
zlIEW^Ft%z?*|fpXda>Jr^1noFZEwFgVV%|*XhH@acv8rdGxeEX{M$(vG{Zw+x(ei@
zmfXb22}8-?Fi`vo-YVrTH*C?a8%M=Hv9MqVH7H^J$KsD?>!SFZ;ZsvnHr_gn=7acz
z#W?0eCdVhVMWN12VV^$>WlQ?f;P^{(&pYTops|btm6aj>_Uz+hqpGwB)vWp0Cf5y<
zft8-je~nn?W11plq}N)4A{l8I7$!ks_x$PXW-2XaRFswX_BnF{R#6YIwMhAgd5F9X
zGmwdadS6(a^fjHtXg8=l?Rc0Sm%hk6E9!5cLVloEy4eh(=FwgP`)~I^5~pBEWo+F6
zSf2ncyMurJN91#cJTy_u8Y}@%!bq1RkGC~-bV@SXRd4F{R-*V`bS+6;W5vZ(&+I<9$;-V|eNfLa5n-6%
z2(}&uGRF;p92eS*sE*oR$@pexaqr*meB)VhmIg@h{uzkk$9~qh#cHhw#>O%)b@+(|
z^IQgqzuj~Sk(J;swEM-3TrJAPCq9k^^^`q{IItKBRXYe}e0Tdr=Huf7da3$l4PdpwWDop%^}n;dD#K4s#DYA8SHZ
z&1!riV4W4R7R#C))JH1~axJ)RYnM$$lIR%6fIVA@zV{XVyx}C+a-Dt8Y9M)^KU0+H
zR4IUb2CJ{Hg>CuaXtD50jB(_Tcx=Z$^WYu2u5kubqmwp%drJ6
z?Fo40g!Qd<-l=TQxqHEOuPX0;^z7iX?Ke^a%XT<13TA^5`4Xcw6D@Ur&VT&CUe0d}
z1GjOVF1^L@>O)l@?bD~$wzgf(nxX1OGD8fEV?TdJcZc2KoUe|oP1#=$$7ee|xbY)A
zDZq+cuTpc(fFdj^=!;{k03C69lMQ(|>uhRfRu%+!k&YOi-3|1QKB
z
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
Xviia!U7SGha1wx#SCgwmn*{w2TRX*I
literal 0
HcmV?d00001
diff --git a/mail_visible_email/static/description/index.html b/mail_visible_email/static/description/index.html
new file mode 100644
index 000000000..d523a5cdb
--- /dev/null
+++ b/mail_visible_email/static/description/index.html
@@ -0,0 +1,462 @@
+
+
+
+
+
+Make emails for to, cc and bcc visible
+
+
+
+
+
Make emails for to, cc and bcc visible
+
+
+

+
In Odoo mails it is often unclear who where the other recipients of mails
+received, or what the actual mail addresses where of mails sent.
+
This module adds the following fields to mail_message:
+- email_to
+- email_cc
+- email_bcc
+
For both incoming and outgoing mails, the actual to and cc headers
+from the mails will be stored here. For outgoing mails also the bcc
+header.
+
In case we receive a mail because we received it on an address that was
+in the bcc of the email sent, the address will actually be shown on the
+email_to field. This is because there is no bcc header in an incoming mail,
+we will have the address in the Delivered-To header.
+
Note that we will only store the unadorned email (without partner name),
+as this will be the relevant part, and the partner names are visible on
+other fields.
+
For technical reasons this module depends on mail_composer_cc_bcc:
+
+- We need the email_bcc field on mail.mail;
+- The module mail_composer_bcc fundamentally changes the workings of the _send()
+method on mail.mail. In order not to have to support both methods depending
+on whether mail_composer_bcc is installed or not, it is easier to just make sure
+it is installed.
+
+
+
Important
+
This is an alpha version, the data model and design can change at any time without warning.
+Only for development or testing purpose, do not use in production.
+More details on development status
+
+
Table of contents
+
+
+
+
This module has no separate configuration options.
+
+
+
+
Bugs are tracked on GitHub Issues.
+In case of trouble, please check there if your issue has already been reported.
+If you spotted it first, help us to smash it by providing a detailed and welcomed
+feedback.
+
Do not contact contributors directly about support or help with technical issues.
+
+
+
+
+
+
+
+
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.
+
Current maintainer:
+

+
This module is part of the OCA/social project on GitHub.
+
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
+
+
+
+
+
diff --git a/mail_visible_email/tests/__init__.py b/mail_visible_email/tests/__init__.py
new file mode 100644
index 000000000..76b133608
--- /dev/null
+++ b/mail_visible_email/tests/__init__.py
@@ -0,0 +1,4 @@
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+from . import test_mail_receive
+from . import test_mail_send
diff --git a/mail_visible_email/tests/test_mail_receive.py b/mail_visible_email/tests/test_mail_receive.py
new file mode 100644
index 000000000..9ca9eb2ff
--- /dev/null
+++ b/mail_visible_email/tests/test_mail_receive.py
@@ -0,0 +1,61 @@
+# Copyright 2025 Therp BV .
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+from odoo.tests.common import TransactionCase, tagged
+from odoo.tools import mute_logger
+
+from odoo.addons.test_mail.data.test_mail_data import MAIL_TEMPLATE
+
+
+@tagged("-at_install", "post_install")
+class TestMailReceive(TransactionCase):
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ cls.Alias = cls.env["mail.alias"]
+ cls.Partner = cls.env["res.partner"]
+ cls.MailThread = cls.env["mail.thread"]
+ cls.Message = cls.env["mail.message"]
+
+ ICP = cls.env["ir.config_parameter"].sudo()
+ ICP.set_param("mail.catchall.domain", "fsf.org")
+
+ cls.partner_model = cls.env["ir.model"].search([("model", "=", "res.partner")])
+ cls.mail_alias_test = cls.Alias.create(
+ {
+ "alias_name": "test_alias",
+ "alias_model_id": cls.partner_model.id,
+ "alias_defaults": "{'name': 'Test Alias', 'is_company': True}",
+ }
+ )
+
+ @mute_logger("odoo.addons.mail.models.mail_thread", "odoo.models")
+ def test_incoming_email(self):
+ # Imitate what self.server.fetch_mail() would do
+ thread_id = self.MailThread.message_process(
+ self.Partner._name,
+ MAIL_TEMPLATE.format(
+ return_path="spambot@example.com",
+ email_from="spambot@example.com",
+ to="test_alias@fsf.org",
+ cc="nobody@fsf.org, anybody@fsf.org",
+ subject="I'm a robot, hello",
+ extra="",
+ msg_id="",
+ ),
+ )
+ # We should now have a partner with the name 'Test Alias'.
+ self.assertTrue(thread_id)
+ partner = self.Partner.browse(thread_id)
+ self.assertEqual(partner.name, "Test Alias")
+ # We should have a mail message referring to this partner.
+ message = self.Message.search(
+ [
+ ("model", "=", partner._name),
+ ("res_id", "=", partner.id),
+ ]
+ )
+ self.assertTrue(message)
+ self.assertEqual(message.email_to, "test_alias@fsf.org")
+ # Use In to be independent of ordering and separator.
+ self.assertIn("anybody@fsf.org", message.email_cc)
+ self.assertIn("nobody@fsf.org", message.email_cc)
diff --git a/mail_visible_email/tests/test_mail_send.py b/mail_visible_email/tests/test_mail_send.py
new file mode 100644
index 000000000..1f5698622
--- /dev/null
+++ b/mail_visible_email/tests/test_mail_send.py
@@ -0,0 +1,69 @@
+# Copyright 2025 Therp BV .
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+from odoo.tests import Form
+
+from odoo.addons.mail.tests.test_mail_composer import TestMailComposer
+
+
+class TestMailSend(TestMailComposer):
+ @classmethod
+ def setUpClass(cls):
+ # Based on example in mail_composer_cc_bcc.
+ super().setUpClass()
+ env = cls.env
+ cls.partner = env.ref("base.res_partner_address_31")
+ cls.partner_cc = env.ref("base.partner_demo")
+ cls.partner_cc2 = env.ref("base.partner_demo_portal")
+ cls.partner_bcc = env.ref("base.res_partner_main1")
+ cls.mail_template = cls._create_template(
+ "res.partner",
+ template_values={
+ "auto_delete": False,
+ "email_to": cls.partner.email,
+ "email_cc": cls.partner_cc.email,
+ "email_bcc": cls.partner_bcc.email,
+ },
+ )
+
+ def open_mail_composer_form(self):
+ # Based on example in mail_composer_cc_bcc.
+ # Use form to populate data
+ ctx = {
+ "default_partner_ids": self.partner.ids,
+ "default_model": self.partner._name,
+ "default_res_id": self.partner.id,
+ # to ensure consistent test results even when mail_post_defer is installed
+ "mail_notify_force_send": True,
+ }
+ form = Form(self.env["mail.compose.message"].with_context(**ctx))
+ form.body = "Hello
"
+ return form
+
+ def test_email_to_cc(self):
+ form = self.open_mail_composer_form()
+ composer = form.save()
+ # Use object to update Many2many fields (form can't do like this)
+ composer.partner_cc_ids = self.partner_cc
+ composer.partner_cc_ids |= self.partner_cc2
+ composer.partner_bcc_ids = self.partner_bcc
+ with self.mock_mail_gateway():
+ composer._action_send_mail()
+ # Verify recipients of mail.message
+ message = self.partner.message_ids[0]
+ self.assertEqual(message.email_to, self.partner.email)
+ self.assertIn(self.partner_cc.email, message.email_cc)
+ self.assertIn(self.partner_cc2.email, message.email_cc)
+ self.assertEqual(message.email_bcc, self.partner_bcc.email)
+
+ def test_email_to(self):
+ """Test when using email_to directly."""
+ Mail = self.env["mail.mail"]
+ mail_id = self.mail_template.send_mail(self.partner.id, force_send=True)
+ self.assertTrue(mail_id)
+ mail = Mail.browse(mail_id)
+ message = mail.mail_message_id
+ self.assertTrue(message)
+ self.assertEqual(message.email_to, self.partner.email)
+ self.assertEqual(message.email_cc, self.partner_cc.email)
+ # Odoo ignores the email_bcc field in the template!
+ # self.assertEqual(message.email_bcc, self.partner_bcc.email)
diff --git a/mail_visible_email/views/mail_message_views.xml b/mail_visible_email/views/mail_message_views.xml
new file mode 100644
index 000000000..735d76763
--- /dev/null
+++ b/mail_visible_email/views/mail_message_views.xml
@@ -0,0 +1,15 @@
+
+
+
+ mail.message.form - mail_visible_email
+ mail.message
+
+
+
+
+
+
+
+
+
+
From bfb146d2722d1f6d48dc5696a84eb9b777d2a1fc Mon Sep 17 00:00:00 2001
From: Nikos Tsirintanis
Date: Tue, 23 Jun 2026 13:53:15 +0200
Subject: [PATCH 2/3] [IMP] mail_visible_email: pre-commit auto fixes
---
mail_visible_email/README.rst | 49 +++++++++----------
mail_visible_email/pyproject.toml | 3 ++
.../readme/{CONFIGURE.rst => CONFIGURE.md} | 0
mail_visible_email/readme/CONTRIBUTORS.md | 3 ++
mail_visible_email/readme/CONTRIBUTORS.rst | 3 --
mail_visible_email/readme/DESCRIPTION.md | 25 ++++++++++
mail_visible_email/readme/DESCRIPTION.rst | 28 -----------
.../static/description/index.html | 44 ++++++++---------
8 files changed, 76 insertions(+), 79 deletions(-)
create mode 100644 mail_visible_email/pyproject.toml
rename mail_visible_email/readme/{CONFIGURE.rst => CONFIGURE.md} (100%)
create mode 100644 mail_visible_email/readme/CONTRIBUTORS.md
delete mode 100644 mail_visible_email/readme/CONTRIBUTORS.rst
create mode 100644 mail_visible_email/readme/DESCRIPTION.md
delete mode 100644 mail_visible_email/readme/DESCRIPTION.rst
diff --git a/mail_visible_email/README.rst b/mail_visible_email/README.rst
index 2921be17e..8882428ef 100644
--- a/mail_visible_email/README.rst
+++ b/mail_visible_email/README.rst
@@ -17,33 +17,30 @@ Make emails for to, cc and bcc visible
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsocial-lightgray.png?logo=github
- :target: https://github.com/OCA/social/tree/16.0/mail_visible_email
+ :target: https://github.com/OCA/social/tree/18.0/mail_visible_email
:alt: OCA/social
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
- :target: https://translation.odoo-community.org/projects/social-16-0/social-16-0-mail_visible_email
+ :target: https://translation.odoo-community.org/projects/social-18-0/social-18-0-mail_visible_email
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
- :target: https://runboat.odoo-community.org/builds?repo=OCA/social&target_branch=16.0
+ :target: https://runboat.odoo-community.org/builds?repo=OCA/social&target_branch=18.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
-In Odoo mails it is often unclear who where the other recipients of mails
-received, or what the actual mail addresses where of mails sent.
+In Odoo mails it is often unclear who where the other recipients of
+mails received, or what the actual mail addresses where of mails sent.
-This module adds the following fields to mail_message:
-- email_to
-- email_cc
-- email_bcc
+This module adds the following fields to mail_message: - email_to -
+email_cc - email_bcc
-For both incoming and outgoing mails, the actual to and cc headers
-from the mails will be stored here. For outgoing mails also the bcc
-header.
+For both incoming and outgoing mails, the actual to and cc headers from
+the mails will be stored here. For outgoing mails also the bcc header.
In case we receive a mail because we received it on an address that was
in the bcc of the email sent, the address will actually be shown on the
-email_to field. This is because there is no bcc header in an incoming mail,
-we will have the address in the Delivered-To header.
+email_to field. This is because there is no bcc header in an incoming
+mail, we will have the address in the Delivered-To header.
Note that we will only store the unadorned email (without partner name),
as this will be the relevant part, and the partner names are visible on
@@ -51,11 +48,11 @@ other fields.
For technical reasons this module depends on mail_composer_cc_bcc:
-* We need the email_bcc field on mail.mail;
-* The module mail_composer_bcc fundamentally changes the workings of the _send()
- method on mail.mail. In order not to have to support both methods depending
- on whether mail_composer_bcc is installed or not, it is easier to just make sure
- it is installed.
+- We need the email_bcc field on mail.mail;
+- The module mail_composer_bcc fundamentally changes the workings of
+ the \_send() method on mail.mail. In order not to have to support
+ both methods depending on whether mail_composer_bcc is installed or
+ not, it is easier to just make sure it is installed.
.. IMPORTANT::
This is an alpha version, the data model and design can change at any time without warning.
@@ -78,7 +75,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues `_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
-`feedback `_.
+`feedback `_.
Do not contact contributors directly about support or help with technical issues.
@@ -86,19 +83,19 @@ Credits
=======
Authors
-~~~~~~~
+-------
* Therp BV
Contributors
-~~~~~~~~~~~~
+------------
-* `Therp BV `_:
+- `Therp BV `__:
- * Ronald Portier
+ - Ronald Portier
Maintainers
-~~~~~~~~~~~
+-----------
This module is maintained by the OCA.
@@ -118,6 +115,6 @@ Current `maintainer `__:
|maintainer-NL66278|
-This module is part of the `OCA/social `_ project on GitHub.
+This module is part of the `OCA/social `_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/mail_visible_email/pyproject.toml b/mail_visible_email/pyproject.toml
new file mode 100644
index 000000000..4231d0ccc
--- /dev/null
+++ b/mail_visible_email/pyproject.toml
@@ -0,0 +1,3 @@
+[build-system]
+requires = ["whool"]
+build-backend = "whool.buildapi"
diff --git a/mail_visible_email/readme/CONFIGURE.rst b/mail_visible_email/readme/CONFIGURE.md
similarity index 100%
rename from mail_visible_email/readme/CONFIGURE.rst
rename to mail_visible_email/readme/CONFIGURE.md
diff --git a/mail_visible_email/readme/CONTRIBUTORS.md b/mail_visible_email/readme/CONTRIBUTORS.md
new file mode 100644
index 000000000..676028b8e
--- /dev/null
+++ b/mail_visible_email/readme/CONTRIBUTORS.md
@@ -0,0 +1,3 @@
+- [Therp BV](https://therp.nl):
+
+ > - Ronald Portier \<\>
diff --git a/mail_visible_email/readme/CONTRIBUTORS.rst b/mail_visible_email/readme/CONTRIBUTORS.rst
deleted file mode 100644
index 1659ed220..000000000
--- a/mail_visible_email/readme/CONTRIBUTORS.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-* `Therp BV `_:
-
- * Ronald Portier
diff --git a/mail_visible_email/readme/DESCRIPTION.md b/mail_visible_email/readme/DESCRIPTION.md
new file mode 100644
index 000000000..292f1f584
--- /dev/null
+++ b/mail_visible_email/readme/DESCRIPTION.md
@@ -0,0 +1,25 @@
+In Odoo mails it is often unclear who where the other recipients of
+mails received, or what the actual mail addresses where of mails sent.
+
+This module adds the following fields to mail_message: - email_to -
+email_cc - email_bcc
+
+For both incoming and outgoing mails, the actual to and cc headers from
+the mails will be stored here. For outgoing mails also the bcc header.
+
+In case we receive a mail because we received it on an address that was
+in the bcc of the email sent, the address will actually be shown on the
+email_to field. This is because there is no bcc header in an incoming
+mail, we will have the address in the Delivered-To header.
+
+Note that we will only store the unadorned email (without partner name),
+as this will be the relevant part, and the partner names are visible on
+other fields.
+
+For technical reasons this module depends on mail_composer_cc_bcc:
+
+- We need the email_bcc field on mail.mail;
+- The module mail_composer_bcc fundamentally changes the workings of the
+ \_send() method on mail.mail. In order not to have to support both
+ methods depending on whether mail_composer_bcc is installed or not, it
+ is easier to just make sure it is installed.
diff --git a/mail_visible_email/readme/DESCRIPTION.rst b/mail_visible_email/readme/DESCRIPTION.rst
deleted file mode 100644
index e2ec870b3..000000000
--- a/mail_visible_email/readme/DESCRIPTION.rst
+++ /dev/null
@@ -1,28 +0,0 @@
-In Odoo mails it is often unclear who where the other recipients of mails
-received, or what the actual mail addresses where of mails sent.
-
-This module adds the following fields to mail_message:
-- email_to
-- email_cc
-- email_bcc
-
-For both incoming and outgoing mails, the actual to and cc headers
-from the mails will be stored here. For outgoing mails also the bcc
-header.
-
-In case we receive a mail because we received it on an address that was
-in the bcc of the email sent, the address will actually be shown on the
-email_to field. This is because there is no bcc header in an incoming mail,
-we will have the address in the Delivered-To header.
-
-Note that we will only store the unadorned email (without partner name),
-as this will be the relevant part, and the partner names are visible on
-other fields.
-
-For technical reasons this module depends on mail_composer_cc_bcc:
-
-* We need the email_bcc field on mail.mail;
-* The module mail_composer_bcc fundamentally changes the workings of the _send()
- method on mail.mail. In order not to have to support both methods depending
- on whether mail_composer_bcc is installed or not, it is easier to just make sure
- it is installed.
diff --git a/mail_visible_email/static/description/index.html b/mail_visible_email/static/description/index.html
index d523a5cdb..42331f0ad 100644
--- a/mail_visible_email/static/description/index.html
+++ b/mail_visible_email/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 {
@@ -368,30 +369,27 @@ Make emails for to, cc and bcc visible
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:53373ba10ebe61d982a5d796725296eee83924dc9d4d6aa7e54e0ec9839f59a5
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
-

-In Odoo mails it is often unclear who where the other recipients of mails
-received, or what the actual mail addresses where of mails sent.
-This module adds the following fields to mail_message:
-- email_to
-- email_cc
-- email_bcc
-For both incoming and outgoing mails, the actual to and cc headers
-from the mails will be stored here. For outgoing mails also the bcc
-header.
+

+In Odoo mails it is often unclear who where the other recipients of
+mails received, or what the actual mail addresses where of mails sent.
+This module adds the following fields to mail_message: - email_to -
+email_cc - email_bcc
+For both incoming and outgoing mails, the actual to and cc headers from
+the mails will be stored here. For outgoing mails also the bcc header.
In case we receive a mail because we received it on an address that was
in the bcc of the email sent, the address will actually be shown on the
-email_to field. This is because there is no bcc header in an incoming mail,
-we will have the address in the Delivered-To header.
+email_to field. This is because there is no bcc header in an incoming
+mail, we will have the address in the Delivered-To header.
Note that we will only store the unadorned email (without partner name),
as this will be the relevant part, and the partner names are visible on
other fields.
For technical reasons this module depends on mail_composer_cc_bcc:
- We need the email_bcc field on mail.mail;
-- The module mail_composer_bcc fundamentally changes the workings of the _send()
-method on mail.mail. In order not to have to support both methods depending
-on whether mail_composer_bcc is installed or not, it is easier to just make sure
-it is installed.
+- The module mail_composer_bcc fundamentally changes the workings of
+the _send() method on mail.mail. In order not to have to support
+both methods depending on whether mail_composer_bcc is installed or
+not, it is easier to just make sure it is installed.
Important
@@ -421,7 +419,7 @@
Bugs are tracked on GitHub Issues.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
-feedback.
+
feedback.
Do not contact contributors directly about support or help with technical issues.
@@ -447,13 +445,15 @@
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.
Current maintainer:

-
This module is part of the OCA/social project on GitHub.
+
This module is part of the OCA/social project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
From 30b58967017e4590847b6288afcd01ed27a55e87 Mon Sep 17 00:00:00 2001
From: Nikos Tsirintanis
Date: Tue, 23 Jun 2026 14:25:09 +0200
Subject: [PATCH 3/3] [MIG] mail_visible_email: Migration to 18.0
---
mail_visible_email/README.rst | 35 +++++-----
mail_visible_email/__manifest__.py | 8 +--
mail_visible_email/models/mail_mail.py | 65 ++++++++++---------
mail_visible_email/models/mail_thread.py | 13 +++-
mail_visible_email/readme/CONFIGURE.md | 1 +
mail_visible_email/readme/CONTRIBUTORS.md | 1 +
mail_visible_email/readme/DESCRIPTION.md | 28 ++++----
.../static/description/index.html | 28 ++++----
mail_visible_email/tests/test_mail_receive.py | 14 ++--
mail_visible_email/tests/test_mail_send.py | 40 +++++-------
10 files changed, 114 insertions(+), 119 deletions(-)
diff --git a/mail_visible_email/README.rst b/mail_visible_email/README.rst
index 8882428ef..cc89e358a 100644
--- a/mail_visible_email/README.rst
+++ b/mail_visible_email/README.rst
@@ -16,23 +16,26 @@ Make emails for to, cc and bcc visible
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
-.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsocial-lightgray.png?logo=github
- :target: https://github.com/OCA/social/tree/18.0/mail_visible_email
- :alt: OCA/social
+.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fmail-lightgray.png?logo=github
+ :target: https://github.com/OCA/mail/tree/18.0/mail_visible_email
+ :alt: OCA/mail
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
- :target: https://translation.odoo-community.org/projects/social-18-0/social-18-0-mail_visible_email
+ :target: https://translation.odoo-community.org/projects/mail-18-0/mail-18-0-mail_visible_email
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
- :target: https://runboat.odoo-community.org/builds?repo=OCA/social&target_branch=18.0
+ :target: https://runboat.odoo-community.org/builds?repo=OCA/mail&target_branch=18.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
-In Odoo mails it is often unclear who where the other recipients of
-mails received, or what the actual mail addresses where of mails sent.
+In Odoo mails it is often unclear who were the other recipients of mails
+received, or what the actual mail addresses were of mails sent.
-This module adds the following fields to mail_message: - email_to -
-email_cc - email_bcc
+This module adds the following fields to mail_message:
+
+- email_to
+- email_cc
+- email_bcc
For both incoming and outgoing mails, the actual to and cc headers from
the mails will be stored here. For outgoing mails also the bcc header.
@@ -46,14 +49,6 @@ Note that we will only store the unadorned email (without partner name),
as this will be the relevant part, and the partner names are visible on
other fields.
-For technical reasons this module depends on mail_composer_cc_bcc:
-
-- We need the email_bcc field on mail.mail;
-- The module mail_composer_bcc fundamentally changes the workings of
- the \_send() method on mail.mail. In order not to have to support
- both methods depending on whether mail_composer_bcc is installed or
- not, it is easier to just make sure it is installed.
-
.. IMPORTANT::
This is an alpha version, the data model and design can change at any time without warning.
Only for development or testing purpose, do not use in production.
@@ -72,10 +67,10 @@ This module has no separate configuration options.
Bug Tracker
===========
-Bugs are tracked on `GitHub Issues `_.
+Bugs are tracked on `GitHub Issues `_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
-`feedback `_.
+`feedback `_.
Do not contact contributors directly about support or help with technical issues.
@@ -115,6 +110,6 @@ Current `maintainer `__:
|maintainer-NL66278|
-This module is part of the `OCA/social `_ project on GitHub.
+This module is part of the `OCA/mail `_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/mail_visible_email/__manifest__.py b/mail_visible_email/__manifest__.py
index 808a6d3bd..4e6ec44fb 100644
--- a/mail_visible_email/__manifest__.py
+++ b/mail_visible_email/__manifest__.py
@@ -3,10 +3,10 @@
{
"name": "Make emails for to, cc and bcc visible",
"summary": "Save and show the actual email addresses used in mail.message.",
- "version": "16.0.1.0.0",
+ "version": "18.0.1.0.0",
"development_status": "Alpha",
- "category": "Social",
- "website": "https://github.com/OCA/social",
+ "category": "Email",
+ "website": "https://github.com/OCA/mail",
"author": "Therp BV, Odoo Community Association (OCA)",
"maintainers": ["NL66278"],
"license": "AGPL-3",
@@ -14,8 +14,8 @@
"installable": True,
"depends": [
"mail",
- "test_mail",
"mail_composer_cc_bcc",
+ "test_mail",
],
"data": [
"views/mail_message_views.xml",
diff --git a/mail_visible_email/models/mail_mail.py b/mail_visible_email/models/mail_mail.py
index 73d713f4a..455a8ede2 100644
--- a/mail_visible_email/models/mail_mail.py
+++ b/mail_visible_email/models/mail_mail.py
@@ -1,54 +1,57 @@
-# Copyright 2025 Therp BV .
+# Copyright 2025 Therp BV .
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
-from odoo import models, tools
+from odoo import api, models, tools
def list_emails(partners):
return [
- p.email and tools.mail._normalize_email(p.email) for p in partners if p.email
+ tools.mail.email_normalize(p.email)
+ for p in partners
+ if p.email and tools.mail.email_normalize(p.email)
]
class MailMail(models.Model):
_inherit = "mail.mail"
- def _send(self, auto_commit=False, raise_exception=False, smtp_session=None):
- """Store email_to, email_cc, email_bcc also in mail.message."""
- for this in self.filtered(lambda r: r.state == "outgoing"):
+ @api.model_create_multi
+ def create(self, values_list):
+ mails = super().create(values_list)
+ for mail in mails:
message_vals = {}
- email_values = this._get_email_values()
- for fieldname in ["email_to", "email_cc", "email_bcc"]:
- emails = email_values.get(fieldname, [])
- if not emails and not this[fieldname]:
- continue
- message_vals[fieldname] = this._append_email(fieldname, emails)
+ email_values = mail._get_email_values()
+ for fname in ("email_to", "email_cc", "email_bcc"):
+ emails = email_values.get(fname, [])
+ if emails:
+ message_vals[fname] = mail._append_email(fname, emails)
if message_vals:
- this.mail_message_id.write(message_vals)
- return super()._send(
- auto_commit=auto_commit,
- raise_exception=raise_exception,
- smtp_session=smtp_session,
- )
+ mail.mail_message_id.write(message_vals)
+ return mails
def _get_email_values(self):
+ """Return normalized email lists for to, cc and bcc.
+ - Composer send: recipient_cc_ids/recipient_bcc_ids are set on mail.mail
+ at create time by the composer's _prepare_mail_values.
+ - Template send (send_mail): email_to, email_cc, email_bcc
+ are written directly to mail.mail at create time from the rendered
+ template values.
+ """
self.ensure_one()
- partners_to = (
- self.recipient_ids - self.recipient_cc_ids - self.recipient_bcc_ids
- )
+ cc_bcc = self.recipient_cc_ids + self.recipient_bcc_ids
+ to_partners = self.recipient_ids - cc_bcc
return {
- "email_to": list_emails(partners_to),
- "email_cc": list_emails(self.recipient_cc_ids),
- "email_bcc": list_emails(self.recipient_bcc_ids),
+ "email_to": list_emails(to_partners)
+ or tools.mail.email_normalize_all(self.email_to or ""),
+ "email_cc": list_emails(self.recipient_cc_ids)
+ or tools.mail.email_normalize_all(self.email_cc or ""),
+ "email_bcc": list_emails(self.recipient_bcc_ids)
+ or tools.mail.email_normalize_all(self.email_bcc or ""),
}
def _append_email(self, fieldname, emails):
- """Do not override existing emails."""
+ """Merge new emails with any already stored on mail.message."""
self.ensure_one()
- message = self.mail_message_id
- preset_emails = self[fieldname]
- if preset_emails:
- emails += tools.email_normalize_all(preset_emails)
- existing = message[fieldname]
+ existing = self.mail_message_id[fieldname]
if existing:
emails += existing.split(",")
- return ",".join(list(set(emails)))
+ return ",".join(dict.fromkeys(filter(None, emails)))
diff --git a/mail_visible_email/models/mail_thread.py b/mail_visible_email/models/mail_thread.py
index aa1238124..43f8df124 100644
--- a/mail_visible_email/models/mail_thread.py
+++ b/mail_visible_email/models/mail_thread.py
@@ -1,8 +1,10 @@
-# Copyright 2025 Therp BV .
+# Copyright 2025 Therp BV .
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import api, models
+_VISIBLE_EMAIL_FIELDS = {"email_to", "email_cc", "email_bcc"}
+
class MailThread(models.AbstractModel):
_inherit = "mail.thread"
@@ -19,3 +21,12 @@ def _message_route_process(self, message, message_dict, routes):
message_dict["email_to"] = message_dict.get("to", False)
message_dict["email_cc"] = message_dict.get("cc", False)
return super()._message_route_process(message, message_dict, routes)
+
+ def _get_message_create_ignore_field_names(self):
+ return super()._get_message_create_ignore_field_names() | _VISIBLE_EMAIL_FIELDS
+
+ def _message_post_after_hook(self, message, msg_values):
+ vals = {k: msg_values[k] for k in _VISIBLE_EMAIL_FIELDS if msg_values.get(k)}
+ if vals:
+ message.write(vals)
+ return super()._message_post_after_hook(message, msg_values)
diff --git a/mail_visible_email/readme/CONFIGURE.md b/mail_visible_email/readme/CONFIGURE.md
index 7d2c7b671..c233bc2c8 100644
--- a/mail_visible_email/readme/CONFIGURE.md
+++ b/mail_visible_email/readme/CONFIGURE.md
@@ -1 +1,2 @@
This module has no separate configuration options.
+
\ No newline at end of file
diff --git a/mail_visible_email/readme/CONTRIBUTORS.md b/mail_visible_email/readme/CONTRIBUTORS.md
index 676028b8e..a184afa07 100644
--- a/mail_visible_email/readme/CONTRIBUTORS.md
+++ b/mail_visible_email/readme/CONTRIBUTORS.md
@@ -1,3 +1,4 @@
- [Therp BV](https://therp.nl):
> - Ronald Portier \<\>
+
\ No newline at end of file
diff --git a/mail_visible_email/readme/DESCRIPTION.md b/mail_visible_email/readme/DESCRIPTION.md
index 292f1f584..284aa9e56 100644
--- a/mail_visible_email/readme/DESCRIPTION.md
+++ b/mail_visible_email/readme/DESCRIPTION.md
@@ -1,25 +1,21 @@
-In Odoo mails it is often unclear who where the other recipients of
-mails received, or what the actual mail addresses where of mails sent.
+In Odoo mails it is often unclear who were the other recipients of mails
+received, or what the actual mail addresses were of mails sent.
-This module adds the following fields to mail_message: - email_to -
-email_cc - email_bcc
+This module adds the following fields to mail_message:
-For both incoming and outgoing mails, the actual to and cc headers from
-the mails will be stored here. For outgoing mails also the bcc header.
+- email_to
+- email_cc
+- email_bcc
+
+For both incoming and outgoing mails, the actual to and cc headers
+from the mails will be stored here. For outgoing mails also the bcc
+header.
In case we receive a mail because we received it on an address that was
in the bcc of the email sent, the address will actually be shown on the
-email_to field. This is because there is no bcc header in an incoming
-mail, we will have the address in the Delivered-To header.
+email_to field. This is because there is no bcc header in an incoming mail,
+we will have the address in the Delivered-To header.
Note that we will only store the unadorned email (without partner name),
as this will be the relevant part, and the partner names are visible on
other fields.
-
-For technical reasons this module depends on mail_composer_cc_bcc:
-
-- We need the email_bcc field on mail.mail;
-- The module mail_composer_bcc fundamentally changes the workings of the
- \_send() method on mail.mail. In order not to have to support both
- methods depending on whether mail_composer_bcc is installed or not, it
- is easier to just make sure it is installed.
diff --git a/mail_visible_email/static/description/index.html b/mail_visible_email/static/description/index.html
index 42331f0ad..f28cd7f74 100644
--- a/mail_visible_email/static/description/index.html
+++ b/mail_visible_email/static/description/index.html
@@ -369,11 +369,15 @@ Make emails for to, cc and bcc visible
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:53373ba10ebe61d982a5d796725296eee83924dc9d4d6aa7e54e0ec9839f59a5
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
-

-In Odoo mails it is often unclear who where the other recipients of
-mails received, or what the actual mail addresses where of mails sent.
-This module adds the following fields to mail_message: - email_to -
-email_cc - email_bcc
+

+In Odoo mails it is often unclear who were the other recipients of mails
+received, or what the actual mail addresses were of mails sent.
+This module adds the following fields to mail_message:
+
+- email_to
+- email_cc
+- email_bcc
+
For both incoming and outgoing mails, the actual to and cc headers from
the mails will be stored here. For outgoing mails also the bcc header.
In case we receive a mail because we received it on an address that was
@@ -383,14 +387,6 @@
Make emails for to, cc and bcc visible
Note that we will only store the unadorned email (without partner name),
as this will be the relevant part, and the partner names are visible on
other fields.
-For technical reasons this module depends on mail_composer_cc_bcc:
-
-- We need the email_bcc field on mail.mail;
-- The module mail_composer_bcc fundamentally changes the workings of
-the _send() method on mail.mail. In order not to have to support
-both methods depending on whether mail_composer_bcc is installed or
-not, it is easier to just make sure it is installed.
-
Important
This is an alpha version, the data model and design can change at any time without warning.
@@ -416,10 +412,10 @@
-
Bugs are tracked on GitHub Issues.
+
Bugs are tracked on GitHub Issues.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
-feedback.
+
feedback.
Do not contact contributors directly about support or help with technical issues.
diff --git a/mail_visible_email/tests/test_mail_receive.py b/mail_visible_email/tests/test_mail_receive.py
index 9ca9eb2ff..e24defe4f 100644
--- a/mail_visible_email/tests/test_mail_receive.py
+++ b/mail_visible_email/tests/test_mail_receive.py
@@ -15,14 +15,19 @@ def setUpClass(cls):
cls.Partner = cls.env["res.partner"]
cls.MailThread = cls.env["mail.thread"]
cls.Message = cls.env["mail.message"]
-
- ICP = cls.env["ir.config_parameter"].sudo()
- ICP.set_param("mail.catchall.domain", "fsf.org")
+ cls.alias_domain = cls.env["mail.alias.domain"].create(
+ {
+ "name": "fsf.org",
+ "catchall_alias": "catchall",
+ }
+ )
+ cls.env.company.alias_domain_id = cls.alias_domain
cls.partner_model = cls.env["ir.model"].search([("model", "=", "res.partner")])
cls.mail_alias_test = cls.Alias.create(
{
"alias_name": "test_alias",
+ "alias_domain_id": cls.alias_domain.id,
"alias_model_id": cls.partner_model.id,
"alias_defaults": "{'name': 'Test Alias', 'is_company': True}",
}
@@ -43,11 +48,9 @@ def test_incoming_email(self):
msg_id="",
),
)
- # We should now have a partner with the name 'Test Alias'.
self.assertTrue(thread_id)
partner = self.Partner.browse(thread_id)
self.assertEqual(partner.name, "Test Alias")
- # We should have a mail message referring to this partner.
message = self.Message.search(
[
("model", "=", partner._name),
@@ -56,6 +59,5 @@ def test_incoming_email(self):
)
self.assertTrue(message)
self.assertEqual(message.email_to, "test_alias@fsf.org")
- # Use In to be independent of ordering and separator.
self.assertIn("anybody@fsf.org", message.email_cc)
self.assertIn("nobody@fsf.org", message.email_cc)
diff --git a/mail_visible_email/tests/test_mail_send.py b/mail_visible_email/tests/test_mail_send.py
index 1f5698622..182fd0189 100644
--- a/mail_visible_email/tests/test_mail_send.py
+++ b/mail_visible_email/tests/test_mail_send.py
@@ -1,20 +1,19 @@
# Copyright 2025 Therp BV .
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
-from odoo.tests import Form
+from odoo.tests import Form, tagged
-from odoo.addons.mail.tests.test_mail_composer import TestMailComposer
+from odoo.addons.mail.tests.common import MailCommon
-class TestMailSend(TestMailComposer):
+@tagged("-at_install", "post_install")
+class TestMailSend(MailCommon):
@classmethod
def setUpClass(cls):
- # Based on example in mail_composer_cc_bcc.
super().setUpClass()
- env = cls.env
- cls.partner = env.ref("base.res_partner_address_31")
- cls.partner_cc = env.ref("base.partner_demo")
- cls.partner_cc2 = env.ref("base.partner_demo_portal")
- cls.partner_bcc = env.ref("base.res_partner_main1")
+ cls.partner = cls.env.ref("base.res_partner_address_31")
+ cls.partner_cc = cls.env.ref("base.partner_demo")
+ cls.partner_cc2 = cls.env.ref("base.partner_demo_portal")
+ cls.partner_bcc = cls.env.ref("base.res_partner_main1")
cls.mail_template = cls._create_template(
"res.partner",
template_values={
@@ -26,44 +25,35 @@ def setUpClass(cls):
)
def open_mail_composer_form(self):
- # Based on example in mail_composer_cc_bcc.
- # Use form to populate data
ctx = {
"default_partner_ids": self.partner.ids,
"default_model": self.partner._name,
- "default_res_id": self.partner.id,
- # to ensure consistent test results even when mail_post_defer is installed
+ "default_res_ids": self.partner.ids,
"mail_notify_force_send": True,
}
form = Form(self.env["mail.compose.message"].with_context(**ctx))
form.body = "Hello
"
return form
- def test_email_to_cc(self):
+ def test_email_to_cc_bcc_via_composer(self):
+ """Sending via composer populates email_to, cc, bcc on mail.message."""
form = self.open_mail_composer_form()
composer = form.save()
- # Use object to update Many2many fields (form can't do like this)
- composer.partner_cc_ids = self.partner_cc
- composer.partner_cc_ids |= self.partner_cc2
+ composer.partner_cc_ids = self.partner_cc | self.partner_cc2
composer.partner_bcc_ids = self.partner_bcc
with self.mock_mail_gateway():
composer._action_send_mail()
- # Verify recipients of mail.message
message = self.partner.message_ids[0]
- self.assertEqual(message.email_to, self.partner.email)
+ self.assertEqual(message.email_to, self.partner.email) # add this
self.assertIn(self.partner_cc.email, message.email_cc)
self.assertIn(self.partner_cc2.email, message.email_cc)
self.assertEqual(message.email_bcc, self.partner_bcc.email)
- def test_email_to(self):
- """Test when using email_to directly."""
+ def test_email_to_cc_via_template(self):
+ """Sending via template populates email_to and email_cc on mail.message."""
Mail = self.env["mail.mail"]
mail_id = self.mail_template.send_mail(self.partner.id, force_send=True)
- self.assertTrue(mail_id)
mail = Mail.browse(mail_id)
message = mail.mail_message_id
- self.assertTrue(message)
self.assertEqual(message.email_to, self.partner.email)
self.assertEqual(message.email_cc, self.partner_cc.email)
- # Odoo ignores the email_bcc field in the template!
- # self.assertEqual(message.email_bcc, self.partner_bcc.email)