fix: prevent report dropdown parameter mismatch
This commit is contained in:
+7
-3
@@ -740,9 +740,13 @@ if ($route === 'reports') {
|
|||||||
$reportStmt->execute($params);
|
$reportStmt->execute($params);
|
||||||
$reportRows = $reportStmt->fetchAll();
|
$reportRows = $reportStmt->fetchAll();
|
||||||
$rows = array_map(static fn (array $row): array => [$row['client_name'], (int)$row['jobcards'], round((float)$row['hours'], 2)], $reportRows);
|
$rows = array_map(static fn (array $row): array => [$row['client_name'], (int)$row['jobcards'], round((float)$row['hours'], 2)], $reportRows);
|
||||||
$reportClients = $user['role_name'] === 'Technician' ? db()->prepare('SELECT DISTINCT c.id, c.name FROM clients c JOIN jobcards j ON j.client_id = c.id JOIN jobcard_assignments ja ON ja.jobcard_id = j.id AND ja.user_id = :user ORDER BY c.name') : db()->query('SELECT id, name FROM clients ORDER BY name');
|
if ($user['role_name'] === 'Technician') {
|
||||||
if ($reportClients instanceof PDOStatement) $reportClients->execute(['user' => $user['id']]);
|
$reportClientsStmt = db()->prepare('SELECT DISTINCT c.id, c.name FROM clients c JOIN jobcards j ON j.client_id = c.id JOIN jobcard_assignments ja ON ja.jobcard_id = j.id AND ja.user_id = :user ORDER BY c.name');
|
||||||
$reportClients = $reportClients->fetchAll();
|
$reportClientsStmt->execute(['user' => $user['id']]);
|
||||||
|
$reportClients = $reportClientsStmt->fetchAll();
|
||||||
|
} else {
|
||||||
|
$reportClients = db()->query('SELECT id, name FROM clients ORDER BY name')->fetchAll();
|
||||||
|
}
|
||||||
$filterQuery = http_build_query(array_filter(['client_id' => $filters->clientId, 'date_from' => $filters->dateFrom, 'date_to' => $filters->dateTo, 'technician_id' => $filters->technicianId, 'status' => $filters->status, 'priority' => $filters->priority], static fn($value): bool => $value !== null && $value !== ''));
|
$filterQuery = http_build_query(array_filter(['client_id' => $filters->clientId, 'date_from' => $filters->dateFrom, 'date_to' => $filters->dateTo, 'technician_id' => $filters->technicianId, 'status' => $filters->status, 'priority' => $filters->priority], static fn($value): bool => $value !== null && $value !== ''));
|
||||||
if ($format === 'print') { header('Content-Type: text/html; charset=UTF-8'); header('Cache-Control: no-store'); echo (new \PrintReportRenderer())->render('Hours per client', ['Client', 'Jobcards', 'Hours'], $rows); exit; }
|
if ($format === 'print') { header('Content-Type: text/html; charset=UTF-8'); header('Cache-Control: no-store'); echo (new \PrintReportRenderer())->render('Hours per client', ['Client', 'Jobcards', 'Hours'], $rows); exit; }
|
||||||
if ($format === 'csv') {
|
if ($format === 'csv') {
|
||||||
|
|||||||
@@ -15,5 +15,7 @@ jobcard_feature_assert(str_contains($front, "j.status <> 'closed'"), 'Default Jo
|
|||||||
jobcard_feature_assert(str_contains($front, "j.status = 'closed'"), 'Closed filter must explicitly select closed records.');
|
jobcard_feature_assert(str_contains($front, "j.status = 'closed'"), 'Closed filter must explicitly select closed records.');
|
||||||
jobcard_feature_assert(str_contains($front, 'All clients') && str_contains($front, '$reportClient'), 'Reports must use a client-name dropdown.');
|
jobcard_feature_assert(str_contains($front, 'All clients') && str_contains($front, '$reportClient'), 'Reports must use a client-name dropdown.');
|
||||||
jobcard_feature_assert(str_contains($front, 'format=xls&detail=1'), 'Reports must expose detailed XLS export.');
|
jobcard_feature_assert(str_contains($front, 'format=xls&detail=1'), 'Reports must expose detailed XLS export.');
|
||||||
|
jobcard_feature_assert(str_contains($front, "if (\$user['role_name'] === 'Technician') {") && str_contains($front, '$reportClientsStmt->execute'), 'Report client dropdown must bind parameters only on the technician prepared-query branch.');
|
||||||
|
jobcard_feature_assert(!str_contains($front, 'if ($reportClients instanceof PDOStatement) $reportClients->execute'), 'Report client dropdown must not execute parameters against the non-technician query branch.');
|
||||||
foreach (['Work requested', 'Technician notes / Work performed', 'Hours notes'] as $heading) jobcard_feature_assert(str_contains($front, $heading), "Detailed report must include {$heading}.");
|
foreach (['Work requested', 'Technician notes / Work performed', 'Hours notes'] as $heading) jobcard_feature_assert(str_contains($front, $heading), "Detailed report must include {$heading}.");
|
||||||
printf("Jobcard search/close/report tests: 10 passed\n");
|
printf("Jobcard search/close/report tests: 10 passed\n");
|
||||||
|
|||||||
Reference in New Issue
Block a user