details: https://code.tryton.org/tryton/commit/96b6fec7e199
branch: default
user: Cédric Krier <[email protected]>
date: Fri Oct 17 14:51:15 2025 +0200
description:
Accept email without content as incoming document
It allow the creation of incoming document without data as long as it
has
children. This supports the case of email without text nor HTML content
but
only an attachment.
Closes #14109
diffstat:
modules/document_incoming/document.py | 15 +++++++++++-
modules/document_incoming/tests/test_module.py | 29 ++++++++++++++++++++++++++
2 files changed, 42 insertions(+), 2 deletions(-)
diffs (71 lines):
diff -r 2ec9d05201de -r 96b6fec7e199 modules/document_incoming/document.py
--- a/modules/document_incoming/document.py Tue Oct 21 13:35:04 2025 +0200
+++ b/modules/document_incoming/document.py Fri Oct 17 14:51:15 2025 +0200
@@ -41,8 +41,11 @@
company = fields.Many2One('company.company', "Company", states=_states)
data = fields.Binary(
"Data", filename='name',
- file_id=file_id, store_prefix=store_prefix, required=True,
- states=_states)
+ file_id=file_id, store_prefix=store_prefix,
+ states={
+ 'required': ~Eval('children'),
+ 'readonly': _states['readonly'],
+ })
parsed_data = fields.Dict(None, "Parsed Data", readonly=True)
file_id = fields.Char("File ID", readonly=True)
mime_type = fields.Function(
@@ -125,6 +128,14 @@
},
)
+ @classmethod
+ def __register__(cls, module):
+ super().__register__(module)
+ table_h = cls.__table_handler__(module)
+
+ # Migration from 7.6: remove not null on data
+ table_h.not_null_action('data', action='remove')
+
@fields.depends('name')
def on_change_with_mime_type(self, name=None):
if self.name:
diff -r 2ec9d05201de -r 96b6fec7e199
modules/document_incoming/tests/test_module.py
--- a/modules/document_incoming/tests/test_module.py Tue Oct 21 13:35:04
2025 +0200
+++ b/modules/document_incoming/tests/test_module.py Fri Oct 17 14:51:15
2025 +0200
@@ -84,6 +84,35 @@
self.assertEqual(child.data, b'data')
self.assertEqual(child.source, 'inbound_email')
+ @with_transaction()
+ def test_document_from_inbound_email_without_content(self):
+ "Test document from inbound email without content"
+ pool = Pool()
+ Document = pool.get('document.incoming')
+ Email = pool.get('inbound.email')
+ Rule = pool.get('inbound.email.rule')
+
+ with patch.object(Email, 'as_dict') as as_dict:
+ as_dict.return_value = {
+ 'subject': "Subject",
+ 'attachments': [{
+ 'filename': "document",
+ 'data': b'data',
+ }],
+ }
+
+ email = Email()
+ rule = Rule(
+ document_incoming_type='document_incoming',
+ document_incoming_company=None,
+ )
+
+ document = Document.from_inbound_email(email, rule)
+
+ self.assertFalse(document.data)
+ child, = document.children
+ self.assertEqual(child.data, b'data')
+
class DocumentIncomingRouteTestCase(RouteTestCase):
"Test Document Incoming route"