Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 122 additions & 0 deletions mail_user_signature_mass_edit/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
=============================
Mail User Signature Mass Edit
=============================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:d357b4ba6133d43b6b13b074617e6df2d2aeb9500d1856e3a75728bf85b16690
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |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%2Fmail-lightgray.png?logo=github
:target: https://github.com/OCA/mail/tree/18.0/mail_user_signature_mass_edit
:alt: OCA/mail
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/mail-18-0/mail-18-0-mail_user_signature_mass_edit
: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/mail&target_branch=18.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module lets administrators update users email signatures in bulk.

Administrators define one HTML signature template on a mass edit record,
select a company, and confirm the operation. The template is rendered
for each matching internal user.

**Table of contents**

.. contents::
:local:

Usage
=====

1. Give the user the *Signature Mass Edit* access right in Email
Marketing.

2. Go to *Email Marketing > Configuration > Signature Mass Edits*.

Administrators can also access the same records from *Settings >
Users & Companies > Signature Mass Edits*.

3. Create a new record.

4. Select the company whose internal users must be updated.

5. Optionally select one or more groups to restrict the update to users
belonging to those groups. Only internal users are updated.

6. Enter the HTML signature template in the *Source* tab. Use the
*Preview* tab to check the rendered signature.

7. Click *Confirm*.

The signature template is rendered on the ``res.users`` model. For
example:

.. code:: html

<p>
<strong>{{ object.name }}</strong><br/>
{{ object.company_id.name }}<br/>
{{ object.email or '' }}
</p>

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/mail/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 <https://github.com/OCA/mail/issues/new?body=module:%20mail_user_signature_mass_edit%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* ACSONE SA/NV

Contributors
------------

- Souheil Bejaoui <souheil.bejaoui@acsone.eu>

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-sbejaoui| image:: https://github.com/sbejaoui.png?size=40px
:target: https://github.com/sbejaoui
:alt: sbejaoui

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-sbejaoui|

This module is part of the `OCA/mail <https://github.com/OCA/mail/tree/18.0/mail_user_signature_mass_edit>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions mail_user_signature_mass_edit/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
20 changes: 20 additions & 0 deletions mail_user_signature_mass_edit/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright 2026 ACSONE SA/NV
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

{
"name": "Mail User Signature Mass Edit",
"summary": "Mass-edit user email signatures from an HTML template, "
"rendered per user and filtered by company.",
"category": "Mail",
"version": "18.0.1.0.0",
"license": "AGPL-3",
"author": "ACSONE SA/NV,Odoo Community Association (OCA)",
"maintainers": ["sbejaoui"],
"website": "https://github.com/OCA/mail",
"depends": ["mail", "mass_mailing"],
"data": [
"security/res_groups.xml",
"security/signature_mass_edit.xml",
"views/signature_mass_edit_views.xml",
],
}
4 changes: 4 additions & 0 deletions mail_user_signature_mass_edit/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright 2026 ACSONE SA/NV
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from . import signature_mass_edit
134 changes: 134 additions & 0 deletions mail_user_signature_mass_edit/models/signature_mass_edit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# Copyright 2026 ACSONE SA/NV
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import api, fields, models
from odoo.exceptions import UserError


class SignatureMassEdit(models.Model):
_name = "signature.mass.edit"
_description = "Signature Mass Edit"
_order = "id desc"

signature = fields.Html(string="Signature Template", required=True)
company_id = fields.Many2one(
comodel_name="res.company",
string="Company",
required=True,
default=lambda self: self.env.company,
)
group_ids = fields.Many2many(
comodel_name="res.groups",
string="Groups",
help="Apply the signature only to users belonging to at least one of "
"these groups. Leave empty to apply it to all company users.",
)
state = fields.Selection(
selection=[("draft", "Draft"), ("done", "Done")],
string="Status",
required=True,
readonly=True,
copy=False,
default="draft",
)
user_count = fields.Integer(string="Users", compute="_compute_user_count")
processed_user_count = fields.Integer(
string="Processed Users", readonly=True, copy=False
)

@api.depends("company_id", "group_ids")
def _compute_display_name(self):
for record in self:
if not record.company_id:
record.display_name = self.env._("Signature Mass Edit")
continue
display_name = self.env._(
"Signature Mass Edit - %(company)s", company=record.company_id.name
)
if record.group_ids:
group_names = ", ".join(record.group_ids.mapped("display_name"))
display_name = self.env._(
"%(display_name)s (%(groups)s)",
display_name=display_name,
groups=group_names,
)
record.display_name = display_name

@api.depends("company_id", "group_ids")
def _compute_user_count(self):
for record in self:
record.user_count = len(record._get_target_users())

def action_confirm(self):
for record in self:
record._check_can_confirm()
record._process_signature_mass_edit()
return True

def action_view_users(self):
self.ensure_one()
return {
"type": "ir.actions.act_window",
"name": self.env._("Users"),
"res_model": "res.users",
"view_mode": "list,form",
"views": [
(False, "list"),
(self.env.ref("base.view_users_form").id, "form"),
],
"domain": self._get_target_users_domain(),
}

def action_reset_to_draft(self):
self.write({"state": "draft"})
return True

def _check_can_confirm(self):
self.ensure_one()
if self.state != "draft":
raise UserError(
self.env._("Only draft signature mass edits can be confirmed.")
)

def _get_target_users_domain(self):
self.ensure_one()
internal_user_group = self.env.ref("base.group_user")
domain = [
("active", "=", True),
("company_ids", "in", self.company_id.id),
("groups_id", "in", internal_user_group.id),
]
if self.group_ids:
domain.append(("groups_id", "in", self.group_ids.ids))
return domain

def _get_target_users(self):
self.ensure_one()
return self.env["res.users"].sudo().search(self._get_target_users_domain())

def _process_signature_mass_edit(self):
self.ensure_one()
users = self._get_target_users()
for user in users:
self._process_user_signature(user)
self._mark_signature_mass_edit_done(len(users))

def _process_user_signature(self, user):
self.ensure_one()
user.ensure_one()
rendered_signatures = (
self.env["mail.render.mixin"]
.sudo()
._render_template(
self.signature,
"res.users",
user.ids,
engine="inline_template",
options={"post_process": True},
)
)
user.sudo().write({"signature": rendered_signatures.get(user.id, "")})

def _mark_signature_mass_edit_done(self, processed_count):
self.ensure_one()
self.write({"processed_user_count": processed_count, "state": "done"})
3 changes: 3 additions & 0 deletions mail_user_signature_mass_edit/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"
1 change: 1 addition & 0 deletions mail_user_signature_mass_edit/readme/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Souheil Bejaoui \<<souheil.bejaoui@acsone.eu>\>
5 changes: 5 additions & 0 deletions mail_user_signature_mass_edit/readme/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
This module lets administrators update users email signatures in bulk.

Administrators define one HTML signature template on a mass edit record, select a
company, and confirm the operation. The template is rendered for each matching
internal user.
22 changes: 22 additions & 0 deletions mail_user_signature_mass_edit/readme/USAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
1. Give the user the *Signature Mass Edit* access right in Email Marketing.
2. Go to *Email Marketing > Configuration > Signature Mass Edits*.

Administrators can also access the same records from
*Settings > Users & Companies > Signature Mass Edits*.
3. Create a new record.
4. Select the company whose internal users must be updated.
5. Optionally select one or more groups to restrict the update to users belonging
to those groups. Only internal users are updated.
6. Enter the HTML signature template in the *Source* tab. Use the *Preview*
tab to check the rendered signature.
7. Click *Confirm*.

The signature template is rendered on the `res.users` model. For example:

```html
<p>
<strong>{{ object.name }}</strong><br/>
{{ object.company_id.name }}<br/>
{{ object.email or '' }}
</p>
```
16 changes: 16 additions & 0 deletions mail_user_signature_mass_edit/security/res_groups.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!-- Copyright 2026 ACSONE SA/NV
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="group_signature_mass_edit" model="res.groups">
<field name="name">Signature Mass Edit</field>
<field
name="category_id"
ref="base.module_category_marketing_email_marketing"
/>
<field
name="implied_ids"
eval="[(4, ref('mass_mailing.group_mass_mailing_user'))]"
/>
</record>
</odoo>
34 changes: 34 additions & 0 deletions mail_user_signature_mass_edit/security/signature_mass_edit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!-- Copyright 2026 ACSONE SA/NV
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="access_signature_mass_edit_user" model="ir.model.access">
<field name="name">signature.mass.edit user</field>
<field name="model_id" ref="model_signature_mass_edit" />
<field name="group_id" ref="group_signature_mass_edit" />
<field name="perm_read" eval="1" />
<field name="perm_write" eval="1" />
<field name="perm_create" eval="1" />
<field name="perm_unlink" eval="1" />
</record>

<record id="access_signature_mass_edit_system" model="ir.model.access">
<field name="name">signature.mass.edit system</field>
<field name="model_id" ref="model_signature_mass_edit" />
<field name="group_id" ref="base.group_system" />
<field name="perm_read" eval="1" />
<field name="perm_write" eval="1" />
<field name="perm_create" eval="1" />
<field name="perm_unlink" eval="1" />
</record>

<record id="signature_mass_edit_rule_multi_company" model="ir.rule">
<field name="name">Signature Mass Edit: multi-company</field>
<field name="model_id" ref="model_signature_mass_edit" />
<field name="domain_force">[("company_id", "in", company_ids)]</field>
<field
name="groups"
eval="[(4, ref('base.group_system')), (4, ref('group_signature_mass_edit'))]"
/>
</record>
</odoo>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading