Skip to content

Commit 82e92fb

Browse files
committed
[IMP] edi_mail_import_oca: Move logic to backend
1 parent 12991dd commit 82e92fb

File tree

13 files changed

+287
-177
lines changed

13 files changed

+287
-177
lines changed

edi_mail_import_oca/README.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,23 @@ however, there is an standard way to receive files that is emails.
4949
This module tries to offer a way to reuse EDI and mail interface in
5050
order to handle everything.
5151

52+
Configuration
53+
=============
54+
55+
For handling this incoming data, you just need to create a Backend and
56+
define the alias.
57+
58+
The alias will be used to detect input mails. If the system detects an
59+
email, it will take all the exchange types related to the backend and
60+
review by exchange_filename if the pattern is filled. Also, if the
61+
backend has the ``full_mail_exchange_type_id`` field filled, it will
62+
store the full dict.
63+
64+
If not exchange type can be found, a UserError and a bounce email are
65+
sent.
66+
67+
Processing will be handled in the standard way.
68+
5269
Bug Tracker
5370
===========
5471

edi_mail_import_oca/__manifest__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"website": "https://github.com/OCA/edi-framework",
1111
"depends": ["edi_core_oca", "mail"],
1212
"data": [
13-
"views/edi_exchange_type.xml",
13+
"views/edi_backend.xml",
1414
],
1515
"demo": [],
1616
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
from . import edi_exchange_type
1+
from . import edi_backend
22
from . import edi_exchange_record
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Copyright 2026 Dixmit
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
import ast
4+
5+
from odoo import fields, models
6+
7+
8+
class EdiBackend(models.Model):
9+
_name = "edi.backend"
10+
_inherit = ["edi.backend", "mail.alias.mixin"]
11+
12+
full_mail_exchange_type_id = fields.Many2one(
13+
"edi.exchange.type",
14+
)
15+
16+
def _alias_get_creation_values(self):
17+
values = super()._alias_get_creation_values()
18+
values["alias_model_id"] = self.env["ir.model"]._get("edi.exchange.record").id
19+
if self.id:
20+
values["alias_defaults"] = defaults = ast.literal_eval(
21+
self.alias_defaults or "{}"
22+
)
23+
defaults["backend_id"] = self.id
24+
return values
25+
26+
def _mail_exchange_type_pending_input_domain(self):
27+
"""Domain for retrieving input exchange types for emails."""
28+
return [
29+
("backend_type_id", "=", self.backend_type_id.id),
30+
("direction", "=", "input"),
31+
"|",
32+
("backend_id", "=", False),
33+
("backend_id", "=", self.id),
34+
("exchange_filename_pattern", "!=", False),
35+
]

edi_mail_import_oca/models/edi_exchange_record.py

Lines changed: 58 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import re
88

99
from odoo import api, models
10+
from odoo.exceptions import UserError
1011

1112
_logger = logging.getLogger(__name__)
1213

@@ -16,42 +17,69 @@ class EdiExchangeRecord(models.Model):
1617

1718
@api.model
1819
def message_new(self, msg_dict, custom_values=None):
20+
backend_id = custom_values.get("backend_id") if custom_values else None
21+
if backend_id:
22+
backend = self.env["edi.backend"].browse(backend_id)
23+
content = False
24+
filename = False
25+
if (
26+
not custom_values.get("type_id")
27+
and not backend.full_mail_exchange_type_id
28+
):
29+
types = self.env["edi.exchange.type"].search(
30+
backend._mail_exchange_type_pending_input_domain()
31+
)
32+
for exchange_type in types:
33+
for attachment in msg_dict.get("attachments", []):
34+
if re.match(
35+
exchange_type.exchange_filename_pattern,
36+
attachment.fname,
37+
re.IGNORECASE,
38+
):
39+
content = self._process_email_attachment(attachment)
40+
filename = attachment.fname
41+
custom_values["type_id"] = exchange_type.id
42+
break
43+
if content:
44+
custom_values["type_id"] = exchange_type.id
45+
break
46+
else:
47+
if backend.full_mail_exchange_type_id:
48+
custom_values["type_id"] = backend.full_mail_exchange_type_id.id
49+
new_message_dict = msg_dict.copy()
50+
attachments = new_message_dict.pop("attachments", [])
51+
new_message_dict["attachments"] = []
52+
for attachment in attachments:
53+
new_message_dict["attachments"].append(
54+
{
55+
"info": attachment.info,
56+
"data": self._process_email_attachment(attachment),
57+
"fname": attachment.fname,
58+
}
59+
)
60+
content = json.dumps(new_message_dict)
61+
filename = "email_message.json"
62+
if not custom_values or "type_id" not in custom_values:
63+
_logger.warning(
64+
"No exchange type found for incoming email with subject '%s'",
65+
msg_dict.get("subject"),
66+
)
67+
raise UserError(
68+
self.env._(
69+
"No exchange type found for incoming email with subject '%s'",
70+
msg_dict.get("subject"),
71+
)
72+
)
1973
record = super().message_new(
2074
msg_dict,
2175
custom_values=custom_values,
2276
)
23-
if record.type_id.mail_as_attachment:
24-
new_message_dict = msg_dict.copy()
25-
attachments = new_message_dict.pop("attachments", [])
26-
new_message_dict["attachments"] = []
27-
for attachment in attachments:
28-
new_message_dict["attachments"].append(
29-
{
30-
"info": attachment.info,
31-
"data": self._process_email_attachment(attachment),
32-
"fname": attachment.fname,
33-
}
34-
)
35-
record._set_file_content(json.dumps(new_message_dict))
36-
record.edi_exchange_state = "input_received"
37-
else:
38-
content = False
39-
filename = False
40-
for attachment in msg_dict.get("attachments", []):
41-
if re.match(
42-
record.type_id.exchange_filename_pattern or ".*",
43-
attachment.fname,
44-
re.IGNORECASE,
45-
):
46-
content = self._process_email_attachment(attachment)
47-
filename = attachment.fname
48-
break
49-
if content:
50-
record._set_file_content(content)
51-
record.exchange_filename = filename
52-
record.edi_exchange_state = "input_received"
77+
record._set_file_content(content)
78+
record.exchange_filename = filename
79+
record.edi_exchange_state = "input_received"
5380
return record
5481

82+
@api.model
5583
def _process_email_attachment(self, attachment):
5684
"""Process email attachment to be stored as file content."""
5785
data = attachment[1]

edi_mail_import_oca/models/edi_exchange_type.py

Lines changed: 0 additions & 36 deletions
This file was deleted.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
For handling this incoming data, you just need to create a Backend and define the alias.
2+
3+
The alias will be used to detect input mails.
4+
If the system detects an email, it will take all the exchange types related to the backend and review by exchange_filename if the pattern is filled.
5+
Also, if the backend has the `full_mail_exchange_type_id` field filled, it will store the full dict.
6+
7+
If not exchange type can be found, a UserError and a bounce email are sent.
8+
9+
Processing will be handled in the standard way.

edi_mail_import_oca/static/description/index.html

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -381,11 +381,12 @@ <h1>Edi Mail Import Oca</h1>
381381
<div class="contents local topic" id="contents">
382382
<ul class="simple">
383383
<li><a class="reference internal" href="#use-cases-context" id="toc-entry-1">Use Cases / Context</a></li>
384-
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-2">Bug Tracker</a></li>
385-
<li><a class="reference internal" href="#credits" id="toc-entry-3">Credits</a><ul>
386-
<li><a class="reference internal" href="#authors" id="toc-entry-4">Authors</a></li>
387-
<li><a class="reference internal" href="#contributors" id="toc-entry-5">Contributors</a></li>
388-
<li><a class="reference internal" href="#maintainers" id="toc-entry-6">Maintainers</a></li>
384+
<li><a class="reference internal" href="#configuration" id="toc-entry-2">Configuration</a></li>
385+
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-3">Bug Tracker</a></li>
386+
<li><a class="reference internal" href="#credits" id="toc-entry-4">Credits</a><ul>
387+
<li><a class="reference internal" href="#authors" id="toc-entry-5">Authors</a></li>
388+
<li><a class="reference internal" href="#contributors" id="toc-entry-6">Contributors</a></li>
389+
<li><a class="reference internal" href="#maintainers" id="toc-entry-7">Maintainers</a></li>
389390
</ul>
390391
</li>
391392
</ul>
@@ -397,24 +398,37 @@ <h2><a class="toc-backref" href="#toc-entry-1">Use Cases / Context</a></h2>
397398
<p>This module tries to offer a way to reuse EDI and mail interface in
398399
order to handle everything.</p>
399400
</div>
401+
<div class="section" id="configuration">
402+
<h2><a class="toc-backref" href="#toc-entry-2">Configuration</a></h2>
403+
<p>For handling this incoming data, you just need to create a Backend and
404+
define the alias.</p>
405+
<p>The alias will be used to detect input mails. If the system detects an
406+
email, it will take all the exchange types related to the backend and
407+
review by exchange_filename if the pattern is filled. Also, if the
408+
backend has the <tt class="docutils literal">full_mail_exchange_type_id</tt> field filled, it will
409+
store the full dict.</p>
410+
<p>If not exchange type can be found, a UserError and a bounce email are
411+
sent.</p>
412+
<p>Processing will be handled in the standard way.</p>
413+
</div>
400414
<div class="section" id="bug-tracker">
401-
<h2><a class="toc-backref" href="#toc-entry-2">Bug Tracker</a></h2>
415+
<h2><a class="toc-backref" href="#toc-entry-3">Bug Tracker</a></h2>
402416
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/edi-framework/issues">GitHub Issues</a>.
403417
In case of trouble, please check there if your issue has already been reported.
404418
If you spotted it first, help us to smash it by providing a detailed and welcomed
405419
<a class="reference external" href="https://github.com/OCA/edi-framework/issues/new?body=module:%20edi_mail_import_oca%0Aversion:%2019.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
406420
<p>Do not contact contributors directly about support or help with technical issues.</p>
407421
</div>
408422
<div class="section" id="credits">
409-
<h2><a class="toc-backref" href="#toc-entry-3">Credits</a></h2>
423+
<h2><a class="toc-backref" href="#toc-entry-4">Credits</a></h2>
410424
<div class="section" id="authors">
411-
<h3><a class="toc-backref" href="#toc-entry-4">Authors</a></h3>
425+
<h3><a class="toc-backref" href="#toc-entry-5">Authors</a></h3>
412426
<ul class="simple">
413427
<li>Dixmit</li>
414428
</ul>
415429
</div>
416430
<div class="section" id="contributors">
417-
<h3><a class="toc-backref" href="#toc-entry-5">Contributors</a></h3>
431+
<h3><a class="toc-backref" href="#toc-entry-6">Contributors</a></h3>
418432
<ul class="simple">
419433
<li><a class="reference external" href="https://www.dixmit.com">Dixmit</a><ul>
420434
<li>Enric Tobella</li>
@@ -423,7 +437,7 @@ <h3><a class="toc-backref" href="#toc-entry-5">Contributors</a></h3>
423437
</ul>
424438
</div>
425439
<div class="section" id="maintainers">
426-
<h3><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h3>
440+
<h3><a class="toc-backref" href="#toc-entry-7">Maintainers</a></h3>
427441
<p>This module is maintained by the OCA.</p>
428442
<a class="reference external image-reference" href="https://odoo-community.org">
429443
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
from . import test_mail_import_oca
2+
from . import test_mail_import_oca_no_file

0 commit comments

Comments
 (0)