Skip to content

Commit 3fd87f0

Browse files
committed
[ADD] New module microsoft_outlook_multi_client
1 parent 4de56ec commit 3fd87f0

17 files changed

Lines changed: 815 additions & 0 deletions

File tree

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
.. image:: https://odoo-community.org/readme-banner-image
2+
:target: https://odoo-community.org/get-involved?utm_source=readme
3+
:alt: Odoo Community Association
4+
5+
=================================
6+
Microsoft Outlook Multiple CLient
7+
=================================
8+
9+
..
10+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
11+
!! This file is generated by oca-gen-addon-readme !!
12+
!! changes will be overwritten. !!
13+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
14+
!! source digest: sha256:be7d5ec85fb784ac58326e6dd4074d751f779676dfd9f05fe045435b71399353
15+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
16+
17+
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
18+
:target: https://odoo-community.org/page/development-status
19+
:alt: Beta
20+
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
21+
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
22+
:alt: License: AGPL-3
23+
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsocial-lightgray.png?logo=github
24+
:target: https://github.com/OCA/social/tree/14.0/microsoft_outlook_multi_client
25+
:alt: OCA/social
26+
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
27+
:target: https://translation.odoo-community.org/projects/social-14-0/social-14-0-microsoft_outlook_multi_client
28+
:alt: Translate me on Weblate
29+
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
30+
:target: https://runboat.odoo-community.org/builds?repo=OCA/social&target_branch=14.0
31+
:alt: Try me on Runboat
32+
33+
|badge1| |badge2| |badge3| |badge4| |badge5|
34+
35+
By default Odoo only supports a single Outlook connection in the
36+
outgoing mail servers, because the connection information is set
37+
in the system parameters, instead of on the mail server itself.
38+
39+
This module allows you to configure a mail server with the
40+
connection info on the server itself, thereby enabling to
41+
use a multitude of Outlook accounts in multiple domains.
42+
43+
**Table of contents**
44+
45+
.. contents::
46+
:local:
47+
48+
Configuration
49+
=============
50+
51+
* Follow the normal Odoo configuration on how to get a client ID and client Secret
52+
on Microsoft Azure for the Outlook client;
53+
* Create a new mail server, set it to use Outlook, instead of using
54+
the buttons to define system parameters, fill in the ID and secret
55+
directly.
56+
57+
Bug Tracker
58+
===========
59+
60+
Bugs are tracked on `GitHub Issues <https://github.com/OCA/social/issues>`_.
61+
In case of trouble, please check there if your issue has already been reported.
62+
If you spotted it first, help us to smash it by providing a detailed and welcomed
63+
`feedback <https://github.com/OCA/social/issues/new?body=module:%20microsoft_outlook_multi_client%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
64+
65+
Do not contact contributors directly about support or help with technical issues.
66+
67+
Credits
68+
=======
69+
70+
Authors
71+
~~~~~~~
72+
73+
* Therp BV
74+
75+
Contributors
76+
~~~~~~~~~~~~
77+
78+
* `Therp BV <https://therp.nl>`_:
79+
80+
* Ronald Portier
81+
82+
Maintainers
83+
~~~~~~~~~~~
84+
85+
This module is maintained by the OCA.
86+
87+
.. image:: https://odoo-community.org/logo.png
88+
:alt: Odoo Community Association
89+
:target: https://odoo-community.org
90+
91+
OCA, or the Odoo Community Association, is a nonprofit organization whose
92+
mission is to support the collaborative development of Odoo features and
93+
promote its widespread use.
94+
95+
This module is part of the `OCA/social <https://github.com/OCA/social/tree/14.0/microsoft_outlook_multi_client>`_ project on GitHub.
96+
97+
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
2+
3+
from . import models
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright 2026 Therp BV <https://therp.nl>.
2+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
3+
{
4+
"name": "Microsoft Outlook Multiple CLient",
5+
"version": "14.0.1.0.0",
6+
"author": "Therp BV, Odoo Community Association (OCA)",
7+
"license": "AGPL-3",
8+
"category": "Tools",
9+
"website": "https://github.com/OCA/social",
10+
"depends": [
11+
"microsoft_outlook",
12+
],
13+
"data": ["views/ir_mail_server_views.xml"],
14+
"installable": True,
15+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
2+
3+
from . import ir_config_parameter
4+
from . import ir_mail_server
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Copyright 2026 Therp BV <https://therp.nl>.
2+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
3+
"""Patch get_param for microsoft client_id and client_secret.
4+
5+
To avoid having to re-implement a lot of the standard functions that assume
6+
client_id and client_secret are defined in ir.config_parameter, we will patch get_param
7+
to return these values if they have already been set in the context.
8+
9+
Actually we will do this in a way that might have broader application, but for now we
10+
will fill those with the values in ir.mail_server if set.
11+
"""
12+
from odoo import api, models
13+
14+
15+
class IrConfigParameter(models.Model):
16+
_inherit = "ir.config_parameter"
17+
18+
@api.model
19+
def get_param(self, key, default=False):
20+
"""Retrieve the value for a given key.
21+
22+
Override to return value from context, if set there. This is to help
23+
modules to override functions that expect a value from a system parameter
24+
but already have the value set in some other way.
25+
"""
26+
preset_key = f"preset_{key}"
27+
preset_value = self.env.context.get(preset_key, False)
28+
if preset_value:
29+
return preset_value
30+
return super().get_param(key, default=default)
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# Copyright 2026 Therp BV <https://therp.nl>.
2+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
3+
"""We override the standard functionality that only supports one Outlook connection.
4+
5+
To support each outgoing mail server to have its own connection to Outlook,
6+
we provide for the connection parameters to be part of the server definition itself.
7+
8+
If there is no connection information in the server record, we will still fall back to
9+
the default configuration using system parameters.
10+
"""
11+
from odoo import api, fields, models
12+
13+
14+
class IrMailServer(models.Model):
15+
_inherit = "ir.mail_server"
16+
17+
microsoft_outlook_client_identifier = fields.Char(
18+
"Outlook Client Id",
19+
help="Specific client_id for this server",
20+
)
21+
microsoft_outlook_client_secret = fields.Char(
22+
"Outlook Client Secret",
23+
help="Specific client_secret for this server",
24+
)
25+
26+
@api.depends(
27+
"use_microsoft_outlook_service",
28+
"microsoft_outlook_client_identifier",
29+
"microsoft_outlook_client_secret",
30+
)
31+
def _compute_is_microsoft_outlook_configured(self):
32+
"""Check using this record, else fallback to default.
33+
34+
The field microsoft_outlook_configured should be set to
35+
true when client identifier and secret have been set. The
36+
values for these fields must be given by the person who
37+
registered the Odoo tenant in the Azure directory.
38+
"""
39+
# Cannot depend on trick to override get_param as original
40+
# method might fail on Singleton error.
41+
for this in self:
42+
if not this.use_microsoft_outlook_service:
43+
# The super method also returns True for any record, whether configured
44+
# to use Outlook or not, if system parameters for outlook have been set.
45+
# This is pure madness, so we override this.
46+
self.is_microsoft_outlook_configured = False
47+
elif this._has_id_and_secret():
48+
self.is_microsoft_outlook_configured = True
49+
else:
50+
super(IrMailServer, this)._compute_is_microsoft_outlook_configured()
51+
52+
@api.depends("is_microsoft_outlook_configured")
53+
def _compute_outlook_uri(self):
54+
"""The outlook_uri contains the information that is needed activate the client.
55+
56+
After client id and secret have been set, the user must click on the
57+
"Connect Your Outlook account" button. This will open a Microsoft
58+
webpage containing the needed information. Microsoft will then
59+
generate an authorization token and call back a controller that sets
60+
this token, and a refresh token and expiration on the server record.
61+
"""
62+
record = self._get_preset_record() if self._has_id_and_secret() else self
63+
return super(IrMailServer, record)._compute_outlook_uri()
64+
65+
def _fetch_outlook_refresh_token(self, authorization_code):
66+
record = self._get_preset_record() if self._has_id_and_secret() else self
67+
return super(IrMailServer, record).__fetch_outlook_refresh_token(
68+
authorization_code
69+
)
70+
71+
def _smtp_login(self, connection, smtp_user, smtp_password):
72+
record = self._get_preset_record() if self._has_id_and_secret() else self
73+
return super(IrMailServer, record)._smtp_login(
74+
connection, smtp_user, smtp_password
75+
)
76+
77+
def _has_id_and_secret(self):
78+
"""Check whether called on record with specific client ID and Secret."""
79+
if (
80+
len(self) == 1
81+
and self.microsoft_outlook_client_identifier
82+
and self.microsoft_outlook_client_secret
83+
):
84+
return True
85+
return False
86+
87+
def _get_preset_record(self):
88+
"""Return record with context filled with preset client id and secret."""
89+
self.ensure_one()
90+
return self.with_context(
91+
preset_microsoft_outlook_client_id=self.microsoft_outlook_client_identifier,
92+
preset_microsoft_outlook_client_secret=self.microsoft_outlook_client_secret,
93+
)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
* Follow the normal Odoo configuration on how to get a client ID and client Secret
2+
on Microsoft Azure for the Outlook client;
3+
* Create a new mail server, set it to use Outlook, instead of using
4+
the buttons to define system parameters, fill in the ID and secret
5+
directly.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
* `Therp BV <https://therp.nl>`_:
2+
3+
* Ronald Portier
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
By default Odoo only supports a single Outlook connection in the
2+
outgoing mail servers, because the connection information is set
3+
in the system parameters, instead of on the mail server itself.
4+
5+
This module allows you to configure a mail server with the
6+
connection info on the server itself, thereby enabling to
7+
use a multitude of Outlook accounts in multiple domains.
9.23 KB
Loading

0 commit comments

Comments
 (0)