HandyCafe Docs
owner

Harga Sesi

HandyCafe menggunakan mesin harga berbasis segmen untuk menghitung biaya sesi di warnet atau pusat gaming Anda. Alih-alih menerapkan satu tarif tetap untuk seluruh sesi, mesin membagi setiap sesi menjadi segmen, masing-masing dengan konteks harganya sendiri. Pendekatan ini memastikan penagihan yang akurat bahkan saat sesi melintasi beberapa slot waktu, perubahan harga, jeda, atau pemutusan koneksi.

Konsep Inti

Sebelum mendalami detail, berikut istilah kunci:

Istilah Definisi
Tarif per jam dasar Harga per jam sebelum pengali diterapkan. Diatur di Pengaturan > Harga.
Slot harga Periode waktu bernama dengan pengali tertentu. Ada 8 slot, masing-masing berkode warna.
Pengali Faktor yang diterapkan pada tarif dasar. 1.0 = harga standar, 0.5 = setengah harga, 2.0 = harga ganda.
Segmen Periode berkelanjutan dalam sesi di mana konteks harga (slot, pengali, harga dasar) tetap tidak berubah.
Penyelesaian Perhitungan akhir yang menentukan berapa banyak yang harus dibayar pelanggan saat sesi berakhir.

Tarif Per Jam Dasar

Tarif per jam dasar adalah dasar dari semua perhitungan harga. Diatur di Pengaturan > Harga dan mewakili harga standar per jam penggunaan PC.

Semua perhitungan internal menggunakan unit minor mata uang (misalnya sen untuk USD). Jika tarif dasar Anda adalah Rp30.000 per jam, nilai internalnya adalah 3000000. Ini menghilangkan masalah pembulatan floating-point.

Dukungan Mata Uang Ganda

HandyCafe mendukung mata uang dasar dan mata uang lokal dengan kurs tukar (FX). Jika Anda beroperasi di negara di mana harga internasional berbeda dari harga lokal:

  • Mata uang dasar. Mata uang yang digunakan untuk perhitungan harga internal.
  • Mata uang lokal. Mata uang yang ditampilkan kepada pelanggan dan digunakan untuk pembayaran.
  • Kurs FX. Faktor konversi antara mata uang dasar dan lokal.

Jika kedua mata uang sama, kurs FX diperlakukan sebagai 1.0 dan tidak berpengaruh.

Slot Harga

Ada 8 slot harga berkode warna, masing-masing mewakili tingkat harga yang berbeda:

Slot Warna Penggunaan Tipikal
Biru Biru Tarif standar
Oranye Oranye Biaya tambahan sore atau akhir pekan
Merah Merah Premium jam sibuk
Hijau Hijau Diskon di luar jam sibuk
Teal Teal Tarif pelajar atau anggota
Abu-abu Abu-abu Harga hari libur atau khusus
Sian Sian Tarif malam
Zamrud Zamrud Tarif promosi

Setiap slot memiliki tiga properti:

  1. Nama. Label deskriptif (misalnya "Jam Sibuk" atau "Diskon Malam").
  2. Pengali. Nilai desimal yang memodifikasi tarif dasar. Nilai umum termasuk 1.0 (standar), 0.5 (setengah harga), 1.5 (biaya tambahan 50%), 2.0 (harga ganda). Pengali harus nol atau positif.
  3. Data jadwal. Representasi internal yang mendefinisikan jam mana pada hari mana slot berlaku. Ini dikelola secara otomatis melalui grid jadwal.

Slot dapat diaktifkan atau dinonaktifkan secara individual. Slot yang dinonaktifkan diabaikan oleh mesin harga.

Grid Jadwal

Jadwal harga adalah matriks 7 hari x 24 jam (168 blok satu jam secara total). Setiap blok ditugaskan ke satu slot harga. Jadwal menentukan pengali mana yang berlaku pada saat tertentu.

Grid dikonfigurasi di Pengaturan > Jadwal Harga. Hari berjalan dari Senin hingga Minggu dan jam berjalan dari 00:00 hingga 23:00. Untuk menetapkan slot ke blok waktu, pilih blok di grid dan pilih warna slot yang diinginkan.

Cara Mesin Membaca Jadwal

Secara internal, setiap blok jam memetakan ke posisi dalam data jadwal. Mesin memeriksa data jadwal setiap slot yang diaktifkan untuk menentukan slot mana yang aktif untuk hari dan jam tertentu.

Jika tidak ada slot yang diatur untuk jam tertentu, mesin kembali ke tarif dasar dengan pengali 1.0.

Saat fitur jadwal harga dinonaktifkan sepenuhnya (di Pengaturan > Harga), semua sesi menggunakan tarif dasar dengan pengali 1.0 terlepas dari waktu.

Segmen Harga

Segmen adalah periode waktu berkelanjutan dalam sesi di mana konteks harga tidak berubah. Mesin harga membuat segmen baru setiap kali peristiwa batas berikut terjadi:

Batas Pemicu
session_start Sesi baru dimulai
session_stop Sesi dihentikan
pause Kasir menjeda sesi
resume Kasir melanjutkan sesi yang dijeda
tick Jam melintasi batas jam ke slot harga yang berbeda
disconnect PC klien kehilangan koneksi jaringannya
offline PC klien menjadi offline
load_recovery Server restart dan memulihkan sesi yang berjalan

Setiap segmen mencatat:

Kolom Deskripsi
session_id Sesi yang dimiliki segmen ini
segment_start Stempel waktu Unix saat segmen dimulai
segment_end Stempel waktu Unix saat segmen berakhir (null jika masih terbuka)
pricing_slot_id ID slot harga yang aktif (misalnya "blue", "red", atau "base")
multiplier Nilai pengali dari slot harga
base_price_snapshot Tarif per jam dasar yang diambil pada saat segmen dibuka
amount Biaya yang dihitung untuk segmen ini (diatur saat segmen ditutup)
boundary_reason Mengapa segmen ini dibuat

Mengapa Menyimpan Snapshot Harga Dasar?

base_price_snapshot menangkap tarif per jam dasar pada saat persis segmen dibuka. Ini penting karena administrator dapat mengubah tarif dasar di tengah sesi. Dengan menyimpan snapshot, setiap segmen menggunakan tarif yang berlaku saat dimulai, memastikan penagihan yang adil dan dapat diaudit.

Formula Biaya

Biaya satu segmen dihitung sebagai:

amount = ceil( (base_price_snapshot * multiplier * duration_seconds) / 3600 )

Lebih tepatnya, mesin menggunakan aritmatika integer berskala untuk menghindari kesalahan floating-point:

  1. Pengali diskalakan ke integer fixed-point (dikalikan 1.000.000).
  2. Perhitungan dilakukan sepenuhnya dalam integer 128-bit.
  3. Pembagian ceiling digunakan. Hasilnya selalu dibulatkan ke atas ke unit minor berikutnya.

Perhitungan berdasarkan Menit

Jika opsi "hitung berdasarkan menit" diaktifkan di Pengaturan > Harga, formula berubah sedikit:

amount = ceil( (base_price_snapshot * multiplier * used_minutes) / 60 )

Di mana used_minutes = ceil(duration_seconds / 60). Ini berarti setiap menit parsial dihitung sebagai menit penuh.

Perhitungan Total Sesi

Total biaya sesi dihitung dalam tiga langkah:

Langkah 1: Jumlahkan Semua Segmen

raw_total = jumlah semua jumlah segmen tertutup + jumlah parsial segmen terbuka

Langkah 2: Terapkan Pembulatan

rounded_total = round_up(raw_total, rounding_step)

Pembulatan selalu ke atas (ceiling) untuk melindungi pendapatan. Langkah pembulatan dapat dikonfigurasi di Pengaturan > Harga.

Langkah 3: Terapkan Minimum Biaya Awal

final_total = max(rounded_total, startup_fee)

Biaya awal adalah biaya minimum untuk sesi apa pun, terlepas dari durasi.

Penyelesaian

Penyelesaian adalah proses finalisasi penagihan untuk sesi. Ada dua tahap penyelesaian:

Penyelesaian Awal (Hanya Prabayar)

Saat sesi prabayar dimulai, catatan penyelesaian "mulai" dibuat. Ini menangkap:

  • Biaya yang dihitung. Biaya yang dihitung sistem untuk waktu yang dibeli.
  • Jumlah yang dibebankan. Jumlah yang benar-benar dibayar pelanggan (biasanya sama dengan biaya yang dihitung).

Untuk mode prabayar "Kunci saat Pembelian", jumlah yang dikunci ini menentukan biaya sesi terlepas dari perubahan harga selama sesi.

Penyelesaian Akhir

Saat sesi apa pun (prabayar atau pascabayar) dihentikan, catatan penyelesaian "hentikan" dibuat:

Kolom Deskripsi
Biaya yang dihitung Total yang dihitung sistem dari semua segmen harga
Jumlah yang dibebankan Jumlah yang benar-benar dibebankan (default ke biaya yang dihitung)
Jumlah yang disesuaikan manual Jika kasir menyesuaikan harga secara manual, biaya yang dihitung asli dipertahankan di sini
Tarif komisi Tarif komisi metode pembayaran (sebagai persentase)
commission_fee Jumlah komisi yang dihitung
fixed_fee Biaya tetap metode pembayaran
computed_timeline_snapshot Catatan JSON dari setiap segmen harga dalam sesi

Snapshot timeline menyediakan jejak audit lengkap yang menunjukkan persis bagaimana biaya dihitung, segmen demi segmen.

PPN (Pajak Pertambahan Nilai)

PPN dikonfigurasi sebagai persentase (0-100%) di Pengaturan > Harga. Diterapkan di atas jumlah sesi yang dihitung:

PPN = jumlah yang dibebankan x (tarif PPN / 100)

Jumlah PPN ditampilkan secara terpisah di dialog pembayaran sehingga kasir dapat melihat rincian pajak.

Mode Harga Prabayar

Seperti yang dijelaskan di Manajemen Sesi, sesi prabayar mendukung dua mode harga:

Kunci saat Pembelian

Saat sesi prabayar dimulai, penyelesaian "mulai" mengunci jumlah yang dibebankan. Selama durasi sesi:

  • Waktu akhir sesi ditetapkan berdasarkan menit yang dibeli.
  • Bahkan jika jadwal harga berubah, sesi berlanjut hingga waktu yang dikunci habis.
  • Penyelesaian akhir menggunakan jumlah yang dikunci dari penyelesaian awal.

Jadwal Langsung

Waktu tersisa sesi dihitung ulang secara terus-menerus saat slot harga berubah:

  • Jika sesi memasuki slot yang lebih murah, waktu tersisa bertambah (pelanggan mendapat lebih banyak menit untuk uang mereka).
  • Jika sesi memasuki slot yang lebih mahal, waktu tersisa berkurang.
  • Penyelesaian akhir mencerminkan harga aktual yang diterapkan sepanjang sesi.

Contoh Praktis

Contoh 1: Sesi Pascabayar Sederhana

  • Tarif dasar: Rp30.000/jam (3000000 unit minor)
  • Jadwal: Slot standar (pengali 1.0) sepanjang hari
  • Sesi: 10:00 hingga 11:30 (90 menit)
  • Biaya awal: Rp5.000

Perhitungan:

Segmen 1: (3000000 * 1.0 * 5400) / 3600 = 4500000 unit minor (Rp45.000)
Total: max(Rp45.000, Rp5.000) = Rp45.000

Contoh 2: Sesi Melintasi Dua Slot

  • Tarif dasar: Rp40.000/jam (4000000 unit minor)
  • Jadwal: Standar (1.0) dari 10:00-12:00, Happy Hour (0.5) dari 12:00-14:00
  • Sesi: 11:00 hingga 13:00 (120 menit)
  • Biaya awal: Rp10.000

Perhitungan:

Segmen 1 (11:00-12:00, standar): (4000000 * 1.0 * 3600) / 3600 = 4000000 (Rp40.000)
Segmen 2 (12:00-13:00, happy hour): (4000000 * 0.5 * 3600) / 3600 = 2000000 (Rp20.000)
Total: Rp40.000 + Rp20.000 = Rp60.000
Final: max(Rp60.000, Rp10.000) = Rp60.000

Contoh 3: Sesi dengan Jeda

  • Tarif dasar: Rp20.000/jam (2000000 unit minor)
  • Jadwal: Slot standar (pengali 1.0) sepanjang hari
  • Sesi: Mulai 10:00, Jeda 10:30, Lanjutkan 11:00, Hentikan 11:45
  • Biaya awal: Rp5.000

Perhitungan:

Segmen 1 (10:00-10:30, aktif): (2000000 * 1.0 * 1800) / 3600 = 1000000 (Rp10.000)
Periode jeda (10:30-11:00): tanpa biaya
Segmen 2 (11:00-11:45, aktif): (2000000 * 1.0 * 2700) / 3600 = 1500000 (Rp15.000)
Total: Rp10.000 + Rp15.000 = Rp25.000
Final: max(Rp25.000, Rp5.000) = Rp25.000

Langkah Selanjutnya