update barcode, kasir

This commit is contained in:
adityaalfarison 2025-10-14 10:23:05 +07:00
parent a3e68b8cd0
commit a6be703b10
4 changed files with 67 additions and 44 deletions

View File

@ -42,9 +42,16 @@ class ItemController extends Controller
/**
* Display the specified resource.
*/
public function show(int $id)
public function show(string $kode_item)
{
$item = Item::with('produk.foto','nampan')->findOrFail($id);
$item = Item::with(['produk.foto', 'nampan'])
->where('kode_item', $kode_item)
->first();
if (!$item) {
return response()->json(['message' => 'Item tidak ditemukan'], 404);
}
return response()->json($item);
}

View File

@ -102,14 +102,16 @@ const createdItem = ref(null);
// QR Code generator - berdasarkan logika dari brankas list
const qrCodeUrl = computed(() => {
if (createdItem.value && props.product) {
const itemId = createdItem.value.id || createdItem.value.kode_item;
const productName = props.product.nama.replace(/\s/g, "");
const data = `ITM-${itemId}-${productName}`;
return `https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=${encodeURIComponent(data)}`;
const itemId = createdItem.value.kode_item || createdItem.value.id;
const data = `${itemId}`;
// Barcode Code128
return `https://barcode.tec-it.com/barcode.ashx?data=${encodeURIComponent(data)}&code=Code128&dpi=96`;
}
return "";
});
// Methods
const loadNampanList = async () => {
try {
@ -204,7 +206,7 @@ const printItem = () => {
</head>
<body>
<div class="qr-container">
<img src="${qrCodeUrl.value}" alt="QR Code" style="width: 200px; height: 200px;" />
<img src="${qrCodeUrl.value}" alt="Barcode" style="width: 300px; height: 100px;" />
<div class="item-info">
<div style="font-weight: bold; margin-bottom: 5px;">${itemCode}</div>
<div>${props.product.nama}</div>

View File

@ -0,0 +1,20 @@
<template>
<div class="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
<div class="bg-white rounded-lg p-6 max-w-sm w-full shadow-xl">
<h3 class="text-lg font-semibold mb-4">{{ title }}</h3>
<p class="mb-6">{{ message }}</p>
<div class="flex justify-end gap-2">
<button @click="$emit('cancel')" class="px-4 py-2 bg-gray-300 rounded">Batal</button>
<button @click="$emit('confirm')" class="px-4 py-2 bg-blue-600 text-white rounded">Ya</button>
</div>
</div>
</div>
</template>
<script setup>
defineProps({
title: String,
message: String
});
defineEmits(["confirm", "cancel"]);
</script>

View File

@ -33,16 +33,26 @@
</div>
</div>
</div>
<!-- POPUP KONFIRMASI -->
<ModalConfirm
v-if="showConfirm"
title="Konfirmasi"
:message="confirmMessage"
@confirm="handleConfirm"
@cancel="showConfirm = false"
/>
</mainLayout>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { ref, onMounted, onUnmounted } from "vue";
import axios from "axios";
import mainLayout from "../layouts/mainLayout.vue";
import KasirForm from "../components/KasirForm.vue";
import KasirTransaksiList from "../components/KasirTransaksiList.vue";
import ModalConfirm from "../components/ModalConfirm.vue"; // Tambah ini
const transaksi = ref({
data: [],
@ -52,13 +62,22 @@ const loading = ref(true);
const currentPage = ref(1);
const limit = 10;
const showConfirm = ref(false); //
const confirmMessage = ref("Apakah kamu yakin?"); //
let lastTransaksi = null; // untuk tau data transaksi terakhir
// Placeholder jika user tekan "Ya"
const handleConfirm = () => {
showConfirm.value = false;
console.log("User konfirmasi, cetak struk di sini...", lastTransaksi);
// TODO: jalankan fungsi cetakStruk(lastTransaksi)
};
// Fetch hanya transaksi hari ini
const fetchTransaksiHariIni = async (page = 1) => {
try {
loading.value = true;
currentPage.value = page;
// Hanya fetch transaksi hari ini
const today = new Date().toISOString().split('T')[0];
const params = new URLSearchParams({
limit: limit,
@ -67,8 +86,6 @@ const fetchTransaksiHariIni = async (page = 1) => {
end_date: today
}).toString();
// console.log('Fetching transaksi hari ini:', params);
const res = await axios.get(`/api/transaksi?${params}`, {
headers: {
Authorization: `Bearer ${localStorage.getItem("token")}`,
@ -79,23 +96,11 @@ const fetchTransaksiHariIni = async (page = 1) => {
data: res.data.data || [],
pagination: res.data.pagination || null
};
// console.log("Transaksi hari ini:", transaksi.value);
} catch (err) {
console.error("Gagal fetch transaksi hari ini:", err);
transaksi.value = { data: [], pagination: null };
let errorMessage = 'Gagal memuat transaksi hari ini';
if (err.response) {
errorMessage += `: ${err.response.status} - ${err.response.data?.message || err.response.statusText}`;
} else if (err.request) {
errorMessage += ': Tidak ada respon dari server';
} else {
errorMessage += `: ${err.message}`;
}
alert(errorMessage);
alert("Gagal memuat transaksi hari ini");
} finally {
loading.value = false;
}
@ -103,18 +108,13 @@ const fetchTransaksiHariIni = async (page = 1) => {
// Handle pagination
const handlePageChange = (page) => {
// console.log('Page changed to:', page);
if (page >= 1 && page <= (transaksi.value.pagination?.last_page || 1)) {
fetchTransaksiHariIni(page);
}
};
// Handle transaksi baru dari KasirForm
// Popup setelah transaksi tersimpan
const handleTransaksiSaved = async (newTransaksi) => {
// console.log("Transaksi baru disimpan:", newTransaksi);
// Karena ini transaksi hari ini, selalu tambahkan ke list
const formattedNewTransaksi = {
id: newTransaksi.id,
kode_transaksi: newTransaksi.kode_transaksi,
@ -125,31 +125,28 @@ const handleTransaksiSaved = async (newTransaksi) => {
total_items: newTransaksi.itemTransaksi?.length || 0,
tanggal: new Date(newTransaksi.created_at).toLocaleDateString('id-ID')
};
// Tambahkan ke awal array
transaksi.value.data.unshift(formattedNewTransaksi);
// Update pagination
lastTransaksi = formattedNewTransaksi; // Simpan untuk cetak
if (transaksi.value.pagination) {
transaksi.value.pagination.total += 1;
// Jika sudah penuh, hapus item terakhir
if (transaksi.value.data.length > limit) {
transaksi.value.data.pop();
}
}
// console.log("Transaksi baru ditambahkan ke list hari ini");
confirmMessage.value = "Transaksi berhasil disimpan. Cetak struk sekarang?";
showConfirm.value = true; // Munculkan popup
};
// Auto-refresh setiap 10 detik untuk update real-time
let refreshInterval = null;
const startAutoRefresh = () => {
if (refreshInterval) clearInterval(refreshInterval);
refreshInterval = setInterval(() => {
fetchTransaksiHariIni(currentPage.value);
}, 10000); // 10 detik
}, 10000);
};
const stopAutoRefresh = () => {
@ -159,14 +156,11 @@ const stopAutoRefresh = () => {
}
};
// Initialize
onMounted(async () => {
await fetchTransaksiHariIni();
startAutoRefresh();
});
// Cleanup
import { onUnmounted } from 'vue';
onUnmounted(() => {
stopAutoRefresh();
});