CONTEXT BIJ DEZE POST
- De AI-serie (6 delen): standaard Odoo AI-functies — aanzetten en gebruiken
- Deze post: een eigen AI-toepassing bouwen binnen Odoo Online — maatwerk zonder custom module
ODOO AI LOGISTIEK
Magazijnrouting met AI — wat werkt, en wat niet
De AI-serie behandelde standaardfuncties die je aanzet. Dit is een stap verder: een eigen AI-toepassing bouwen binnen Odoo Online — zonder custom module, maar wel met technische inzet. En een eerlijke vergelijking met een pure Python-aanpak.
In de serie Odoo AI in de praktijk behandelden we zes modules waar AI direct bruikbaar is voor MKB-bedrijven — standaardfuncties die je aanzet en instelt, zonder technische kennis. In het slotdeel stond de conclusie: de functies zijn er al — ze wachten op iemand die ze aanzet en goed instelt.
Deze post is een ander verhaal. Hier bouwen we iets wat Odoo standaard niet biedt: een intelligente magazijnrouting die zichzelf instelt op basis van het afleveradres van de klant én de actuele voorraadsituatie. Geen standaardfunctie — maar ook geen custom module. Alles is gebouwd met de technische mogelijkheden die Odoo Online biedt: server actions, Studio en Python-code. Geen ontwikkelomgeving, geen installatie, geen externe modules.
Dat is een wezenlijk verschil met de AI-serie. Dit vereist technische inzet — iemand die weet hoe server actions werken en Python-code kan schrijven. Maar het resultaat is een uitbreiding die volledig binnen Odoo Online draait en geen onderhoud van een custom module vereist.
En om het eerlijk te testen heb ik het twee keer gebouwd: één keer met AI, één keer puur in Python. Om te kijken waar AI daadwerkelijk waarde toevoegt — en waar een wiskundige berekening simpelweg beter werkt.
Het proces dat we wilden automatiseren
De automatisering bestaat uit drie stappen:
Stap 1 — Op contactniveau: bepaal voor elke klant welke magazijnen geografisch binnen bereik liggen en sla de rangorde op. Dit hoeft maar één keer te gebeuren, bij aanmaken of adreswijziging van het contact.
Stap 2 — Bij het aanmaken van een verkooporder: stel automatisch het dichtstbijzijnde magazijn in op basis van de opgeslagen rangorde.
Stap 3 — Op verzoek van de verkoper: herbereken het magazijn op basis van actuele voorraad en selecteer het dichtstbijzijnde magazijn dat voldoende voorraad heeft.
De drempelwaarde: een essentieel onderdeel van de configuratie
Voordat we de testresultaten bespreken, is het belangrijk om de drempelwaarde te begrijpen — want die bepaalt direct welke magazijnen als alternatief worden aangeboden en heeft daarmee grote invloed op het resultaat.
De gedachte is simpel: het heeft weinig zin om een order vanuit een magazijn in San Francisco te verzenden naar een klant in Ossendrecht, zelfs als dat magazijn wél voorraad heeft en het dichtstbijzijnde dat niet heeft. De extra verzendkosten wegen niet op tegen het voordeel. De drempelwaarde bepaalt hoe ver een alternatief magazijn maximaal verder weg mag liggen dan het dichtstbijzijnde — uitgedrukt in kilometers.
VOORBEELD
Het dichtstbijzijnde magazijn voor een klant in Ossendrecht is Antwerpen op 23 km. Met een drempelwaarde van 100 km worden alleen magazijnen opgeslagen die binnen 23 + 100 = 123 km liggen. Eindhoven (81 km) en Düsseldorf (93 km) vallen daar binnen. Amsterdam (116 km) ook. San Francisco (8.800 km) uiteraard niet.
De drempelwaarde is instelbaar per bedrijf — wat logisch is, want wat acceptabel is in een dichtbevolkt land als Nederland verschilt sterk van een land als de Verenigde Staten waar magazijnen honderden kilometers uit elkaar kunnen liggen. In de testopstelling hebben we gewerkt met een drempelwaarde van 300 km voor het Amerikaanse bedrijf en 100 km voor het Nederlandse bedrijf.
Dit is een wezenlijk configuratiepunt. Een te lage drempelwaarde betekent dat er vrijwel nooit een alternatief magazijn beschikbaar is bij voorraadtekort. Een te hoge drempelwaarde leidt tot onnodig hoge verzendkosten. De juiste waarde is een bewuste bedrijfskeuze die afhangt van de logistieke structuur en de acceptabele meerkosten per zending.
Het testproces
Om de twee benaderingen — AI en Python — eerlijk te kunnen vergelijken, zijn beide versies gebouwd en getest op dezelfde contactgegevens en magazijnconfiguratie. Als referentie voor de werkelijke afstanden is navigatiesoftware gebruikt. De navigatiesoftware geeft rijafstanden, niet de rechte lijn. Beide berekenmethoden geven rechte-lijnafstanden. De vergelijking is dus niet één op één, maar geeft wel een betrouwbare indicatie van de mate van afwijking.
Voor de testopstelling zijn vijf magazijnen geconfigureerd met volledige adres- en coördinatengegevens: WH Antwerpen BE, WH Eindhoven NL, WH Amsterdam NL, WH Düsseldorf DE en WH San Francisco US. Als testcontact is gebruikt: een klant in Ossendrecht, Noord-Brabant NL — een locatie die geografisch interessant is omdat zowel een Belgisch, Nederlands als Duits magazijn op vergelijkbare afstand liggen.
Wat AI goed doet
GEOGRAFISCHE REDENERING OP CONTACTNIVEAU
De eerste test was simpel: geef de AI de coördinaten van een klant en een lijst magazijnen, en vraag welk magazijn het dichtst bij is. Dat werkt verrassend goed. De AI heeft geografische kennis ingebakken en redeneert er correct mee — zonder dat je een formule hoeft te schrijven.
HOE DAT ERUITZIET
Een klant in Ossendrecht, Noord-Brabant. Vijf magazijnen verspreid over Europa. De AI krijgt de coördinaten en rangschikt de magazijnen correct: Antwerpen op 11 km, Eindhoven op 72 km, Amsterdam op 118 km, Düsseldorf op 167 km, San Francisco op 8.800 km. Zonder één regel wiskundige code.
NAUWKEURIGER DAN VERWACHT
Interessant detail: de AI berekent afstanden nauwkeuriger dan de wiskundige benadering die ik zelf had geprogrammeerd. Voor de Python-versie gebruikte ik de zogenaamde equirectangulaire formule — een vereenvoudigde manier om afstanden te berekenen op basis van lengte- en breedtegraden. Die formule behandelt de aarde alsof het een plat vlak is, wat op korte afstanden prima werkt. Maar de aarde is rond, en hoe verder je van de evenaar af bent, hoe meer de lengtegraadlijnen naar elkaar toe lopen. Op de breedtegraad van Nederland is een graad oost-west merkbaar korter dan een graad noord-zuid. De formule houdt daar onvoldoende rekening mee, wat bij oost-westverbindingen — zoals Ossendrecht naar Düsseldorf — leidt tot een fors te lage afstandsschatting. De AI gebruikt kennelijk een accuratere methode die wél rekening houdt met de bolling van de aarde.
ROUTE (vanuit Ossendrecht) | PYTHON (KM) | AI (KM) | NAVIGATIE PROGRAMMA |
|---|---|---|---|
→ Antwerpen BE | 23 km | 11 km | ± 28 km |
→ Eindhoven NL | 81 km | 72 km | ± 85 km |
→ Amsterdam NL | 116 | 118 | - |
→ Düsseldorf DE | niet gemeten* | 167 km | 224 km |
→ San Francisco US | niet gemeten* | 8.823 | - |
* Python-versie werkte in deze test met threshold 300 km — San Francisco en Düsseldorf vielen buiten de threshold en werden niet berekend. AI-versie berekent altijd alle warehouses en filtert daarna op threshold.
Voor de Düsseldorf-route is de AI-schatting van 167 km goed te valideren tegen de navigatiesoftware rijafstand van 224 km — het verschil is de rechte lijn versus de werkelijke route. De Python-versie berekende Düsseldorf niet in deze testopstelling omdat het buiten de threshold viel, maar een eerdere test op een contactlocatie in Eindhoven gaf voor Düsseldorf een Python-afstand van 93 km — terwijl de werkelijke rechte lijn ruim 150 km bedraagt. Dat bevestigt de onderschatting van de formule bij oost-westverbindingen.
PRAKTISCH GEVOLG
De AI-variantie bij Eindhoven (72.5 vs 84.2 km bij twee opeenvolgende runs) illustreert dat AI niet volledig deterministisch is. Voor threshold-berekeningen kan dit betekenen dat een warehouse de ene keer wel en de andere keer niet wordt opgeslagen als alternatief. Bij Python geeft dezelfde invoer altijd exact dezelfde uitkomst.
De AI berekent afstanden nauwkeuriger dan mijn eigen wiskundige benadering. Dat had ik niet verwacht.
Waar AI vastloopt
VOORRAADGEGEVENS ZIJN NIET BESCHIKBAAR IN HET PROMPT
Zodra je de AI ook de voorraadsituatie wil laten meewegen, stopt het. Actuele voorraadaantallen per magazijn zijn berekende waarden die op het moment van opvragen per magazijn afzonderlijk worden bepaald. Ze staan niet als veld beschikbaar in de veldkiezer van de AI server action. De AI kan er simpelweg niet bij.
FUNDAMENTELE GRENS
Dit is geen tekortkoming van Odoo AI — het is een fundamentele grens van wat je een taalmodel kunt vragen. De AI kan alleen redeneren over informatie die je hem meegeeft. Real-time voorraaddata zit niet in het prompt, dus kan de AI er geen beslissing op baseren.
REKENKRACHT EN RESPONSTIJD
Een LLM-aanroep duurt merkbaar langer dan een Python-berekening. Voor een handmatige actie is dat acceptabel. Voor een automatisering die bij elke adreswijziging van een klant wordt uitgevoerd, telt dat op. Python is in dit geval niet alleen betrouwbaarder — het is ook aanzienlijk sneller.
ONDERHOUD VAN HET PROMPT
De AI-versie vereist dat magazijncoördinaten handmatig worden opgenomen in het prompt. Voeg je een nieuw magazijn toe, dan moet het prompt worden bijgewerkt. De Python-versie haalt warehouses automatisch op uit de database — geen handmatig onderhoud nodig.
TOKENKOSTEN
Elke AI-aanroep in Odoo verbruikt IAP-credits — Odoo's interne betaalmunt voor clouddiensten. Achterliggend worden die omgezet in kosten bij de onderliggende AI-provider. De basiseenheid daarvoor is een token: ruwweg één woord of woorddeel in de tekst die naar de AI wordt gestuurd én terugontvangen wordt. Hoe langer het prompt, hoe meer tokens, hoe hoger de kosten per aanroep.
In deze oplossing valt dat mee — het prompt is compact en de AI wordt alleen aangeroepen bij aanmaken of adreswijziging van een contact, niet bij elke verkooporder. Bij een normale contactdatabase zijn de tokenkosten verwaarloosbaar. Het wordt een serieuze afweging bij een bulk-initialisatie waarbij alle bestaande contacten in één keer worden verwerkt, of bij een grote database met veel mutaties. In die gevallen is de Python-versie de verstandige keuze: zelfde resultaat, geen IAP-kosten.
De vergelijking op een rij
ASPECT | PYTHON | AI |
|---|---|---|
Afstandsnauwkeurigheid | Onderschat oost-westafstanden op hogere breedtegraden | Nauwkeuriger, valideert beter tegen rijafstand |
Voorraad meewegen | Ja, real-time | Niet mogelijk |
Responstijd | Snel | Merkbaar trager |
Deterministisch | Altijd zelfde uitkomst | Kleine variantie tussen runs |
Nieuw magazijn toevoegen | Automatisch | Prompt handmatig bijwerken |
Drempelwaarde (threshold) | Ja, per bedrijf instelbaar | Ja, via Python tool |
Tokenkosten (IAP-credits) | Geen | Per aanroep, afhankelijk van promptlengte |
Wat als de selectiecriteria uitgebreid moeten worden?
Magazijnrouting op basis van afstand en voorraad is een goed startpunt — maar in de praktijk spelen vaak meer criteria mee. Denk aan een voorkeur voor verzending vanuit hetzelfde land als de klant, specifieke afspraken per klantsegment, of seizoensgebonden spreiding van orders over magazijnen. De vraag is dan: voeg je dat toe aan het AI-prompt, of bouw je het uit in Python-code?
UITBREIDEN VAN HET PROMPT
Het grote voordeel van de AI-aanpak is dat nieuwe criteria in gewone taal kunnen worden toegevoegd. Je hoeft geen code te schrijven — je beschrijft de gewenste logica in het prompt. Dat werkt goed voor criteria die redeneren vereisen over kwalitatieve context, zoals: "geef voorkeur aan het magazijn in hetzelfde land als de klant, tenzij een magazijn in een aangrenzend land meer dan 30% dichter bij ligt." Dat soort nuance is lastig in code te vangen, maar begrijpt een taalmodel direct.
De keerzijde: naarmate het prompt langer en complexer wordt, neemt de kans op inconsistent gedrag toe. De AI weegt criteria af op een manier die niet altijd transparant is. Je kunt niet eenvoudig testen of de logica klopt — je kunt alleen steekproeven nemen en hopen dat het gedrag stabiel is. En elk criterium dat real-time data vereist — voorraad, actuele levertijden, transportkosten — is sowieso niet via het prompt te realiseren.
UITBREIDEN VAN DE PYTHON-CODE
Python is deterministisch en transparant. De beslissingslogica staat expliciet in de code, is testbaar, en geeft altijd hetzelfde resultaat bij dezelfde invoer. Real-time data integreren — zoals voorraadniveaus, gewichten of transporttarieven — is rechtstreeks mogelijk via de Odoo ORM. Dat maakt Python de enige optie zodra criteria afhankelijk zijn van live bedrijfsdata.
Het nadeel is dat complexe afwegingen tussen meerdere criteria snel leiden tot uitgebreide if/else-structuren die moeilijk leesbaar worden. En elke aanpassing vereist technische kennis.
SELECTIECRITERIUM | VIA PROMPT (AI) | VIA PYTHON |
|---|---|---|
Geografische afstand | ✓ Sterk | ✓ Sterk |
Landenvoorkeur | ✓ Natuurlijke taal | ✓ Eenvoudige code |
Voorraad beschikbaarheid | ✗ Niet mogelijk | ✓ Real-time via ORM |
Levertijd per magazijn | ✗ Niet mogelijk | ✓ Real-time via ORM |
Transportkosten | ✗ Niet mogelijk | ✓ Berekening mogelijk |
Klantspecifieke voorkeur | ✓ Contextuele redenering | ✓ Via veld op contact |
Combinatie van criteria | ⚠ Onvoorspelbaar bij complexiteit | ✓ Deterministisch |
DE VUISTREGEL
Criteria die redeneren vereisen over kwalitatieve context → prompt. Criteria die real-time data of exacte berekeningen vereisen → Python. Bij combinaties van beide: Python bereidt de data voor, AI redeneert erover.
Na beide versies te hebben gebouwd en getest is de conclusie helder. AI en Python vullen elkaar aan — elk op het onderdeel waar ze het sterkst zijn.
ARCHITECTUUR - HYBRIDE AANPAK
CONTACTNIVEAU
AI server action
Rangschikt magazijnen op geografische afstand bij aanmaken of adreswijziging
Python tool
Past drempelwaarde toe en slaat rangorde op in het contactrecord
↓
ORDERNIVEAU
PYTHON — AUTOMATISCH
Zet dichtstbijzijnde magazijn bij aanmaken order (Flow 1)
PYTHON — OP VERZOEK
Herberekent op basis van actuele voorraad eerste orderregel (Flow 2)
DE CONCLUSIE
→ AI op contactniveau — geografische redenering is precies waar een taalmodel goed in is. Eenmalig, bij adreswijziging, geen tijdsdruk.
→ Python op orderniveau — real-time voorraaddata, snelle uitvoering, deterministisch. Geen LLM-aanroep nodig.
→ Geen custom module — de volledige oplossing draait binnen Odoo 19 Online via server actions, Studio en Python. Wel technische inzet vereist — dit is maatwerk, geen standaardfunctie.
Wat dit je als ondernemer oplevert
Als je met meerdere magazijnen werkt en de magazijnkeuze nu handmatig of op basis van vaste regels gebeurt, dan levert deze automatisering direct resultaat:
Kortere levertijden doordat het dichtstbijzijnde magazijn met voorraad wordt gekozen. Lagere verzendkosten. Minder handmatig werk voor verkopers. En een realistischere leverdate voor de klant — zonder dat iemand er iets voor hoeft te beslissen.
MEER WETEN?
Wil je weten of deze aanpak werkt voor jouw magazijnstructuur, of hoe ver je kunt komen met de standaard AI-functies in jouw Odoo-versie? Neem gerust contact op — het eerste gesprek is altijd vrijblijvend.
DvB
Daniel van Baalen · KoTeJa
Als onafhankelijk Odoo-consultant help ik MKB-bedrijven bepalen welke AI-functies direct bruikbaar zijn in hun versie, en zorg ik dat ze betrouwbaar werken in de praktijk.
DE VOLLEDIGE AI-SERIE
Odoo AI in de praktijk — zes praktijkvoorbeelden van Inventory tot Helpdesk