changeset 4786abb9094b in modules/notification_email:default
details:
https://hg.tryton.org/modules/notification_email?cmd=changeset;node=4786abb9094b
description:
Add optional subject to notifications
issue9321
review290011002
diffstat:
CHANGELOG | 2 +
exceptions.py | 8 +++++
message.xml | 10 ++++++
notification.py | 35 +++++++++++++++++++++-
setup.py | 2 +-
tests/test_notification_email.py | 62 ++++++++++++++++++++++++++++++++++++++++
tryton.cfg | 1 +
view/email_form.xml | 2 +
8 files changed, 120 insertions(+), 2 deletions(-)
diffs (216 lines):
diff -r efe62fbd57cb -r 4786abb9094b CHANGELOG
--- a/CHANGELOG Fri May 08 17:45:42 2020 +0200
+++ b/CHANGELOG Sat Jul 04 20:07:54 2020 +0200
@@ -1,3 +1,5 @@
+* Add optional subject to notifications
+
Version 5.6.0 - 2020-05-04
* Bug fixes (see mercurial logs for details)
* Add commission agent as a recipient
diff -r efe62fbd57cb -r 4786abb9094b exceptions.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exceptions.py Sat Jul 04 20:07:54 2020 +0200
@@ -0,0 +1,8 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.model.exceptions import ValidationError
+
+
+class TemplateError(ValidationError):
+ pass
diff -r efe62fbd57cb -r 4786abb9094b message.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/message.xml Sat Jul 04 20:07:54 2020 +0200
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
+this repository contains the full copyright notices and license terms. -->
+<tryton>
+ <data grouped="1">
+ <record model="ir.message" id="msg_notification_invalid_subject">
+ <field name="text">Invalid e-mail subject in notification
"%(notification)s" with exception "%(exception)s".</field>
+ </record>
+ </data>
+</tryton>
diff -r efe62fbd57cb -r 4786abb9094b notification.py
--- a/notification.py Fri May 08 17:45:42 2020 +0200
+++ b/notification.py Sat Jul 04 20:07:54 2020 +0200
@@ -8,13 +8,17 @@
from email.mime.nonmultipart import MIMENonMultipart
from email.utils import formataddr, getaddresses
+from genshi.template import TextTemplate
+
from trytond.config import config
+from trytond.i18n import gettext
from trytond.model import ModelView, ModelSQL, fields
from trytond.pool import Pool
from trytond.pyson import Eval
from trytond.report import get_email
from trytond.sendmail import sendmail_transactional, SMTPDataManager
from trytond.transaction import Transaction
+from .exceptions import TemplateError
_EMAIL_MODELS = [
'res.user',
@@ -37,6 +41,11 @@
from_ = fields.Char(
"From",
help="Leave empty for the value defined in the configuration file.")
+ subject = fields.Char(
+ "Subject", translate=True,
+ help="The Genshi syntax can be used "
+ "with 'record' in the evaluation context.\n"
+ "If empty the report name will be used.")
recipients = fields.Many2One(
'ir.model.field', "Recipients",
domain=[
@@ -240,11 +249,17 @@
# TODO order languages to get default as last one for title
content, title = get_email(self.content, record, languages)
+ language = list(languages)[-1]
+ if self.subject:
+ with Transaction().set_context(language=language.code):
+ notification = self.__class__(self.id)
+ title = (TextTemplate(notification.subject)
+ .generate(record=record)
+ .render())
if self.attachments:
msg = MIMEMultipart('mixed')
msg.attach(content)
- language = list(languages)[-1]
for report in self.attachments:
msg.attach(Attachment.get_mime(report, record, language.code))
else:
@@ -329,6 +344,24 @@
if logs:
Log.create(logs)
+ @classmethod
+ def validate(cls, notifications):
+ super().validate(notifications)
+ for notification in notifications:
+ notification.check_subject()
+
+ def check_subject(self):
+ if not self.subject:
+ return
+ try:
+ TextTemplate(self.subject)
+ except Exception as exception:
+ raise TemplateError(
+ gettext('notification_email.'
+ 'msg_notification_invalid_subject',
+ notification=self.rec_name,
+ exception=exception)) from exception
+
class EmailAttachment(ModelSQL):
"Email Notification Attachment"
diff -r efe62fbd57cb -r 4786abb9094b setup.py
--- a/setup.py Fri May 08 17:45:42 2020 +0200
+++ b/setup.py Sat Jul 04 20:07:54 2020 +0200
@@ -51,7 +51,7 @@
if local_version:
version += '+' + '.'.join(local_version)
-requires = []
+requires = ['Genshi']
for dep in info.get('depends', []):
if not re.match(r'(ir|res)(\W|$)', dep):
requires.append(get_require_version('trytond_%s' % dep))
diff -r efe62fbd57cb -r 4786abb9094b tests/test_notification_email.py
--- a/tests/test_notification_email.py Fri May 08 17:45:42 2020 +0200
+++ b/tests/test_notification_email.py Sat Jul 04 20:07:54 2020 +0200
@@ -168,6 +168,68 @@
attachment.get_content_type(), 'text/plain')
self.assertEqual(attachment.get_filename(), "Attachment.txt")
+ @with_transaction()
+ def test_notification_email_subject(self):
+ "Test email notificiation with subject"
+ pool = Pool()
+ Model = pool.get('ir.model')
+ User = pool.get('res.user')
+ NotificationEmail = pool.get('notification.email')
+ Language = pool.get('ir.lang')
+
+ self._setup_notification()
+ model, = Model.search([
+ ('model', '=', User.__name__),
+ ])
+ en, = Language.search([('code', '=', 'en')])
+
+ notification_email, = NotificationEmail.search([])
+ notification_email.subject = 'Notification for ${record.name}'
+ notification_email.save()
+
+ user, = User.create([{'name': "Michael Scott", 'login': "msc"}])
+
+ msg = notification_email.get_email(
+ user, FROM, ['Administrator <[email protected]>'], [], [], [en])
+
+ self.assertEqual(msg['Subject'], 'Notification for Michael Scott')
+
+ @with_transaction()
+ def test_notification_email_translated_subject(self):
+ "Test email notificiation with translated subject"
+ pool = Pool()
+ Model = pool.get('ir.model')
+ User = pool.get('res.user')
+ NotificationEmail = pool.get('notification.email')
+ Language = pool.get('ir.lang')
+
+ self._setup_notification()
+ model, = Model.search([
+ ('model', '=', User.__name__),
+ ])
+ es, = Language.search([('code', '=', 'es')])
+ Language.load_translations([es])
+
+ notification_email, = NotificationEmail.search([])
+ notification_email.subject = 'Notification for ${record.name}'
+ notification_email.save()
+
+ with Transaction().set_context(lang='es'):
+ notification_email, = NotificationEmail.search([])
+ notification_email.subject = 'Notificación para ${record.name}'
+ notification_email.save()
+
+ user, = User.create([{
+ 'name': "Michael Scott",
+ 'login': "msc",
+ 'language': es.id,
+ }])
+
+ msg = notification_email.get_email(
+ user, FROM, ['Administrator <[email protected]>'], [], [], [es])
+
+ self.assertEqual(msg['Subject'], 'Notificación para Michael Scott')
+
@unittest.skipIf(
(3, 5, 0) <= sys.version_info < (3, 5, 2), "python bug #25195")
@with_transaction()
diff -r efe62fbd57cb -r 4786abb9094b tryton.cfg
--- a/tryton.cfg Fri May 08 17:45:42 2020 +0200
+++ b/tryton.cfg Sat Jul 04 20:07:54 2020 +0200
@@ -11,3 +11,4 @@
xml:
notification.xml
ir.xml
+ message.xml
diff -r efe62fbd57cb -r 4786abb9094b view/email_form.xml
--- a/view/email_form.xml Fri May 08 17:45:42 2020 +0200
+++ b/view/email_form.xml Sat Jul 04 20:07:54 2020 +0200
@@ -6,6 +6,8 @@
<field name="from_"/>
<label name="content"/>
<field name="content"/>
+ <label name="subject"/>
+ <field name="subject" colspan="3"/>
<label name="recipients"/>
<field name="recipients"/>
<label name="fallback_recipients"/>