v1.0.0-020 : Dokumentasi Lengkap Aturan Prompt OCR & Parsing Transaksi (Beserta Perbaikan INDOMARCO Model 2)
Kompilasi seluruh 12 aturan utama OCR Engine, 16 aturan Smart Transaction Parser, serta dokumentasi penanganan spesifik Nota INDOMARCO Model 2.
Dokumen ini mendokumentasikan secara lengkap seluruh Aturan Statis OCR (STATIC_OCR_PROMPT) dan Aturan Smart Transaction Parser (parseTransactionSystemPrompt) yang berlaku di kodebase mcp-server, serta solusi khusus penanganan Nota PT. INDOMARCO ADI PRIMA (Model 1 & Model 2).
Berikut adalah 12 Aturan Ekstraksi & Validasi Otentik yang diterapkan pada ocrTool.ts:
- KEJUJURAN MUTLAK: Jika gambar BUKAN nota/faktur (misal: hanya teks sepotong, pemandangan), ATAU jika teks sangat buram, WAJIB mengisi
readability_statusdenganTIDAK_TERBACAdan mengosongkan seluruh field lainnya. DILARANG MENGARANG. - BEBAS HALUSINASI & PEMBERSIHAN NAMA:
- Tulis HANYA teks yang terlihat jelas.
- Tulisan Tangan: Penambahan item tulisan tangan oleh sales/staff WAJIB dimasukkan jika terbaca jelas.
- Kapitalisasi: Nama barang (
product_name) WAJIB ditulis dalam HURUF KAPITAL SEMUA (UPPERCASE). - Pembersihan Kode Barang / SKU Prefix (PENTING): Jika nama barang diawali kode angka/SKU supplier (contoh:
143210 KID115C-SUSU UHT INDOMILK KIDS), BUANG kode angka/SKU di depan tanda strip-. Ambil HANYA deskripsi nama barang setelah tanda-(contoh:SUSU UHT INDOMILK KIDS).
- KLASIFIKASI TRANSAKSI: Jika nota diterbitkan oleh pihak eksternal (minimarket, grosir, supplier) kepada kita, maka
transaction_typeWAJIB disetpurchase(pembelian/pengeluaran). - FORMAT TANGGAL: Menggunakan standar ISO 8601 (
YYYY-MM-DD). Gunakan tahun berjalan jika nota hanya mencantumkan Hari & Bulan. - PEMBERSIHAN ANGKA: Nominal berupa integer/float. Pertahankan angka desimal pada Qty (contoh
2.00atau1.5). Hapus simbol Rp dan pemisah ribuan. - NORMALISASI UOM: Petakan UOM nota (misal
DUS) ke UOM database yang cocok (contohbox). - LOGIKA HARGA SATUAN & SUBTOTAL: Jika
unit_pricekosong, hitungunit_price = subtotal / quantity. Pastikansubtotal = (quantity * unit_price) - discount_amount. - LOGIKA DISKON & PAJAK (ANTI DOUBLE COUNTING):
- Diskon per baris dimasukkan ke
discount_amountitem. Rumus:net_price = unit_price - (discount_amount / quantity). - Set
summary.discount_totalmenjadi0jika semua diskon sudah dialokasikan ke item per baris. - HANYA isi
summary.discount_totaljika diskon diberikan di akhir nota secara global.
- Diskon per baris dimasukkan ke
- NO INVOICE:
invoice_numberHANYA diisi jika ada penanda seperti “No. Faktur”, “Invoice”, “Nota”. - FORMAT KOLOM QTY PECAH & HARGA SATUAN (KRITIS):
- Kolom Qty Pecah: Jika kuantitas tercetak dalam dua angka sejajar (contoh
0 10atau0 3), angka tersebut adalah(Karton, Pcs). Jika angka kedua > 0, gunakan angka kedua sebagai Qty dengan UOMpcs. - Net Subtotal: Kolom TERAKHIR di kanan baris nota computer printout adalah NET SUBTOTAL per baris.
- Formula Unit Price: WAJIB hitung
unit_price = net_subtotal_kolom_terakhir / qty.
- Kolom Qty Pecah: Jika kuantitas tercetak dalam dua angka sejajar (contoh
- FORMAT OUTPUT: Hanya keluarkan JSON mentah tanpa markdown formatter (tanpa
```json).
Berikut adalah 16 Aturan Ekstraksi Bahasa Natural pada transactionParser.ts:
- KLASIFIKASI RINGKASAN VS DETAIL:
- Jika input bertipe rekapitulasi harian/omset global (misal: “total penjualan kemarin 2.500.000”), set
itemsmenjadi array kosong[]. - Isi
itemsHANYA jika pengguna menyebutkan nama barang retail, qty, dan harga secara eksplisit.
- Jika input bertipe rekapitulasi harian/omset global (misal: “total penjualan kemarin 2.500.000”), set
- JENIS TRANSAKSI: Set
transaction_typeke salah satu pilihan valid:purchase,sales,income,operational,non_cash_out,non_cash_in,capital,manual,cash_count,purchase_return,sales_return. - ATURAN RETUR:
- Ke Supplier/Sales →
purchase_return. - Dari Pelanggan →
sales_return.
- Ke Supplier/Sales →
- CHAIN OF THOUGHT (_reasoning): Anda WAJIB memberikan langkah pemikiran pada properti
_reasoningsebelum menghasilkan data JSON. - EKSTRAKSI ITEMS & PEMBERSIHAN SKU:
- Properti wajib per item:
name,qty,unit,unit_price,discount,total. - Pembersihan Kode SKU: Jika nama barang diawali kode angka/SKU supplier dan tanda strip (seperti
143210 KID115C-SUSU UHT INDOMILK KIDS), BUANG kode angka/SKU di depan tanda-, ambil HANYA nama barang bersihnya (SUSU UHT INDOMILK KIDS).
- Properti wajib per item:
- TOTAL AMOUNT: Jika nominal total tidak disebutkan, hitung total secara otomatis dari penjumlahan
qty * unit_priceseluruh item. - CONTACT NAME: Tangkap nama pelanggan atau supplier jika disebutkan.
- METODE PEMBAYARAN: Peta frasa seperti “TEMPO” atau “JATUH TEMPO” menjadi
payment_method: "tempo". Default jika tidak disebutkan adalahcash. - JATUH TEMPO (due_date): Format ke
YYYY-MM-DDatau tulis teks relatifnya seperti+14 days. - SATUAN DAN HARGA (LOGIKA MATEMATIS):
1 Dus (40 Pcs) @ 110.000→qty = 1,unit = Dus,unit_price = 110000.- Tanda Sama Dengan (=): Angka setelah
=adalah HARGA TOTAL.unit_price = total / qty. - Tanpa Simbol @ atau =: Jika
Angka * Qtymelampaui total belanja secara tak masuk akal, angka tersebut adalah HARGA TOTAL baris. WAJIB dibagi Qty untuk mendapatunit_price.
- KOREKSI NAMA (RAG INJECTION): Jika Katalog Database disertakan, gunakan nama persis dari katalog jika ada kemiripan typo.
- DILARANG MENGGABUNGKAN BARANG (NO AGGREGATION): Tulis semua item persis baris per baris. JANGAN menjumlahkan barang bermerek sama.
- TANGGAL TRANSAKSI: Format wajib
YYYY-MM-DD. Dilarang menggunakan string literal “YYYY-MM-DD” atau mengarang tahun lampau. - DEFAULT PEMBAYARAN & TEMPO LEWAT:
- Default
payment_methodadalah"cash". - Jika tanggal jatuh tempo sudah lewat dibanding hari ini, PAKSA
payment_methodmenjadi"cash"dandue_date: null.
- Default
- DUA POLA DISKON:
- Diskon Inline (Per Item):
unit_pricediisi harga netto (unit_price - diskon). - Diskon Global (Total Nota): Biarkan
unit_priceutuh, sesuaikantotal_amountdi akhir.
- Diskon Inline (Per Item):
- FORMAT OUTPUT: Hanya keluarkan JSON mentah tanpa markdown formatter.
Berdasarkan analisis visual nota WhatsApp Image 2026-07-28 at 12.17.50.jpeg:
- Header: Computer printout tanpa garis tebal.
- Qty Kolom Pecah: Angka
0 10dibaca Qty = 10 pcs. - Kolom Terakhir: Adalah NET SUBTOTAL per baris.
- Formulasi Harga Satuan:
unit_price = net_subtotal_kolom_terakhir / qty.
| Nama Produk di Nota | Hasil Ekstraksi Nama (Bersih) | Qty | Net Subtotal (Kolom Terakhir) | Diskon Rp | Hasil unit_price |
|---|---|---|---|---|---|
143210 KID115C-SUSU UHT INDOMILK KIDS |
SUSU UHT INDOMILK KIDS | 10 pcs | Rp 24.500 | Rp 0 | Rp 2.450 / pcs |
129153 SCIC190-SUSU STERIL INDOMILK CH |
SUSU STERIL INDOMILK CH | 6 pcs | Rp 20.700 | Rp 0 | Rp 3.450 / pcs |
439433 UHT180MT-Susu UHT Indomilk Matcha |
SUSU UHT INDOMILK MATCHA | 3 pcs | Rp 10.500 | Rp 1.350 | Rp 3.500 / pcs |