diff --git a/app/Http/Controllers/TransaksiController.php b/app/Http/Controllers/TransaksiController.php index 350a82f..eff0b59 100644 --- a/app/Http/Controllers/TransaksiController.php +++ b/app/Http/Controllers/TransaksiController.php @@ -6,34 +6,79 @@ use App\Models\Transaksi; use App\Models\ItemTransaksi; use App\Models\Item; use App\Models\Sales; +use Carbon\Carbon; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; class TransaksiController extends Controller { // List semua transaksi - public function index() + public function index(Request $request) { - $limit = request()->query('limit', null); - $query = Transaksi::with(['kasir', 'sales', 'itemTransaksi.produk'])->latest(); - if ($limit) { - $query->limit((int)$limit); + $limit = $request->query('limit', 10); + $page = $request->query('page', 1); + $startDate = $request->query('start_date'); + $endDate = $request->query('end_date'); + + $query = Transaksi::with(['kasir', 'sales', 'itemTransaksi.produk']); + + // Filter berdasarkan interval tanggal + if ($startDate && $endDate) { + $query->whereBetween('created_at', [ + Carbon::parse($startDate)->startOfDay(), + Carbon::parse($endDate)->endOfDay() + ]); + } + // Default: hanya transaksi hari ini + elseif (!$startDate && !$endDate) { + $today = Carbon::today(); + $query->whereDate('created_at', $today); } - $transaksi = $query->get(); - $transaksi->each(function ($transaksi) { + // Order by latest + $query->latest(); + + // Pagination + $transaksi = $query->paginate($limit, ['*'], 'page', $page); + + // Transform data + $transaksi->getCollection()->transform(function ($transaksi) { $transaksi->total_items = $transaksi->itemTransaksi->count(); - $transaksi->tanggal = $transaksi->created_at->format('d/m/Y'); + $transaksi->tanggal = $transaksi->created_at->format('d/m/Y H:i'); + $transaksi->pendapatan = $transaksi->total_harga ?? 0; + + return $transaksi; }); - return response()->json($transaksi); + return response()->json([ + 'data' => $transaksi->items(), + 'pagination' => [ + 'current_page' => $transaksi->currentPage(), + 'last_page' => $transaksi->lastPage(), + 'per_page' => $transaksi->perPage(), + 'total' => $transaksi->total(), + 'from' => $transaksi->firstItem(), + 'to' => $transaksi->lastItem(), + ] + ]); } - - // Detail transaksi by ID + // Detail transaksi public function show($id) { - $transaksi = Transaksi::with(['kasir', 'sales', 'itemTransaksi.produk.foto'])->findOrFail($id); + $transaksi = Transaksi::with([ + 'kasir', + 'sales', + 'itemTransaksi.produk', + 'itemTransaksi' => function ($query) { + $query->orderBy('created_at', 'asc'); + } + ])->findOrFail($id); + + $transaksi->total_items = $transaksi->itemTransaksi->count(); + $transaksi->tanggal = $transaksi->created_at->format('d/m/Y H:i'); + $transaksi->pendapatan = $transaksi->total_harga ?? 0; + return response()->json($transaksi); } diff --git a/resources/js/components/KasirTransaksiList.vue b/resources/js/components/KasirTransaksiList.vue index 6fc9638..a33ac85 100644 --- a/resources/js/components/KasirTransaksiList.vue +++ b/resources/js/components/KasirTransaksiList.vue @@ -1,51 +1,135 @@ + \ No newline at end of file diff --git a/resources/js/components/RiwayatTransaksi.vue b/resources/js/components/RiwayatTransaksi.vue new file mode 100644 index 0000000..65172a4 --- /dev/null +++ b/resources/js/components/RiwayatTransaksi.vue @@ -0,0 +1,449 @@ + + + \ No newline at end of file diff --git a/resources/js/pages/Kasir.vue b/resources/js/pages/Kasir.vue index 52bc489..695aa54 100644 --- a/resources/js/pages/Kasir.vue +++ b/resources/js/pages/Kasir.vue @@ -7,7 +7,7 @@
@@ -18,49 +18,15 @@
- -
-
- Memuat transaksi... -
- - -
- - - -

- Belum ada transaksi -

-
- - +
@@ -78,36 +44,130 @@ import mainLayout from "../layouts/mainLayout.vue"; import KasirForm from "../components/KasirForm.vue"; import KasirTransaksiList from "../components/KasirTransaksiList.vue"; -const transaksi = ref([]); +const transaksi = ref({ + data: [], + pagination: null +}); const loading = ref(true); +const currentPage = ref(1); +const limit = 10; -// Fungsi untuk fetch transaksi -const fetchTransaksi = async () => { +// Fetch hanya transaksi hari ini +const fetchTransaksiHariIni = async (page = 1) => { try { loading.value = true; - const res = await axios.get("/api/transaksi?limit=10", { + currentPage.value = page; + + // Hanya fetch transaksi hari ini + const today = new Date().toISOString().split('T')[0]; + const params = new URLSearchParams({ + limit: limit, + page: page, + start_date: today, + 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")}`, }, }); - transaksi.value = res.data; - console.log("Fetched transaksi:", transaksi.value); + transaksi.value = { + data: res.data.data || [], + pagination: res.data.pagination || null + }; + + console.log("Transaksi hari ini:", transaksi.value); } catch (err) { - console.error("Gagal fetch transaksi:", 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); } finally { loading.value = false; } }; +// 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 +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, + created_at: newTransaksi.created_at, + total_harga: newTransaksi.total_harga || 0, + itemTransaksi: newTransaksi.itemTransaksi || [], + pendapatan: newTransaksi.total_harga || 0, + 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 + 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"); +}; + +// 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 +}; + +const stopAutoRefresh = () => { + if (refreshInterval) { + clearInterval(refreshInterval); + refreshInterval = null; + } +}; + +// Initialize onMounted(async () => { - await fetchTransaksi(); + await fetchTransaksiHariIni(); + startAutoRefresh(); }); -// Handle ketika transaksi baru disimpan -const handleTransaksiSaved = async (newTransaksi) => { - // Refresh daftar transaksi - await fetchTransaksi(); -}; +// Cleanup +import { onUnmounted } from 'vue'; +onUnmounted(() => { + stopAutoRefresh(); +}); diff --git a/resources/js/pages/Laporan.vue b/resources/js/pages/Laporan.vue index 2f5dbfb..9d3f653 100644 --- a/resources/js/pages/Laporan.vue +++ b/resources/js/pages/Laporan.vue @@ -31,6 +31,11 @@
+ +
+ +
+
@@ -42,6 +47,7 @@ import RingkasanLaporan from '../components/RingkasanLaporan.vue'; import mainLayout from '../layouts/mainLayout.vue'; import DetailPerNampan from '../components/DetailPerNampan.vue'; import DetailPerProduk from '../components/DetailPerProduk.vue'; +import RiwayatTransaksi from '../components/RiwayatTransaksi.vue'; const activeTab = ref('ringkasan'); @@ -49,5 +55,6 @@ const tabs = [ { name: 'Ringkasan Laporan', id: 'ringkasan' }, { name: 'Detail per Nampan', id: 'detail-nampan' }, { name: 'Detail per Produk', id: 'detail-produk' }, + { name: 'Riwayat Transaksi', id: 'riwayat' }, ]; \ No newline at end of file