[ 'label' => 'Hari Ini', 'start' => date('Y-m-d'), 'end' => date('Y-m-d') ], 'yesterday' => [ 'label' => 'Kemarin', 'start' => date('Y-m-d', strtotime('-1 day')), 'end' => date('Y-m-d', strtotime('-1 day')) ], 'this_week' => [ 'label' => 'Minggu Ini', 'start' => date('Y-m-d', strtotime('monday this week')), 'end' => date('Y-m-d') ], 'last_week' => [ 'label' => 'Minggu Lalu', 'start' => date('Y-m-d', strtotime('monday last week')), 'end' => date('Y-m-d', strtotime('sunday last week')) ], 'this_month' => [ 'label' => 'Bulan Ini', 'start' => date('Y-m-01'), 'end' => date('Y-m-d') ], ]; // Preset hanya untuk admin if ($isAdmin) { $presets['last_month'] = [ 'label' => 'Bulan Lalu', 'start' => date('Y-m-d', strtotime('first day of last month')), 'end' => date('Y-m-d', strtotime('last day of last month')) ]; $presets['all_time'] = [ 'label' => 'Sepanjang Waktu', 'start' => '2000-01-01', // Tetapkan tanggal mulai yang masuk akal 'end' => date('Y-m-d') ]; } return $presets; } // Dapatkan preset tanggal yang sesuai berdasarkan peran pengguna $isAdmin = isAdmin(); $datePresets = getDatePresets($isAdmin); // Tangani permintaan reset if (isset($_GET['reset']) && $_GET['reset'] == 1) { // Jika reset diminta, alihkan ke halaman yang sama dengan tanggal default header("Location: index.php"); exit; } // Jika pengguna bukan admin, batasi akses data historis if (!$isAdmin && empty($_GET['preset']) && empty($_GET['start_date'])) { // Default pengguna non-admin ke minggu ini jika tidak ada tanggal yang ditentukan $_GET['preset'] = 'this_week'; } // Periksa apakah preset dipilih $activePreset = isset($_GET['preset']) && !empty($_GET['preset']) ? $_GET['preset'] : ''; // Terapkan rentang tanggal berdasarkan preset atau pemilihan manual function getStartDate() { global $datePresets, $activePreset; // Jika preset dipilih, gunakan tanggal preset if (!empty($activePreset) && isset($datePresets[$activePreset])) { return $datePresets[$activePreset]['start']; } // Jika tidak, gunakan parameter tanggal jika disediakan $startDate = isset($_GET['start_date']) && !empty($_GET['start_date']) ? $_GET['start_date'] : date('Y-m-01'); // Default ke hari pertama bulan ini // Pastikan tanggal dalam format YYYY-MM-DD if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $startDate)) { $startDate = date('Y-m-01'); } return $startDate; } function getEndDate() { global $datePresets, $activePreset; // Jika preset dipilih, gunakan tanggal preset if (!empty($activePreset) && isset($datePresets[$activePreset])) { return $datePresets[$activePreset]['end']; } // Jika tidak, gunakan parameter tanggal jika disediakan $endDate = isset($_GET['end_date']) && !empty($_GET['end_date']) ? $_GET['end_date'] : date('Y-m-d'); // Default ke hari ini // Pastikan tanggal dalam format YYYY-MM-DD if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $endDate)) { $endDate = date('Y-m-d'); } return $endDate; } $startDate = getStartDate(); $endDate = getEndDate(); // Pastikan tanggal mulai tidak setelah tanggal akhir if (strtotime($startDate) > strtotime($endDate)) { $temp = $startDate; $startDate = $endDate; $endDate = $temp; } // Fungsi untuk mendapatkan kueri yang sesuai dengan peran dengan penanganan tidak ada data yang lebih baik function getReportQueries($startDate, $endDate, $isAdmin = false) { global $conn; // Tambahkan komponen waktu untuk membuat rentang tanggal inklusif $startDateTime = $startDate . ' 00:00:00'; $endDateTime = $endDate . ' 23:59:59'; // Siapkan kueri transaksi dasar dengan filter tanggal $baseQuery = "SELECT t.id_transaksi, t.kode_transaksi, t.tanggal, t.total_item, t.subtotal, t.total, t.cash_amount, t.change_amount, COUNT(DISTINCT dt.id_barangK) as total_products FROM transaksi t LEFT JOIN detail_transaksi dt ON t.id_transaksi = dt.id_transaksi WHERE t.tanggal BETWEEN ? AND ?"; // Admin melihat semuanya if ($isAdmin) { $transactionQuery = $baseQuery . " GROUP BY t.id_transaksi ORDER BY t.tanggal DESC"; } // Karyawan melihat data terbatas dan hanya transaksi terbaru else { // Untuk karyawan, kami membatasi jumlah catatan $transactionQuery = $baseQuery . " GROUP BY t.id_transaksi ORDER BY t.tanggal DESC LIMIT 100"; } // Siapkan dan jalankan kueri transaksi $stmt = mysqli_prepare($conn, $transactionQuery); if (!$stmt) { // Tangani kesalahan persiapan kueri return [ 'result' => false, 'paymentResult' => null, 'totals' => [ 'total_transactions' => 0, 'total_items' => 0, 'total_subtotal' => 0, 'grand_total' => 0 ], 'error' => 'Gagal menyiapkan kueri: ' . mysqli_error($conn), 'has_data' => false ]; } mysqli_stmt_bind_param($stmt, "ss", $startDateTime, $endDateTime); $execResult = mysqli_stmt_execute($stmt); if (!$execResult) { // Tangani kesalahan eksekusi kueri return [ 'result' => false, 'paymentResult' => null, 'totals' => [ 'total_transactions' => 0, 'total_items' => 0, 'total_subtotal' => 0, 'grand_total' => 0 ], 'error' => 'Gagal mengeksekusi kueri: ' . mysqli_stmt_error($stmt), 'has_data' => false ]; } $result = mysqli_stmt_get_result($stmt); $rowCount = mysqli_num_rows($result); // Dapatkan total untuk ringkasan $totalQuery = "SELECT COUNT(id_transaksi) as total_transactions, SUM(total_item) as total_items, SUM(subtotal) as total_subtotal, SUM(total) as grand_total FROM transaksi WHERE tanggal BETWEEN ? AND ?"; $totalStmt = mysqli_prepare($conn, $totalQuery); if (!$totalStmt) { // Tangani kesalahan persiapan kueri total return [ 'result' => $result, 'paymentResult' => null, 'totals' => [ 'total_transactions' => 0, 'total_items' => 0, 'total_subtotal' => 0, 'grand_total' => 0 ], 'error' => 'Gagal menyiapkan kueri total: ' . mysqli_error($conn), 'has_data' => ($rowCount > 0) ]; } mysqli_stmt_bind_param($totalStmt, "ss", $startDateTime, $endDateTime); $totalExecResult = mysqli_stmt_execute($totalStmt); if (!$totalExecResult) { // Tangani kesalahan eksekusi kueri total return [ 'result' => $result, 'paymentResult' => null, 'totals' => [ 'total_transactions' => 0, 'total_items' => 0, 'total_subtotal' => 0, 'grand_total' => 0 ], 'error' => 'Gagal mengeksekusi kueri total: ' . mysqli_stmt_error($totalStmt), 'has_data' => ($rowCount > 0) ]; } $totalResult = mysqli_stmt_get_result($totalStmt); $totals = mysqli_fetch_assoc($totalResult); // Tangani kasus di mana tidak ada data yang ditemukan if (!$totals) { $totals = [ 'total_transactions' => 0, 'total_items' => 0, 'total_subtotal' => 0, 'grand_total' => 0 ]; } // Untuk pengguna non-admin, masker data keuangan tertentu if (!$isAdmin && $totals) { // Hanya tampilkan kuantitas, sembunyikan angka keuangan if (!canAccessFeature('view_financial')) { $totals['total_subtotal'] = 0; $totals['grand_total'] = 0; } } // Dapatkan detail produk terjual jika dibutuhkan oleh admin /* Produk Terlaris functionality removed as requested $productDetailsResult = null; if ($isAdmin && $rowCount > 0) { $productQuery = "SELECT bk.nama_barang, bk.kode_barang, SUM(dt.jumlah) as total_qty, SUM(dt.total_harga) as total_amount FROM detail_transaksi dt JOIN barang_kasir bk ON dt.id_barangK = bk.id_barangK JOIN transaksi t ON dt.id_transaksi = t.id_transaksi WHERE t.tanggal BETWEEN ? AND ? GROUP BY dt.id_barangK ORDER BY total_qty DESC LIMIT 10"; $productStmt = mysqli_prepare($conn, $productQuery); if ($productStmt) { mysqli_stmt_bind_param($productStmt, "ss", $startDateTime, $endDateTime); $productExecResult = mysqli_stmt_execute($productStmt); if ($productExecResult) { $productDetailsResult = mysqli_stmt_get_result($productStmt); } } } */ return [ 'result' => $result, 'totals' => $totals, 'has_data' => ($rowCount > 0) ]; } // Fungsi untuk memeriksa apakah karyawan memiliki izin untuk fitur laporan tertentu function canAccessFeature($feature) { // Izin default berdasarkan peran $permissions = [ 'admin' => [ 'export_excel' => true, 'export_pdf' => true, 'print_report' => true, 'view_financial' => true, 'view_payment_methods' => true, 'view_all_time' => true, 'view_summary' => true ], 'manager' => [ 'export_excel' => true, 'export_pdf' => false, 'print_report' => true, 'view_financial' => true, 'view_payment_methods' => true, 'view_all_time' => false, 'view_summary' => true ], 'employee' => [ 'export_excel' => false, 'export_pdf' => false, 'print_report' => false, 'view_financial' => false, 'view_payment_methods' => false, 'view_all_time' => false, 'view_summary' => false ] ]; $role = getUserRole(); // Jika peran tidak ada dalam izin kami, default ke karyawan if (!isset($permissions[$role])) { $role = 'employee'; } // Kembalikan status izin return isset($permissions[$role][$feature]) ? $permissions[$role][$feature] : false; } // Dapatkan kueri yang sesuai berdasarkan peran pengguna $queryData = getReportQueries($startDate, $endDate, $isAdmin); $result = $queryData['result']; $totals = $queryData['totals']; // Dapatkan peran pengguna dari sesi untuk izin menu $userRole = getUserRole(); // Menangani permintaan ekspor PDF if (isset($_POST['export_pdf']) || (isset($_GET['export']) && $_GET['export'] == 'pdf')) { // Periksa izin if (!($isAdmin || canAccessFeature('export_pdf'))) { die("Akses ditolak. Anda tidak memiliki izin untuk mengekspor ke PDF."); } // Dapatkan parameter tanggal $exportStartDate = isset($_POST['start_date']) ? $_POST['start_date'] : (isset($_GET['start_date']) ? $_GET['start_date'] : $startDate); $exportEndDate = isset($_POST['end_date']) ? $_POST['end_date'] : (isset($_GET['end_date']) ? $_GET['end_date'] : $endDate); // Tetapkan header untuk PDF (memaksa unduhan) header('Content-Type: text/html; charset=utf-8'); // Mulai output buffering ob_start(); // Konten HTML ramah PDF echo ''; echo ''; echo ''; echo ''; echo 'Laporan Penjualan'; echo ''; echo ''; echo ''; // Tambahkan tombol cetak echo '
'; echo ''; echo '

Setelah mencetak, gunakan dialog cetak browser Anda untuk menyimpan sebagai PDF

'; echo '
'; // Header laporan echo '
'; echo '

Ayula Store - Laporan Penjualan

'; echo '

Periode: ' . date('d M Y', strtotime($exportStartDate)) . ' sampai ' . date('d M Y', strtotime($exportEndDate)) . '

'; echo '

Dibuat pada: ' . date('d M Y H:i:s') . '

'; echo '

Dibuat oleh: ' . ($userRole) . '

'; echo '
'; // Jalankan kembali kueri untuk mendapatkan data baru $exportQueryData = getReportQueries($exportStartDate, $exportEndDate, true); $exportResult = $exportQueryData['result']; $exportTotals = $exportQueryData['totals']; // Bagian ringkasan echo '
'; echo '

Ringkasan

'; echo ''; echo ''; echo ''; echo ''; echo ''; $daysDiff = (strtotime($exportEndDate) - strtotime($exportStartDate)) / (60 * 60 * 24) + 1; $dailyAvg = $daysDiff > 0 ? $exportTotals['grand_total'] / $daysDiff : 0; echo ''; echo '
Total Transaksi' . number_format($exportTotals['total_transactions']) . '
Total Item Terjual' . number_format($exportTotals['total_items']) . '
SubtotalRp. ' . number_format($exportTotals['total_subtotal']) . '
TotalRp. ' . number_format($exportTotals['grand_total']) . '
Rata-rata HarianRp. ' . number_format($dailyAvg) . '
'; echo '
'; // Tabel transaksi echo '

Transaksi

'; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; if ($exportResult && mysqli_num_rows($exportResult) > 0) { mysqli_data_seek($exportResult, 0); // Reset pointer ke awal set hasil while ($row = mysqli_fetch_assoc($exportResult)) { echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; } } else { echo ''; } echo ''; echo '
ID TransaksiTanggalItemSubtotalTotalTunaiKembalian
' . $row['kode_transaksi'] . '' . date('d M Y H:i', strtotime($row['tanggal'])) . '' . $row['total_item'] . 'Rp. ' . number_format($row['subtotal']) . 'Rp. ' . number_format($row['total']) . 'Rp. ' . number_format($row['cash_amount']) . 'Rp. ' . number_format($row['change_amount']) . '
Tidak ada transaksi ditemukan
'; // Produk Terlaris section removed from PDF export (for admin) /* if ($isAdmin) { $exportProductDetails = $exportQueryData['productDetailsResult']; if ($exportProductDetails && mysqli_num_rows($exportProductDetails) > 0) { echo '

Produk Terlaris

'; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; mysqli_data_seek($exportProductDetails, 0); while ($prodRow = mysqli_fetch_assoc($exportProductDetails)) { echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; } echo ''; echo '
Kode ProdukNama ProdukJumlah TerjualTotal Penjualan
' . $prodRow['kode_barang'] . '' . $prodRow['nama_barang'] . '' . number_format($prodRow['total_qty']) . 'Rp. ' . number_format($prodRow['total_amount']) . '
'; } } */ // Footer echo ''; echo ''; echo ''; // Keluarkan buffer dan akhiri ob_end_flush(); exit; } ?>