Innledning
I Odoo organiseres all forretningsdata i modeller — det er skjemaene som bestemmer hvilke opplysninger som lagres og hvordan de henger sammen. Alt fra kunder og produkter til ordre og fakturaer finnes som poster i modeller i databasen.
Å forstå modeller er kritisk både for utviklere og funksjonelle konsulenter. Modellene utgjør kjernen i Odoos datamodell: feltene, koblingene mellom poster og forretningslogikken som kjører når noe endres.
Denne teksten tar for seg et av de mest brukte objektene i salgsmodulen: sale.order.line. Enten du lager tilpassede moduler, kobler mot eksterne systemer eller bygger prising og faktureringsflyt, vil du nesten alltid møte denne modellen.
Hva er modellen sale.order.line
sale.order.line representerer enkeltlinjene på tilbud og salgsordre — hver rad beskriver vanligvis et produkt eller en tjeneste med mengde, pris og skatterelaterte verdier.
Modellen lever i salgspakken (sale) og arver funksjonalitet som analytisk sporbarhet for prosjektkostnader. Når en selger legger til et produkt på et tilbud, opprettes en sale.order.line-post bak kulissene.
Kjernen av modellen ligger i sale-modulen, men andre moduler bygger på den ved arv. For eksempel legger lagerintegrasjoner til leveranserelaterte felt, mens margin-moduler beregner fortjeneste — hver modul utvider uten å kopiere grunnstrukturen.
Viktige felt i modellen
Nedenfor finner du en oversikt over de viktigste feltene i sale.order.line. Kjennskap til disse gjør det enklere å forstå priser, levering og fakturering per linje.
1. order_id
Type: Many2one (sale.order). Obligatorisk. Feltet peker til den overordnede salgsordren og knytter linjen til den tilhørende ordren. Ved sletting av ordren fjernes linjene (kaskade).
2. sequence
Type: Integer. Standard 10. Bestemmer rekkefølgen linjene vises i dokumentet — nyttig for å sortere seksjoner, notater og produktlinjer.
3. company_id
Type: Many2one (res.company). Hentes fra order_id. Brukes for regler ved flere selskaper og tilgangsstyring.
4. currency_id
Type: Many2one (res.currency). Hentes fra order_id. Påvirker alle pengeverdi-felt på linjen og sikrer riktig valuta i prisberegninger.
5. order_partner_id
Type: Many2one (res.partner). Hentes fra order_id. Kunden på ordren — viktig for prisregler og skattematrise.
6. salesman_id
Type: Many2one (res.users). Hentes fra order_id. Angir ansvarlig selger — nyttig ved rapportering og provisjonsberegning.
7. state
Type: Selection. Hentes fra order_id. Viser status på ordren (for eksempel draft, sent, sale, done, cancel) og avgjør hvilke felt som kan endres.
8. display_type
Type: Selection. Verdier: line_section eller line_note. Setter linjen som overskrift eller kommentar i stedet for et produkt — produktfelt blir da tomme.
9. is_downpayment
Type: Boolean. Angir om linjen er et forskuddsbeløp. Slike linjer faktureres ofte separat.
10. is_expense
Type: Boolean. Sann når linjen stammer fra en kostnad eller leverandørfaktura. Brukes for prosjektkostnadsoppfølging.
11. product_id
Type: Many2one (product.product). Produktet som selges. Domenet begrenser til salgbare produkter. Påkrevde for produktlinjer.
12. product_template_id
Type: Many2one (product.template). Beregnes fra product_id. Brukes særlig i produktkonfiguratorer for å velge varianter.
13. name
Type: Text. Linjebeskrivelse. Genereres ut fra produkt og eventuelle egendefinerte attributter — inkluderer variantdetaljer ved behov.
14. product_uom_qty
Type: Float. Obligatorisk. Bestiller mengde. Standard 1.0. Kan påvirkes av emballasjevalg.
15. product_uom
Type: Many2one (uom.uom). Enhet for mengde. Standard hentes fra produktet og brukes i pris- og lagerberegninger.
16. tax_id
Type: Many2many (account.tax). Skatter som gjelder for linjen. Beregnes fra produkt og eventuell skattemessig posisjon.
17. price_unit
Type: Float. Obligatorisk. Enhetspris per valgt enhet. Bestemmes av prisliste eller produkt og kan overstyres manuelt.
18. discount
Type: Float. Rabattprosent. Påvirker pris_unit før skatt beregnes.
19. price_subtotal
Type: Monetary. Delbeløp før skatt. Beregnes ut fra mengde, enhetspris og rabatt.
20. price_tax
Type: Float. Totalt skattebeløp for linjen. Beregnes fra price_subtotal og tax_id.
21. price_total
Type: Monetary. Totalbeløp inkludert skatt. Dette er ofte tallet som brukes ved fakturering.
22. product_packaging_id
Type: Many2one (product.packaging). Valgfri emballasje (for eksempel kasse med 12). Når satt kan det styre beregning av mengde.
23. customer_lead
Type: Float. Ledetid i dager mellom ordre og avsendelse. Brukes til å estimere leveringsdato.
24. qty_delivered
Type: Float. Mengde som er levert. Oppdateres av varelagerbevegelser eller manuelt, og spiller inn ved delvis fakturering.
25. qty_invoiced
Type: Float. Mengde som allerede er fakturert. Beregnes fra fakturalinjer.
26. qty_to_invoice
Type: Float. Mengde som gjenstår å fakturere. Beregnes fra qty_delivered og qty_invoiced.
27. invoice_status
Type: Selection. Verdier: upselling, invoiced, to invoice, no. Viser faktureringsstatus for linjen.
28. invoice_lines
Type: Many2many (account.move.line). Kobling til fakturalinjer opprettet fra salgslinjen for sporbarhet.
29. create_date
Type: Datetime. Tidspunkt for opprettelse av posten. Administreres automatisk av Odoo.
30. write_date
Type: Datetime. Tidspunkt for siste endring. Nyttig for revisjon og synkronisering.
Hvordan modellen inngår i forretningsflyten
1. Tilbud og salgsordre
Når en selger bygger et tilbud legger vedkommende til produkter som hver blir sin linje — disse linjene viser mengde, enhetspris, eventuell rabatt og linjetotal. Når kunden godtar tilbudet, konverteres det til en bekreftet ordre.
2. Prislister og rabatter
Prislister og rabatter anvendes per linje. price_unit og discount hentes ofte fra prisliste-regler som håndterer volumbaserte priser eller kundeavtaler.
3. Levering og fakturering
Leveransestatus oppdaterer qty_delivered, og systemet kan fakturere basert på leverte mengder eller samle alt i én faktura. invoice_status gir et tydelig bilde av hva som fortsatt må faktureres.
4. Prosjekt og tjenester
For tjenester kan salgslinjer kobles til prosjektoppgaver og timelister. Arven fra analytisk miks gjør det mulig å spore kostnad per prosjekt.
5. Nettbutikk og portal
Når kunder handler på nett blir hver handlekurvlinje en sale.order.line ved ordredannelse. Produktkonfiguratoren og produkt_template_id spiller ofte sammen ved valg av varianter.
Slik utvider utviklere modellen
Utviklere utvider sale.order.line ved hjelp av Odoos arvemønstre og egne moduler for å legge til felt eller logikk.
Modellarv
Sett _inherit = 'sale.order.line' i din modul for å bygge på modellen. Du kan legge til felt, overstyre metoder eller legge inn begrensninger — endringene ligger i en egen modul slik at oppgraderinger blir enklere å håndtere.
Legge til felt
Definer nye felt i din arvede modell med passende typer: Char, Many2one, Boolean, Integer, Text, Selection osv. Vurder selskapsspesifikke felt ved flerselskapsoppsett.
Python-utvidelser
Overstyr beregningsmetoder (for eksempel for pris eller totaler) eller legg til logikk i create/write. Husk å bruke super() der det er nødvendig, og vær oppmerksom på avhengigheter i beregnede felt.
Odoo Studio
Odoo Studio lar deg raskt legge til felt uten koding — nyttig for raske tilpasninger. For mer komplisert logikk og for vedlikeholdbarhet anbefales egendefinerte moduler.
Gode fremgangsmåter
- Bruk display_type for å skille seksjoner og notater fra produktslinjer; det gir renere rapporter og unngår valideringsproblemer.
- Ved API-integrasjoner oppretter du linjer ved å sende dem via order_line-feltet på salgsordren med korrekt kommandosyntaks slik at relasjonen til ordre er riktig.
- Respekter databasens begrensninger: produktlinjer må ha product_id og product_uom, mens notat- eller seksjonslinjer skal bruke display_type for å markeres riktig.
- For tilpasset prising er det ofte best å bruke prislister fremfor å overstyre beregningsfunksjoner — overstyring bør kun brukes når prislister ikke dekker behovet.
- Navngi egne felt med x_ eller et modulprefiks for å minimere kollisjoner med fremtidige Odoo-versjoner.
Vanlige feil
- Å opprette linjer uten order_id. Feltet er påkrevd — opprett alltid linjer i kontekst av en ordre for å sikre konsistens.
- Forveksling mellom product_id og product_template_id. Bruk product_id for konkrete produktlinjer; product_template_id brukes typisk i konfiguratorstrømmer når du skal velge varianter.
- Endring av pris eller rabatt etter at en delmengde er fakturert. Når qty_invoiced > 0 kan etterfølgende prisendringer skape avvik i regnskapet.
- Å overstyre kjernemetoder uten å kalle super(). Det kan bryte andre utvidelser eller gjøre fremtidige oppgraderinger vanskelige.
- Glemme å sette display_type for seksjon- eller notatlinjer. Uten dette behandles linjen som et produkt, noe som kan føre til valideringsfeil.
Oppsummering
sale.order.line er hjørnesteinen i salgsflyten i Odoo — den lagrer hver enkelt linje på tilbud og ordre. Kjennskap til feltene og hvordan andre moduler bygger på modellen gjør det lettere å konfigurere, tilpasse og integrere systemet.
Enten du kartlegger forretningsprosesser som funksjonell konsulent eller utvikler tilpassede løsninger, vil god forståelse av sale.order.line spare tid og forebygge feil.
Trenger du hjelp med Odoo-implementasjonen?
Dasolo hjelper selskaper med å implementere, tilpasse og optimalisere Odoo. Vi har spesialkompetanse på API-integrasjoner og utvikling, og inngående erfaring med Odoos datamodell og sentrale modeller som sale.order.line.
Trenger du bistand med Odoo-implementasjon, utvikling av moduler eller integrasjoner, bistår vi gjerne. Book en demo for å diskutere prosjektet ditt.