From 9569441a12436fc9a285606f3bb669a941bb1645 Mon Sep 17 00:00:00 2001 From: Marco0300 Date: Wed, 2 Sep 2026 00:37:03 +0200 Subject: [PATCH] fix: correct global client search join --- public/index.php | 2 +- tests/JobcardSearchCloseReportTest.php | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/public/index.php b/public/index.php index 9bdd81c..0de93c6 100644 --- a/public/index.php +++ b/public/index.php @@ -131,7 +131,7 @@ if ($route === 'search') { $jobScope = $user['role_name'] === 'Technician' ? ' JOIN jobcard_assignments ja ON ja.jobcard_id = j.id AND ja.user_id = ?' : ''; if ($user['role_name'] === 'Technician') $params[] = $user['id']; $parts[] = 'SELECT DISTINCT j.id, CONCAT("Jobcard ", j.reference_no) AS result_title, c.name AS result_context, CONCAT("/?route=jobcard&id=", j.id) AS result_url, "Jobcard" AS result_type FROM jobcards j JOIN clients c ON c.id = j.client_id' . $jobScope . ' WHERE (j.reference_no LIKE ? OR c.name LIKE ? OR j.work_requested LIKE ? OR j.technician_notes LIKE ?) AND j.status <> "closed"'; array_push($params, $like, $like, $like, $like); - $contactScope = $user['role_name'] === 'Technician' ? ' JOIN jobcards j ON j.client_id = c.client_id JOIN jobcard_assignments ja ON ja.jobcard_id = j.id AND ja.user_id = ?' : ''; + $contactScope = $user['role_name'] === 'Technician' ? ' JOIN jobcards j ON j.client_id = c.id JOIN jobcard_assignments ja ON ja.jobcard_id = j.id AND ja.user_id = ?' : ''; if ($user['role_name'] === 'Technician') $params[] = $user['id']; $parts[] = 'SELECT DISTINCT c.id, CONCAT("Client: ", c.name), c.support_email, CONCAT("/?route=client&id=", c.id), "Client" FROM clients c' . $contactScope . ' WHERE (c.name LIKE ? OR c.support_email LIKE ?)'; array_push($params, $like, $like); if ($user['role_name'] !== 'Technician') { $parts[] = 'SELECT DISTINCT cc.id, CONCAT("Contact: ", cc.name), c.name, CONCAT("/?route=client&id=", c.id), "Contact" FROM client_contacts cc JOIN clients c ON c.id = cc.client_id WHERE (cc.name LIKE ? OR cc.email LIKE ? OR cc.phone LIKE ?)'; array_push($params, $like, $like, $like); } diff --git a/tests/JobcardSearchCloseReportTest.php b/tests/JobcardSearchCloseReportTest.php index 08ea133..3b37bd6 100644 --- a/tests/JobcardSearchCloseReportTest.php +++ b/tests/JobcardSearchCloseReportTest.php @@ -28,6 +28,8 @@ jobcard_feature_assert(str_contains($front, 'j.client_id = :client') && str_cont jobcard_feature_assert(str_contains($front, "['TOTAL HOURS'") && str_contains($front, 'totalReportHours'), 'Detailed report downloads must include total hours.'); jobcard_feature_assert(str_contains($front, "if (\$route === 'settings')") && str_contains($front, "role_name'] ?? '') !== 'Administrator'"), 'Branding settings must be Administrator-only.'); jobcard_feature_assert(str_contains($front, "if (\$route === 'search')") && str_contains($front, 'attachments') && str_contains($front, 'client_contacts'), 'Global search must cover jobcards, clients, contacts and attachments.'); +jobcard_feature_assert(!str_contains($front, 'j.client_id = c.client_id'), 'Global client search must join jobcards through clients.id.'); + jobcard_feature_assert(str_contains($front, "if (\$route === 'saved_filter_save')") && str_contains($front, 'saved_filters'), 'Users must be able to save Jobcards filters.'); jobcard_feature_assert(str_contains($front, 'LIMIT 25 OFFSET') && str_contains($front, 'LIMIT 50 OFFSET'), 'Large list pages must use bounded pagination.'); jobcard_feature_assert(str_contains($front, 'technician-bottom-nav') && str_contains($front, 'sidebarMenu'), 'Mobile navigation controls must be present.');