E-Mails mit Odoo versenden
Warum eigene E-Mails in Odoo? Odoo ist eine mächtige Plattform, aber manchmal reicht die Standardfunktionalität nicht aus. Du möchtest vielleicht: Eine spezielle Benachrichtigung versenden, wenn ein bestimmtes Kriterium in deinem benutzerdefinierten Modul erfüllt ist. Eine E-Mail mit dynamischen Inhalten an einen externen Dienstleister schicken. Ein einzigartiges Design für Transaktions-E-Mails verwenden, das nicht zum Standard passt. Der einfachste und robusteste Weg in Odoo ist die Verwendung von E-Mail-Templates (XML) in Kombination mit Python-Code (API-Aufrufe). So trennst du das Design vom Code und profitierst von Odoos integrierter E-Mail-Infrastruktur.
Das E-Mail-Template in XML erstellen
Zuerst definierst du das Aussehen und den Inhalt deiner E-Mail. Für dynamische und strukturierte Inhalte nutzen wir ein QWeb2 Template innerhalb des body_html-Feldes deines mail.template Datensatzes. Dieses Template speicherst du typischerweise in einer XML-Datei in deinem Modul, z.B. unter data/mail_template.xml
<odoo>
<data noupdate="1">
<record id="email_template_custom_notification" model="mail.template">
<field name="name">Benutzerdefinierte Benachrichtigung (QWeb2)</field>
<field name="model_id" ref="dein_modul.model_dein_modell"/>
<field name="subject">Ihre Anfrage wurde erfolgreich bearbeitet! (#{{ object.name }})</field>
<field name="email_to">{{ object.partner_id.email }}</field>
<field name="body_html" type="html">
<![CDATA[
<div style="font-family: 'Arial', sans-serif; font-size: 14px;">
<p>Sehr geehrte/r <t t-out="object.partner_id.name or 'Kunde'"/>,</p>
<p>
Vielen Dank für Ihre Bestellung/Anfrage <strong>#<t t-out="object.name"/></strong>.
Sie wurde erfolgreich verarbeitet und wird nun weiter bearbeitet.
</p>
<t t-if="object.details_available">
<h3>Details Ihrer Anfrage:</h3>
<ul>
<li>Referenz: <t t-out="object.reference_number"/></li>
<li>Betrag: <t t-out="object.amount" t-options='{"widget": "monetary", "display_currency": object.currency_id}'/></li>
</ul>
</t>
<p>
Bei Fragen kontaktieren Sie uns gerne.
</p>
<p>Mit freundlichen Grüßen,</p>
<p>Ihr Team</p>
</div>
]]>
</field>
<field name="auto_delete" eval="True"/>
</record>
</data>
</odoo>
Was ist QWeb2 und wie funktioniert es hier?
QWeb2 ist Odoos serverseitiges Templating-System, das HTML-Strukturen mit dynamischen Daten füllen kann. Innerhalb des <field name="body_html" type="html"> Blocks definieren wir den Inhalt.
<![CDATA[ ... ]]>: Dies ist wichtig, um sicherzustellen, dass dein HTML-Code und die QWeb2-Direktiven nicht vom XML-Parser als Tags interpretiert werden, sondern als reiner Textinhalt des Feldes.<t t-out="expression"/>: Gibt den Wert einer Variablen aus (vergleichbar mit{{ variable }}in Jinja). Hier z.B.object.partner_id.name.<t t-if="condition"> ... </t>: Ermöglicht bedingte Inhalte. Der Block wird nur gerendert, wenn die Bedingung wahr ist.<t t-options='{"widget": "monetary", "display_currency": object.currency_id}'/>: Dies zeigt die Leistungsfähigkeit von QWeb2. Du kannst Odoo-Widgets direkt im Template verwenden, um Daten wie Währungen korrekt zu formatieren. Dafür musst du sicherstellen, dass deinobjectauch eincurrency_idFeld besitzt.Variablenzugriff: Wie zuvor wird der Record, für den die E-Mail gesendet wird, als
objectim Template verfügbar gemacht. Du kannst auf alle seine Felder und verknüpften Felder zugreifen.
Den Versand im Python-Code auslösen
Nun benötigst du den Python-Code, der den E-Mail-Versand basierend auf einem Ereignis in deinem Odoo-Modul auslöst. Dies geschieht in einer Methode deines Modells (z.B. bei einem Statuswechsel).
from odoo import api, fields, models
class DeinModell(models.Model):
_name = 'dein_modul.dein_modell'
_description = 'Ein benutzerdefiniertes Odoo-Modell'
name = fields.Char(string="Referenz")
partner_id = fields.Many2one('res.partner', string="Kunde")
status = fields.Selection([('draft', 'Entwurf'), ('done', 'Erledigt')], default='draft')
details_available = fields.Boolean(string="Details vorhanden", default=False)
reference_number = fields.Char(string="Interne Referenz")
amount = fields.Monetary(string="Betrag")
currency_id = fields.Many2one('res.currency', string="Währung", default=lambda self: self.env.company.currency_id)
def action_send_notification_mail(self):
"""Versendet die E-Mail, z.B. sobald der Status auf 'done' gesetzt wird."""
# Hole die ID des E-Mail-Templates
template = self.env.ref('dein_modul.email_template_custom_notification')
# Die E-Mail pro Record in der Recordset (self) versenden
for record in self:
if record.status == 'done' and record.partner_id.email: # Sicherstellen, dass eine E-Mail-Adresse existiert
try:
# Sende das Template. Der Record wird als Kontextobjekt übergeben (object)
template.send_mail(
record.id,
force_send=True, # E-Mail sofort versenden, nicht in der Queue lassen
raise_exception=True # Exception werfen, falls etwas schief geht
)
except Exception as e:
record.message_post(body=f"Fehler beim Senden der E-Mail an {record.partner_id.email}: {e}")
self.env.cr.rollback() # Optional: Rollback bei Fehler
return True
Erklärung der Schlüsselfunktion template.send_mail():
self.env.ref('dein_modul.email_template_custom_notification'): Dies holt das XML-Template anhand der externen ID (<record id="..." />).record.id: Dies ist der entscheidende Parameter. Odoo weiß dadurch, dass der Record (record) des aktuellen Modells (dein_modul.dein_modell) als Kontext-Objekt (object) für das Template verwendet werden soll. Alle Platzhalter (<t t-out="object.name" />) werden von diesem Record gefüllt.
Fazit: Die volle Macht der Odoo E-Mail-Automatisierung
Die Kombination aus einem dedizierten QWeb2-Template in XML und dem Aufruf per Python-Code ist die Best Practice in Odoo, insbesondere wenn du:
Komplexe Layouts oder dynamische Inhalte basierend auf Geschäftslogik benötigst.
Odoo-Widgets zur korrekten Formatierung von Daten (z.B. Datumsangaben, Währungen) nutzen möchtest.
Übersichtlichkeit im Code beibehalten und das E-Mail-Design von der Versandlogik trennen willst.
Mit QWeb2 hast du die volle Kontrolle über den E-Mail-Inhalt und kannst ansprechende, datengesteuerte Nachrichten direkt aus deinem Odoo-System versenden.