Introduktion
I Odoo er modellerne de skabeloner, der bestemmer, hvordan forretningsdata organiseres i databasen. Alt fra ordrer og fakturaer til kunder og varer ligger i modeller — de er strukturens rygrad.
At kende Odoo-modeller er vigtigt både for udviklere og forretningskonsulenter. Modeller udstikker felter, relationer og forretningslogik, og de danner fundamentet for rapporter, workflows og udvidelser.
Denne guide går i dybden med en af de mest centrale modeller: sales.order. Uanset om du bygger moduler, laver integrationer eller tilpasser salgsprocessen, vil du ofte støde på denne model.
Hvad er modellen sales.order?
Modellen sales.order fanger både tilbud og salgsaftaler i Odoo. Her samles alle oplysninger om en salgshændelse, før den eventuelt bliver leveret eller faktureret.
Modellen anvendes primært af Salg-modulet i Odoo.
Procesmæssigt starter en sælger typisk med et udkast til et tilbud — det oprettes som en sales.order i tilstand 'draft'. Når kunden bekræfter, skifter posten status til 'sale' og kan udløse leverancer og fakturaer. Ét og samme objekt håndterer hele denne livscyklus, mens feltet state styrer, hvad der må ske næste.
Andre moduler bygger videre på sales.order gennem arv og tilføjelser. CRM kan koble en mulighed til ordren, regnskab tilføjer fakturarelaterede felter, og lagerstyring tilføjer leveringsdatoer — alle arbejder på samme grundmodel uden at gentage kerneopbygningen.
Væsentlige felter i modellen
Her er de vigtigste felter, du møder i sales.order, og hvorfor de betyder noget i praksis.
1. name
Type: Char. Feltet indeholder ordrenummeret eller tilbudsreferencen. Det vises i lister og dokumenter og fungerer som den synlige identifikation af ordren — ofte automatisk genereret.
2. state
Type: Selection. Viser ordrestadiet (fx draft, sent, sale, done, cancel). State bestemmer, hvilke handlinger der er tilladte i hver fase og er central for workflow-styring.
3. partner_id
Type: Many2one (res.partner). Kunden på ordren. Obligatorisk. Bruges til priser, kontaktinformation og rapportering.
4. partner_invoice_id
Type: Many2one (res.partner). Fakturaadressen. Hvis den ikke er angivet, benyttes partner_id som standard — vigtig når fakturering skal gå til et andet sted.
5. partner_shipping_id
Type: Many2one (res.partner). Leveringsadressen. Standard er partner_id, men sæt dette felt når varen skal sendes et andet sted.
6. user_id
Type: Many2one (res.users). Den ansvarlige sælger eller bruger. Bruges til kommission, aktivitetsstyring og ejerskab af ordren.
7. team_id
Type: Many2one (crm.team). Salgsteamet. Hjælper med gruppering, rapporter og målstyring.
8. date_order
Type: Datetime. Ordredatoen — for kladder er det oprettelsesdato, for bekræftede ordrer er det bekræftelsesdatoen. Bruges i rapporter og tidsfiltre.
9. validity_date
Type: Date. Tilbudsudløbsdato. Efter denne dato bør tilbuddet betragtes som udløbet eller kræve fornyet accept.
10. commitment_date
Type: Datetime. Lovet leveringsdato. Når denne er sat, planlægges leverancer og logistik omkring den — vigtigt for kundeløfter.
11. order_line
Type: One2many (sale.order.line). Ordens linjer — hvert element beskriver produkt, mængde, enhedspris og skat. Dette er selve kernen i ordren.
12. amount_untaxed
Type: Float. Subtotal før skat. Beregnes ud fra linjerne og bruges til visning og rapportering.
13. amount_tax
Type: Float. Samlet skattebeløb. Beregnes ud fra linjernes skattekonfiguration og vises på ordre og faktura.
14. amount_total
Type: Float. Totalbeløbet inkl. skat — det vigtigste tal ved fakturering og økonomirapportering.
15. currency_id
Type: Many2one (res.currency). Valutaen for ordren. Ofte arvet fra virksomheden eller prisliste, og alle pengebeløb refererer hertil.
16. pricelist_id
Type: Many2one (product.pricelist). Den prisliste, der bestemmer enhedspriserne. Kan vælges manuelt eller foreslås fra kunden.
17. payment_term_id
Type: Many2one (account.payment.term). Betalingsbetingelser (fx netto 30 dage eller delbetaling). Overføres til fakturaen.
18. fiscal_position_id
Type: Many2one (account.fiscal.position). Bruges til skattemapping ved grænseoverskridende salg eller særlige skatteregimer.
19. client_order_ref
Type: Char. Kundens eget ordrenummer eller PO-reference. Nyttigt for dokumenter og sporbarhed, når kunden har sit eget referencefelt.
20. origin
Type: Char. Kilde-dokumentet — fx navnet på en CRM-mulighed, der skabte ordren. Hjælper med sporbarhed i processer.
21. create_date
Type: Datetime. Tidspunktet for oprettelse af posten — styres automatisk af Odoo og bruges i revision og rapporter.
22. write_date
Type: Datetime. Tidspunkt for seneste ændring — også automatisk, nyttigt ved fejlsøgning og synkronisering.
23. note
Type: Text. Fritekst til betingelser, interne kommentarer eller specielle instrukser, som kan vises på tilbud og fakturaer.
24. require_signature
Type: Boolean. Hvis sand, kræves kundesignatur online før ordren kan bekræftes — relevant ved webshop eller portal-bestillinger.
25. require_payment
Type: Boolean. Hvis sand, skal betaling gennemføres før bekræftelse — bruges til forudbetaling eller depositum.
26. invoice_status
Type: Selection. Viser faktureringsstatus: ikke faktureret, klar til fakturering, faktureret eller supplerende faktureringslinjer.
27. locked
Type: Boolean. Låser ordren for ændringer når den er bekræftet eller relaterede dokumenter er bogført — beskytter dataintegriteten.
28. company_id
Type: Many2one (res.company). Angiver hvilken virksomhed i et multivirksomhedssetup ordren hører til — påvirker synlighed og adgangsregler.
29. tag_ids
Type: Many2many (crm.tag). Frie tags til kategorisering og segmentering — praktisk til filtrering og rapporter uden at ændre datamodellen.
30. signed_by
Type: Char. Navnet på den person, der underskrev ordren ved krav om digital signatur — nyttigt i revision.
31. signed_on
Type: Datetime. Tidspunktet for signaturen — bruges sammen med signed_by til sporbarhed.
32. prepayment_percent
Type: Float. Procentdel af ordren der skal forudbetales. Bruges sammen med require_payment til depositumberegninger.
Hvordan modellen bruges i forretningsprocesser
1. Fra tilbud til ordre
Typisk flow: sælger opretter et tilbud (draft), tilføjer linjer og sender det til kunden. Når kunden accepterer, skifter ordren til bekræftet (sale) og kan udløse leverancer og fakturaer.
2. Webshop og portal
Når kunder bestiller via webshoppen, oprettes salgsordrer automatisk. Felter som require_payment og require_signature kan tvinge betaling eller underskrift før ordren går videre.
3. Fra CRM til salg
Når en mulighed vindes i CRM, kan der genereres et tilbud direkte fra muligheden. origin-feltet binder ordren tilbage til muligheden, mens user_id/team_id bevarer ansvar og rapportering.
4. Fakturering
Fra en bekræftet ordre oprettes fakturaer, hvor linjerne kopieres fra ordrelinjerne. Betalingsbetingelser og fiscal position følger med, og invoice_status viser fremskridtet.
5. Levering og lovet dato
commitment_date bruges til at planlægge leverancer; når den er sat, planlægges pluk og forsendelse omkring den. partner_shipping_id angiver, hvor varerne skal leveres.
Hvordan udviklere udvider modellen
Udviklere bygger videre på sales.order med flere mønstre, hvor modelarv er den mest almindelige metode.
Modelarv
Brug _inherit = 'sale.order' for at tilføje felter, ændre metoder eller indføre valideringer. Ved at lave ændringer i et separat modul bevares overskueligheden og opgraderbarheden.
Tilføjelse af felter
Definér nye felttyper i din arvede model — Char, Many2one, Boolean, Integer, Text eller Selection efter behov. Overvej virksomhedsspecifikke (company-dependent) felter i multivirksomhedsscenarier.
Python-udvidelser
Overskriv metoder som action_confirm, create eller write for at indsprøjte logik. Husk altid at kalde super() hvor relevant, især ved computed fields og afhængigheder.
Odoo Studio
Odoo Studio giver mulighed for at tilføje felter uden kode — hurtig og brugervenlig til simple behov. Til mere kompleks logik eller vedligeholdelse over tid er custom-moduler dog at foretrække.
Gode fremgangsmåder
- Brug altid korrekt status i workflowet. Spring ikke stadier over og undgå at omgå bekræftelseslogik, da det kan skabe inkonsistens.
- Sæt commitment_date når der er en aftalt leveringsdato — det forbedrer planlægning og kundekommunikation.
- Brug commercial_partner_id når du har brug for topniveau-entiteten for kreditvurdering eller konsolideret rapportering.
- Ved API-integrationer benyt XML-RPC eller JSON-RPC, som begge eksponerer sales.order. Kortlæg eksterne id'er omhyggeligt for at undgå dubletter eller fejlagtige opdateringer.
- For nye felter anbefales et modul- eller x_-prefix for at undgå navnekonflikter ved fremtidige Odoo-opgraderinger.
Almindelige fejl
- Forsøg aldrig at redigere en bekræftet ordre uden at tjekke locked-flaget. Hvis en ordre er låst, lav en revision eller følg det korrekte workflow for ændringer.
- Undgå at blande partner_id, partner_invoice_id og partner_shipping_id sammen — de tjener hver deres formål. Udfyld alle tre ved forskellig adressehåndtering.
- Glem ikke at kalde super() når du overskriver action_confirm — ellers risikerer du at bryde andre modulers forventninger eller kompatibilitet ved opgraderinger.
- Tilføj ikke obligatoriske brugerdefinerede felter uden fornuftige defaults — ellers kan eksisterende poster fejle ved opgraderinger eller import.
- Manglende sætning af pricelist_id ved forskellige valutaer eller prisregler fører ofte til forkerte priser og dermed fejlfakturering.
Konklusion
Sales.order er hjørnestenen i Odoo Salg: den samler tilbud og bekræftede ordrer og er det primære arbejdsobjekt for konfiguration, tilpasning og integration.
Uanset om du kortlægger salgsprocesser som konsulent eller udvikler specialmoduler, vil en grundlæggende forståelse af sales.order spare tid og forhindre fejl.
Brug for hjælp til din Odoo-implementering?
Dasolo hjælper virksomheder med at implementere, tilpasse og optimere Odoo — med særlig erfaring i API-integrationer og dyb viden om Odoos datamodel, herunder sales.order.
Har du brug for assistance til din Odoo-implementering, udvikling af moduler eller integrationer? Vi kan hjælpe. Book en demo for at drøfte dit projekt.