Johdanto
Odoossa jokainen liiketoiminnan tieto — tarjousriveistä laskuihin ja yhteystietoihin — tallennetaan tietomallien kautta. Mallit määrittävät, miten tiedot jäsennellään ja miten ne pysyvät järjestyksessä tietokannassa.
Mallien ymmärtäminen on tärkeää niin kehittäjille kuin toiminnallisille konsultseille, koska ne muodostavat Odoon tietorakenteen ytimen. Mallit kuvaavat kentät, niiden väliset suhteet ja liiketoimintasäännöt.
Tässä artikkelissa keskitytään Sales‑moduulin yhteen tärkeimpään malliin: sale.order.line. Oli tavoitteesi räätälöidä moduuleja, kytkeä ulkoisia järjestelmiä tai muotoilla hinnoittelukäytäntöjä, tämä malli tulee vastaan useimmiten myynnin riveihin liittyvissä toiminnoissa.
Mikä on sale.order.line‑malli
sale.order.line edustaa yksittäistä riviä tarjouksessa tai myyntitilauksessa. Yksi rivi kuvaa yleensä yhtä tuotetta tai palvelua — siihen liittyy määrä, yksikköhinta ja verotiedot.
Mallia käyttää myyntimoduuli (sale). Se periytyy analytic.mixinistä, jotta projektien kustannusseuranta ja tuntikirjaukset toimivat saumattomasti. Kun lisäät tuotteen tarjoukseen, luot käytännössä uuden sale.order.line‑tietueen.
sale‑moduuli määrittelee mallin ydinrakenteen, mutta muut moduulit voivat laajentaa sitä periytymällä. Esimerkiksi sale_stock lisää toimituksiin liittyviä kenttiä ja sale_margin laskee katteita — jokainen lisäys täydentää ydintä ilman sen kopioimista.
Mallin keskeiset kentät
Seuraavaksi on koottu mallin tärkeimmät kenttätyypit ja niiden tarkoitus. Näiden tuntemus auttaa hallitsemaan tarjouksia ja myyntitilauksia oikein.
1. order_id
Tyyppi: Many2one (sale.order). Pakollinen. Viittaa emämyyntitilaukseen. Tämä kenttä yhdistää rivin tilaukseen; rivit poistetaan järjestelmästä, kun tilaus poistetaan (cascade).
2. sequence
Tyyppi: Integer. Oletus 10. Määrittää rivien näyttöjärjestyksen tilauksessa. Käytetään osioiden, huomautusten ja tuoteryhmien lajitteluun.
3. company_id
Tyyppi: Many2one (res.company). Peritty order_id:stä. Tarpeellinen moniyritysympäristöissä ja käyttöoikeuksien rajoittamisessa.
4. currency_id
Tyyppi: Many2one (res.currency). Peritty order_id:stä. Rahayksikkö, jota käytetään rivin arvoissa, jotta hinnoittelu on oikeaa valuuttaa.
5. order_partner_id
Tyyppi: Many2one (res.partner). Peritty order_id:stä. Asiakas, jonka perusteella toimeksiannon hinnasto‑ ja verosäännöt määräytyvät.
6. salesman_id
Tyyppi: Many2one (res.users). Peritty order_id:stä. Myyjävastuussa oleva käyttäjä, tärkeä komissioille ja raportoinnille.
7. state
Tyyppi: Selection. Peritty order_id:stä. Tilan arvot (draft, sent, sale, done, cancel) ohjaavat, mitkä kentät ovat muokattavissa.
8. display_type
Tyyppi: Selection. Arvot: line_section tai line_note. Kun arvo asetetaan, rivi toimii otsikkona tai kommenttina eikä tuotteena — tuotetiedot jätetään tyhjiksi.
9. is_downpayment
Tyyppi: Boolean. Ilmaisee, onko rivi ennakkomaksu. Ennakot käsitellään ja laskutetaan erikseen.
10. is_expense
Tyyppi: Boolean. Totta, jos rivi tulee kululaskusta tai toimittajalta. Käytetään projektikulujen seurannassa.
11. product_id
Tyyppi: Many2one (product.product). Myytävä tuote. Rajaus sallii vain myytäviksi merkittyjä tuotteita. Tuoterivit vaativat yleensä tuotteen.
12. product_template_id
Tyyppi: Many2one (product.template). Lasketaan product_id:stä. Käytetään tuotevarianttivalinnan ja konfiguroinnin apuna.
13. name
Tyyppi: Text. Rivin kuvaus. Rakentuu tuotteen ja mahdollisten lisäominaisuuksien perusteella, ja sisältää varianttitiedot tarvittaessa.
14. product_uom_qty
Tyyppi: Float. Pakollinen. Tilattu määrä. Oletuksena 1.0. Määrään voi vaikuttaa esimerkiksi pakkauskoko.
15. product_uom
Tyyppi: Many2one (uom.uom). Mittayksikkö, joka periytyy tuotteesta. Vaikuttaa määrään ja hinnoitteluun.
16. tax_id
Tyyppi: Many2many (account.tax). Riville sovellettavat verot. Lasketaan tuotteen ja asiakkaan veropolitiikan perusteella.
17. price_unit
Tyyppi: Float. Pakollinen. Yksikköhinta per product_uom. Hinta määrittyy hinnaston tai tuotteen perusteella, mutta sen voi myös päivittää manuaalisesti.
18. discount
Tyyppi: Float. Alennusprosentti. Sovelletaan ennen verolaskentaa.
19. price_subtotal
Tyyppi: Monetary. Välisumma ennen veroja. Lasketaan määrästä, yksikköhinnasta ja alennuksesta.
20. price_tax
Tyyppi: Float. Veron osuus. Lasketaan price_subtotal:sta ja tax_id:stä.
21. price_total
Tyyppi: Monetary. Kokonaissumma veroineen. Tätä käytetään laskutuksen pääsummana.
22. product_packaging_id
Tyyppi: Many2one (product.packaging). Valinnainen pakkauskenttä (esim. 12 kpl laatikko). Asetettaessa pakkaus voi ohjata tilausmääriä.
23. customer_lead
Tyyppi: Float. Toimitusaika päivinä. Aika tilauksen vahvistuksesta lähetykseen — käytetään arvioimaan toimituspäivää.
24. qty_delivered
Tyyppi: Float. Toimitettu määrä. Päivittyy varastosiirroista tai voidaan säätää käsin. Tärkeä osalaskutuksissa.
25. qty_invoiced
Tyyppi: Float. Jo laskutettu määrä. Lasketaan laskuriveistä.
26. qty_to_invoice
Tyyppi: Float. Jäljellä laskutettava määrä. Lasketaan toimitusten ja laskujen perusteella.
27. invoice_status
Tyyppi: Selection. Arvot: upselling, invoiced, to invoice, no. Näyttää rivin laskutuksen tilan.
28. invoice_lines
Tyyppi: Many2many (account.move.line). Linkitys laskuriveihin, jotka on luotu tästä myyntirivistä — tärkeä jäljitettävyyden kannalta.
29. create_date
Tyyppi: Datetime. Milloin tietue luotiin. Hallitaan automaattisesti.
30. write_date
Tyyppi: Datetime. Milloin tietuetta viimeksi muokattiin. Käytetään auditointiin.
Miten malli toimii liiketoimintaprosesseissa
1. Tarjous ja myyntitilaus
Myyjä rakentaa tarjouksen lisäämällä tuotteita riveille; jokaisesta lisätystä tuotteesta muodostuu sale.order.line. Rivit näyttävät määrän, hinnan, alennuksen ja rivisumman. Asiakas hyväksyy tarjouksen ja tilaus vahvistetaan.
2. Hinnastot ja alennukset
Hinnastot koskevat rivikohtaisesti. price_unit ja discount määräytyvät hinnastosääntöjen mukaan — tilauksissa voidaan ottaa huomioon asiakaskohtaiset hinnat ja määrälliset alennukset.
3. Toimitus ja laskutus
Kun tuotteet lähetetään, qty_delivered päivittyy varastotapahtumista. Laskutus voidaan tehdä toimitusten mukaan tai kerralla koko tilauksesta; invoice_status kertoo, mitä vielä pitää laskuttaa.
4. Projektit ja palvelut
Palvelutuotteiden riveillä voidaan linkittää projektitehtäviin ja tuntikirjauksiin. Analyyttisen seurantamixin ansiosta kustannukset löytyvät projektikohtaisesti.
5. Verkkokauppa ja portaali
Verkkokaupassa ostoskoriin lisätyt tuotteet muuttuvat myyntitilauksen riveiksi tilauksen luodessa. Tuotteen konfigurointi hyödyntää product_template_id:tä ja mahdollisia mukautettuja attribuutteja.
Miten kehittäjät laajentavat mallia
Kehittäjät laajentavat sale.order.lineia useilla tavoilla, mutta Odoon malliperintä on yleisin ja suositeltava tapa.
Malliperintä
Käytä _inherit = 'sale.order.line' lisätäksesi kenttiä, ylikirjoittaaksesi metodeja tai lisätäksesi validaatioita. Muutos jää omaan moduuliin, mikä helpottaa päivityksiä ja ylläpitoa.
Uusien kenttien lisääminen
Määrittele periytetyssä mallissa tarvittavat kenttätyypit: Char, Many2one, Boolean, Integer, Text, Selection jne. Moniyrityskäytöissä harkitse company‑riippuvaisia kenttiä.
Python‑laajennukset
Ylikirjoita esimerkiksi laskentametodeja kuten _compute_price_unit tai _compute_price_subtotal tai lisää logiikkaa create/write‑metodeihin. Muista kutsua super() kun laajennat olemassa olevaa toimintaa ja suunnittele computed‑kenttien riippuvuudet huolellisesti.
Odoo Studio
Odoo Studio mahdollistaa kenttien lisäämisen ilman ohjelmointia — nopea ratkaisu yksinkertaisiin muutoksiin. Monimutkaisempi logiikka ja pitkäaikainen ylläpito kannattaa toteuttaa omassa moduulissa.
Hyvät käytännöt
- Käytä display_typea otsikoihin ja huomautuksiin sen sijaan, että luot niiden varjoksi tuoteryhmiä. Näin raportit ja validoinnit pysyvät siisteinä.
- API‑integraatioissa luo rivit aina order_idn kautta. Käytä sale.orderin order_line_ids‑kenttää ja oikeaa komentomuotoa (write/commands) luotettaviin päivityksiin.
- Noudata tietokantaan sidottuja SQL‑rajoitteita: tuoteryhmän rivillä tulee olla product_id ja product_uom, kun taas osio‑ tai huomautusrivin tulee käyttää display_typea.
- Mukautetussa hinnoittelussa hyödynnä hinnastosääntöjä aina kun mahdollista. Override‑metodeja kannattaa käyttää vain, jos hinnastot eivät pysty kattamaan vaadittua logiikkaa.
- Oma‑kentät merkitse x_‑tai moduulin etuliitteellä välttääksesi yhteentörmäyksiä tulevissa Odoo‑versioissa.
Yleisimmät virheet
- Rivien luominen ilman order_idtä on virheellinen käytäntö, sillä kenttä on pakollinen. Luo rivit aina tilauksen kontekstissa.
- Älä sekoita product_id:tä ja product_template_id:tä: varsinaiset tuoterekisteröinnit tehdään product_id:llä; konfiguroinnissa tai varianttivalinnoissa käytetään product_template_id:tä.
- Älä muuta price_unitia tai discountia sen jälkeen kun qty_invoiced on suurempi kuin nolla — tällaiset muutokset voivat aiheuttaa ristiriitoja laskutuksessa ja kirjanpidossa.
- Älä ylikirjoita ydintoimintoja ilman super()‑kutsua — se voi rikkoa muiden moduulien toiminnan tai vaikeuttaa tulevia päivityksiä.
- Muista asettaa display_type osioille ja huomautuksille. Jos jätät sen pois, rivi käsitellään tuotena ja validointi voi epäonnistua.
Yhteenveto
sale.order.line on myynnin kannalta keskeinen malli: se tallentaa kaikki tilausrivit ja niiden taloudelliset vaikutukset. Mallin kenttien ja laajennusmekanismien tuntemus tekee Odoo‑konfiguroinnista, räätälöinnistä ja integraatioista tehokkaampaa.
Toiminnallisena konsulttina tai kehittäjänä hyvän ymmärryksen hankkiminen tästä mallista säästää aikaa ja vähentää virheiden riskiä toteutusten aikana.
Tarvitsetko apua Odoo‑käyttöönotossa?
Dasolo auttaa yrityksiä Odoo‑käyttöönotossa, räätälöinneissä ja optimoinnissa. Erikoisosaamistamme ovat API‑integraatiot ja räätälöity kehitys — tuntemuksemme Odoon tietomalleista, kuten sale.order.line, on syvällinen.
Tarvitsetko apua Odoo‑projektiin, moduulikehitykseen tai integraatioihin? Ota yhteyttä — autamme mielellämme. Varaa demo keskustellaksesi projektistasi.