ODT or PDF report as an attachment for the emailed reports

I added the emailing function for the reports:

        <record model="ir.action.report" id="email_report">
            <field name="name">Device</field>
            <field name="model">mymodule.device</field>
            <field name="report_name">mymodule.device.email_report</field>
            <field name="report">mymodule/vehicle.fodt</field>
            <!-- DON'T USE  field name="template_extension">html</field-->

How to attach ODT file (I found HTML example, but want to send ODT or even better — PDF)?
If I need to use template_extension?? What extensions are available?


What are you talking about?

You are just showing the declaration of a report.
It is not clear what is your purpose.

I created a wizard ‘Email report’:

from trytond.sendmail import sendmail_transactional

class EmailDeviceReport(Wizard):
    'E-mail a device report'
    __name__ = 'mymodule.device.email_report'
    start = StateTransition()

    def transition_start(self):
        pool = Pool()
        Device = pool.get('mymodule.device')
        device = Device(Transaction().context['active_id'])
        Language = pool.get('ir.lang')
        languages = [Language.get()]
        from_ = config.get('email', 'from')
        msg, title = get_email(
            'mymodule.device', device, languages)
        emails = [...<here some emails, will update later>...]
        msg['From']= config.get('email', 'from')
        msg['To'] = ','.join(emails)
        msg['Subject'] = Header(title, 'utf-8')
        res = sendmail_transactional(from_, emails, msg)
 #        For debugging purposes
        with open('/tmp/report.odt','w') as f: 
        return 'end'

You have to render the report first and then attach the output to the email message content. You can take a look at the notification-email module. If you want, tomorrow I can take a look at some of my modules. With this module my client sends an email with the report attached as a PDF.

1 Like

Yes, I would be happy to see the example!
I have mymodule/vehicle.fodt — that is a custom template I created.
I see an attachment in the email I received, but this attachment doesn’t readable.
And I want a PDF.


The first thing you have to do it to make sure you can print the report as PDF. When you can do that, the next step is to attach it to the email. To print a report to PDF I think you have to use:

<field name="extension">pdf</field>

Also add a keyword in the XML to make the report available in the client. For an example see Reports — trytond latest documentation

1 Like

OK, I found some code which shows how to send an email with a report attached. Like I said, if you want to attach the report as PDF make sure you can print the report as PDF.

In this code I’m first searching for the reports. In other cases I made an extra field in the configuration, so the user can enter the report they want to send. When I find the report, I execute it and get the data back. This data is then added to the email.

# You need some imports here
import mimetypes
from email.encoders import encode_base64
from email.header import Header
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.nonmultipart import MIMENonMultipart
from email.utils import formataddr, getaddresses
from trytond.sendmail import sendmail_transactional, SMTPDataManager
from trytond.report import get_email

def send_email(self, email=None, datamanager=None):
    # do all your email stuff like getting addresses etc. You can
    # find enough examples around how to do that.
    # put your email together
    msg = self._email(from_, to, cc, bcc, languages)

    # send the email. Nothing is different from the examples.

def _email(self, from_, to, cc, bcc, languages):
    pool = Pool()
    # you should be thinking to put both reports into a configuration,
    # so users can modify them.

    # Get the report to be used for the email content
    ActionReport = pool.get('ir.action.report')
    action_reports = ActionReport.search([
            ('report_name', '=', 'project.email.testresult'),
    assert action_reports, 'project.email.testresult not found'
    EmailReport = action_reports[0]

    # Get the report which will be attached as PDF
    action_reports = ActionReport.search([
            ('report_name', '=', 'project.testresult')
    assert action_reports, 'project.testresult not found'
    TestReport = action_reports[0]

    content, title = get_email(EmailReport, self, languages)
    if TestReport:
        msg = MIMEMultipart('mixed')
        language = list(languages)[-1]
        msg.attach(self.get_mime(TestReport, self, language.code))
        msg = content

    msg['From'] = from_
    msg['To'] = ', '.join(to)
    msg['Cc'] = ', '.join(cc)
    msg['Bcc'] = ', '.join(bcc)
    msg['Subject'] = Header(title, 'utf-8')
    msg['Auto-Submitted'] = 'auto-generated'

    return msg

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 = name = '%s.%s' % (title, ext)

    mimetype, _ = mimetypes.guess_type(name)
    if mimetype:
        msg = MIMENonMultipart(*mimetype.split('/'))
        msg = MIMEApplication(content)
    if not isinstance(name, str):
        name = name.encode('utf-8')
    if not isinstance(language, str):
        language = language.encode('utf-8')
        'Content-Disposition', 'attachment',
        filename=name)  # using ('utf-8', language, name) will scare gmail
                        # gmail doesn't display the filename
    return msg

I also advice you to take a look at the trytond_notification_email-5.6.1.tar.gz or trytond_account_dunning_email-5.6.0.tar.gz. Dunning also shows how to add a report to your configuration.