jan@dunkel.tech
dunkel.Tech
Odoo

Die eigene Odoo Extension

In diesem Beitrag zeige ich, wie man in Odoo eine bestehende App – in unserem Fall die HR-App (Human Resources) – technisch erweitert. Wir erstellen eine eigene Erweiterung, mit der sich die Standard-Ansicht der Mitarbeiterliste auf Listenansicht umstellen lässt. Zusätzlich erweitern wir das zugehörige Datenmodell um ein eigenes benutzerdefiniertes Feld, das sich direkt im Backend verwenden lässt. Der Artikel richtet sich an Entwickler:innen, die bestehende Odoo-Module gezielt anpassen und eigene Funktionen integrieren möchten – ohne die Kernlogik zu verändern.

Die eigene Odoo Extension

Die Grundlage: Die richtige Verzeichnisstruktur für eine Odoo-Erweiterung

Bevor wir mit der eigentlichen Entwicklung beginnen, ist es wichtig, die grundlegende Verzeichnisstruktur für eine Odoo-Erweiterung zu verstehen. Odoo erwartet, dass jede Erweiterung (bzw. jedes Modul) einem bestimmten Aufbau folgt, damit sie korrekt geladen und verarbeitet werden kann. Das bedeutet: Auch wenn wir lediglich eine bestehende App – wie die HR-App – anpassen möchten, legen wir unser eigenes, unabhängiges Modul an. So stellen wir sicher, dass wir keine Core-Dateien überschreiben und die Wartbarkeit des Systems erhalten bleibt.

Ein typisches Modulverzeichnis besteht aus folgenden zentralen Komponenten:

my_hr_extension/
├── __init__.py
├── __manifest__.py
├── models/
│   └── employee.py
├── views/
│   └── employee_list_view.xml
  • __init__.py sorgt dafür, dass das Modul als Python-Paket erkannt wird.

  • __manifest__.py enthält die Modulbeschreibung, Abhängigkeiten und Konfigurationsdaten.

  • Der Ordner models/ enthält unsere Python-Klassen zur Erweiterung des bestehenden Datenmodells.

  • Im Verzeichnis views/ definieren wir XML-Dateien, mit denen wir z. B. die Ansicht der Mitarbeiterliste anpassen.

Diese modulare Struktur erlaubt es uns, gezielt und sauber auf bestehende Funktionalitäten aufzusetzen – ohne das Odoo-Kernsystem direkt zu verändern.

Die __manifest__.py: Das Herzstück jedes Moduls

Jedes Odoo-Modul benötigt eine __manifest__.py-Datei – sie ist sozusagen der Steckbrief deiner Erweiterung. Hier definiert man, was das Modul tut, auf welchen Apps oder Modulen es aufbaut und welche Komponenten beim Laden berücksichtigt werden sollen. Ohne diese Datei erkennt Odoo dein Modul nicht.

Ein Beispiel für unsere HR-Erweiterung könnte so aussehen:

{
    'name': 'HR Employee List Extension',
    'version': '18.0.1.0.0',
    'summary': 'Erweiterung der HR-App um eine benutzerdefinierte Listenansicht und ein Zusatzfeld',
    'author': 'Dein Name oder Unternehmen',
    'category': 'Human Resources',
    'depends': ['hr'],
    'data': [
        'views/employee_list_view.xml',
    ],
    'installable': True,
    'application': False,
}

Hier eine kurze Erklärung der wichtigsten Felder:

  • name: Der sichtbare Name des Moduls.

  • version: Versionsnummer im Format <odoo_version>.<major>.<minor>.<patch>.

  • summary: Eine kurze Beschreibung, was das Modul macht.

  • author: Der oder die Entwickler:in bzw. das Unternehmen hinter dem Modul.

  • category: Ordnet das Modul thematisch ein – hier z. B. „Human Resources“.

  • depends: Eine Liste von Modulen, auf denen diese Erweiterung basiert. Für unsere Zwecke benötigen wir lediglich 'hr'.

  • data: Eine Liste von XML- oder CSV-Dateien, die beim Laden des Moduls verarbeitet werden sollen – in unserem Fall die neue oder geänderte Ansicht.

  • installable: Gibt an, ob das Modul über das Odoo-Backend installiert werden kann.

  • application: Legt fest, ob das Modul als eigenständige App erscheinen soll. Für reine Erweiterungen ist dies in der Regel False.

Diese Datei ist entscheidend für das Zusammenspiel deines Moduls mit dem Odoo-System. Achte darauf, dass alle Pfade korrekt gesetzt sind und keine Abhängigkeiten fehlen – sonst wird dein Modul beim Start nicht erkannt oder lässt sich nicht installieren.

Erweiterung des Datenmodells: Ein benutzerdefiniertes Feld für Mitarbeiter:innen

Nachdem die Modulstruktur steht und das Manifest definiert ist, erweitern wir nun das Datenmodell der HR-App um ein eigenes benutzerdefiniertes Feld. In unserem Fall möchten wir jedem Mitarbeitereintrag ein zusätzliches Feld hinzufügen – zum Beispiel einen internen „Status“ oder eine simple Kennzeichnung.

Der Schlüssel dabei: Wir erben das bestehende Modell (hr.employee) und erweitern es über eine eigene Python-Klasse innerhalb unseres Moduls. So bleiben die Standardfunktionalitäten unberührt, und unsere Änderungen sind jederzeit rückbaubar oder anpassbar.

Hier ein Beispielcode, der in der Datei models/employee.py liegt:

from odoo import models, fields

class Employee(models.Model):
    _inherit = 'hr.employee'

    custom_status = fields.Char(string='Interner Status')

Was passiert hier genau?

  • Wir importieren die nötigen Basisklassen aus dem odoo-Framework.

  • Mit _inherit = 'hr.employee' signalisieren wir, dass wir das bestehende HR-Mitarbeitermodell erweitern.

  • Das neue Feld custom_status vom Typ Char wird als einfacher Text gespeichert und steht sofort im Backend zur Verfügung – sofern es in der Ansicht eingebunden wird (dazu im nächsten Abschnitt mehr).

Optional kannst du auch andere Feldtypen wie fields.Selection, fields.Boolean oder fields.Date verwenden, je nachdem, welche Art von Information du speichern möchtest.

Dank des Vererbungskonzepts von Odoo bleibt die Originalstruktur des hr.employee-Modells erhalten. Unsere Erweiterung wird dynamisch hinzugefügt, sobald das Modul installiert ist – ohne Risiken für Systemupdates oder zukünftige Kompatibilität.

Anpassung der Benutzeroberfläche: Benutzerdefiniertes Feld

Damit unser neues Feld custom_status im Odoo-Backend sichtbar wird, müssen wir die Benutzeroberfläche entsprechend anpassen. Dazu definieren wir eine neue XML-Ansicht, in der wir das Feld in der Mitarbeiterlistenansicht anzeigen.

Odoo verwendet XML-Dateien zur Definition von Views. In unserem Modul legen wir unter views/employee_list_view.xml eine neue View-Datei an:

<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <record id="view_employee_tree_custom" model="ir.ui.view">
        <field name="name">hr.employee.tree.custom</field>
        <field name="model">hr.employee</field>
        <field name="inherit_id" ref="hr.view_employee_form" />
        <field name="arch" type="xml">
            <xpath expr="//page[@name='personal_information']" position="inside">
                <group string="Meine benutzerdefinierten Felder" name="custom_fields">
                    <field name="custom_status"/>
                </group>
            </xpath>
        </field>
    </record>
</odoo>

Was passiert hier genau?

  • Wir erstellen eine neue View, die sich auf das Modell hr.employee bezieht.

  • Über inherit_id verweisen wir auf die vorhandene Tree-View (Listenansicht) der HR-App.

  • Mit einem XPath-Ausdruck fügen wir unser neues Feld direkt nach dem bestehenden Namensfeld ein – so wird custom_status sauber in die bestehende Struktur integriert.

Wenn du möchtest, kannst du auch die gesamte Ansicht überschreiben und die Darstellung vollständig selbst bestimmen. Für die meisten Fälle reicht jedoch eine solche Vererbung und gezielte Erweiterung völlig aus.

Die eigene Odoo Extension

Von Kanban zu Liste: Die Standardansicht der Mitarbeiterübersicht umstellen

Standardmäßig zeigt Odoo die Mitarbeiterübersicht der HR-App im Kanban-Layout – mit Kacheln, Bildern und wenigen Details. Für viele Anwendungsfälle ist jedoch eine Listenansicht übersichtlicher und effizienter, z. B. wenn man mit vielen Datensätzen arbeitet oder zusätzliche Felder auf einen Blick sehen möchte.

Zum Glück lässt sich die Standarddarstellung relativ einfach ändern – ohne die bestehende Logik zu überschreiben. Wir nutzen dazu das Prinzip der Aktionserweiterung in Odoo. Ziel ist es, die Standard-Aktion der HR-App so zu verändern, dass beim Öffnen der Mitarbeiterliste automatisch die Listenansicht anstelle der Kanban-Ansicht verwendet wird.

Dazu ergänzen wir folgende Definition in unserer XML-Datei (employee_list_view.xml):

<record id="hr.act_hr_employee_kanban_view" model="ir.actions.act_window.view">
    <field name="sequence" eval="15"/>
</record>

<record id="hr.act_hr_employee_tree_view" model="ir.actions.act_window.view">
    <field name="sequence" eval="10"/>
</record>

Was passiert hier?

  • Wir greifen gezielt die bestehenden Aktionen hr.act_hr_employee_kanban_view und hr.act_hr_employee_tree_view auf – diese werden verwendet, wenn man über das Menü die Mitarbeiterliste aufruft.

  • Mit dem Feld sequence legen wir fest, in welcher Reihenfolge Odoo die verfügbaren Ansichten priorisiert. Durch 10 und 15 setzen wir die Listenansicht (hr.act_hr_employee_tree_view) als erste Option, gefolgt von der Kanbanansicht (hr.act_hr_employee_kanban_view).

Wichtig: Wenn du die Aktion direkt referenzierst, ohne sie komplett neu zu definieren, überschreibst du nur die gewünschten Teile – in diesem Fall das sequence. So bleibt die restliche Logik intakt.

Nach einem Server-Neustart oder Modul-Update wird die Mitarbeiterübersicht nun standardmäßig in der Listenansicht geöffnet. Natürlich bleibt die Kanban-Ansicht weiterhin verfügbar, wenn du sie manuell über das Ansichtssymbol wechselst – aber für die meisten Nutzer:innen bietet die neue Standarddarstellung einen effizienteren Einstieg.

Die eigene Odoo Extension

Manifest anpassen: Alles für die Installation vorbereiten

Nachdem wir unser Modul um eine Modell-Erweiterung und eine benutzerdefinierte Ansicht ergänzt haben, müssen wir nun sicherstellen, dass alle relevanten Dateien in der __manifest__.py-Datei korrekt referenziert sind. Nur so weiß Odoo, welche Komponenten geladen werden sollen.

Falls du dem Beispiel aus den vorherigen Abschnitten gefolgt bist, sollte deine __manifest__.py nun so oder so ähnlich aussehen:

{
    'name': 'HR Employee List Extension',
    'version': '15.0.1.0.0',
    'summary': 'Erweiterung der HR-App um eine benutzerdefinierte Listenansicht und ein Zusatzfeld',
    'author': 'Dein Name oder Unternehmen',
    'category': 'Human Resources',
    'depends': ['hr'],
    'data': [
        'views/employee_list_view.xml',
    ],
    'installable': True,
    'application': False,
}

Was wurde hier ergänzt bzw. angepasst?

  • depends: Enthält weiterhin 'hr', weil unser Modul darauf aufbaut.

  • data: Hier haben wir sicherstellt, dass unsere neue XML-Datei (employee_list_view.xml) eingebunden ist. Sie enthält sowohl die angepasste Tree-View als auch die erweiterte Aktionsdefinition, um die Standardansicht umzustellen.

  • installable: Muss auf True stehen, damit das Modul im Odoo-Backend zur Installation angezeigt wird.

Falls du später weitere View-Dateien hinzufügst (z. B. eine angepasste Formularansicht), müssen diese ebenfalls im data-Abschnitt eingetragen werden. Odoo verarbeitet diese Dateien beim Installieren des Moduls automatisch in der angegebenen Reihenfolge.

Ein kleiner Tipp: Wenn du nach Änderungen am Manifest oder an den View-Dateien keinen Unterschied siehst, hilft es oft, den Odoo-Server neu zu starten und ggf. das Modul zu aktualisieren (per UI oder mit -u <modulname> im Terminal).

Nicht vergessen: Die __init__.py-Dateien – das Bindeglied zwischen Odoo und deinem Code

Damit Odoo überhaupt erkennt, welche Python-Dateien in deinem Modul enthalten sind und ausgeführt werden sollen, müssen entsprechende __init__.py-Dateien vorhanden sein. Diese Dateien dienen als Einstiegspunkte für das Python-Modul und stellen sicher, dass deine Klassen und Erweiterungen korrekt geladen werden.

Du brauchst zwei __init__.py-Dateien:

  1. Im Stammverzeichnis deines Moduls (my_hr_extension/__init__.py)

  2. Im models/-Verzeichnis selbst (my_hr_extension/models/__init__.py)
# my_hr_extension/__init__.py
# Hier importierst du den models-Ordner, damit Odoo weiß, dass sich darin ausführbarer Code befindet:
from . import models

# my_hr_extension/models/__init__.py
# Hier importierst du die konkreten Python-Dateien mit den Modell-Erweiterungen. In unserem Fall:
from . import employee

Damit ergibt sich folgendes Zusammenspiel:

  • __init__.py im Stammverzeichnis sorgt dafür, dass der models-Ordner als Python-Paket behandelt wird.

  • __init__.py im models/-Ordner lädt die Datei employee.py, in der wir das hr.employee-Modell erweitert haben.

Wichtig: Wenn du mehrere Python-Dateien im models/-Ordner hast (z. B. für unterschiedliche Erweiterungen), musst du jede davon explizit importieren.

Ohne diese __init__.py-Dateien bleibt dein Code für Odoo unsichtbar – selbst wenn alles andere korrekt eingerichtet ist. Also: Diese kleinen Dateien nicht vergessen, sie sind entscheidend für den reibungslosen Start deiner Erweiterung!

Installation des Moduls: Die Erweiterung in Odoo aktivieren

Nachdem wir nun unser Modul vollständig aufgebaut haben – inklusive Datenmodell, Views, Manifest und Initialisierungsdateien – fehlt nur noch ein letzter Schritt: die Installation in Odoo.

Hier sind die Schritte zur erfolgreichen Aktivierung deiner Erweiterung:

1. Modulverzeichnis platzieren

Kopiere deinen Modulordner (z. B. my_hr_extension/) in das Odoo-Addons-Verzeichnis. Der Pfad kann je nach System unterschiedlich sein, häufig liegt er z. B. unter:

/odoo/custom_addons/

Falls du ein eigenes Verzeichnis verwendest, achte darauf, dass dieses in der odoo.conf-Datei unter addons_path eingetragen ist.

2. Server neu starten

Starte deinen Odoo-Server neu, damit das neue Modul erkannt wird:

./odoo-bin -d deine_datenbank -u my_hr_extension

Alternativ kannst du den Server einfach neu starten und das Modul später manuell über das Backend installieren.

3. Modul im Backend sichtbar machen

Melde dich im Odoo-Backend an, wechsle in den App Store (Menüpunkt Apps) und klicke auf "Apps aktualisieren" bzw. "Update Apps List" (du musst ggf. den Entwicklermodus aktivieren).

Danach kannst du im Suchfeld nach deinem Modulnamen suchen – z. B. „HR Employee List Extension“ – und es über einen Klick auf "Installieren" aktivieren.

4. Änderungen überprüfen

Sobald die Installation abgeschlossen ist:

  • Öffne die HR-App → Mitarbeiterübersicht.

  • Die Standard-Kanban-Ansicht sollte nun durch die Listenansicht ersetzt sein.

  • Dein benutzerdefiniertes Feld (z. B. Interner Status) sollte als Spalte sichtbar sein.

Wenn du die Ansicht oder Datenstruktur später änderst, kannst du dein Modul jederzeit mit folgendem Befehl aktualisieren:

./odoo-bin -d deine_datenbank -u my_hr_extension

Fazit: Saubere Odoo-Erweiterungen für nachhaltige Entwicklungen

Mit dieser einfachen, aber wirkungsvollen Erweiterung haben wir gezeigt, wie sich bestehende Odoo-Module gezielt und sauber anpassen lassen – ganz ohne die Kernlogik zu verändern. Durch die modulare Struktur und das Vererbungssystem von Odoo ist es möglich, Funktionalität flexibel zu erweitern und gleichzeitig update-sicher zu bleiben.

Wir haben Schritt für Schritt gelernt:

  • wie eine eigene Odoo-Erweiterung strukturiert ist,

  • wie man das Datenmodell eines bestehenden Moduls erweitert,

  • wie Ansichten angepasst und Standardverhalten (z. B. die Kanban-Ansicht) verändert werden können,

  • und wie man das eigene Modul korrekt installiert und im Backend aktiviert.

Diese Vorgehensweise ist nicht nur technisch sauber, sondern auch langfristig wartbar – besonders in größeren Projekten oder produktiven Odoo-Installationen. Statt direkt im Core-Code Änderungen vorzunehmen, setzt du auf eine klar abgegrenzte Erweiterung, die unabhängig gepflegt und bei Bedarf leicht angepasst werden kann.

Ob du nur kleine Optimierungen einführen oder komplexe Funktionen integrieren willst: Der modulare Weg ist in Odoo immer der nachhaltigste.

Mehr aus Odoo
Eigene Cronjobs in Odoo
25. October 2025

Eigene Cronjobs in Odoo

Was sind Cronjobs in Odoo? In Odoo sind Cronjobs (auch bekannt als Scheduled Actions oder Geplante Aktionen) das Herzstück der Automatisierung. Sie ermöglichen es dir, Python-Code zu bestimmten, wiederkehrenden Zeiten auszuführen, ohne dass ein Benutzer eingreifen muss. Typische Anwendungsfälle sind: Tägliches Abholen von Wechselkursen. Wöchentliches Versenden von Marketing-E-Mails. Automatische Lagerbereinigungen. In diesem Artikel zeigen wir, wie du einen benutzerdefinierten Cronjob erstellst, um Mitarbeiter automatisch an ihr jährliches Performance-Gespräch zu erinnern – einen Monat vor ihrem Jahrestag.

Mehr erfahren
E-Mails mit Odoo versenden
18. October 2025

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.

Mehr erfahren