Topics

Ik heb een bestelformulier-generator (desktopapp) gemaakt met Claude Code omdat we bestelformulieren nodig hadden

  • column

Steeds vaker ontstaat in het dagelijks werk de situatie waarin we denken: "Dit handmatig blijven doen is wel vermoeiend." Dan bouwen we met Claude Code snel een kleine oplossing. Dat is inmiddels vanzelfsprekend geworden!

Dit keer is het een typisch voorbeeld van dat patroon. Aanleiding was een kapitaalverhoging van ons bedrijf.

Ons boekjaar begint in februari en de kapitaalverhoging vond ook in februari plaats. Door het hogere kapitaal moeten we de bestelprocessen richting externe partners en onderaannemers nog zorgvuldiger inrichten dan voorheen.

Dit gebied valt onder de zogenoemde Subcontractorwet, die sinds januari 2026 bekendstaat als de "Tekst Afspraken Wet" (Tegenprestatie- en Afspraken Wet). Als opdrachtgever moeten we steeds meer zaken regelen, zoals het duidelijk vastleggen van de opdracht, het opstellen en bewaren van transactiedocumenten en het vaststellen van betalingstermijnen.

Dit gaat uiteraard niet alleen om "we doen het omdat de wet dat voorschrijft"!

Wanneer we externe partners een opdracht geven, is het voor zowel de opdrachtgever als de opdrachtnemer belangrijk dat de opdracht, het bedrag, de data en de koppeling met offertes helder zijn vastgelegd. (Kiri)

Het was ook geen functie die al in onze boekhoudtool zat.

Ons bedrijf gebruikt tools van MoneyForward (hierna "Manefo") voor boekhouding, offertes en facturatie.
Voor het dagelijkse boekhoud- en factuurwerk zijn ze handig, maar wat we nu wilden doen, was net iets anders.

Een Liberogic-bestelbon-PDF maken op basis van een offerte-PDF die we van een externe partner hebben ontvangen

Binnen het gedeelte van MoneyForward dat wij gebruiken, is er minstens geen functie die goed past, en het zou zonde zijn om daarvoor een abonnement af te sluiten.

Als we dit handmatig zouden doen,

  • een sjabloon voor de bestelbon maken
  • de gegevens van de offerte handmatig overnemen in het bestelbonsjabloon
  • de besteldatum invullen
  • het offertenummer overnemen
  • de specificaties overnemen
  • de inhoud controleren, waaronder het totaalbedrag
  • Bestandsnamen opschonen
  • Overig, overig...

Vervelend, toch? Dat er steeds meer taken bij komen... Dus hebben we besloten er zelf een te bouwen.

Binnen iets minder dan een uur praktisch inzetbaar met Claude Code

Het moment was ook goed gekozen.

Het begin van het boekjaar in februari, een kapitaalverhoging in februari en de release van Claude Code en de snelle adoptie binnen ons team vielen samen.

Op dat moment was er binnen het bedrijf juist een hackathon-achtige beweging ontstaan: met Claude Code bedrijfsprocesverbeteringstools en kleine interne apps bouwen, tot en met het deployen van eigen ideeën.

Van een eenvoudige specificatie tot instructies voor Claude Code en fijnafstemming, alles inbegrepen...

We kregen het in iets minder dan een uur zover dat het praktisch bruikbaar was.

Natuurlijk voltooit je niet alles zomaar door het volledig aan AI over te laten, maar met een goed uitgewerkte prompt is het snel en handig!

Voltooid: desktopapp

Een eenvoudige tool voor het genereren van bestelformulieren die waarschijnlijk op het besturingssysteem draait dat u ook gebruikt.

Sleep een offerte-PDF naar de speciale .app, waarna een Python-script wordt uitgevoerd. Het script leest de inhoud van de offerte-PDF en genereert een bestelformulier-PDF in dezelfde map.
Na afloop verschijnt een macOS-melding en wordt het gegenereerde bestelformulier automatisch geopend. Het is een eenvoudige opzet.

De opzet is als volgt.

~/Desktop/発注書生成/
 見積書をドロップ→発注書生成.app
 _lib/
  generate_purchase_order.py
  liberogic_logo.png
  liberogic_seal.png
  purchase_order_counter.json

Omdat we wilden dat ook medewerkers van financiële en administratieve afdelingen het zonder Terminal konden gebruiken, hebben we een AppleScript-droplet als startpunt gebruikt. Het daadwerkelijke genereren van de PDF gebeurt in Python.

Kortom, het is een desktopapp waarmee u een offerte-PDF naar de app sleept en een bestelformulier-PDF terugkrijgt. Omdat u Terminal niet hoeft te openen, is het ook voor interne administratieve taken eenvoudig in gebruik.

De vormgeving van het bestelformulier-PDF is afgestemd op de factuur- en offerte-PDF's in het Moneyforward-formaat, die wij zelf gebruiken.
In het opmerkingenveld hebben we de volgende tekst opgenomen.

Met dit bestelformulier wordt de bestelling formeel geplaatst. Bestelling op basis van offertenummer XXX.

Het bestelnummer volgt onderstaand formaat.

{会社略称}t.a.v. {会社略称} bestelformulier {YYYY}{MM}{3桁連番}

Bijvoorbeeld: als het het eerste bestelformulier van februari 2026 is voor 〇〇, dan wordt het

〇〇様 発注書202602001

.

Het volgnummer per bedrijf en per maand beheer ik via purchase_order_counter.json, en de besteldatum wordt automatisch berekend als 5 werkdagen na de datum op de offerte. (Dit is slechts een voorlopige opzet, die ik later nog zal aanpassen op basis van het beheer!)
Omdat niet alleen zaterdagen en zondagen, maar ook Japanse nationale feestdagen moeten worden uitgesloten, heb ik de Python-bibliotheek jpholiday gebruikt.

Een klein beetje lastig onderdeel

De offertes waarop de bestelformulieren zijn gebaseerd, komen van externe partners en samenwerkende bedrijven, dus de indeling verschilt per bedrijf.
Het is niet genoeg om simpelweg vast te leggen dat de bedrijfsnaam op een bepaalde coördinaat staat of dat het totaalbedrag op een bepaalde positie staat.

Uiteindelijk heb ik reguliere expressies gebruikt om zo flexibel mogelijk de leverancier, adres, telefoonnummer, offertenummer, offertedatum, onderwerp, regels, subtotaal, btw en totaalbedrag te extraheren. Bedrijven met de aanduiding "御中" behandel ik als eigen bedrijf, alle andere als leverancier. Ook zijn er momenten waarin informatie die er in de PDF visueel gescheiden uitziet, na tekstextractie aan elkaar blijft plakken, enzovoort, enzovoort, enzovoort.

Soms kwamen gebouwnamen of verdiepingsnummers achter het onderwerp terecht te staan, dus heb ik een verwerking toegevoegd die overbodige adresinformatie afsnijdt op basis van aanduidingen zoals "ビル" en "階".

Of het nu AI is of niet, bij dit soort PDF-verwerking zijn de klassieke problemen gewoon weer van de partij.

Prompt die ik aan Claude Code heb gegeven

Het is niet zo efficiënt om vage verzoeken te doen. Het is zuiniger qua tokengebruik om zo concreet mogelijk te zijn, bijvoorbeeld over de mappenstructuur, de verwerkingsstroom, de lay-out, de nummeringsregels, de berekening van werkdagen, de te extraheren velden uit PDF's, enzovoort.
Laat Claude ook het voorbeeld-PDF lezen!

以下の条件で、見積書PDFを発注書PDFに自動変換するツールをmacOS向けに作ってください。

## 環境

- macOS / Python3(pip可)
- フォント:`~/Library/Fonts/NotoSansJP-Regular.ttf` / `NotoSansJP-Bold.ttf`

## フォルダ構成

`~/Desktop/発注書生成/
  見積書をドロップ→発注書生成.app
  _lib/
    generate_purchase_order.py
    liberogic_logo.png
    liberogic_seal.png
    purchase_order_counter.json`

## 処理フロー

1. `.app` に見積書PDFをドラッグ&ドロップ
2. Pythonスクリプトを実行し発注書PDFを生成
3. 完了通知(macOS通知)を出して発注書PDFを自動で開く
4. 発注書PDFは見積書と同じフォルダに保存

## 発注書の仕様

出力フォーマットは添付のMoneyForward形式のPDFに合わせること。

このPDFから以下を抽出して使う:

- ロゴ画像
- 押印画像
- レイアウト座標
- 列幅
- 余白
- フォントサイズ

## 自社情報

リベロジック株式会社
登録番号:T2010401081132
〒108-0073 東京都港区三田1-3-37 板金会館2F
TEL: 03-6809-4366 / FAX: 03-6809-4367

## 発注書番号

- 形式:`{会社略称}様 発注書{YYYY}{MM}{3桁連番}`
- 会社別・月別の連番を `purchase_order_counter.json` で管理
- 出力ファイル名もこの発注書番号に揃える

## 発注日

- 見積書の日付から5営業日後
- 土日と日本の祝日を除外する

## 見積書からの情報抽出

- どんな会社のフォーマットでも対応できる柔軟な正規表現で抽出
- 抽出項目:ベンダー名・住所・TEL、見積書番号、見積日、件名、明細、小計・消費税・合計
- ベンダー判定:「御中」の付いた会社=自社、それ以外=発注先
- 件名に住所の建物名が混入するケースに対応

## 発注書レイアウト

- タイトル「発注書」中央大文字
- 左:発注先の社名・住所・TEL
- 右:自社情報+ロゴ+押印+発注書番号・発注日・見積書番号・見積日
- 件名・発注金額を大きく表示
- 明細テーブル:品目/単価/数量/単位/価格
- 交互グレー背景
- 最低8行
- 合計エリア:小計・消費税・合計のみ
- 備考欄を枠付きで表示
- ページ番号なし

Dit is in feite een eenvoudige specificatie, maar het is belangrijk om niet alleen te zeggen "maak het maar mooi", maar zo concreet mogelijk de bedrijfsmatige beperkingen en het gewenste eindresultaat aan te geven.
Uiteindelijk moet ik Claude soms nog extra aansturen, omdat het mislukt als je het een ander formaat laat lezen.
(Het aantal externe medewerkers en samenwerkingspartners waar wij mee werken is nog geen twintig, dus dat is geen groot verhaal!)

Juist omdat het handig is, letten we ook op de beveiliging

Aan de andere kant moet je bij het gebruik van AI-ontwikkelondersteuning ook op de beveiliging letten, niet alleen op het gemak.

Terwijl we werken door instructies te geven aan Claude Code, worden er verschillende handelingen uitgevoerd in de lokale omgeving.

- ~/Desktop へのファイル読み書き
- ~/Library/Services/ へのアクセス検討
- pip install によるPythonライブラリの追加
- osacompile によるAppleScriptアプリの生成
- ~/Library/Fonts/ にあるフォントファイルの読み取り

Dit is misschien geen groot verhaal, maar als je AI uitvoeringsrechten op je lokale omgeving geeft, is het toch wel eng, hè? 😨

Als je terminalbewerkingen of bestandsbewerkingen aan AI overlaat, kunnen er onbedoeld bestanden worden aangemaakt, overschreven of verwijderd.

  • Controleer wat je toestaat!
  • Maak een back-up!
  • Controleer bij alles wat met git beheerd kan worden de wijzigingen (diff)!
  • Splits de werkmappen op!

Basismaatregelen zoals deze zijn belangrijk. Als je het gebruikt voor ontwikkelwerk, is het misschien een goed idee om het .env-bestand via 1Password in te laden. Het is wat omslachtig, maar het maakt wel een flink verschil. (door onze CTO)

Aan de andere kant is het risico bij een gebruik zoals in dit geval, waarbij alles alleen lokaal draait, relatief beperkt. Het komt zelden voor dat de invloed via het netwerk naar buiten reikt; in de meeste gevallen blijft het effect beperkt tot je eigen omgeving.

Er zijn nog veel andere aandachtspunten, maar "snel kunnen bouwen" en "veilig kunnen gebruiken" zijn twee verschillende zaken. Bij ontwikkeling met AI is het belangrijk om onderweg te controleren: uitvoeringsrechten / bestandsbewerkingen / externe bibliotheken / de verwerking van invoergegevens!

Volgende stap: delen met collega's en koppeling met Supabase

Wat ik nu heb gemaakt, is een eenvoudige tool voor het genereren van bestelformulieren die lokaal draait.

In eerste instantie heb ik purchase_order_counter.json gebruikt om per bedrijf en per maand een doorlopend nummer bij te houden. Maar als je wilt dat meerdere collega's ermee werken, ontstaan er al snel problemen: als je de nummers alleen lokaal in een JSON-bestand beheert, krijg je al gauw dubbele bestelnummers.

Daarom houd ik de tellers per bedrijf en per maand nu in Supabase bij, zodat meerdere gebruikers zonder dubbele nummers kunnen werken. Daarnaast voeg ik de geschiedenis van bestelformulieren, leverancier, offertenummer, bestelbedrag, besteldatum en de opslaglocatie van de PDF's toe!

Over de auteur

Hoewel hij directeur is, werkt hij altijd als gesprekspartner van de klant. Hij raakt enthousiast van het begrijpen van nieuwe technologieën en van het moment dat iets handiger wordt, en duikt daar volledig in. Een echte praktijkmens die van de werkvloer houdt. Hij blijft ook op latere leeftijd graag nieuwe ervaringen opdoen en kijkt uit naar toekomstige technologieën.

Tadanori Morimoto

Projectmanager / Director / Opgericht in 2007

Bekijk de artikelen van deze medewerker

Ons grootste pluspunt is een betrouwbaar team en een snelle reactie

Bij Liberogic wordt er door onze ervaren medewerkers proactief aan projecten gewerkt, waardoor klanten ons hoog waarderen.
We zorgen ervoor dat er zorgvuldig een projectmanager en een director worden toegewezen, zodat het gehele project soepel verloopt. We voorkomen onnodige kostenstijging door middel van volledige inzet en verdelen de middelen op een manier die past bij de taak. Ook staan we bekend om ons snelle inzicht in de werkzaamheden en het snel opstellen en indienen van offertes.

* Liberogic zet zich niet in voor SES-achtige detacheringsopdrachten op locatie bij klanten. Houd hier alstublieft rekening mee.

U kunt vrijwel alle belangrijke tools voor projectmanagement en chat gebruiken, waaronder Slack, Teams, Redmine, Backlog, Asana, Jira, Notion, Google Workspace, Zoom, Webex en meer.

Neem gerust contact op met uw vragen over het web.

Casestudies