Hotel Management System
Sistem manajemen hotel lengkap berbasis Laravel 11 — dirancang untuk hotel butik hingga resort bintang 5 di Indonesia.
Front Office
Reservasi, check-in/out, folio, night audit
POS
Kasir F&B, minibar, charge to room
Channel Manager
Booking.com, Agoda, Traveloka ARI sync
Open Pricing
Dynamic pricing engine, rate overrides
Accounting
Double-entry GL, AR/AP, trial balance
RMS
Yield management, forecast, rate shopper
Housekeeping
Room status board, task assignment
Spa & Banquet
Treatments, therapists, events, BEO
Guest 360
Loyalty, upsell score, churn risk, LTV
HR & Payroll
Karyawan, absensi, payslip, service charge
BYOK Integration
AI / Payment / SMS / WA — user konfigurasi sendiri
REST API
OAuth + PAT, webhook, idempotency
Statistik Teknis
| Metrik | Jumlah |
|---|---|
| PHP source files | 341+ |
| Database migrations | 46 |
| Eloquent models | 130 |
| Blade views | 141 (100% redesigned) |
| Routes | ~430 |
| Pest tests | 84/84 ✅ 206 assertions |
| Services | 38 |
| Queue jobs | 16 |
| Dokumentasi | 27 file |
Teknologi
- Backend: Laravel 11, PHP 8.3, Eloquent ORM
- Database: PostgreSQL (recommended) / MySQL / SQLite (dev)
- Frontend: Tailwind CSS 3, Alpine.js, Blade templates
- Queue: Laravel Queues (Redis/database driver)
- Testing: Pest PHP, 84/84 passing
- Auth: Laravel Sanctum + Spatie Permission (11 roles)
- Compliance: PB1, NSFP, WNA reporting, UU PDP
Instalasi
Panduan setup dari nol hingga aplikasi berjalan di server.
Kebutuhan Sistem
| Komponen | Minimum | Rekomendasi |
|---|---|---|
| PHP | 8.2 | 8.3 |
| Database | MySQL 8 / PostgreSQL 15 | PostgreSQL 16 |
| RAM | 2 GB | 4 GB+ |
| Storage | 20 GB | 50 GB SSD |
| Node.js | 18 | 20 LTS |
| Composer | 2.5 | 2.7+ |
Langkah Instalasi
-
Clone & Install Dependencies
git clone https://github.com/your-org/hotel.git cd hotel composer install --optimize-autoloader npm install && npm run build -
Konfigurasi Environment
cp .env.example .env php artisan key:generateEdit
.env: setDB_*,APP_URL,APP_MODE(standaloneatausaas) -
Jalankan Migrasi & Seeder
php artisan migrate --seedMembuat 60+ tabel dan seed data: roles, room types contoh, admin user
-
Setup Storage & Queue
php artisan storage:link php artisan queue:work --queue=default,notifications,reports & -
Setup WizardBuka
/setup/wizarddi browser → isi nama property, alamat, pajak, dan buat akun admin pertama.
/panel dan portal tamu di / (homepage booking engine).Akun Demo (setelah DemoDataSeeder)
Semua akun demo memakai password password123. Cukup login di /login dan akses panel staff.
| Password | Role | Akses Utama | |
|---|---|---|---|
superadmin@demohotel.id | password123 | super_owner | Semua modul + user management + license |
admin@demohotel.id | password123 | super_owner | Alias super admin (kompatibilitas) |
manager@demohotel.id | password123 | manager | Semua operasional (tanpa user mgmt) |
fo@demohotel.id | password123 | front_office | Reservasi, check-in/out, folio |
cashier@demohotel.id | password123 | cashier | Folio payment + read folio |
housekeeping@demohotel.id | password123 | housekeeping | Status kamar, task, lost & found |
pos@demohotel.id | password123 | pos_cashier | POS order: create, update, settle |
accountant@demohotel.id | password123 | accountant | Journal, AR/AP, reports |
auditor@demohotel.id | password123 | auditor | Read-only semua modul + audit log |
sales@demohotel.id | password123 | sales_marketing | Guest read + report operasional |
it@demohotel.id | password123 | it_admin | Settings, integration, API token |
Login & Sistem Role
Hotel HMS menggunakan Spatie Laravel Permission dengan 11 role berbeda.
Cara Login
- Buka URL LoginAkses
/loginlangsung atau klik tombol Login di pojok kanan atas homepage. - Masukkan KredensialEmail + password. Centang "Remember Me" untuk session persisten.
- 2FA (Opsional)Jika diaktifkan admin, masukkan kode TOTP dari Google Authenticator / Authy.
Akun Demo Siap Pakai
Password semua akun: password123
| Role | |
|---|---|
superadmin@demohotel.id | super_owner |
manager@demohotel.id | manager |
fo@demohotel.id | front_office |
cashier@demohotel.id | cashier |
housekeeping@demohotel.id | housekeeping |
pos@demohotel.id | pos_cashier |
accountant@demohotel.id | accountant |
auditor@demohotel.id | auditor |
sales@demohotel.id | sales_marketing |
it@demohotel.id | it_admin |
Daftar Role & Akses
| Role | Akses | Keterangan |
|---|---|---|
| super_owner | Semua modul | Full akses + user management + license |
| manager | Semua operasional | Tanpa sett.user.* |
| front_office | FO + folio + guest | Reservasi, check-in/out, kasir |
| cashier | Folio payment | Read folio + post payment |
| housekeeping | HK board, task, lost & found | Update status kamar & tugas HK |
| pos_server | POS create + update | Input order tanpa settle |
| pos_cashier | POS create + update + settle | POS outlet penuh |
| accountant | Accounting + reports | Journal, AR/AP, period close |
| auditor | Semua endpoint .read | Read-only + audit log |
| sales_marketing | Guest read + report ops | Untuk sales / outlet marketing |
| it_admin | Settings + integration + token | Konfigurasi sistem & API |
Menambah User Baru
Buka Panel → Settings → Users. Klik "Add User", isi nama/email/password, pilih role. User langsung bisa login.
super_owner punya akses penuh termasuk license, integrasi, dan user management. Role lain dibatasi sesuai permission di RolesAndPermissionsSeeder.Reservasi
Kelola semua reservasi — dari booking langsung, OTA, telepon, hingga walk-in.
Membuat Reservasi Baru
- Buka Panel → Front Office → ReservasiKlik tombol "Reservasi Baru" di pojok kanan atas.
- Isi Data TamuCari tamu existing atau buat tamu baru: nama lengkap, email, telepon, kebangsaan.
- Pilih Kamar & TanggalPilih room type, check-in / check-out, jumlah dewasa & anak. Sistem otomatis cek ketersediaan.
- Tentukan Rate PlanPilih rate plan (Room Only, Breakfast, dll). Harga otomatis dihitung termasuk PB1 & service charge.
- Simpan & KonfirmasiKlik "Buat Reservasi" → sistem generate kode referensi unik (misal:
RES-2024-001234).
Status Reservasi
| Status | Arti | Aksi Tersedia |
|---|---|---|
| Tentative | Belum konfirmasi | Confirm / Cancel |
| Confirmed | Booking confirmed | Check-in / Cancel |
| Checked In | Tamu sudah masuk | Check-out / Add Charge |
| Checked Out | Selesai menginap | View only |
| Cancelled | Dibatalkan | View only |
| No Show | Tidak datang (ditandai saat night audit) | View only |
Tape Chart
Buka FO → Tape Chart untuk melihat visual ketersediaan kamar per hari. Pilih range tanggal (default 14 hari ke depan). Setiap sel berwarna menunjukkan kamar yang terisi beserta nama tamu.
Check-in & Check-out
Proses check-in dan check-out dari panel Front Office.
Proses Check-in
- Buka Daftar ArrivalsPanel → FO → Arrivals — semua reservasi "Confirmed" hari ini tampil di sini.
- Verifikasi TamuKlik reservasi → konfirmasi identitas tamu (KTP/passport). Upload scan KTP jika perlu.
- Assign Kamar FisikPilih nomor kamar spesifik dari dropdown (otomatis filter kamar clean + available).
- Klik "Check-in"Status berubah ke "Checked In". Folio tamu otomatis dibuat. Kamar berubah status FO = Occupied.
Proses Check-out
- Buka Daftar DeparturesPanel → FO → Departures — reservasi "Checked In" dengan checkout hari ini.
- Review FolioKlik "View Folio" → pastikan semua charge sudah benar (kamar, F&B, minibar, misc).
- Proses PembayaranPilih metode bayar: Cash, Kartu, Transfer, OTA Collect. Masukkan jumlah yang diterima.
- Cetak InvoiceKlik "Print Invoice" → halaman invoice terpisah dengan tombol print otomatis.
- Klik "Check-out"Status berubah ke "Checked Out". Kamar otomatis Dirty, siap untuk dibersihkan HK.
/self-checkin/{ref} menggunakan kode booking mereka. Sistem akan kirim link otomatis via email/WhatsApp.Folio & Billing
Setiap reservasi memiliki folio sebagai wadah semua transaksi selama menginap.
Struktur Folio
- Room Charges — diposting otomatis setiap malam oleh Night Audit
- POS Charges — F&B, minibar yang di-charge ke kamar
- Misc Charges — laundry, transport, dll ditambah manual
- Payments — pembayaran yang masuk (cash, card, OTA)
- Balance — saldo tersisa (Total Charges − Total Payments)
Menambah Charge Manual
Buka folio → klik "+ Add Charge" → pilih type (room/fnb/misc), isi deskripsi, amount, tanggal, COA account. Sistem otomatis hitung PB1 sesuai konfigurasi property.
Split Folio
Untuk tamu korporat atau group: buka folio → "Split" → pindahkan charge tertentu ke folio baru (misal F&B ke folio terpisah yang dibayar company).
Transfer Charge
Untuk memindahkan charge dari folio satu ke folio lain (mis. dari kamar A ke kamar B untuk tamu yang pindah kamar).
Night Audit
Proses penutupan hari akuntansi hotel — dijalankan setiap malam setelah pukul 00:00.
Apa yang Dilakukan Night Audit
- Post room charges ke semua folio tamu yang masih check-in
- Tandai reservasi "Confirmed" yang tidak check-in sebagai No Show
- Post jurnal akuntansi otomatis (DR: AR, CR: Room Revenue + Tax)
- Hitung KPI harian: occupancy, ADR, RevPAR
- Generate laporan daily revenue
- Tutup periode akuntansi untuk tanggal tersebut (period lock)
Cara Menjalankan
- Buka FO → Night AuditSistem menampilkan summary: kamar terisi, expected charges, catatan khusus.
- Verifikasi DataPastikan tidak ada reservasi yang belum diselesaikan (checkout terlambat, dll).
- Klik "Run Night Audit"Proses berjalan otomatis ±30 detik. Progress bar ditampilkan.
- Review HasilLaporan Daily Revenue otomatis tersedia di Reports → Daily Revenue.
Otomasi via Scheduler
Tambahkan ke crontab server untuk jalankan otomatis pukul 00:05:
* * * * * cd /var/www/hotel && php artisan schedule:run >> /dev/null 2>&1
Konfigurasi di app/Console/Kernel.php: $schedule->job(new RunNightAuditJob)->dailyAt('00:05')
Housekeeping
Manajemen status kebersihan kamar real-time dan penugasan staf HK.
Room Status Board
Buka Panel → Housekeeping → Board. Setiap kamar ditampilkan sebagai card dengan:
- Clean — siap untuk tamu
- Dirty — perlu dibersihkan (otomatis setelah checkout)
- Inspected — sudah diperiksa supervisor HK
- Cleaning — sedang dibersihkan
- Out of Order — tidak tersedia (maintenance)
Update Status Kamar
Dari Board: pilih status baru di dropdown bawah card kamar → otomatis tersimpan real-time. Staf HK bisa akses via mobile browser.
HK Tasks
Buka HK → Tasks untuk melihat daftar tugas (cleaning, turndown, amenities replenishment). Supervisor bisa assign task ke staf tertentu.
Out of Order (OOO)
Buka FO → OOO: blokir kamar dari reservasi untuk periode tertentu dengan alasan (maintenance, renovasi, dll). Kamar yang OOO tidak muncul di availability check.
POS (Point of Sale)
Sistem kasir untuk outlet F&B — restaurant, bar, minibar, in-room dining.
Membuka Kasir
- Pilih OutletPanel → POS → pilih outlet (Restaurant, Bar, dll)
- Pilih MejaKlik meja yang akan dilayani. Status meja: Available (hijau) / Occupied (merah).
- Input OrderPilih item dari menu → tambah ke keranjang. Modifiers dan catatan khusus tersedia per item.
- SettlePilih metode bayar atau "Charge to Room" (otomatis masuk ke folio tamu).
Charge to Room
Di POS, pilih "Charge to Room" → masukkan nomor kamar atau nama tamu. Charge langsung masuk ke folio tamu yang bersangkutan. Akan muncul saat proses checkout.
Laporan Shift POS
FO → Shifts → pilih shift → lihat rekap pembayaran, breakdown per metode, dan variance cash.
Banquet & Event
Manajemen event, function rooms, dan BEO (Banquet Event Order).
Membuat Event Baru
- Panel → Banquet → Events → CreateIsi nama event, tipe (wedding/conference/gala/dll)
- Jadwal & SetupTanggal, jam mulai-selesai, jumlah pax, layout ruangan (classroom/theatre/banquet)
- Assign Function RoomPilih function room yang tersedia. Sistem cek konflik jadwal otomatis.
- Tambah F&B MenuDi halaman detail event, tambah item F&B (catering, beverages, dll) per orang atau paket.
BEO (Banquet Event Order)
Buka event → klik "Print BEO". Sistem generate dokumen formal berisi detail event, F&B, setup, total biaya. Bisa di-print atau save sebagai PDF menggunakan print browser (Ctrl+P).
Banquet Calendar
Panel → Banquet → Calendar: lihat semua event per function room dalam tampilan kalender. Event ditampilkan dengan status dan jumlah pax.
Spa Management
Kelola treatment, therapist, dan appointment spa.
Setup Awal
- Panel → Spa → Treatments: tambah treatment (nama, kode, durasi menit, harga)
- Panel → Spa → Therapists: daftarkan therapist (nama, gender, specializations, status aktif)
Appointment
Panel → Spa → Appointments: buat appointment baru — pilih tamu, treatment, therapist, tanggal/jam. Sistem cek konflik jadwal therapist otomatis.
Charge ke Folio
Di halaman appointment: klik "Charge to Folio" → masukkan nomor kamar tamu. Biaya spa langsung masuk ke folio dan terhitung saat checkout.
Channel Manager
Sinkronisasi availability, rate, dan restriction (ARI) ke OTA secara real-time.
Channel yang Didukung
| OTA | Format | Fitur |
|---|---|---|
| Booking.com | XML / OTA API | ARI push + booking pull |
| Agoda | JSON REST (YCS) | ARI push + booking pull |
| Traveloka | JSON REST (TPI) | ARI push + booking pull |
| Channel lain | Generic REST | Konfigurasi via BYOK adapter |
Konfigurasi Channel
- Panel → Channel → IndexKlik "+ Add Channel" → pilih OTA → masukkan API credentials (Hotel ID, API Key, Secret)
- Room MappingPanel → Channel → Mapping: hubungkan room type HMS dengan room type ID di OTA
- Rate MappingPanel → Channel → Rates: setup rate plan yang di-push ke masing-masing OTA
- Restriction SetupPanel → Channel → Restrictions: min stay, stop sell, closed to arrival per tanggal/kamar
Sync Log
Panel → Channel → Sync Log: monitor semua ARI push (status, timestamp, payload, error). Berguna untuk troubleshoot jika ada inkonsistensi di OTA.
Conflict Detection
Panel → Channel → Conflicts: sistem otomatis deteksi double booking dan rate mismatch antar channel. Resolve manual atau otomatis via rule.
Open Pricing
Engine harga terbuka per tanggal, room type, dan channel — dengan dynamic pricing otomatis.
Rate Calendar
Panel → Pricing → Calendar. Pilih room type + channel + range tanggal → klik "Load". Grid menampilkan harga per hari dengan sumber (base/dynamic/override) dan restriction.
Bulk Override
Setelah load grid, isi form Bulk Override di bawah → set harga, min stay, stop sell untuk semua tanggal yang terload sekaligus. Klik "Save Overrides".
Dynamic Pricing Rules
Panel → Pricing → Rules. Buat rule otomatis:
| Trigger | Contoh | Action |
|---|---|---|
| Occupancy % | Occupancy ≥ 80% | +15% price increase |
| Days to Arrival | ≤ 3 days before | −10% last-minute discount |
| Pickup Pace | Pickup ≥ 5/day | +10% demand surge |
Klik "Apply Now" untuk jalankan semua rule aktif terhadap inventory 30 hari ke depan.
Parity Monitor
Panel → Pricing → Parity. Monitor perbedaan rate antara direct booking vs OTA. Alert otomatis muncul jika gap > threshold yang dikonfigurasi (critical/high/medium/low).
Revenue Management (RMS)
Tools untuk mengoptimalkan pendapatan — forecast, yield, dan competitive intelligence.
RMS Dashboard
Panel → RMS → Dashboard: overview KPI revenue — occupancy, ADR, RevPAR, TRevPAR dibanding periode sebelumnya.
Forecast
Panel → RMS → Forecast: proyeksi occupancy dan revenue 30/60/90 hari ke depan berdasarkan historis dan pickup pace. Export ke Excel tersedia.
Yield Management
Panel → RMS → Yield: tabel yield per room type — room nights sold, ADR, ALOS, variance vs budget. Warna merah/hijau otomatis untuk quick scan.
Rate Shopper
Panel → RMS → Rate Shopper: bandingkan rate kita vs kompetitor. Rate index dihitung (hijau ≥1.05 = premium, merah ≤0.95 = below market). Data diupdate via integrasi rate shopping API (konfigurasi di Integrations).
Akuntansi
Double-entry accounting terintegrasi — semua transaksi hotel otomatis membuat jurnal.
Chart of Accounts (COA)
Panel → Accounting → COA: lihat semua akun dengan kode, nama, tipe (Asset/Liability/Equity/Revenue/Expense). Default seeder sudah include ~50 akun standar hotel Indonesia.
Journal Entries
Sebagian besar jurnal dibuat otomatis (room charge, payment, night audit). Untuk jurnal manual: Panel → Accounting → Journal → Create. Input baris debit/kredit, sistem validasi balance otomatis.
AR (Accounts Receivable)
Panel → Accounting → AR: invoice ke company account atau travel agent. Lihat aging, outstanding balance, dan riwayat pembayaran per invoice.
AP (Accounts Payable)
Panel → Accounting → AP: tagihan dari supplier — laundry, F&B supplier, maintenance. Track outstanding bills dan tanggal jatuh tempo (overdue ditandai merah).
Laporan Keuangan
- Daily Revenue — breakdown pendapatan per hari per kategori
- Trial Balance — neraca saldo periode tertentu, warning jika tidak balance
- P&L Statement — laba rugi dengan margin % dan KPI cards
Laporan
Semua laporan operasional dan keuangan dalam satu tempat.
Laporan Tersedia
| Laporan | Modul | Frekuensi |
|---|---|---|
| Daily Revenue | Accounting | Harian (otomatis night audit) |
| Trial Balance | Accounting | Bulanan |
| Profit & Loss | Accounting | Bulanan / Tahunan |
| Flash Report | Reports | Harian |
| Occupancy Report | Reports | Harian / Bulanan |
| Channel Production | Reports | Bulanan |
| Cashier Shift | Reports | Per shift |
| Service Charge | HR | Bulanan |
| Payroll Summary | HR | Bulanan |
Flash Report
Panel → Reports → Flash: snapshot KPI hari ini — occupancy %, rooms sold, revenue, ADR, RevPAR. Desain print-friendly untuk morning briefing.
Tamu & Loyalty
Database tamu terpadu dengan profil 360° dan program loyalitas.
Guest Directory
Panel → Guests: cari tamu berdasarkan nama, email, atau telepon. Klik tamu untuk lihat riwayat menginap.
Guest 360 Profile
Untuk setiap tamu, klik "360° Profile" untuk melihat:
- Loyalty Score — 0–100, semakin tinggi = semakin loyal
- Upsell Score — potensi tamu untuk upgrade/add-on
- Churn Risk — risiko tamu tidak kembali (merah = AT RISK)
- LTV — total nilai lifetime tamu
- Behavioral Profile — frekuensi kunjungan, preferred room type, lead days
- Spend Patterns — avg F&B, spa per menginap
Klik "Rebuild Profile" untuk refresh skor berdasarkan data terbaru.
Loyalty Tiers
Panel → Loyalty → Tiers: Bronze / Silver / Gold / Platinum. Set threshold poin dan rate discount per tier.
Vouchers
Panel → Loyalty → Vouchers: issue voucher diskon, complimentary night, atau F&B credit kepada tamu. Set tanggal expired dan nilai nominal.
HR & Payroll
Manajemen karyawan, absensi, dan penggajian terintegrasi.
Data Karyawan
Panel → HR → Employees: kelola data karyawan (nama, posisi, departemen, tanggal bergabung, gaji pokok). Upload dokumen (KTP, BPJS, kontrak).
Absensi
Panel → HR → Attendance: input absensi harian per karyawan atau import dari fingerprint system. Track jam kerja, overtime, cuti.
Payroll
Panel → HR → Payroll: generate payroll bulanan. Otomatis hitung komponen:
- Gaji pokok + tunjangan
- Lembur (overtime hours × rate)
- Service charge share per karyawan
- Potongan BPJS Kesehatan & Ketenagakerjaan
- PPh 21 (perhitungan otomatis)
Payslip
Klik nama karyawan → pilih periode → "Print Payslip". Slip gaji formal dalam format SLIP GAJI yang print-friendly.
Service Charge Distribution
Panel → HR → Service Charge: distribusi service charge bulanan ke semua karyawan berdasarkan formula yang dikonfigurasi (equal share, atau per jabatan).
Aset & Maintenance
Tracking aset hotel dan work order maintenance.
Daftar Aset
Panel → Assets: semua aset hotel (furniture, elektronik, A/C, dll). Track cost, depresiasi, nilai buku, dan lokasi.
Work Orders
Panel → Assets → Work Orders: buat work order untuk maintenance. Tipe: Corrective (kerusakan), Preventive (rutin), Inspection. Assign ke teknisi dan set priority.
PPM (Planned Preventive Maintenance)
Panel → Assets → PPM: jadwal maintenance rutin per aset (mis: A/C service setiap 3 bulan). Tampilan visual: Overdue / Due Soon / Scheduled.
Komunikasi & Marketing
Inbox terpusat, template pesan, dan campaign marketing.
Inbox
Panel → Comm → Inbox: semua pesan masuk dari tamu (via email, WhatsApp, SMS) dalam satu tampilan. Balas langsung dari panel.
Thread / Chat View
Klik thread untuk melihat percakapan dalam format chat. Pesan keluar (biru, kanan) dan masuk (abu, kiri) dengan timestamp.
Templates
Panel → Comm → Templates: buat template pesan untuk booking confirmation, check-in reminder, post-stay review request. Tersedia per channel (email/WhatsApp/SMS) dan bahasa.
Campaigns
Panel → Comm → Campaigns: blast pesan ke segment tamu (mis: semua tamu yang menginap 3+ bulan lalu). Set jadwal kirim, track open rate dan sent count.
Referral Program
Panel → Marketing → Referrals: program referral — tamu dapat unique link, earning points setiap ada booking dari link mereka.
Konfigurasi
Semua pengaturan property, pajak, dan sistem.
Property Settings
Panel → Settings → Property: nama hotel, alamat, telepon, NPWP, logo, timezone, mata uang. Pengaturan ini muncul di semua invoice dan dokumen resmi.
Tax Settings
Panel → Settings → Tax: aktifkan/nonaktifkan PB1, set persentase (default 10%), input NSFP prefix, daftar history rate PB1 untuk audit.
Cancellation Policies
Panel → Settings → Cancellation Policies: buat kebijakan pembatalan (nama, grace period, aturan penalty per X hari sebelum checkin). Assign ke rate plan.
Document Templates
Panel → Settings → Doc Templates: kustomisasi template folio, invoice, BEO — header HTML, body, footer. Variabel dinamis tersedia (nama tamu, total, dll).
Users
Panel → Settings → Users: kelola user staff — tambah, edit role, reset password, aktif/nonaktif.
Integrasi BYOK
Bring Your Own Key — semua integrasi dikonfigurasi oleh user sendiri, tidak ada provider yang hardcoded.
Kategori Integrasi
| Kategori | Contoh Provider | Format Adapter |
|---|---|---|
| AI / LLM | OpenAI, Claude, DeepSeek, Groq, Ollama | OpenAI-compatible / Anthropic / Gemini |
| Payment | Midtrans, Xendit, Stripe, Doku | Redirect / Embed / QR |
| SMS Gateway | Twilio, Zenziva, Vonage | REST-format |
| Wablas, Fonnte, WA Cloud API | REST-format | |
| Mailgun, SendGrid, SES, SMTP | SMTP / API | |
| Storage | S3, Backblaze, Cloudflare R2, local | S3-compatible |
| Channel OTA | Booking.com, Agoda, Traveloka | XML / JSON REST |
Cara Menambah Integrasi
- Panel → Settings → IntegrationsKlik "+ Add Integration" → pilih kategori
- Pilih Format AdapterMisal untuk LLM: pilih "OpenAI-Compatible" jika provider pakai format OpenAI (DeepSeek, Groq, Ollama, dll)
- Input CredentialsBase URL, API Key (dienkripsi AES-256 saat disimpan), model name, extra headers jika perlu
- Assign ke FiturPilih fitur mana yang menggunakan integrasi ini (AI: guest profile / translate / demand forecast)
- Test ConnectionKlik "Test" untuk verifikasi koneksi sebelum aktifkan
REST API
Hotel HMS menyediakan REST API v1 untuk integrasi dengan sistem eksternal.
Authentication
Dua metode autentikasi:
- OAuth 2.0 — untuk aplikasi pihak ketiga
- Personal Access Token (PAT) — untuk integrasi langsung (webhook, scripts)
Authorization: Bearer {your-token}
Base URL
https://yourdomain.com/api/v1
Endpoint Utama
| Endpoint | Method | Deskripsi |
|---|---|---|
/reservations | GET / POST | List & create reservasi |
/reservations/{id} | GET / PATCH | Detail & update |
/reservations/{id}/check-in | POST | Proses check-in |
/reservations/{id}/check-out | POST | Proses check-out |
/rooms | GET | List kamar & availability |
/guests | GET / POST | Directory tamu |
/folios/{id}/charges | POST | Tambah charge ke folio |
/pricing/calendar | GET / POST | Rate grid & override |
/webhooks | POST | Register webhook endpoint |
Idempotency
Untuk request yang bisa duplikat (pembayaran, dll), gunakan header Idempotency-Key: {uuid}. Sistem menyimpan hasil 24 jam — request sama tidak akan diproses dua kali.
Webhook Events
reservation.createdreservation.checked_inreservation.checked_outfolio.payment_receivednight_audit.completed
Lihat dokumentasi lengkap di /api/v1/openapi.json (OpenAPI 3.0 spec).
Beli Source Code
Dapatkan source code lengkap Hotel HMS untuk digunakan di hotel Anda.
Hotel HMS — Full Source Code
Laravel 11 · PostgreSQL · Tailwind CSS · Alpine.js · 341 PHP files
Hubungi via WhatsApp📞 081296052010 · Respon cepat
Yang Termasuk dalam Paket
- ✅ Source code Laravel 11 lengkap (341+ PHP files)
- ✅ 141 Blade views — UI modern Tailwind CSS
- ✅ 46 database migrations + seeder lengkap
- ✅ 130 Eloquent models dengan relasi lengkap
- ✅ ~430 routes (panel, portal, API, admin)
- ✅ Pest test suite 84/84 passing
- ✅ 27 file dokumentasi teknis (00-24)
- ✅ BYOK integration system (AI, Payment, SMS, Channel)
- ✅ pSEO 15+ pattern untuk booking engine
- ✅ License pairing system (standalone mode)
- ✅ Indonesia compliance (PB1, NSFP, WNA reporting)
- ✅ Dukungan setup via WhatsApp
Cocok Untuk
Pemilik Hotel
Deploy langsung untuk hotel Anda. Customisasi bebas tanpa biaya bulanan.
Developer / Agency
Base yang solid untuk project HMS klien Anda. Hemat ratusan jam development.
Belajar
Studi kasus nyata Laravel 11 enterprise — ideal untuk portofolio atau tugas akhir.
SaaS Starter
Infrastruktur SaaS multi-tenant sudah disiapkan (stancl/tenancy ready).
Kontak Pembelian
WhatsApp: 081296052010
Chat sekarang untuk info harga, demo, dan proses pembelian
Alur Kerja End-to-End
Dari user klik tombol → kode jalan → tabel database terisi. Semua relational, satu alur.
📌 Cara baca dokumen ini
Setiap workflow di-decompose jadi langkah. Per langkah ada aksi user → file kode → tabel database yang terisi. Tabel yang masih kosong di DB-mu = fitur belum pernah dipakai (normal kalau fresh install). Kalau sudah ada data, alur sudah dilalui.
1️⃣ Workflow: Reservasi Direct (Booking Engine)
Tamu pesan langsung dari website hotel. Tanpa OTA.
| Step | Aksi User | Kode | Tabel Terisi |
|---|---|---|---|
| 1 | Buka /booking + isi tanggal | BookingEngineController@search | (read-only) inventory, rate_plans, rates |
| 2 | Klik kamar → Pilih | BookingEngineController@results | (read-only) |
| 3 | Isi data tamu → Submit | BookingEngineController@submit | ✏️ guests, reservations, reservation_rooms, folios |
| 4 | Bayar via gateway | Webhook booking.payment-callback | ✏️ folio_payments, folios.balance |
| 5 | Email konfirmasi terkirim | Job SendReservationConfirmationJob | ✏️ notifications, email_logs |
2️⃣ Workflow: Booking dari OTA (Channel Manager)
Booking masuk dari Booking.com / Agoda / Traveloka / dll. lewat webhook atau polling.
| Step | Aksi | Kode | Tabel Terisi |
|---|---|---|---|
| 1 | Setup OTA channel pertama kali | panel/channel → ChannelController@store | ✏️ channels, channel_room_mappings |
| 2 | OTA push booking via webhook | WebhookController@channel → BookingComAdapter (atau adapter lain) | ✏️ reservations, reservation_rooms, guests, folios, ari_sync_log |
| 3 | PMS push availability ke OTA | Job PushAriToChannelJob → adapter | ✏️ ari_sync_log, inventory (sync timestamp) |
| 4 | Konflik tarif/avail | ConflictDetectionService | ✏️ channel_conflicts, channel_parity_alerts |
| 5 | Resolve konflik (admin) | ConflictController@resolve | ✏️ channel_conflicts.resolved_at |
3️⃣ Workflow: Check-In → Stay → Check-Out
Inti operasional Front Office. Semua charge di-track di folio.
| Step | Aksi User | Kode | Tabel Terisi |
|---|---|---|---|
| 1 | Tamu datang → Receptionist klik Check-in | panel/fo/reservations/{id}/check-in | ✏️ reservations.status='checked_in', reservation_rooms.actual_arrival, rooms.status='occupied' |
| 2 | Scan KTP/Paspor (vision LLM) | OcrService@extractKtp | ✏️ guests.ktp_number, guests.id_document_url |
| 3 | Tamu sign e-registration card | e-registration/store | ✏️ e_registrations, guests.signature_url |
| 4 | WNA? Auto generate Lapor Imigrasi | WnaReporter@queueReport | ✏️ wna_reports, compliance_jobs |
| 5 | Tamu order makanan via QR menu di kamar | QrMenuController@placeOrder | ✏️ pos_orders, pos_order_items |
| 6 | POS settle: charge to room | PosController@settle | ✏️ folio_charges (linked ke folio reservasi), pos_orders.status='settled' |
| 7 | Minibar consumption (HK input) | HkController@minibarPost | ✏️ folio_charges, minibar_consumptions |
| 8 | Tamu check-out → settle folio | panel/fo/folios/{id}/settle | ✏️ folio_payments, folios.balance=0, reservations.status='checked_out', rooms.status='dirty' |
| 9 | HK dapat task auto-clean | RoomCheckedOutObserver | ✏️ hk_tasks, rooms.status='cleaning' |
| 10 | HK selesai inspeksi → kamar sellable lagi | HkController@inspect | ✏️ hk_inspections, rooms.status='clean', inventory.available++ |
4️⃣ Workflow: Night Audit (Closing Day)
Auto-post room charge, freeze inventory, generate laporan harian.
| Step | Aksi | Kode | Tabel Terisi |
|---|---|---|---|
| 1 | Click Run Night Audit (atau cron 03:00 WIB) | NightAuditController@run | — |
| 2 | Auto-post room charge per occupied room | NightAuditService@postRoomCharges | ✏️ folio_charges (category=room) |
| 3 | Snapshot occupancy & rate | NightAuditService@snapshot | ✏️ inventory.sold, inventory.adr |
| 4 | Generate flash report | FlashReportGenerator@generate | ✏️ daily_flash_reports |
| 5 | Auto-post journal entries (PSAK + USALI) | JournalPostingService@postEod | ✏️ journal_entries, journal_lines |
| 6 | Lock period (no edits) | AccountingPeriod@close | ✏️ accounting_periods, audit_logs |
| 7 | Email digest ke owner | Job SendDailyDigestJob | ✏️ email_logs |
5️⃣ Workflow: Procurement (Inventory)
PR → PO → GR. Auto-update stock card & journal AP.
| Step | Aksi User | Kode | Tabel Terisi |
|---|---|---|---|
| 1 | HK / Kitchen butuh barang → bikin PR | panel/inventory/pr/create | ✏️ purchase_requests, purchase_request_lines |
| 2 | Manager approve | panel/inventory/pr/{id}/approve | ✏️ purchase_requests.status='approved', approval_requests |
| 3 | Purchasing convert PR → PO | panel/inventory/po/create | ✏️ purchase_orders, purchase_order_lines |
| 4 | PO send ke vendor (email/print) | PoController@send | ✏️ purchase_orders.sent_at, email_logs |
| 5 | Barang datang → input GR | panel/inventory/gr/create | ✏️ goods_receipts, goods_receipt_lines |
| 6 | GR accept → stock + AP bill auto-create | GrController@accept | ✏️ inventory_movements, inventory_items.stock_qty, ap_bills, ap_bill_lines |
| 7 | Pay AP bill | panel/accounting/ap/{id}/pay | ✏️ ap_payments, ap_bills.status='paid', journal_entries |
6️⃣ Workflow: AI Concierge (BYOK)
Chatbot tamu yang BYOK ke provider apapun (DeepSeek, Gemini, Anthropic, Self-hosted).
| Step | Aksi | Kode | Tabel Terisi |
|---|---|---|---|
| 1 | Owner setup AI provider di Settings → Integrations | panel/settings/integrations | ✏️ integrations (kategori 'ai', api_format, encrypted key) |
| 2 | Tamu chat di guest portal / WhatsApp | POST /api/v1/ai/concierge | ✏️ ai_conversations, ai_messages |
| 3 | ConciergeService panggil adapter (OpenAI-compat / Anthropic / Gemini) | ConciergeService@chat → OpenAICompatibleAdapter (etc) | ✏️ ai_usage_logs (token count, cost tracking) |
| 4 | Response streaming ke tamu | SSE response | ✏️ ai_messages |
7️⃣ Workflow: Lisensi Pairing (Buyer Activation)
Saat buyer install app pertama kali — pair ke whitelabel.co.id.
| Step | Aksi | Kode | File / Tabel |
|---|---|---|---|
| 1 | Buyer buka domain pertama kali | Middleware RequirePair | (read-only) storage/app/.license.lock |
| 2 | Belum paired → redirect ke /__pair wizard | PairController@show | — |
| 3 | Buyer paste activation key | LicenseClient@activate → POST whitelabel.co.id | — |
| 4 | Server return signed_payload (RSA-signed) | — | 📦 storage/app/.license.lock (AES-256-GCM encrypted) |
| 5 | Heartbeat tiap 24 jam | LicenseClient@maybeHeartbeat | (cache: license:heartbeat:last) |
8️⃣ Workflow: SaaS Onboarding (Vendor Side)
Calon customer signup di marketplace, vendor admin provision tenant.
| Step | Aksi | Kode | Tabel Terisi |
|---|---|---|---|
| 1 | Calon customer signup di /signup | TenantSignupController@store | ✏️ tenants (status='trial') |
| 2 | Vendor admin provision di /admin/tenants/{id}/provision | TenantProvisioner@provision | ✏️ tenant_domains, tenant_subscriptions (plan), users (admin tenant) |
| 3 | Generate tenant invoice pertama | InvoiceGenerator@generate | ✏️ tenant_invoices (status='unpaid') |
| 4 | Customer bayar via Midtrans | Webhook payment.success | ✏️ tenant_invoices.status='paid', tenants.status='active' |
| 5 | Vendor impersonate untuk troubleshoot | panel/admin/tenants/{id}/impersonate | ✏️ impersonation_logs |
| 6 | Vendor suspend (telat bayar) | panel/admin/tenants/{id}/suspend | ✏️ tenants.status='suspended' |
✅ Relational Integrity
Setiap tabel anak punya FK ke parent — folio_charges.folio_id → folios.id, folios.reservation_id → reservations.id, reservation_rooms.reservation_id → reservations.id, journal_lines.journal_entry_id → journal_entries.id, dst. Semua di-enforce via migration foreign() constraints. Cascade delete dipakai untuk parent-child wajib (folio_charges ikut hilang kalau folio dihapus); restrict untuk reference master (rooms, guests).
Skema Database
167 tabel total · 24 ada data sekarang · 143 menunggu workflow dilalui
Tabel dengan Data (Sudah Pernah Dipakai)
Tabel yang sudah punya rows di DB-mu — fitur sudah diaktifkan, alur sudah dilalui:
| Tabel | Rows | Diisi oleh workflow |
|---|---|---|
folio_charges | 2,452 | Setiap charge ke folio (room, F&B, minibar, addon) |
rates | 1,086 | Setup rate plan + rate calendar |
guests | 1,001 | Setiap reservasi baru (auto-create kalau guest belum ada) |
reservation_rooms | 801 | Per kamar dalam reservasi (multi-room booking) |
reservations | 801 | Booking direct + dari OTA |
folios | 748 | 1 folio per reservasi (auto-create saat reservasi) |
inventory | 543 | Snapshot per kamar per tanggal (dari Night Audit) |
folio_payments | 370 | Setiap payment masuk (cash, transfer, gateway) |
permissions | 56 | Spatie permission seeded |
rooms | 30 | Master kamar (30 untuk demo hotel) |
roles | 11 | Spatie role: super_owner, manager, FO, cashier, dll |
room_types | 3 | Superior, Deluxe, Junior Suite |
properties | 1 | Demo Hotel Mandala |
users | 1 | admin@demohotel.id |
admin_users | 1 | superadmin@hotelhub.id (vendor) |
Tabel Kosong (Fitur Belum Dipakai)
143 tabel masih kosong — ini NORMAL. Akan terisi otomatis sesuai alur kerja:
| Kategori Fitur | Tabel Kosong | Akan terisi saat |
|---|---|---|
| Channel / OTA | channels, channel_room_mappings, channel_conflicts, channel_parity_alerts, ari_sync_log | Setup OTA pertama (Booking.com, Agoda, dll) |
| POS / F&B | pos_orders, pos_order_items, pos_outlets, pos_menu_items, pos_tables | Pertama kali order F&B di restoran |
| Housekeeping | hk_tasks, hk_inspections, linen_audits, lost_found_items | Pertama kali check-out (auto-create cleaning task) |
| Accounting | journal_entries, journal_lines, ar_invoices, ar_payments, ap_bills, ap_payments, accounting_periods | Night Audit pertama atau manual journal |
| Inventory / Procurement | purchase_requests, purchase_orders, goods_receipts, inventory_items, inventory_movements | PR pertama dibuat |
| HR & Payroll | employees, attendance_logs, leave_requests, payrolls, payslips | Tambah employee pertama |
| Banquet / MICE | banquet_events, banquet_function_rooms, banquet_event_menus | Booking event pertama |
| Spa | spa_appointments, spa_therapists, spa_treatments | Booking spa pertama |
| Asset / Maintenance | assets, work_orders, ppm_schedules | Tambah aset pertama |
| Loyalty / CRM | loyalty_members, loyalty_tiers, loyalty_vouchers | Enroll member loyalty pertama |
| Communication | conversations, messages, campaigns, notifications | Kirim email/WA pertama |
| Compliance | wna_reports, sipgar_submissions, e_faktur_logs | Check-in tamu WNA pertama / submit pajak |
| SaaS / Multi-tenant | tenants, tenant_domains, tenant_subscriptions, tenant_invoices | Cuma kepakai kalau APP_MODE=saas |
Relational Integrity Map
Cara tabel terhubung — semua FK enforced di migration:
properties (1)
├─ rooms ─── room_types
├─ inventory (per room per tanggal)
├─ rate_plans ─── rates
│
├─ reservations
│ ├─ reservation_rooms ─── rooms
│ ├─ guests (primary_guest)
│ └─ folios
│ ├─ folio_charges
│ ├─ folio_payments
│ └─ folio_transfers
│
├─ channels (Booking.com, Agoda, …)
│ ├─ channel_room_mappings ─── room_types
│ ├─ channel_conflicts
│ └─ ari_sync_log
│
├─ pos_outlets ─── pos_menu_items, pos_tables
│ └─ pos_orders ─── pos_order_items
│ └─ folio_charges (charge to room)
│
├─ hk_tasks ─── rooms, employees
│ ├─ hk_inspections
│ ├─ linen_audits
│ └─ lost_found_items
│
├─ journal_entries ─── journal_lines ─── chart_of_accounts
│ ├─ ar_invoices ─── ar_invoice_lines, ar_payments
│ └─ ap_bills ─── ap_bill_lines, ap_payments
│
├─ purchase_requests ── purchase_orders ── goods_receipts
│ └─ inventory_movements ─── inventory_items
│
├─ employees ── attendance_logs, leave_requests, payrolls, payslips
│
└─ users ── roles ── permissions (Spatie)
admin_users (vendor side, terpisah)
├─ tenants ── tenant_domains, tenant_subscriptions, tenant_invoices
└─ license_events
Cara Cek Relational Integrity Sendiri
# List semua FK constraint:
mysql hotel_main -e "SELECT TABLE_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME
FROM information_schema.KEY_COLUMN_USAGE
WHERE REFERENCED_TABLE_NAME IS NOT NULL
ORDER BY TABLE_NAME;"
# Test cascade — coba delete reservation, lihat folio + folio_charges ikut hilang:
php artisan tinker
> \App\Models\Reservation::find(1)->delete();
> // folios + folio_charges + folio_payments otomatis ikut