Introduksjon
Datoer og tidspunkter ligger i kjernen av de fleste forretningsprosesser: når ble en ordre lagt inn, når skal en levering skje, eller når stemplet en ansatt inn? I Odoo brukes et eget Datetime-felt for å fange både dato og klokkeslett presist, slik at systemet kan svare på slike spørsmål uten tolkningsfeil.
I motsetning til et rent Dato-felt, som bare registrerer en kalenderdag, lagrer Datetime både dato og eksakt tidspunkt. Det blir spesielt viktig i miljøer med brukere i flere tidssoner eller når oppgaver må logges ned på minutt- eller sekundnivå.
Denne veiledningen gir deg en praktisk gjennomgang av Datetime-feltet i Odoo: hva slags data det holder, hvordan det oppfører seg i modellen og i visninger, hvordan du kan opprette det via Studio, Python eller API, og konkrete eksempler på hvordan bedrifter bruker det i hverdagen.
Hva er Datetime-feltet i Odoo
I Odoo sitt ORM representeres feltet som fields.Datetime og lagrer dato + tid ned til sekundet. I PostgreSQL blir dette til en TIMESTAMP-kolonne. Internt lagres alltid verdiene i UTC, mens Odoo konverterer og viser tidene basert på den aktive brukerens tidssone når de vises i grensesnittet.
For sluttbrukeren vises Datetime som en kombinert datovelger og klokkeslettfelt i skjemaer, med kalender for dato og separat inndata for tid. I lister og rapporter formateres verdien etter språk- og tidssoneinnstillingene til brukeren som ser den.
Slik definerer man typisk et Datetime-felt i en Python-modell:
from odoo import fields, models
class SaleOrder(models.Model):
_inherit = 'sale.order'
x_confirmed_on = fields.Datetime(
string='Confirmed On',
default=fields.Datetime.now,
readonly=True,
copy=False,
)
Parameterne styrer hvordan feltet oppfører seg: string gir etiketten i UI, default fyller inn nåværende tidspunkt ved opprettelse, og readonly gjør feltet skrivebeskyttet — vanlig for automatiske tidsstempel-felt.
I Odoo Studio heter typen Date & Time. Felt som opprettes fra Studio får automatisk et x_studio_-prefiks. Oppretter du feltet i kode eller via API, bestemmer du selv teknisk navn.
Hvordan feltet fungerer
Når du definerer et Datetime-felt i modellen, oppretter Odoo selv den nødvendige databasetabellkolonnen under modulinstallasjon eller oppgradering. Du trenger som regel ikke skrive egne SQL-migrasjoner.
En utfordring mange støter på er tidssonehåndteringen: verdier lagres alltid i UTC. Hvis en bruker i Paris setter et møte til 15:00, vil dette bli lagret som 13:00 UTC. En bruker i New York vil se datoen vist som 09:00 i sitt grensesnitt. Odoo gjør denne konverteringen automatisk ut fra hver brukers tidssoneinnstilling.
Viktige feltattributter
Her er de viktigste egenskapene du bør kjenne til for et Datetime-felt i Odoo-rammeverket:
- default: Ofte satt til
fields.Datetime.nowfor å automatisk fylle inn gjeldende UTC-tid ved opprettelse av posten. - required: Gjør feltet obligatorisk både i skjema og på modellenivå.
- readonly: Hindrer manuell redigering i brukergrensesnittet — nyttig for systemgenererte tidsstempler.
- compute: Kan kobles til en Python-metode som beregner feltets verdi dynamisk fra andre felt eller forretningslogikk.
- store: I kombinasjon med
computelagres den beregnede verdien i databasen, slik at den kan brukes i søk og rapporter. - copy: Styrer om verdien skal kopieres ved duplisering av poster. Standard er
True; brukFalsefor tidsstempel som ikke skal følge med duplikater. - index: Oppretter en databaseindeks. Nyttig for felter som ofte brukes i filtre på store tabeller, for eksempel planlagte datoer.
Slik vises feltet i visninger
I skjemaer vises Datetime som en kombinert datokalender og klokkeslettboks. I listevisninger vises det som en formatert tekststreng basert på brukerens språk. I søk kan man bruke rekkeviddefiltre som før, etter og mellom to datoer for å snevre inn resultater.
Du kan også bruke date_range-widgeten sammen med Datetime for å vise et tidsvindu direkte i skjemaet — praktisk for planlegging av vaktvinduer eller tidsbegrensede oppgaver.
Datetime vs Date — hvilket skal du velge?
Hovedregelen er enkel: bruk fields.Date når tidspunktet på dagen ikke har betydning, og fields.Datetime når du trenger nøyaktighet ned til time eller minutt.
Velg Date for tilfeller som forfallsdato på fakturaer, fødselsdager, produktets utløpsdatoer eller fornyelsesdatoer på kontrakter.
Velg Datetime for hendelser som ordrebekreftelser, møtestart, ansattes innsjekk, eller planlagte lagringsoperasjoner i logistikk.
Unødvendig bruk av Datetime introduserer tidssone-kompleksitet uten fordel. Still deg selv om tidspunktet på dagen faktisk betyr noe for prosessen du modellerer.
Forretningsscenarier
Praktiske eksempler fra Odoo-moduler
CRM: Sporing av aktiviteter på leads
I CRM sporer Datetime-felt når viktige hendelser skjer: date_open når en lead settes til Aktiv, date_deadline for planlagt oppfølging. Slike tidspunkter gir salgsledelsen innsikt i responstid, identifisering av gamle leads og aktivitetsrapportering. Skreddersydde Datetime-felt kan logge når tilbud ble sendt eller når en samtale fant sted.
Salg: Tidspunkt for ordrebekreftelse
På salgsposter fanges bekreftelsestidspunktet i et Datetime-felt (date_order). Dette er nyttig for time- eller dagsbasert salgsovervåkning, måling av behandlingstid og revisjon når posterior endringer skjer. Å filtrere ordrer på dette feltet er en av de vanligste rapportoperasjonene i salgsarbeidet.
Lager: Planlagte overføringer
I lagerstyring brukes scheduled_date for å planlegge når plukking eller forsendelse skal utføres. Automatisering kan trigges ut fra hvordan denne datoen står i forhold til nåtid — for eksempel sende varsler ved forsinkede leveranser slik at kundekommunikasjon kan gjøres proaktivt.
Produksjon: Start- og slutttider
I produksjon registreres start- og stoptidspunkter for jobber i Datetime-felt. Informasjonen flyter inn i kapasitetsplanlegging, effektivitetsovervåkning og analyse. For bedrifter med skift er presise tidspunkter nødvendige for å sammenligne planlagt og faktisk produksjon og finne flaskehalser på ulike tidspunkter av døgnet.
HR: Fravær og tidspunktsregistrering
HR-moduler bruker Datetime for innsjekk/utsjekk og for å definere presise start- og sluttidspunkter for permisjoner. Lønnskjøring og overtidsberegning er avhengig av at disse verdiene er nøyaktige. Manglende eller unøyaktige tidsstempler kan direkte påvirke lønnsutbetalinger, så nøyaktighet her er ofte et forretningskrav.
Opprette eller tilpasse Datetime-feltet
Tre måter å legge til et Datetime-felt på
Avhengig av teknisk nivå og ønsket arbeidsflyt kan du legge til feltet via Studio, i modulkode eller via API.
Bruke Odoo Studio (uten kode)
- Odoo Studio er verktøyet for rask tilpasning uten utviklerarbeid.
- Åpne Studio fra hovedmenyen.
- Gå til skjemaet der du vil legge til feltet.
- Dra inn et Date & Time-felt fra verktøylinjen og slipp det på skjemaet.
- Angi label, kravstatus og eventuelt standardverdi i feltets egenskapspanel.
Lagre og lukk Studio. Feltet opprettes automatisk med x_studio_-prefiks og legges til i visningen — ingen database-migrasjoner kreves. Dette er den enkleste løsningen for forretningsbrukere som vil utvide skjemaer raskt.
Definere i Python i en tilpasset modul
For versjonskontrollerte, deployerbare tilpasninger bør felt defineres i Python-modulen.
from odoo import fields, models
class ResPartner(models.Model):
_inherit = 'res.partner'
x_last_contact_date = fields.Datetime(
string='Last Contact Date',
default=fields.Datetime.now,
copy=False,
)
Etter modelldefinisjon legger du feltet inn i relevant visnings-XML slik at det vises i UI. Odoo sørger for å opprette TIMESTAMP-kolonnen ved installasjon eller oppgradering — du trenger ikke egen SQL.
Opprette via XML-RPC API
For automatisering eller fjernkonfigurasjon kan du opprette felt programmatisk via XML-RPC:
field_id = models.execute_kw(
ODOO_DB, uid, ODOO_API_KEY,
'ir.model.fields', 'create',
[{
'name': 'x_last_contact_date',
'field_description': 'Last Contact Date',
'model_id': model_id,
'ttype': 'datetime',
'state': 'manual',
}]
)
Angi ttype: datetime for Datetime-felt. state: manual markerer at feltet er opprettet utenfor en modul (f.eks. fra Studio eller API), som er riktig for eksterne konfigurasjoner eller migrasjoner.
Gode fremgangsmåter
1. Bruk fields.Datetime.now som funksjonsreferanse, ikke kall den
Når du setter standard, skriv default=fields.Datetime.now uten parentes. Hvis du kaller funksjonen med parenteser, evalueres den én gang ved lasting av klassen, og alle nye poster får det samme «frosne» tidspunkter — en vanlig, vanskelig å oppdage feil.
2. Sett copy=False på hendelsestidsstempel
Tidsstempel som angir når noe skjedde (for eksempel bekreftelsesdato) bør ha copy=False. Ved duplisering av poster vil slike datoer ellers følge med, noe som forurarens revisjonsspor og historikk.
3. Alltid skriv UTC ved bruk av API
Når du skriver tidspunkter via XML-RPC, send verdiene i UTC i formatet YYYY-MM-DD HH:MM:SS. API-et gjør ikke tidssonekonvertering ved skriving — det som sendes, lagres som UTC. Å sende lokal tid uten konvertering fører ofte til subtile skjevheter i tid som er vanskelige å feilsøke.
4. Bruk readonly for systemgenererte tidsstempel
Systemgenererte tidspunkter bør som hovedregel være readonly i UI, slik at brukere ikke utilsiktet endrer logger. Ved behov for manuell endring, styr dette gjennom tilgangsregler i stedet for å la feltet være åpent redigerbart.
5. Velg Date når tid ikke er nødvendig
Hvis kun kalenderdatoen er relevant (f.eks. forfallsdato eller fornyelsesdato), bruk fields.Date. Det forenkler modellen og unngår unødvendig tidssone-logikk ved visning og rapportering.
Vanlige fallgruver
Tidssoneforvirring ved rå databaseverdier
Mesteparten av forvirringen oppstår når man leser rå verdier fra databasen eller API-et, fordi disse viser UTC-verdien — ikke den lokale visningen brukeren ser i UI. Integrasjoner og rapporter som baserer seg på rå API-verdier uten å konvertere tidssoner ender ofte med feil klokkeslett. Gjør tidssonekonvertering på klientsiden til en eksplisitt del av alle integrasjoner.
Skrive lokal tid via API
Hvis du sender et tidspunkt i lokal tid til API-et, vil det bli lagret som om det var UTC. Et møte skrevet som 2026-01-01 15:00:00 for Paris kan dermed vises feil i UI når sommer- eller vintertid slår inn. Slike feil dukker ofte først i produksjon når ekte brukere i ulike tidssoner benytter systemet.
Bruke fields.Datetime.now() med parenteser (feil)
Å inkludere parenteser betyr at standarden evalueres én gang ved oppstart av Odoo-prosessen. Alle senere poster får samme tid — en stille feil som kan være vanskelig å oppdage fordi tidsstemplene tilsynelatende eksisterer, men er identiske.
Glemme copy=False på hendelsestidsstempel
Uten copy=False følger tidsstemplene med ved duplisering, og nye poster arver historiske datoer. Det ødelegger datakvaliteten i rapporter og gjør revisjoner upålitelige — en liten innstilling med stor effekt.
Bruke Datetime når Date er nok
Å velge Datetime for enkle datoformål skaper unødvendige problemer: brukere får se tidselementet som ikke betyr noe, tidssonelogikk kjøres unødvendig, og grensesnittet blir mer tungrodd. Velg den enkleste felt-typen som dekker behovet.
Konklusjon
Oppsummering
Datetime-feltet er ekstremt nyttig der presisjon betyr noe—fra når en lead åpnes til produksjonsstart og ansattes innsjekk. Feltet finnes i nesten alle moduler og gir viktig kontekst for drift og rapportering.
Hovedregelen å ta med seg er UTC-lagring: alt i databasen er i UTC og Odoo konverterer ved visning. Men alle eksterne skriver og leser må aktivt ta hensyn til dette for å unngå tidssonefeil. Bruk riktig default-syntaks, sett copy=False der det trengs, og velg Date når tid ikke er relevant for å holde modellen ryddig og rapportene pålitelige.
Hos Dasolo hjelper vi bedrifter med implementasjon, tilpasning og optimalisering av Odoo på tvers av avdelinger. Enten du trenger hjelp med datamodellering, å legge til skreddersydde felt eller utvikle en full modul, står vårt team klart til å bistå. Ta kontakt med oss så tar vi en prat om ditt Odoo-prosjekt.