prepare("SELECT username, full_name, role, is_active FROM users WHERE id = ?"); $uStmt->execute([$userId]); $dbUser = $uStmt->fetch(PDO::FETCH_ASSOC); } catch (PDOException $e) { $dbUser = false; } if (!$dbUser || (int)($dbUser['is_active'] ?? 1) !== 1) { // Account removed or retired: end the session. $_SESSION = []; session_destroy(); header('Location: login.php'); exit; } $allowedDbRoles = ['Admin', 'Calling Admin', 'Operator Admin', 'Finance', 'Operator', 'Editor']; if (!in_array($dbUser['role'], $allowedDbRoles, true)) { $_SESSION = []; session_destroy(); header('Location: login.php'); exit; } // Role changed in the database -> drop any leftover Admin "view as" state. if (($_SESSION['role'] ?? '') !== $dbUser['role']) { unset($_SESSION['view_as'], $_SESSION['view_editor_id']); } $_SESSION['role'] = $dbUser['role']; $_SESSION['username'] = $dbUser['username']; $_SESSION['full_name'] = $dbUser['full_name']; $userRole = $dbUser['role']; $username = $dbUser['username']; // ── Calling Admin / Operator Admin ────────────────────────────────────────── // Both are limited admins. The rest of this page treats them as 'Admin' for // record access, and the flags below hide what they must not see. // Admin : everything // Calling Admin : all call records, Assign Editors, Editors Summary, view-as-editor // Operator Admin : Management (Operator) view of all confirmed records, Assign Operators $realRole = $userRole; $isFullAdmin = ($realRole === 'Admin'); $isCallingAdmin = ($realRole === 'Calling Admin'); $isOperatorAdmin = ($realRole === 'Operator Admin'); if ($isCallingAdmin || $isOperatorAdmin) { $userRole = 'Admin'; unset($_GET['view_as']); // they cannot switch views themselves if ($isCallingAdmin) { unset($_SESSION['view_as']); // never the Operator view } else { $_SESSION['view_as'] = 'Operator'; // always the Operator view unset($_SESSION['view_editor_id'], $_GET['view_editor_id']); } } // Internal Messages: unread count for the actual logged-in user. $internalUnreadCount = 0; try { $msgCountStmt = $pdo->prepare("SELECT COUNT(*) FROM internal_messages WHERE receiver_id = ? AND is_read = 0"); $msgCountStmt->execute([(int)$userId]); $internalUnreadCount = (int)$msgCountStmt->fetchColumn(); } catch (PDOException $e) { $internalUnreadCount = 0; } // Admin View-As logic (Persistent via Session) if ($userRole === 'Admin') { if (isset($_GET['view_as'])) { if ($_GET['view_as'] === 'Operator') { $_SESSION['view_as'] = 'Operator'; unset($_SESSION['view_editor_id']); } else { unset($_SESSION['view_as']); unset($_SESSION['view_editor_id']); } } if (isset($_GET['view_editor_id'])) { if ($_GET['view_editor_id'] !== '') { $_SESSION['view_editor_id'] = (int)$_GET['view_editor_id']; unset($_SESSION['view_as']); } else { unset($_SESSION['view_editor_id']); } } } $actualUserRole = $userRole; $viewAsOperator = ($actualUserRole === 'Admin' && ($_SESSION['view_as'] ?? '') === 'Operator'); $viewEditorId = ($actualUserRole === 'Admin') ? ($_SESSION['view_editor_id'] ?? '') : ''; $displayRole = $viewAsOperator ? 'Operator' : ($viewEditorId ? 'Editor' : $actualUserRole); $effectiveUserId = $viewEditorId ?: $userId; // New Arrivals -> Process: make sure the registered client has a Confirm inquiry // and an operator_process_details row, then open the operator processing page. if (isset($_GET['arrival_process']) && $displayRole === 'Operator') { $rcId = (int)$_GET['arrival_process']; try { $rcStmt = $pdo->prepare("SELECT * FROM registered_clients WHERE id = ?"); $rcStmt->execute([$rcId]); $rc = $rcStmt->fetch(PDO::FETCH_ASSOC); if ($rc) { $inqStmt = $pdo->prepare("SELECT id FROM inquiries WHERE phone_number = ? ORDER BY id DESC LIMIT 1"); $inqStmt->execute([$rc['phone_number']]); $inqId = (int)$inqStmt->fetchColumn(); $pdo->beginTransaction(); if (!$inqId) { $ins = $pdo->prepare("INSERT INTO inquiries (customer_name, phone_number, location_name, details, customer_category, status, operator_id, year, month, created_at, updated_at) VALUES (?, ?, ?, ?, ?, 'Confirm', ?, ?, ?, NOW(), NOW())"); $ins->execute([ $rc['customer_name'] ?: ($rc['name_with_initial'] ?? ''), $rc['phone_number'], $rc['location_name'] ?? '', $rc['details'] ?? '', $rc['customer_category'] ?? null, ($userRole === 'Operator') ? (int)$userId : null, (int)date('Y'), date('F'), ]); $inqId = (int)$pdo->lastInsertId(); } else { $pdo->prepare("UPDATE inquiries SET status = 'Confirm', operator_id = COALESCE(operator_id, ?), updated_at = NOW() WHERE id = ?") ->execute([($userRole === 'Operator') ? (int)$userId : null, $inqId]); } $chk = $pdo->prepare("SELECT COUNT(*) FROM operator_process_details WHERE inquiry_id = ?"); $chk->execute([$inqId]); if (!(int)$chk->fetchColumn()) { $pdo->prepare("INSERT INTO operator_process_details (inquiry_id, operator_stage) VALUES (?, 'Confirm')")->execute([$inqId]); } $pdo->commit(); header('Location: operator_edit.php?id=' . $inqId . '&return_url=' . urlencode('index.php?view_as=Operator')); exit; } } catch (PDOException $e) { if ($pdo->inTransaction()) $pdo->rollBack(); } } // Search & Filter $search = $_GET['search'] ?? ''; $category = $_GET['category'] ?? ''; $month = $_GET['month'] ?? ''; $selectedYear = $_GET['year'] ?? 'current'; $operator_stage = $_GET['operator_stage'] ?? ''; $payment_status = $_GET['payment_status'] ?? ''; $passport_status_filter = $_GET['passport_status'] ?? ''; $whereClauses = []; $params = []; // Apply year filter if ($selectedYear === 'current') { $whereClauses[] = "inquiries.year = ?"; $params[] = (int)date('Y'); } elseif ($selectedYear !== 'all') { $whereClauses[] = "inquiries.year = ?"; $params[] = (int)$selectedYear; } $isDefaultView = !isset($_GET['category']) && !isset($_GET['search']) && !isset($_GET['month']) && !isset($_GET['payment_status']) && !isset($_GET['operator_stage']) && !isset($_GET['year']) && !isset($_GET['passport_status']); if ($displayRole === 'Editor') { // Editor sees only their assigned calls $whereClauses[] = "inquiries.assigned_to = ?"; $params[] = $effectiveUserId; if ($isDefaultView) { $whereClauses[] = "(DATE(inquiries.created_at) = CURDATE() OR DATE(inquiries.updated_at) = CURDATE())"; } } elseif ($displayRole === 'Admin') { if ($isDefaultView) { $whereClauses[] = "(DATE(inquiries.created_at) >= DATE_SUB(CURDATE(), INTERVAL 2 DAY) OR DATE(inquiries.updated_at) >= DATE_SUB(CURDATE(), INTERVAL 2 DAY))"; } } elseif ($displayRole === 'Finance') { $whereClauses[] = "inquiries.status = 'Confirm'"; } elseif ($displayRole === 'Operator') { $whereClauses[] = "inquiries.status = 'Confirm'"; // Actual Operators only see their assignedConfirmed list // Admin viewing as Operator sees all confirmed (for oversight) if ($userRole === 'Operator') { $whereClauses[] = "inquiries.operator_id = ?"; $params[] = $userId; } } if ($category) { if ($category === 'WhatsApp') { $whereClauses[] = "inquiries.status IN ('No Answer', 'Not Reachable')"; } elseif ($category === 'Active') { $whereClauses[] = "inquiries.status IN ('New Calls', 'In Progress', 'Special Call')"; } elseif ($category === 'Confirmed') { $whereClauses[] = "inquiries.status = 'Confirm'"; } elseif ($category === 'Complete') { $whereClauses[] = "opd.operator_stage = 'Complete'"; } elseif ($category === 'Cancel') { $whereClauses[] = "inquiries.status = 'Cancel'"; } elseif ($category === 'RecentUpdates') { $whereClauses[] = "(DATE(inquiries.created_at) >= DATE_SUB(CURDATE(), INTERVAL 2 DAY) OR DATE(inquiries.updated_at) >= DATE_SUB(CURDATE(), INTERVAL 2 DAY) OR DATE(opd.updated_at) >= DATE_SUB(CURDATE(), INTERVAL 2 DAY))"; } elseif (in_array($category, ['Platinum', 'Gold', 'Silver'])) { $whereClauses[] = "inquiries.customer_category = ?"; $params[] = $category; } else { $whereClauses[] = "inquiries.status = ?"; $params[] = $category; } } if ($operator_stage) { if ($operator_stage === 'Confirm') { $whereClauses[] = "(inquiries.status = 'Confirm' OR opd.operator_stage IS NULL)"; } else { $whereClauses[] = "opd.operator_stage = ?"; $params[] = $operator_stage; } } if ($month) { $whereClauses[] = "inquiries.month = ?"; $params[] = $month; } if ($payment_status) { if ($payment_status === 'Full') { $whereClauses[] = "opd.is_balance_paid = 1"; } elseif ($payment_status === 'Advance') { $whereClauses[] = "(opd.is_balance_paid = 0 OR opd.is_balance_paid IS NULL) AND inquiries.advanced_payment > 0"; } elseif ($payment_status === 'Unpaid') { $whereClauses[] = "(opd.is_balance_paid = 0 OR opd.is_balance_paid IS NULL) AND (inquiries.advanced_payment = 0 OR inquiries.advanced_payment IS NULL)"; } } if ($passport_status_filter) { if ($passport_status_filter === 'No Passport') { $whereClauses[] = "(opd.passport_status IS NULL OR opd.passport_status NOT IN ('In Progress','Completed'))"; } else { $whereClauses[] = "opd.passport_status = ?"; $params[] = $passport_status_filter; } } if ($search) { $whereClauses[] = "(inquiries.id LIKE ? OR inquiries.customer_name LIKE ? OR inquiries.phone_number LIKE ? OR inquiries.location_name LIKE ? OR DATE_FORMAT(inquiries.created_at, '%Y-%m-%d') LIKE ?)"; $searchTerm = "%$search%"; $params[] = $searchTerm; $params[] = $searchTerm; $params[] = $searchTerm; $params[] = $searchTerm; $params[] = $searchTerm; } $whereSql = ''; if (count($whereClauses) > 0) { $whereSql = "WHERE " . implode(' AND ', $whereClauses); } // Pagination $perPage = 50; $page = max(1, (int)($_GET['page'] ?? 1)); $offset = ($page - 1) * $perPage; // Count total records for pagination $countStmt = $pdo->prepare("SELECT COUNT(*) FROM inquiries LEFT JOIN users ON inquiries.assigned_to = users.id LEFT JOIN operator_process_details opd ON inquiries.id = opd.inquiry_id $whereSql"); $countStmt->execute($params); $totalRecords = (int)$countStmt->fetchColumn(); $totalPages = max(1, (int)ceil($totalRecords / $perPage)); $page = min($page, $totalPages); $offset = ($page - 1) * $perPage; // Fetch inquiries (paginated) - also fetch payment fields // LIMIT and OFFSET must be cast to int and embedded directly — PDO binds them as strings which MariaDB rejects $orderBy = "inquiries.updated_at DESC"; if (!empty($category) || !empty($operator_stage) || !empty($search) || !empty($month) || !empty($payment_status) || $displayRole === 'Operator') { $orderBy = "inquiries.id DESC"; } $stmt = $pdo->prepare("SELECT inquiries.*, opd.operator_stage, opd.is_balance_paid, opd.passport_status, users.username as assigned_user, users.full_name as assigned_full_name FROM inquiries LEFT JOIN users ON inquiries.assigned_to = users.id LEFT JOIN operator_process_details opd ON inquiries.id = opd.inquiry_id $whereSql ORDER BY $orderBy LIMIT " . (int)$perPage . " OFFSET " . (int)$offset); $stmt->execute($params); $inquiries = $stmt->fetchAll(PDO::FETCH_ASSOC); // Fetch stats $statClauses = []; if ($displayRole === 'Editor') { $statClauses[] = "inquiries.assigned_to = " . (int)$effectiveUserId; } elseif ($displayRole === 'Finance') { $statClauses[] = "inquiries.status = 'Confirm'"; } elseif ($displayRole === 'Operator') { $statClauses[] = "inquiries.status = 'Confirm'"; if ($userRole === 'Operator') { $statClauses[] = "inquiries.operator_id = " . (int)$userId; } } if ($selectedYear === 'current') { $statClauses[] = "inquiries.year = " . (int)date('Y'); } elseif ($selectedYear !== 'all') { $statClauses[] = "inquiries.year = " . (int)$selectedYear; } $statWhere = count($statClauses) > 0 ? "WHERE " . implode(" AND ", $statClauses) : ""; $statStmt = $pdo->query("SELECT inquiries.status, COUNT(*) as count FROM inquiries LEFT JOIN operator_process_details opd ON inquiries.id = opd.inquiry_id $statWhere GROUP BY inquiries.status"); $statusCounts = $statStmt->fetchAll(PDO::FETCH_KEY_PAIR); // Operator specific stats $operatorStats = []; if ($displayRole === 'Operator') { $opWhereClauses = ["inquiries.status = 'Confirm'"]; if ($userRole === 'Operator') { $opWhereClauses[] = "inquiries.operator_id = " . (int)$userId; } if ($selectedYear === 'current') { $opWhereClauses[] = "inquiries.year = " . (int)date('Y'); } elseif ($selectedYear !== 'all') { $opWhereClauses[] = "inquiries.year = " . (int)$selectedYear; } $opWhereSql = "WHERE " . implode(" AND ", $opWhereClauses); $opStmt = $pdo->query("SELECT IFNULL(opd.operator_stage, 'Confirm') as stage, COUNT(*) as count FROM inquiries LEFT JOIN operator_process_details opd ON inquiries.id = opd.inquiry_id $opWhereSql GROUP BY stage"); $operatorStats = $opStmt->fetchAll(PDO::FETCH_KEY_PAIR); } // Passport status stats for Operator view $passportStats = ['In Progress' => 0, 'No Passport' => 0, 'Completed' => 0]; if ($displayRole === 'Operator') { $ppWhereClauses = ["inquiries.status = 'Confirm'"]; if ($userRole === 'Operator') { $ppWhereClauses[] = "inquiries.operator_id = " . (int)$userId; } if ($selectedYear === 'current') { $ppWhereClauses[] = "inquiries.year = " . (int)date('Y'); } elseif ($selectedYear !== 'all') { $ppWhereClauses[] = "inquiries.year = " . (int)$selectedYear; } $ppWhereSql = "WHERE " . implode(" AND ", $ppWhereClauses); $ppStmt = $pdo->query("SELECT IFNULL(opd.passport_status, 'No Passport') as ps, COUNT(*) as count FROM inquiries LEFT JOIN operator_process_details opd ON inquiries.id = opd.inquiry_id $ppWhereSql GROUP BY ps"); foreach ($ppStmt->fetchAll(PDO::FETCH_ASSOC) as $row) { $key = $row['ps']; if ($key === 'In Progress') $passportStats['In Progress'] = (int)$row['count']; elseif ($key === 'Completed') $passportStats['Completed'] = (int)$row['count']; else $passportStats['No Passport'] += (int)$row['count']; } } $monthlyConfirmedStats = []; if ($displayRole === 'Operator' || $displayRole === 'Admin' || $displayRole === 'Editor' || $displayRole === 'Finance') { $mq = "SELECT month, COUNT(*) as count FROM inquiries WHERE status = 'Confirm' AND month IS NOT NULL AND month != ''"; if ($userRole === 'Operator') { $mq .= " AND operator_id = " . (int)$userId; } elseif ($displayRole === 'Editor') { $mq .= " AND assigned_to = " . (int)$effectiveUserId; } if ($selectedYear === 'current') { $mq .= " AND year = " . (int)date('Y'); } elseif ($selectedYear !== 'all') { $mq .= " AND year = " . (int)$selectedYear; } $mq .= " GROUP BY month"; $monthStmt = $pdo->query($mq); $monthlyConfirmedStats = $monthStmt->fetchAll(PDO::FETCH_KEY_PAIR); } // Finance: amount received per month (keyed by month name e.g. "January") $monthlyAmountStats = []; if ($displayRole === 'Finance') { $maStmt = $pdo->query("SELECT MONTHNAME(i.payment_date) as mname, SUM(IF(opd.is_balance_paid = 1, i.total_payment - i.discount, i.advanced_payment)) as total FROM inquiries i LEFT JOIN operator_process_details opd ON i.id = opd.inquiry_id WHERE i.status = 'Confirm' AND i.payment_date IS NOT NULL " . ($selectedYear === 'current' ? "AND YEAR(i.payment_date) = " . (int)date('Y') : ($selectedYear !== 'all' ? "AND YEAR(i.payment_date) = " . (int)$selectedYear : "")) . " GROUP BY mname"); foreach ($maStmt->fetchAll(PDO::FETCH_ASSOC) as $row) { $monthlyAmountStats[$row['mname']] = (float)$row['total']; } } // Finance: expense per month (keyed by month name) $monthlyExpenseStats = []; if ($displayRole === 'Finance') { $meStmt = $pdo->query("SELECT MONTHNAME(expense_date) as mname, SUM(amount) as total FROM company_expenses WHERE 1=1 " . ($selectedYear === 'current' ? "AND YEAR(expense_date) = " . (int)date('Y') : ($selectedYear !== 'all' ? "AND YEAR(expense_date) = " . (int)$selectedYear : "")) . " GROUP BY mname"); foreach ($meStmt->fetchAll(PDO::FETCH_ASSOC) as $row) { $monthlyExpenseStats[$row['mname']] = (float)$row['total']; } } // Finance: selected-month detail (revenue, expenses, net) when a month filter is active $selectedMonthRevenue = 0; $selectedMonthExpenses = 0; if ($displayRole === 'Finance' && $month) { $smrStmt = $pdo->prepare("SELECT SUM(IF(opd.is_balance_paid = 1, i.total_payment - i.discount, i.advanced_payment)) as total FROM inquiries i LEFT JOIN operator_process_details opd ON i.id = opd.inquiry_id WHERE i.status = 'Confirm' AND i.payment_date IS NOT NULL AND MONTHNAME(i.payment_date) = ? " . ($selectedYear === 'current' ? "AND YEAR(i.payment_date) = " . (int)date('Y') : ($selectedYear !== 'all' ? "AND YEAR(i.payment_date) = " . (int)$selectedYear : ""))); $smrStmt->execute([$month]); $selectedMonthRevenue = (float)$smrStmt->fetchColumn() ?: 0; $smeStmt = $pdo->prepare("SELECT SUM(amount) FROM company_expenses WHERE MONTHNAME(expense_date) = ? " . ($selectedYear === 'current' ? "AND YEAR(expense_date) = " . (int)date('Y') : ($selectedYear !== 'all' ? "AND YEAR(expense_date) = " . (int)$selectedYear : ""))); $smeStmt->execute([$month]); $selectedMonthExpenses = (float)$smeStmt->fetchColumn() ?: 0; } // Overall totals for Finance $overallRevenue = 0; $overallExpenses = 0; if ($displayRole === 'Finance') { $ovrStmt = $pdo->query("SELECT SUM(IF(opd.is_balance_paid = 1, i.total_payment - i.discount, i.advanced_payment)) as total FROM inquiries i LEFT JOIN operator_process_details opd ON i.id = opd.inquiry_id WHERE i.status = 'Confirm' AND i.payment_date IS NOT NULL " . ($selectedYear === 'current' ? "AND YEAR(i.payment_date) = " . (int)date('Y') : ($selectedYear !== 'all' ? "AND YEAR(i.payment_date) = " . (int)$selectedYear : ""))); $overallRevenue = (float)$ovrStmt->fetchColumn() ?: 0; $oveStmt = $pdo->query("SELECT SUM(amount) FROM company_expenses WHERE 1=1 " . ($selectedYear === 'current' ? "AND YEAR(expense_date) = " . (int)date('Y') : ($selectedYear !== 'all' ? "AND YEAR(expense_date) = " . (int)$selectedYear : ""))); $overallExpenses = (float)$oveStmt->fetchColumn() ?: 0; } // Fetch complete count (operator_stage = 'Complete' in operator_process_details) $completeCountClause = " WHERE opd.operator_stage = 'Complete'"; if ($displayRole === 'Editor') { $completeCountClause .= " AND i.assigned_to = " . (int)$effectiveUserId; } elseif ($userRole === 'Operator') { $completeCountClause .= " AND i.operator_id = " . (int)$userId; } if ($selectedYear === 'current') { $completeCountClause .= " AND i.year = " . (int)date('Y'); } elseif ($selectedYear !== 'all') { $completeCountClause .= " AND i.year = " . (int)$selectedYear; } $completeStmt = $pdo->query("SELECT COUNT(*) FROM inquiries i INNER JOIN operator_process_details opd ON i.id = opd.inquiry_id" . $completeCountClause); $completeCount = (int)$completeStmt->fetchColumn(); $recentWhere = $statWhere ? $statWhere . " AND " : "WHERE "; $recentWhere .= "(DATE(inquiries.created_at) >= DATE_SUB(CURDATE(), INTERVAL 2 DAY) OR DATE(inquiries.updated_at) >= DATE_SUB(CURDATE(), INTERVAL 2 DAY) OR DATE(opd.updated_at) >= DATE_SUB(CURDATE(), INTERVAL 2 DAY))"; $recentStmt = $pdo->query("SELECT COUNT(*) FROM inquiries LEFT JOIN operator_process_details opd ON inquiries.id = opd.inquiry_id $recentWhere"); $recentUpdatesCount = (int)$recentStmt->fetchColumn(); $stats = [ 'total' => array_sum($statusCounts ?: []), 'recent_updates' => $recentUpdatesCount, 'new_calls' => ($statusCounts['New Calls'] ?? 0), 'no_answer' => ($statusCounts['No Answer'] ?? 0), 'unreachable' => ($statusCounts['Not Reachable'] ?? 0), 'in_progress' => ($statusCounts['In Progress'] ?? 0), 'special_call' => ($statusCounts['Special Call'] ?? 0), 'confirm' => max(0, ($statusCounts['Confirm'] ?? 0) - ($userRole === 'Operator' || $displayRole === 'Operator' ? ($operatorStats['Complete'] ?? 0) : $completeCount)), 'complete' => ($userRole === 'Operator' || $displayRole === 'Operator') ? ($operatorStats['Complete'] ?? 0) : $completeCount, 'cancel' => ($statusCounts['Cancel'] ?? 0), ]; $monthColors = [ 'January' => '#3498db', 'February' => '#9b59b6', 'March' => '#e67e22', 'April' => '#27ae60', 'May' => '#e74c3c', 'June' => '#1abc9c', 'July' => '#f1c40f', 'August' => '#34495e', 'September' => '#d35400', 'October' => '#7f8c8d', 'November' => '#2980b9', 'December' => '#2c3e50' ]; // Finance specific stats (Amounts received) $dailyTotals = []; $monthlyTotals = []; if ($displayRole === 'Finance') { $finYearCondition = ""; if ($selectedYear === 'current') { $finYearCondition = " AND YEAR(i.payment_date) = " . (int)date('Y'); } elseif ($selectedYear !== 'all') { $finYearCondition = " AND YEAR(i.payment_date) = " . (int)$selectedYear; } $dailyStmt = $pdo->query("SELECT i.payment_date as p_date, SUM(IF(opd.is_balance_paid = 1, i.total_payment - i.discount, i.advanced_payment)) as total FROM inquiries i LEFT JOIN operator_process_details opd ON i.id = opd.inquiry_id WHERE i.status = 'Confirm' AND i.payment_date IS NOT NULL $finYearCondition GROUP BY i.payment_date ORDER BY i.payment_date DESC LIMIT 10"); $dailyTotals = $dailyStmt->fetchAll(PDO::FETCH_ASSOC); $monthlyStmt = $pdo->query("SELECT DATE_FORMAT(i.payment_date, '%Y-%m') as p_month, SUM(IF(opd.is_balance_paid = 1, i.total_payment - i.discount, i.advanced_payment)) as total FROM inquiries i LEFT JOIN operator_process_details opd ON i.id = opd.inquiry_id WHERE i.status = 'Confirm' AND i.payment_date IS NOT NULL $finYearCondition GROUP BY p_month ORDER BY p_month DESC LIMIT 12"); $monthlyTotals = $monthlyStmt->fetchAll(PDO::FETCH_ASSOC); } // Fetch Payment Status stats for the confirmed view $payStats = ['Full' => 0, 'Advance' => 0, 'Unpaid' => 0]; if ($displayRole === 'Operator' || $displayRole === 'Admin' || $displayRole === 'Editor') { $payWhereClauses = []; $payParams = []; // Base filters (Role/Year) if ($displayRole === 'Editor') { $payWhereClauses[] = "inquiries.assigned_to = ?"; $payParams[] = $effectiveUserId; } elseif ($displayRole === 'Operator') { if ($userRole === 'Operator') { $payWhereClauses[] = "inquiries.operator_id = ?"; $payParams[] = $userId; } } if ($selectedYear === 'current') { $payWhereClauses[] = "inquiries.year = ?"; $payParams[] = (int)date('Y'); } elseif ($selectedYear !== 'all') { $payWhereClauses[] = "inquiries.year = ?"; $payParams[] = (int)$selectedYear; } if ($month) { $payWhereClauses[] = "inquiries.month = ?"; $payParams[] = $month; } $payWhereClauses[] = "inquiries.status = 'Confirm'"; $payWhereSql = "WHERE " . implode(' AND ', $payWhereClauses); $payQuery = "SELECT SUM(CASE WHEN opd.is_balance_paid = 1 THEN 1 ELSE 0 END) as full_paid, SUM(CASE WHEN (opd.is_balance_paid = 0 OR opd.is_balance_paid IS NULL) AND inquiries.advanced_payment > 0 THEN 1 ELSE 0 END) as advance_paid, SUM(CASE WHEN (opd.is_balance_paid = 0 OR opd.is_balance_paid IS NULL) AND (inquiries.advanced_payment = 0 OR inquiries.advanced_payment IS NULL) THEN 1 ELSE 0 END) as unpaid FROM inquiries LEFT JOIN operator_process_details opd ON inquiries.id = opd.inquiry_id $payWhereSql"; $payStmt = $pdo->prepare($payQuery); $payStmt->execute($payParams); $payRow = $payStmt->fetch(PDO::FETCH_ASSOC); if ($payRow) { $payStats['Full'] = (int)$payRow['full_paid']; $payStats['Advance'] = (int)$payRow['advance_paid']; $payStats['Unpaid'] = (int)$payRow['unpaid']; } } // New Arrivals (Operator view): clients registered via registered_create.php in the last 7 days $newArrivalsCount = 0; $newArrivals = []; if ($displayRole === 'Operator') { try { $newArrivalsCount = (int)$pdo->query("SELECT COUNT(*) FROM registered_clients WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)")->fetchColumn(); $newArrivals = $pdo->query("SELECT rc.*, u.username, u.full_name, inq.id AS inquiry_id, inq.status AS inq_status, inq.advanced_payment, inq.id_card_number, opd.operator_stage, opd.is_balance_paid, opd.passport_status FROM registered_clients rc LEFT JOIN users u ON rc.registered_by = u.id LEFT JOIN inquiries inq ON inq.id = (SELECT MAX(i2.id) FROM inquiries i2 WHERE i2.phone_number = rc.phone_number) LEFT JOIN operator_process_details opd ON opd.inquiry_id = inq.id WHERE rc.created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY) ORDER BY rc.created_at DESC LIMIT 100")->fetchAll(PDO::FETCH_ASSOC); } catch (PDOException $e) { // Table not created yet (no one has opened Registered Clients) - show 0 $newArrivalsCount = 0; $newArrivals = []; } } function getBadgeClass($status) { switch($status) { case 'No Answer': case 'Not Reachable': return 'badge-missed'; case 'New Calls': return 'badge-new'; case 'In Progress': return 'badge-progress'; case 'Special Call': return 'badge-special'; case 'Confirm': return 'badge-booked'; case 'Complete': return 'badge-complete'; case 'Cancel': return 'badge-cancel'; default: return 'badge-new'; } } function managementAssignmentBadge(array $row): array { if (empty($row['operator_id'])) { return ['Unassigned', 'management-unassigned']; } if (($row['operator_stage'] ?? '') === 'Complete') { return ['Completed', 'management-complete']; } if (empty($row['management_acknowledged_at'])) { return ['Newly Assigned', 'management-new']; } return ['Accepted / In Progress', 'management-accepted']; } ?>
= htmlspecialchars($displayRole) ?>= $displaySuffix ?> · = $selectedYear === 'current' ? 'Current Year' : ($selectedYear === 'all' ? 'All Time' : htmlspecialchars((string)$selectedYear)) ?>
= htmlspecialchars($listTitle) ?> · Showing = $start ?>–= $end ?> of = number_format($totalRecords) ?>
| ID | Payment | Inquiry Details | Name | Phone | Address | Date / Month | Status | Management | Assigned | Actions |
|---|---|---|---|---|---|---|---|---|---|---|
| No records found. | ||||||||||
| Full Paid 0): ?> Advanced Unpaid Passport ✓ Passport… No Pass. | = htmlspecialchars($req['customer_name'] ?: 'Unknown') ?> = htmlspecialchars($req['customer_category']) ?> | = htmlspecialchars($req['phone_number']) ?> | = htmlspecialchars($req['location_name']) ?> |
= date('d/m/y', strtotime($req['updated_at'])) ?>
= htmlspecialchars(substr($req['month'],0,3)) ?>
|
= htmlspecialchars($displayStatus) ?> | = htmlspecialchars($mgmtBadge[0]) ?> | = htmlspecialchars(($req['assigned_full_name'] ?: $req['assigned_user']) ?: '—') ?> | |||
Assigned:
Date / Month:
Address:
Phone: