Home

POS System - Sistem Kasir Online

Banner Atas

POS System - Sistem Kasir Online

POS System adalah alat kasir online gratis yang dirancang untuk membantu pemilik toko, kafe, atau bisnis kecil dalam mengelola penjualan harian dengan lebih mudah. Melalui sistem ini, Anda dapat mencatat transaksi, menambahkan produk, menyimpan data pelanggan dan supplier, hingga mencetak struk otomatis — semuanya langsung dari browser tanpa perlu instalasi.

Dengan tampilan yang sederhana dan fitur lengkap, POS System membantu Anda menghemat waktu dan mengurangi kesalahan pencatatan. Semua data tersimpan secara lokal di perangkat Anda, sehingga privasi dan keamanan informasi bisnis tetap terjaga. Anda juga bisa melakukan ekspor dan impor data untuk keperluan backup atau laporan.

Sistem ini dilengkapi dengan berbagai menu penting seperti pengaturan toko, pelanggan, supplier, produk, transaksi, serta laporan dan grafik penjualan. Setiap transaksi akan otomatis menghitung total, diskon, dan kembalian dengan cepat serta menampilkan ringkasan dalam format struk kasir digital.

POS System juga menyediakan grafik penjualan otomatis yang memudahkan Anda untuk memantau performa produk dan pendapatan bisnis setiap hari. Alat ini bisa digunakan oleh siapa saja — dari pedagang kecil, UMKM, hingga pemilik kafe yang ingin mengelola kasir dengan cara yang lebih modern dan efisien.

💡 Gunakan POS System sekarang dan nikmati pengalaman mengelola penjualan secara online dengan mudah, cepat, dan aman tanpa perlu software tambahan.

Pengaturan Toko
Pelanggan
Supplier
Produk
Transaksi
Laporan & Grafik

Pengaturan Toko

Kelola Pelanggan

Nama Telepon Email Aksi

Kelola Supplier

Nama Telepon Email Aksi

Kelola Produk

Nama SKU Harga Beli Harga Jual Stok Satuan Supplier Aksi

Transaksi / Invoice

Produk Harga Qty Subtotal Aksi
Subtotal: 0
Diskon: 0
Total (Grand Total): 0

Laporan & Grafik

Invoice Tanggal Ringkasan Total Aksi
Promo Tengah
Banner Bawah
Struk ${escapeHtml(tx.invoice)}
${header} ${itemsHtml} ${footer}
`; document.getElementById("receipt").textContent = ""; // clear visual if (openPrintWindow) { const w = window.open("", "_blank", "width=400,height=600"); if (!w) { alert("Popup diblokir. Izinkan popup untuk mencetak struk."); return; } w.document.open(); w.document.write(html); w.document.close(); // biarkan sedikit waktu agar konten render lalu print w.focus(); setTimeout(() => { w.print(); // optionally close after print // w.close(); }, 300); } else { document.getElementById("receipt").textContent = `${tx.invoice}\n${tx.tgl}\n${tx.items .map((i) => i.nama + " " + i.qty + " x " + formatNumber(i.harga) + " = " + formatNumber(i.qty * i.harga)) .join("\n")}\nTotal: ${formatNumber(tx.total)}`; } } // LAPORAN function renderReports() { const tbody = document.querySelector("#reportTable tbody"); if (!db.transaksi.length) { tbody.innerHTML = 'Belum ada transaksi'; } else { tbody.innerHTML = db.transaksi .map( (t, ti) => ` ${escapeHtml(t.invoice)} ${escapeHtml(t.tgl)} ${escapeHtml(t.items.map((it) => it.nama + " x" + it.qty).join("\n")).replace(/\n/g, "
")} ${formatNumber(t.total)} ` ) .join(""); } drawChart(); // refresh chart } function reprintTransaction(invoice) { const tx = db.transaksi.find((t) => t.invoice === invoice); if (!tx) { alert("Transaksi tidak ditemukan"); return; } printReceipt(tx, true); } function deleteTransactionByInvoice(invoice) { if (!confirm("Hapus transaksi dengan invoice " + invoice + "?")) return; const idx = db.transaksi.findIndex((t) => t.invoice === invoice); if (idx >= 0) { db.transaksi.splice(idx, 1); saveData(); renderReports(); } } function deleteTransaction(index) { if (!confirm("Hapus transaksi nomor " + (index + 1) + "?")) return; db.transaksi.splice(index, 1); saveData(); renderReports(); } function clearTransactions() { if (!confirm("Hapus semua transaksi?")) return; db.transaksi = []; saveData(); renderReports(); } // CHART (penjualan per produk) let chartInstance = null; function drawChart() { const ctx = document.getElementById("reportChart").getContext("2d"); // aggregate totals per product across transaksi const map = {}; db.transaksi.forEach((t) => t.items.forEach((i) => { map[i.nama] = (map[i.nama] || 0) + i.qty * i.harga; }) ); const labels = Object.keys(map); const values = labels.map((k) => map[k]); if (chartInstance) chartInstance.destroy(); chartInstance = new Chart(ctx, { type: "bar", data: { labels, datasets: [{ label: "Penjualan (Rp)", data: values }] }, options: { responsive: true, plugins: { legend: { display: false } }, scales: { y: { beginAtZero: true } }, }, }); } // EXPORT TABLES (pelanggan, supplier, produk, laporan) function exportTable(type) { let data = null, name = "export.json"; switch (type) { case "pelanggan": data = db.pelanggan; name = "pelanggan.json"; break; case "supplier": data = db.supplier; name = "supplier.json"; break; case "produk": data = db.produk; name = "produk.json"; break; case "laporan": data = db.transaksi; name = "laporan.json"; break; default: data = db; name = "pos-data.json"; } const blob = new Blob([JSON.stringify(data, null, 2)], { type: "application/json" }); const a = document.createElement("a"); a.href = URL.createObjectURL(blob); a.download = name; a.click(); } // HELPERS function formatNumber(n) { if (n === undefined || n === null) return "0"; return Number(n).toLocaleString("id-ID"); } function escapeHtml(s) { if (s === undefined || s === null) return ""; return String(s).replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """); } function generateId(prefix = "") { return prefix + "-" + Date.now() + "-" + Math.floor(Math.random() * 1000); } function generateInvoiceNumber() { const d = new Date(); const y = d.getFullYear(); const m = String(d.getMonth() + 1).padStart(2, "0"); const day = String(d.getDate()).padStart(2, "0"); const time = String(d.getHours()).padStart(2, "0") + String(d.getMinutes()).padStart(2, "0") + String(d.getSeconds()).padStart(2, "0"); return `INV-${y}${m}${day}-${time}-${Math.floor(Math.random() * 900 + 100)}`; } function activateTab(tabId) { document.querySelectorAll(".tab").forEach((x) => x.classList.remove("active")); document.querySelectorAll(".tab-content").forEach((c) => c.classList.remove("active")); const tabEl = Array.from(document.querySelectorAll(".tab")).find((t) => t.dataset.tab === tabId); if (tabEl) tabEl.classList.add("active"); const content = document.getElementById(tabId); if (content) content.classList.add("active"); } // INITIAL RENDER renderAll();