Source Code POS untuk Restoran

Jam makan siang, meja 7 memesan tambahan dua es teh, tapi pesanan itu tidak pernah sampai ke dapur. Di meja lain, rombongan enam orang minta tagihan dipisah per orang dan kasir men...

Source Code POS untuk Restoran

Jam makan siang, meja 7 memesan tambahan dua es teh, tapi pesanan itu tidak pernah sampai ke dapur. Di meja lain, rombongan enam orang minta tagihan dipisah per orang dan kasir menghitung ulang dengan kalkulator. POS ritel biasa tidak dirancang untuk situasi seperti ini. Artikel ini membahas apa yang membedakan POS restoran, bagaimana datanya disusun, dan apa yang perlu Anda periksa sebelum memakai source code POS restoran.

Kenapa POS Ritel Tidak Cukup untuk Restoran

Di toko ritel, transaksi terjadi sekali: barang dipindai, dibayar, selesai. Di restoran, satu pesanan hidup selama tamu duduk. Pesanan dibuka, ditambah beberapa kali, dikirim ke dapur bertahap, lalu dibayar di akhir, kadang oleh beberapa orang. Jika Anda belum familiar dengan cara kerja POS secara umum, baca dulu apa itu aplikasi kasir dan cara kerjanya.

KebutuhanPOS ritelPOS restoran
Siklus transaksiSekali bayarPesanan terbuka, ditambah bertahap
Lokasi pelangganTidak relevanNomor meja dan statusnya
ProdukSKU tetapMenu dengan varian (level pedas, ukuran, topping)
KoordinasiHanya kasirPelayan, dapur, kasir
PembayaranSatu tagihanGabung atau pisah tagihan
StokPer barang jadiPer bahan baku lewat resep

Modul Inti POS Restoran

1. Manajemen menu dan varian

Menu dikelompokkan per kategori, dengan varian seperti level pedas, ukuran, atau topping tambahan. Menu yang habis harus bisa dinonaktifkan seketika agar pelayan tidak menerima pesanan yang tidak bisa dibuat.

2. Meja dan pesanan

Pelayan membuka pesanan per meja, menambah item, memindahkan tamu antarmeja, serta menggabung atau memisah tagihan. Status meja (kosong, terisi, menunggu bayar) tampil di satu layar.

3. Integrasi dapur

Item baru langsung muncul di layar dapur (kitchen display) atau tercetak di printer dapur. Ini menghapus langkah pelayan berjalan membawa kertas dan menjaga urutan pesanan.

4. Pembayaran dan pembagian tagihan

Mendukung tunai, kartu, dan QRIS, serta pemisahan tagihan per orang atau per item.

5. Laporan

Penjualan harian, menu terlaris, jam tersibuk, dan performa pelayan.

6. Stok bahan baku

Penjualan menu mengurangi stok bahan sesuai resep, sehingga Anda tahu kapan perlu belanja dan berapa bahan yang terbuang.

Desain Tabel yang Disarankan

Inti POS restoran adalah memisahkan pesanan (order) dari pembayaran (payment), karena satu pesanan bisa dibayar beberapa kali. Status per item juga dibutuhkan agar dapur tahu mana yang sudah dibuat.

CREATE TABLE dining_tables (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  code VARCHAR(10) NOT NULL UNIQUE,
  status ENUM('empty','occupied','billing') DEFAULT 'empty'
);

CREATE TABLE orders (
  id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  dining_table_id INT UNSIGNED NULL,
  waiter_id BIGINT UNSIGNED NOT NULL,
  status ENUM('open','closed','void') DEFAULT 'open',
  opened_at DATETIME NOT NULL,
  closed_at DATETIME NULL
);

CREATE TABLE order_items (
  id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  order_id BIGINT UNSIGNED NOT NULL,
  menu_id BIGINT UNSIGNED NOT NULL,
  qty SMALLINT UNSIGNED NOT NULL,
  unit_price DECIMAL(12,2) NOT NULL,
  note VARCHAR(150) NULL,
  kitchen_status ENUM('queued','cooking','served') DEFAULT 'queued',
  payment_id BIGINT UNSIGNED NULL
);

CREATE TABLE payments (
  id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  order_id BIGINT UNSIGNED NOT NULL,
  method ENUM('cash','card','qris') NOT NULL,
  amount DECIMAL(12,2) NOT NULL,
  paid_at DATETIME NOT NULL
);

CREATE TABLE recipes (
  menu_id BIGINT UNSIGNED NOT NULL,
  ingredient_id BIGINT UNSIGNED NOT NULL,
  qty_used DECIMAL(10,3) NOT NULL,
  PRIMARY KEY (menu_id, ingredient_id)
);

Kolom payment_id di order_items memungkinkan split bill per item: setiap tamu membayar item miliknya, dan pesanan ditutup ketika semua item sudah punya pembayaran. Tabel recipes menghubungkan menu ke bahan baku.

Mengurangi stok bahan saat pesanan ditutup

Pengurangan stok sebaiknya dilakukan dalam transaksi database agar tidak setengah jalan jika terjadi error:

use Illuminate\Support\Facades\DB;

DB::transaction(function () use ($order) {
    foreach ($order->items as $item) {
        foreach ($item->menu->recipes as $recipe) {
            Ingredient::whereKey($recipe->ingredient_id)
                ->decrement('stock', $recipe->qty_used * $item->qty);
        }
    }
    $order->update(['status' => 'closed', 'closed_at' => now()]);
});

Untuk restoran ramai, pertimbangkan memindahkan perhitungan ini ke queue agar kasir tidak menunggu. Caranya dibahas di queue dan job di Laravel.

Laporan Jam Tersibuk dan Menu Terlaris

Dua laporan ini paling sering dipakai pemilik restoran untuk mengatur jadwal pegawai dan belanja bahan. Keduanya bisa diambil dari order_items dan orders yang sudah ditutup:

-- Jam tersibuk 30 hari terakhir
SELECT HOUR(o.opened_at) AS jam, COUNT(DISTINCT o.id) AS jumlah_pesanan
FROM orders o
WHERE o.status = 'closed' AND o.opened_at >= NOW() - INTERVAL 30 DAY
GROUP BY HOUR(o.opened_at)
ORDER BY jumlah_pesanan DESC;

-- Menu terlaris
SELECT m.name, SUM(oi.qty) AS terjual, SUM(oi.qty * oi.unit_price) AS omzet
FROM order_items oi
JOIN orders o ON o.id = oi.order_id AND o.status = 'closed'
JOIN menus m ON m.id = oi.menu_id
GROUP BY m.name
ORDER BY terjual DESC
LIMIT 10;

Contoh pemakaian: misalkan laporan memperlihatkan jam 15.00-17.00 hampir selalu sepi. Anda bisa memasang paket camilan sore di jam itu, lalu membandingkan angka minggu berikutnya. Menu yang terus berada di urutan bawah selama beberapa bulan layak dievaluasi: apakah harganya, porsinya, atau memang kurang diminati.

Rencana Implementasi Bertahap

  1. Minggu pertama: input menu, harga, dan meja. Latih pelayan membuka dan menutup pesanan.
  2. Minggu kedua: hubungkan dapur lewat layar atau printer. Hentikan nota kertas ke dapur.
  3. Minggu ketiga: aktifkan split bill dan seluruh metode pembayaran yang Anda terima.
  4. Bulan kedua: isi resep dan stok awal bahan, lalu cocokkan dengan stok fisik tiap minggu.

Bertahap mengurangi kebingungan staf dan memudahkan menemukan bagian yang belum berjalan.

Menjalankan Source Code POS Secara Lokal

  1. Siapkan PHP, Composer, dan MySQL sesuai versi yang tertulis di README proyek.
  2. Jalankan composer install di folder proyek.
  3. Salin .env.example ke .env, isi koneksi database, lalu php artisan key:generate.
  4. Jalankan migrasi dan seeder atau impor SQL bawaan.
  5. Jalankan php artisan serve, login sebagai admin, lalu coba alur lengkap: buka meja, pesan, kirim ke dapur, split bill, tutup.

Jika menemui error saat instalasi, panduan menjalankan source code Laravel membahas masalah yang paling sering muncul.

Checklist Evaluasi Sebelum Memilih

  • Pesanan bisa ditambah setelah dikirim ke dapur tanpa membuat pesanan baru.
  • Item yang sudah dimasak tidak bisa dihapus tanpa otorisasi supervisor (mencegah kecurangan).
  • Split bill per item dan per orang berjalan, totalnya tetap cocok.
  • Harga di order_items tersimpan saat pemesanan, bukan dibaca ulang dari tabel menu.
  • Menu habis bisa dinonaktifkan dan langsung hilang dari layar pelayan.
  • Laporan menu terlaris dan jam tersibuk tersedia atau mudah ditambahkan.
  • Bisa dijalankan di tablet lewat browser tanpa instalasi khusus.
  • Kode mengikuti struktur Laravel standar dan disertai dokumentasi.

Kesalahan Umum dan Solusinya

  • Memakai POS ritel untuk restoran: tidak ada konsep meja, akhirnya pelayan mencatat di kertas lagi. Pilih sistem yang punya pesanan terbuka.
  • Dapur tidak terhubung: pesanan tambahan sering hilang. Minimal gunakan printer dapur jika belum ada layar.
  • Resep tidak diisi: modul stok bahan jadi tidak berguna. Mulai dari 10 menu terlaris dulu.
  • Tidak ada pembatalan berjejak: void tanpa catatan membuka celah kecurangan. Simpan siapa, kapan, dan alasannya.

Keterbatasan Source Code Siap Pakai

Integrasi printer termal dan pembayaran digital sering bergantung pada perangkat dan penyedia yang Anda pakai, sehingga hampir selalu perlu penyesuaian. Mode offline saat internet putus juga jarang tersedia di POS berbasis web; jika lokasi Anda sering gangguan jaringan, pertimbangkan server lokal di jaringan restoran. Anda juga bertanggung jawab atas backup harian dan keamanan server.

Jika Anda sedang menimbang membeli atau membangun sendiri, panduan memilih source code siap pakai memberi kerangka pertimbangannya. Katalog GudangCode juga memuat beberapa aplikasi kasir berbasis Laravel yang bisa dijadikan bahan perbandingan.

Ingin langsung mempraktikkannya?

Buat akun gratis untuk mengunduh contoh aplikasi Laravel, menyimpan tutorial favorit, dan mencoba kursus. Gratis, bisa daftar dengan akun Google.

Daftar Gratis Lihat katalog aplikasi
Yudhi
Ditulis oleh
Yudhi
Founder & Lead Developer, GudangCode

Yudhi adalah founder GudangCode dan developer Laravel dengan pengalaman membangun puluhan sistem informasi bisnis siap pakai — mulai dari POS, HRIS, hingga aplikasi manajemen. Ia menulis panduan dan artikel di GudangCode untuk membantu developer Indonesia menjalankan, memahami, dan men-deploy source code Laravel dengan benar.

Laravel PHP MySQL Sistem Informasi Bisnis
Lihat semua artikel Yudhi
Source Code Pos Restoran Source Code
Bacaan Paling Dicari
📚 Free Learning Hub

Learn Coding for Free at DhieCoderWeb

Explore Laravel, PHP, JavaScript tutorials, source code, web development guides, and practical programming tips.

DhieCoderWeb
100+
Tutorials
Free
Learning
SEO
Tips
Visit Dhiecoderweb.com →