Dezelfde klant, vier namen
In de planning heet hij „Fam. de Vries”, twee regels lager „de vries”, in de mail „H.J. de Vries” en in de chat alleen een straatnaam.
Van Dijk Installatietechniek heeft zes monteurs en ongeveer tien klussen per week. De planning staat in Excel, de afspraken in de mailbox, de uren in een WhatsApp-groep en het materiaal op foto's van kassabonnen. Op vrijdag moet daar een factuur uit komen, en dat is elke week weer een halve dag puzzelen.
Van Dijk is een simulatieopdracht: een bedrijf dat wij zelf hebben opgezet om deze workflow op te bouwen en te testen.
De informatie die je nodig hebt om te factureren staat bij Van Dijk op vier plekken. Elk daarvan is op zichzelf logisch: de planner werkt in Excel, klanten mailen, de monteurs appen elkaar de hele dag, en bonnen worden gefotografeerd omdat dat het snelste gaat.
Er lekt marge weg zonder dat iemand het ziet: meerwerk dat wel gedaan is maar nergens vastligt, uren die niemand meer kan reconstrueren, bonnen die bij de verkeerde klus belanden.
Het echte probleem is niet dat er vier bronnen zijn. Het is dat ze elkaar tegenspreken, en dat het per geval verschilt wie er gelijk heeft.
Geen rampen, gewoon een normale week. Maar elk van deze dingen kost de planner op vrijdag tijd, en drie ervan kosten geld.
In de planning heet hij „Fam. de Vries”, twee regels lager „de vries”, in de mail „H.J. de Vries” en in de chat alleen een straatnaam.
De export bevat „Bouwbedrijf Kroon BV” en „Bouwbedrijf Kroon B.V.” als aparte regels. Voor een computer zijn dat twee klussen.
De klant mailt ’s avonds dat het een dag later moet. De planning wordt nooit bijgewerkt, dus de bon van die dag past nergens bij.
Een monteur meldt uren na, maar zegt er iets bij dat op vandaag slaat. Welke dag hij bedoelt, is uit de chat niet met zekerheid te halen.
Subtotaal plus btw is niet het totaal dat er staat. Geen fraude, gewoon een cijfer dat de scan verkeerd heeft gelezen.
In de chat goedgekeurd, materiaal uit eigen voorraad gepakt. Zonder de chat erbij verdwijnt dit zonder dat iemand het merkt.
Negen klussen na dedupe, twaalf AI-aanroepen. Vijf klussen konden meteen naar de facturatie, drie bleven open omdat er nergens uren van te vinden waren, en één ging naar de nakijklijst.
„Was wel wat meer werk want de leiding zat achter de kast.” Adres en werk passen bij de klus, maar de dag klopt niet met de planning en „2,5 uur denk ik” is een schatting. Er wordt niets geboekt, en het meerwerk apart genoteerd omdat niemand er akkoord op geeft.
„Gister ben ik na de slagerij nog bij bakker langs geweest. 40 minuten.” Gister is donderdag, maar de slagerij was vrijdag. De duur is duidelijk, de dag niet — en dan wordt er geen dag gekozen.
€ 128,35 plus € 26,95 btw is € 155,30, maar er staat € 166,30. Niet gevonden door het model maar door de natelstap erachter. Het model leest over, code rekent na.
Geen enkele bon is aan een klus gekoppeld. Alle vijf bruikbare bonnen kwamen op de lijst met twee tot vier mogelijke klussen, dus het materiaalbedrag bleef op elke klus € 0,00. De workflow weigert bewust te gokken, maar daarmee kwam er deze week geen materiaal op een factuur — en dat was de helft van de belofte. De oplossing zit niet in de workflow maar in de bron: een klusnummer op de bon.
Het is verleidelijk om zo'n proces op te lossen door alles aan een AI-model te geven en te hopen dat het klopt. Dat werkt bij tien klussen en breekt bij tweehonderd. Vier keuzes maken hier het verschil.
Een chatbericht bevat geen klusnummer. In plaats van het model de hele lijst te geven, filtert gewone code eerst op monteur en datum. Het model krijgt een handvol kandidaten en mag daar niet buiten kiezen. Doet het dat toch, dan wordt het antwoord weggegooid.
Het model typt de bedragen van een bon over, meer niet. Daarna telt de workflow zelf na of de regels optellen tot het subtotaal en of de btw klopt. Zo komt die verkeerd gelezen bon vanzelf boven water.
Uren afleiden gaat naar het sterkste model, want een fout daar is een verkeerde factuur. Een bon uitlezen en mail sorteren zijn eenvoudiger werk en gaan naar lichtere modellen. Niet overal het duurste, en ook niet overal het goedkoopste.
Twijfelt de workflow, dan gokt hij niet. Dan komt het op een aparte lijst met de vraag erbij die een mens moet beantwoorden. Die lijst is een volwaardige uitkomst, geen foutmelding.
De workflow draait in n8n op onze eigen server. Links de vier bronnen, in het midden de stap die alles normaliseert en dubbelingen eruit haalt, daarna de splitsing naar de drie AI-stappen, en rechts de vier uitkomsten: weekoverzicht, factureerbaar, nog open, en nakijken door een mens.

Success en Error. Gaat een AI-stap onderuit, dan neemt hij de onderste uitgang en komt die vraag zichtbaar op de lijst, terwijl de rest van de week gewoon doorloopt.
Direct achter elke AI-stap staat een controlestap in code. Die telt het antwoord na voordat het meetelt.

Een half verwerkte week is gevaarlijker dan een week die niet verwerkt is, want het verschil zie je niet terug op de factuur. Daarom heeft elke stap een uitgang voor als het misgaat.
Gaat een AI-stap onderuit door een storing, dan volgen drie pogingen. Lukt het daarna nog niet, dan komt die ene deelvraag zichtbaar op de lijst en wordt de rest van de week gewoon afgemaakt.
Geeft het model een klusnummer terug dat niet in de kandidatenlijst stond, dan gaat de toewijzing eruit.
Is er geen letterlijke chatregel als onderbouwing, dan worden de uren niet geboekt.
Telt een bon niet op, dan wordt hij niet gecorrigeerd en niet weggelaten, maar doorgestuurd naar een mens.
Is een bonfoto onleesbaar, dan is de uitkomst een verzoek om een nieuwe foto — geen geraden bedrag.
Tijdens het testen viel de verbinding met het AI-model weg en faalden alle twaalf stappen tegelijk. De workflow crashte niet: hij rondde netjes af, met alle twaalf vragen zichtbaar op de lijst en de reden erbij.
Dat is precies het gedrag dat je op een vrijdagmiddag wilt. Niet omdat het zo bedacht was, maar omdat het zo gebouwd is.