changeset 2:1ba103fdf476 4.4

Add attachments to email
author Cédric Krier <ced@b2ck.com>
date Tue, 25 Jul 2017 18:33:49 +0200
parents c1f8328fb454
children 2b29d5281b88
files __init__.py doc/index.rst notification.py tests/test_notification_email.py view/email_form.xml
diffstat 5 files changed, 76 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/__init__.py	Tue Jul 25 12:44:06 2017 +0200
+++ b/__init__.py	Tue Jul 25 18:33:49 2017 +0200
@@ -8,6 +8,7 @@
 def register():
     Pool.register(
         notification.Email,
+        notification.EmailAttachment,
         notification.Log,
         ir.Trigger,
         module='notification_email', type_='model')
--- a/doc/index.rst	Tue Jul 25 12:44:06 2017 +0200
+++ b/doc/index.rst	Tue Jul 25 18:33:49 2017 +0200
@@ -3,3 +3,4 @@
 
 The notification email module allows to define email templates which will be
 sent to a list of recipients when a trigger is fired on a record event.
+Some extra reports from the same record can be attached to the email.
--- a/notification.py	Tue Jul 25 12:44:06 2017 +0200
+++ b/notification.py	Tue Jul 25 18:33:49 2017 +0200
@@ -1,6 +1,7 @@
 # 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 email.header import Header
+from email.mime.application import MIMEApplication
 from email.mime.multipart import MIMEMultipart
 from email.mime.text import MIMEText
 from email.utils import formataddr, getaddresses
@@ -17,7 +18,7 @@
 from trytond.sendmail import sendmail_transactional, SMTPDataManager
 from trytond.transaction import Transaction
 
-__all__ = ['Email', 'Log']
+__all__ = ['Email', 'EmailAttachment', 'Log']
 
 
 def _formataddr(name, email):
@@ -84,6 +85,14 @@
         'ir.action.report', "Content", required=True,
         domain=[('template_extension', 'in', ['plain', 'html', 'xhtml'])],
         help="The report used as email template.")
+    attachments = fields.Many2Many(
+        'notification.email.attachment', 'notification', 'report',
+        "Attachments",
+        domain=[
+            ('model', '=', Eval('model')),
+            ],
+        depends=['model'],
+        help="The reports used as attachments.")
 
     triggers = fields.One2Many(
         'ir.trigger', 'notification_email', "Triggers",
@@ -169,6 +178,9 @@
             return {self._get_language(value)}
 
     def get_email(self, record, to, cc, bcc, languages):
+        pool = Pool()
+        Attachment = pool.get('notification.email.attachment')
+
         msg, title = _get_email_template(
             self.content.report_name, record, languages)
         msg['To'] = ', '.join(to)
@@ -176,6 +188,10 @@
         msg['Bcc'] = ', '.join(bcc)
         msg['Subject'] = Header(title, 'utf-8')
         msg['Auto-Submitted'] = 'auto-generated'
+
+        language = list(languages)[-1]
+        for report in self.attachments:
+            msg.attach(Attachment.get_mime(report, record, language))
         return msg
 
     def get_log(self, record, trigger, msg):
@@ -236,6 +252,46 @@
             Log.create(logs)
 
 
+class EmailAttachment(ModelSQL):
+    "Email Notification Attachment"
+    __name__ = 'notification.email.attachment'
+
+    notification = fields.Many2One(
+        'notification.email', "Notification",
+        required=True, select=True)
+    report = fields.Many2One(
+        'ir.action.report', "Report", required=True,
+        domain=[
+            ('model', '=', Eval('model')),
+            ],
+        depends=['model'])
+
+    model = fields.Function(fields.Char("Model"), 'get_model')
+
+    def get_model(self, name):
+        return self.notification.model
+
+    @classmethod
+    def get_mime(cls, report, record, language):
+        pool = Pool()
+        Report = pool.get(report.report_name, type='report')
+        with Transaction().set_context(language=language):
+            ext, content, _, title = Report.execute(
+                [record.id], {
+                    'action_id': report.id,
+                    })
+        name = '%s.%s' % (title, ext)
+        msg = MIMEApplication(content)
+        if not isinstance(name, str):
+            name = name.encode('utf-8')
+        if not isinstance(language, str):
+            language = language.encode('utf-8')
+        msg.add_header(
+            'Content-Disposition', 'attachment',
+            filename=('utf-8', language, name))
+        return msg
+
+
 class Log(ModelSQL, ModelView):
     "Notitification Log"
     __name__ = 'notification.log'
--- a/tests/test_notification_email.py	Tue Jul 25 12:44:06 2017 +0200
+++ b/tests/test_notification_email.py	Tue Jul 25 18:33:49 2017 +0200
@@ -58,6 +58,14 @@
         report.model = model.model
         report.save()
 
+        attachment = Report()
+        attachment.name = "Attachment"
+        attachment.report_name = 'notification_notification.test.report'
+        attachment.template_extension = 'plain'
+        attachment.report_content = b'attachment for ${records[0].name}'
+        attachment.model = model.model
+        attachment.save()
+
         user = User(Transaction().user)
         user.email = 'user@example.com'
         user.save()
@@ -68,6 +76,7 @@
                 ('name', '=', 'create_uid'),
                 ])
         notification_email.content = report
+        notification_email.attachments = [attachment]
         notification_email.save()
 
         Trigger.create([{
@@ -93,6 +102,13 @@
             self.assertEqual(msg.get_content_type(), 'multipart/alternative')
             self.assertEqual(
                 msg.get_payload(0).get_payload(), 'Hello Michael Scott')
+            attachment = msg.get_payload(1)
+            self.assertEqual(
+                attachment.get_payload(None, True),
+                'attachment for Michael Scott')
+            self.assertEqual(
+                attachment.get_content_type(), 'application/octet-stream')
+            self.assertEqual(attachment.get_filename(), "Attachment.plain")
 
         log, = Log.search([])
         self.assertEqual(log.trigger.notification_email, notification_email)
--- a/view/email_form.xml	Tue Jul 25 12:44:06 2017 +0200
+++ b/view/email_form.xml	Tue Jul 25 18:33:49 2017 +0200
@@ -12,5 +12,6 @@
     <field name="recipients_secondary"/>
     <label name="recipients_hidden"/>
     <field name="recipients_hidden"/>
+    <field name="attachments" colspan="2"/>
     <field name="triggers" colspan="2"/>
 </form>