πŸ“· Panduan Robot OCR Pembayaran IPL per Blok

Paguyuban Perumahan JRK 1 β€” baca bukti transfer otomatis & catat IPL

πŸ“‹ Daftar Isi

βš™οΈ 1. Cara Kerja OCR

Warga atau pengurus cukup mengirim foto bukti transfer ke grup OCR. Bot mendeteksi gambar, membacanya dengan OCR lokal, lalu mencocokkan unit, bulan, dan nominal secara otomatis.

πŸ“Έ Warga kirim foto bukti transfer ⬇️ Bot unduh & baca gambar πŸ” RapidOCR lokal + fallback LLM-vision 🧠 Parse nominal bank Β· tanggal Β· nama πŸ”— Cocokkan unit nama β†’ blok/blok no πŸ—“οΈ Hitung tunggakan bulan & multi-unit πŸ’Ύ Simpan Sheets save.php / income-expense βœ… Konfirmasi βœ… Tercatat + rec_id
Kirim gambarβ†’ Unduh & OCRβ†’ Parse nominalβ†’ Cocok unitβ†’ Hitung bulanβ†’ Simpanβ†’ Konfirmasi βœ…

Mesin Pembaca (OCR)

KomponenKeterangan
RapidOCR (lokal)Mesin utama membaca teks pada bukti transfer. Berjalan di server, tanpa kirim gambar ke luar.
Fallback LLM-visionDipakai bila hasil OCR minim/tidak jelas. Dibatasi kuota cloud OCR_CLOUD_DAILY_CAP=100 per hari.
apply_learned_correctionsKoreksi hasil belajar β€” perbaiki pola OCR yang sering salah baca.
Grup OCR (whitelist). Bot hanya memproses gambar di grup OCR yang terdaftar, contoh: 120363410360851430@g.us. Grup Pengurus: 120363316047070840@g.us.

πŸ’¬ 2. Contoh Percakapan WhatsApp

Alur tiga langkah: warga mengirim foto bukti transfer, bot menampilkan tombol konfirmasi, lalu bot menampilkan bukti yang tercatat.

Balasan sukses (format baku)

Caption sebaiknya menyebut blok dan nomor unit. Bot memakainya untuk mencocokkan unit dan nominal dengan tepat. Contoh: IPL Blok X No. 17, IPL X-17, IPL X/17, IPL X_17.
πŸ—“οΈ Peruntukan Bulan. Bot mengalokasikan nominal ke bulan pertama yang belum dibayar, bukan ke bulan tanggal transfer.
  • Basisnya kolom Bulan Huni (format YYYY-MM) di sheet Unit, lalu bot melewati bulan yang sudah tercatat di sheet Pembayaran untuk unit yang sama (tunggakan.first_unpaid_month).
  • Kalau Bulan Huni berada di masa depan, bot mengklaim bulan berjalan (tidak mengklaim bulan yang belum berjalan).
  • Jumlah bulan yang dibayar = nominal // tarif (minimal 1). Jadi nominal berlebih otomatis menutup beberapa bulan sekaligus.
  • Label rentang bulan: September 2026, September–Oktober 2026, atau lintas tahun Desember 2026–Februari 2027.
  • Nilai tersimpan: bulanSelected (format YYYY-MM), bulan, dan tahun.
  • Multi-unit: tiap unit dihitung bulannya sendiri.
Contoh: bulan berjalan September 2026 dan belum dibayar β€” kirim Rp150.000 β†’ tercatat untuk September 2026; kirim Rp300.000 β†’ September–Oktober 2026.

πŸ” 3. Yang Dibaca dari Bukti Transfer

DataKeterangan
Bank / rekeningBank pengirim & tujuan transfer.
NominalDiambil lewat fungsi extract_nominal.
TanggalTanggal transaksi pada bukti.
Nama pengirimDipakai untuk mencocokkan penyewa dengan unit.
Teks pesanCatatan/caption bila ada, untuk memperkuat pencocokan.

Semua hasil bacaan dapat diperbaiki oleh apply_learned_corrections sebelum dipakai.

πŸ”— 4. Pencocokan Unit & Bulan

Nama penyewa dipetakan ke unit/blok melalui unit_lookup, memakai cache data/kwitansi-unit-cache.json yang di-refresh setiap 01:00 WIB.

Format unit

Langkah pencocokan

  1. Baca nama pengirim & teks dari bukti.
  2. Cari nama di cache unit β†’ dapatkan blok & nomor unit.
  3. Hitung bulan. Bot mulai dari bulan pertama yang belum dibayar (basis kolom Bulan Huni format YYYY-MM di sheet Unit; bulan yang sudah tercatat di sheet Pembayaran dilewati). Jumlah bulan = nominal // tarif (minimal 1), lalu diberi label rentang seperti September 2026 atau September–Oktober 2026.
  4. Bila warga punya lebih dari satu unit, bot mendukung multi-unit.

🏘️ 5. Panduan per Blok 14 Blok

Bot mengenali unit dari prefix blok. Total ada 14 blok dengan tarif dan catatan berbeda.

IRp150rb
IIRp150rb
IIIRp150rb
IVRp150rb
VRp150rb
VIRp150rb
VIIRp150rb
VIIIRp150rb
IXRp150rb
X DepanRp150rb
X BelakangRp150rb
Raya DepanRp150rb
Raya BelakangRp150rb
RUHARp200rb

Tabel ringkas

BlokPola UnitTarif/bulanCatatan
IJRK 1 Blok I No. XRp150.000β€”
IIJRK 1 Blok II No. XRp150.000β€”
IIIJRK 1 Blok III No. XRp150.000β€”
IVJRK 1 Blok IV No. XRp150.000β€”
VJRK 1 Blok V No. XRp150.000β€”
VIJRK 1 Blok VI No. XRp150.000β€”
VIIJRK 1 Blok VII No. XRp150.000β€”
VIIIJRK 1 Blok VIII No. XRp150.000β€”
IXJRK 1 Blok IX No. XRp150.000β€”
X DepanJRK 1 Blok X No. XRp150.000β€”
X BelakangJRK 1 Blok X No. XRp150.000β€”
Raya DepanJRK 1 Raya ...Rp150.000β€”
Raya BelakangJRK 1 Raya ...Rp150.000β€”
RUHAJRK 1 RUHA No. XRp200.000β€”

Cara bot mengenali unit

Prefix "JRK 1 Blok"β†’ Nama blok (I–X / Raya / RUHA)β†’ "No. X"β†’ Unit ditemukan

Bila nama unit tidak terdeteksi, bot masuk ke stage unit untuk menanyakan blok/nomor unit kepada warga.

πŸ’Ύ 6. Penyimpanan Data

JenisEndpoint / Kolom
IPL save.php β€” kolom: unit, nama, nominalPerBulan, bulanSelected, bulan, tahun, korlap, keterangan = "Auto OCR. Transfer: {tanggal}", tanggalTransfer, buktiTransfer.
Non-IPL
(pengeluaran / PJM / token PLN)
save-income-expense.php

πŸ” 7. Auto-Save & Whitelist Finance

Bot hanya menyimpan otomatis bila dua syarat terpenuhi:

Bila salah satu tidak terpenuhi, bot tidak auto-save dan meminta konfirmasi finance (atau menunggu tombol konfirmasi).

Nomor non-finance. Bila nomor bukan whitelist finance, bot balas: "Nomor ini belum terdaftar finance, bukti tidak disimpan."

πŸ” 8. State Machine Konfirmasi

Saat bot butuh konfirmasi, ia menjalankan tahapan (stage) berikut:

confirm→ unit→ kategori→ tujuan→ caption_fallback
ParameterNilai
TTL state900 detik (15 menit)
Reminder180 detik (3 menit)
Prompt kategoriBot menampilkan pilihan jenis transaksi (IPL / Pengeluaran / Pemasukan)
Fallback unitBot menanyakan nomor unit bila tidak terdeteksi

⚠️ 9. Edge Case & Penanganan

SituasiPenanganan Bot
Gambar tak terbacaFallback ke LLM-vision β†’ bila tetap gagal, bot mengirim pesan agar bukti dikirim ulang.
Nominal tak terbacaBot mengirim pesan agar bukti dikirim ulang.
Nominal tidak match (tidak pas)Tidak auto-save β†’ bot meminta konfirmasi finance.
Nominal > 50 jutaDitolak oleh validate_nominal.
Unit tak ketemuMasuk stage unit, bot menanyakan blok/nomor unit.
Multi-unitBot tampilkan preview warning sebelum dicatat.
Rekening bukan HARKESPAN / PAGUYUBAN / JRK / YAYASAN / PENGURUSMasuk stage tujuan (bot meminta konfirmasi tujuan).
Nomor non-financeBot balas: "Nomor ini belum terdaftar finance, bukti tidak disimpan."
Gambar rusakBot balas: "⚠️ Media tidak valid/rusak".
Pause per grupBot dapat dijeda per grup; statusnya tersimpan di data/bot-state.json.
Setelah edit file .pyPerlu restart layanan wuzapi-python.service agar perubahan aktif.

❓ 10. FAQ

Bagaimana format caption yang benar saat kirim bukti?

Caption sebaiknya menyebut blok dan nomor unit, misalnya IPL Blok X No. 17, IPL X-17, IPL X/17, atau IPL X_17.

Kenapa bukti saya tidak langsung tercatat?

Auto-save hanya untuk verdict high + nomor whitelist finance. Selain itu bot minta konfirmasi lebih dulu.

Di grup mana bot memproses gambar?

Hanya di grup OCR yang terdaftar (whitelist). Contoh: 120363410360851430@g.us; grup Pengurus: 120363316047070840@g.us.

Bagaimana kalau nominal tidak pas?

Bot tidak menyimpan otomatis dan meminta konfirmasi finance.

Berapa tarif IPL?

Blok I–X & Raya = Rp150.000/bulan; RUHA = Rp200.000/bulan.

Bagaimana cara menjeda bot di grup?

Bot dapat dijeda per grup. Status jeda disimpan di data/bot-state.json.

Bagaimana bot tahu pembayaran saya untuk bulan apa?

Bot mengalokasikan ke bulan pertama yang belum dibayar, bukan bulan tanggal transfer. Dasarnya kolom Bulan Huni (format YYYY-MM) di sheet Unit, dengan melewati bulan yang sudah tercatat di sheet Pembayaran. Jumlah bulan = nominal // tarif (minimal 1), jadi nominal berlebih menutup beberapa bulan. Contoh: Rp150.000 β†’ September 2026; Rp300.000 β†’ September–Oktober 2026.

Mengapa perubahan kode tidak langsung aktif?

Bot menyimpan modul di memori. Setiap edit file .py wajib systemctl restart wuzapi-python.service.