Einleitung
In Odoo bestimmen Modelle die Form und Organisation Ihrer Geschäftsdaten. Alles, was Sie im Tagesgeschäft anlegen — Angebote, Bestellungen, Rechnungen, Kontakte — bekommt in einem Modell seine Struktur und seinen Speicherplatz in der Datenbank.
Für Entwickler und Consultants sind Modelle das Herzstück der Odoo-Architektur. Sie legen Felder, Beziehungen und Geschäftslogik fest und bilden damit die Grundlage für Berichte, Regeln und Automatisierungen.
Dieser Text konzentriert sich auf ein zentrales Modell für den Vertrieb: sales.order. Egal ob Sie Module anpassen, Schnittstellen bauen oder Vertriebsprozesse konfigurieren — dieses Modell werden Sie häufig berühren.
Was ist das Modell sales.order?
Das sales.order-Modell bildet Angebote und Kundenbestellungen ab. Es ist der zentrale Datensatz, in dem alle relevanten Informationen einer Verkaufstransaktion erfasst werden, bevor Lieferung und Rechnung erstellt werden.
Dieses Modell wird primär vom Vertriebsmodul (Sales) genutzt.
Der typische Ablauf: Ein Verkäufer legt ein Angebot an — das ist ein sales.order-Datensatz im Status Entwurf. Bestätigt der Kunde, ändert sich der Status auf bestätigt. Draft-Angebote und finale Aufträge leben im selben Modell; das Feld state steuert den Lebenszyklus.
Andere Module bauen auf diesem Modell auf: CRM kann Opportunities mit Aufträgen verknüpfen, die Buchhaltung ergänzt Rechnungsfelder, die Lagerverwaltung ergänzt Liefertermine. Durch Odoos Vererbungsmechanismen fügt jedes Modul nur die benötigten Erweiterungen hinzu, statt das Kernmodell zu duplizieren.
Wichtige Felder im Modell
Im Folgenden die wichtigsten Felder des sales.order-Modells. Wenn Sie diese Felder kennen, fällt das Arbeiten mit Angeboten und Aufträgen deutlich leichter.
1. name
Typ: Char. Speichert die Auftrags- oder Angebotsnummer, meist automatisch vergeben (z. B. S00042). Sichtbar in Listenansichten und auf Dokumenten — das wichtigste Erkennungsmerkmal eines Auftrags.
2. state
Typ: Selection. Steuert den Status des Auftrags. Mögliche Werte: draft (Angebot), sent (Angebot versendet), sale (bestätigter Auftrag), done (vollständig geliefert und fakturiert), cancel (storniert). Der Status bestimmt verfügbare Aktionen und Workflows.
3. partner_id
Typ: Many2one (res.partner). Der Kunde oder Hauptansprechpartner. Pflichtfeld. Grundlage für Rechnungs- und Lieferlogik sowie Reporting.
4. partner_invoice_id
Typ: Many2one (res.partner). Die Rechnungsadresse. Falls leer, wird partner_id verwendet. Nützlich, wenn die Rechnung an eine zentrale Stelle gehen soll.
5. partner_shipping_id
Typ: Many2one (res.partner). Die Lieferadresse. Standardmäßig partner_id, kann aber abweichen für Lieferungen oder Versandkostenberechnung.
6. user_id
Typ: Many2one (res.users). Der zuständige Verkäufer oder Bearbeiter. Wichtig für Provisionen, Aktivitäten und Reporting. Meist über Team oder Opportunity gesetzt.
7. team_id
Typ: Many2one (crm.team). Das Verkaufsteam. Bildet Gruppen für Dashboards, Zielvorgaben und Auswertungen.
8. date_order
Typ: Datetime. Das Bestelldatum: bei Entwürfen das Erstellungsdatum, bei bestätigten Aufträgen das Bestätigungsdatum. Relevant für Auswertungen und Sortierung.
9. validity_date
Typ: Date. Ablaufdatum des Angebots. Nach diesem Datum kann ein Angebot ungültig sein — praktisch für zeitlich begrenzte Offerten.
10. commitment_date
Typ: Datetime. Vereinbarter Liefertermin. Wenn gesetzt, richten sich Lieferaufträge danach statt nach Standardlieferzeiten — wichtig für Zusagen gegenüber Kunden.
11. order_line
Typ: One2many (sale.order.line). Die Positionen des Auftrags. Jede Zeile enthält Produkt, Menge, Preis und Steuern — das inhaltliche Herz des Auftrags.
12. amount_untaxed
Typ: Float. Zwischensumme ohne Steuern. Wird aus den Positionen berechnet und für Anzeige sowie Berichte genutzt.
13. amount_tax
Typ: Float. Gesamte Steuerbeträge. Ermittelt aus den Positionen und Steuereinstellungen, sichtbar in Angebot und Rechnung.
14. amount_total
Typ: Float. Gesamtbetrag inklusive Steuern. Zentrale Zahl für Fakturierung und Umsatzreports.
15. currency_id
Typ: Many2one (res.currency). Währung des Auftrags. Meistens von Firma oder Preisliste vorgegeben — alle Geldfelder beziehen sich auf diese Währung.
16. pricelist_id
Typ: Many2one (product.pricelist). Preisliste, die auf den Auftrag angewandt wird. Bestimmt die Basispreise der Positionen; kann vom Kunden oder manuell gesetzt werden.
17. payment_term_id
Typ: Many2one (account.payment.term). Zahlungsbedingungen (z. B. 30 Tage netto, Anzahlung). Vererbt auf die Rechnung und steuert Fälligkeiten.
18. fiscal_position_id
Typ: Many2one (account.fiscal.position). Steuerposition für Länder- oder Sonderregelungen. Wird bei der Steuerberechnung auf Kundensituationen angewandt.
19. client_order_ref
Typ: Char. Kundenreferenz/Bestellnummer des Kunden. Wird auf Dokumenten angezeigt und erleichtert Rückverfolgung bei Fremdbezug.
20. origin
Typ: Char. Ursprung des Auftrags, z. B. der Name der Opportunity oder eines Verkaufsbelegs. Dient der Nachverfolgbarkeit über Prozesse hinweg.
21. create_date
Typ: Datetime. Zeitpunkt der Erstellung des Datensatzes. Automatisch gesetzt — nützlich für Audits und Reports.
22. write_date
Typ: Datetime. Zeitpunkt der letzten Änderung. Ebenfalls automatisch — hilft, Änderungszeitpunkte nachzuvollziehen.
23. note
Typ: Text. Freitext für AGB, interne Hinweise oder spezielle Vereinbarungen. Kann auf Angeboten und Rechnungen gezeigt werden.
24. require_signature
Typ: Boolean. Wenn aktiv, ist eine Kundenunterschrift erforderlich, bevor der Auftrag bestätigt wird — wichtig bei E‑Commerce-/Portalprozessen.
25. require_payment
Typ: Boolean. Wenn aktiv, muss die Zahlung vor Bestätigung eingehen — typisch für Anzahlungen oder Vorkasse.
26. invoice_status
Typ: Selection. Status der Fakturierung: no (nicht fakturiert), to invoice (zu fakturieren), invoiced (vollständig fakturiert), upsell (weitere Positionen zu fakturieren).
27. locked
Typ: Boolean. Sperrflag: Ist das Feld gesetzt, lässt sich der Auftrag nicht mehr bearbeiten. Wird beim Bestätigen oder Buchen von Folgebelegen automatisch gesetzt.
28. company_id
Typ: Many2one (res.company). In Multi‑Company-Umgebungen zeigt dieses Feld, zu welcher Firma der Auftrag gehört — relevant für Sichtbarkeit und Berechtigungen.
29. tag_ids
Typ: Many2many (crm.tag). Tags zur Kategorisierung. Praktisch für Filter, Segmentierung und individuelle Workflows.
30. signed_by
Typ: Char. Name der unterschreibenden Person, wenn require_signature genutzt wird — wichtig fürs Audit.
31. signed_on
Typ: Datetime. Zeitpunkt der Unterschrift — dient ebenfalls der Nachweisführung.
32. prepayment_percent
Typ: Float. Prozentualer Anzahlungsanteil, der vorab fällig ist. Wird zusammen mit require_payment für Anzahlungs‑Szenarien genutzt.
Wie dieses Modell in Geschäftsprozessen genutzt wird
1. Vom Angebot zum Auftrag
Ein Verkäufer erstellt ein Angebot, ergänzt Positionen und Preise und schickt es an den Kunden. Bestätigt der Kunde, wandelt sich der Datensatz in einen bestätigten Auftrag (state = sale) — anschließend können Rechnungen und Lieferaufträge erzeugt werden.
2. E‑Commerce und Kundenportal
Webshop‑Bestellungen legen automatisch sales.order‑Datensätze an. Über require_signature oder require_payment lassen sich Online‑Zahlung und Unterschrift als Bedingung vor Bestätigung erzwingen.
3. Vom CRM ins Sales
Gewonnene Opportunities erzeugen Angebote, die über das Feld origin zurückverfolgt werden können. user_id und team_id bestimmen Zuständigkeiten und fließen in Provisions‑ und Reporting‑Logiken ein.
4. Fakturierung
Aus einem bestätigten Auftrag werden Rechnungen erzeugt; Positionen und Konditionen (payment_term_id, fiscal_position_id) werden übernommen. invoice_status zeigt den Status der Rechnungsstellung an.
5. Lieferung und Lieferverpflichtung
Ein eingestelltes commitment_date bestimmt die Planung der Lieferaufträge; partner_shipping_id legt fest, wohin geliefert wird — beides entscheidend für operatives Fulfillment.
Wie Entwickler das Modell erweitern
Entwickler erweitern sales.order typischerweise mit Odoo‑Vererbung und mehreren Erweiterungsmustern.
Modellvererbung
Mit _inherit = 'sale.order' erweitern Sie das bestehende Modell. So fügen Sie neue Felder hinzu, überschreiben Methoden oder definieren Constraints — Änderungen bleiben in Ihrem Modul und sind upgradefreundlich.
Felder hinzufügen
Definieren Sie in der geerbten Klasse neue Felder (Char, Many2one, Boolean, Integer, Text, Selection). Denken Sie an mandantenabhängige Felder bei Multi‑Company‑Szenarien.
Python‑Erweiterungen
Überschreiben Sie Methoden wie action_confirm, create oder write, wenn Sie Geschäftslogik ergänzen wollen — rufen Sie super() auf, um die Standardlogik beizubehalten. Achten Sie besonders auf berechnete Felder und deren Dependencies.
Odoo Studio
Odoo Studio erlaubt schnelle, codefreie Anpassungen und ist ideal für einfache Erweiterungen. Für komplexe Anforderungen oder langfristigen Support sind Custom‑Module jedoch robuster.
Best Practices
- Nutzen Sie für jede Phase den passenden Status. Überspringen Sie keine Zustände und umgehen Sie nicht die Bestätigungslogik.
- Tragen Sie commitment_date ein, sobald ein verbindlicher Liefertermin vereinbart ist — das verbessert die Planung und Kundenzufriedenheit.
- Verwenden Sie commercial_partner_id, wenn Sie die juristische Hauptfirma einer Kontaktgruppe für Kredit‑ oder Reportingzwecke brauchen.
- Für API‑Integrationen nutzen Sie XML‑RPC oder JSON‑RPC. Das sales.order‑Modell ist über die API erreichbar — achten Sie auf korrekte Zuordnung externer IDs.
- Für eigene Felder verwenden Sie das Präfix x_ oder einen Modulpräfix, um Konflikte mit künftigen Odoo‑Versionen zu vermeiden.
Häufige Fehler
- Ändern Sie bestätigte Aufträge nicht einfach, wenn locked gesetzt ist. Erstellen Sie Revisionen oder folgen Sie dem vorgesehenen Workflow.
- Verwechseln Sie nicht partner_id, partner_invoice_id und partner_shipping_id — sie haben unterschiedliche Aufgaben. Setzen Sie alle drei, wenn Adressen abweichen.
- Rufen Sie beim Überschreiben von action_confirm immer super() auf. Ohne den Aufruf kann die Standardlogik anderer Module oder künftiger Versionen beschädigt werden.
- Fügen Sie keine Pflichtfelder ohne sinnvolle Default‑Werte hinzu. Bestehende Datensätze können sonst bei Upgrades Validierungsfehler werfen.
- Vergessen Sie nicht, pricelist_id zu setzen, wenn Preisgestaltung oder Währung abweichen — andernfalls drohen falsche Preise und fehlerhafte Rechnungen.
Fazit
Das sales.order‑Modell ist das Rückgrat des Odoo‑Vertriebs: Angebote und Bestellungen werden hier erfasst. Wer seine Felder, Erweiterungsmöglichkeiten und Integrationspunkte kennt, kann Odoo zielgerichtet konfigurieren und anpassen.
Ob Sie Vertriebsprozesse modellieren oder Module entwickeln — fundierte Kenntnisse des sales.order‑Modells sparen Zeit und vermeiden Fehler im Betrieb.
Brauchen Sie Unterstützung bei Ihrer Odoo-Einführung?
Das Team von Dasolo begleitet Unternehmen bei Odoo‑Einführungen, Individualentwicklung und API‑Anbindungen. Wir bringen Erfahrung mit Odoo‑Datenarchitektur und Modellen wie sales.order mit.
Wenn Sie Unterstützung bei Implementierung, Custom‑Modulen oder Integrationen brauchen, helfen wir Ihnen gern weiter. Demo vereinbaren um Ihr Projekt zu besprechen.