From 0ea233f5eec107492163dce0b102e03a3a2415c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Gla=CC=88ser?= Date: Tue, 16 Jun 2026 20:10:55 +0200 Subject: [PATCH] Fix Bestellungen search filtering --- modules/erp/bestellungen/service.php | 101 ++++++++++++++++----------- 1 file changed, 61 insertions(+), 40 deletions(-) diff --git a/modules/erp/bestellungen/service.php b/modules/erp/bestellungen/service.php index e4dc0ff..ca1e47b 100644 --- a/modules/erp/bestellungen/service.php +++ b/modules/erp/bestellungen/service.php @@ -233,35 +233,38 @@ function escape_sales_order_search_term(string $searchTerm): string ]); } -function get_sales_order_overview(PDO $pdo, array $filters = []): array +function sales_order_row_matches_search_term(array $row, string $searchTerm): bool { - $searchTerm = trim((string) ($filters['search'] ?? '')); - $sortColumn = normalize_sales_order_sort_column((string) ($filters['sort_column'] ?? 'order_date')); - $sortDirection = normalize_sales_order_sort_direction((string) ($filters['sort_direction'] ?? ''), $sortColumn); - $limit = max(1, (int) ($filters['limit'] ?? 20)); - $pageSize = max(1, (int) ($filters['page_size'] ?? 20)); - - $filterSql = ''; - $params = []; - if ($searchTerm !== '') { - $filterSql = <<<'SQL' -WHERE ( - so.external_ref ILIKE :search_term ESCAPE '\' - OR so.order_date::text ILIKE :search_term ESCAPE '\' - OR COALESCE(so.total_amount::text, '') ILIKE :search_term ESCAPE '\' - OR COALESCE(ad.last_name, '') ILIKE :search_term ESCAPE '\' - OR COALESCE(ad.first_name, '') ILIKE :search_term ESCAPE '\' - OR (COALESCE(ad.first_name, '') || ' ' || COALESCE(ad.last_name, '')) ILIKE :search_term ESCAPE '\' - OR COALESCE(ad.street, '') ILIKE :search_term ESCAPE '\' - OR COALESCE(ad.house_number, '') ILIKE :search_term ESCAPE '\' - OR COALESCE(ad.zip, '') ILIKE :search_term ESCAPE '\' - OR COALESCE(ad.city, '') ILIKE :search_term ESCAPE '\' - OR COALESCE(ad.country_name, '') ILIKE :search_term ESCAPE '\' -) -SQL; - $params[':search_term'] = '%' . escape_sales_order_search_term($searchTerm) . '%'; + $needle = trim($searchTerm); + if ($needle === '') { + return true; } + $haystacks = [ + (string) ($row['external_ref'] ?? ''), + (string) ($row['order_date'] ?? ''), + (string) ($row['total_amount'] ?? ''), + (string) ($row['first_name'] ?? ''), + (string) ($row['last_name'] ?? ''), + trim((string) ($row['first_name'] ?? '') . ' ' . (string) ($row['last_name'] ?? '')), + (string) ($row['street'] ?? ''), + (string) ($row['house_number'] ?? ''), + (string) ($row['zip'] ?? ''), + (string) ($row['city'] ?? ''), + (string) ($row['country_name'] ?? ''), + ]; + + foreach ($haystacks as $haystack) { + if ($haystack !== '' && stripos($haystack, $needle) !== false) { + return true; + } + } + + return false; +} + +function fetch_sales_order_overview_rows(PDO $pdo, string $sortColumn, string $sortDirection, ?int $limit = 20): array +{ $sortExpressions = [ 'order_date' => 'so.order_date', 'external_ref' => 'so.external_ref', @@ -289,15 +292,6 @@ LEFT JOIN LATERAL ( ) ad ON TRUE SQL; - $countStmt = $pdo->prepare( - 'SELECT COUNT(*) ' . $baseFromSql . "\n" . $filterSql - ); - foreach ($params as $key => $value) { - $countStmt->bindValue($key, $value, PDO::PARAM_STR); - } - $countStmt->execute(); - $totalCount = (int) $countStmt->fetchColumn(); - $listSql = <<<'SQL' SELECT so.id, @@ -312,15 +306,16 @@ SELECT COALESCE(ad.city, '') AS city, COALESCE(ad.country_name, '') AS country_name SQL; - $listSql .= "\n" . $baseFromSql . "\n" . $filterSql; + $listSql .= "\n" . $baseFromSql; $listSql .= "\nORDER BY {$sortExpression} {$sortDirection}, so.id {$sortDirection}"; - $listSql .= "\nLIMIT :limit"; + if ($limit !== null) { + $listSql .= "\nLIMIT :limit"; + } $listStmt = $pdo->prepare($listSql); - foreach ($params as $key => $value) { - $listStmt->bindValue($key, $value, PDO::PARAM_STR); + if ($limit !== null) { + $listStmt->bindValue(':limit', $limit, PDO::PARAM_INT); } - $listStmt->bindValue(':limit', $limit, PDO::PARAM_INT); $listStmt->execute(); $rows = []; @@ -340,6 +335,32 @@ SQL; ]; } + return $rows; +} + +function get_sales_order_overview(PDO $pdo, array $filters = []): array +{ + $searchTerm = trim((string) ($filters['search'] ?? '')); + $sortColumn = normalize_sales_order_sort_column((string) ($filters['sort_column'] ?? 'order_date')); + $sortDirection = normalize_sales_order_sort_direction((string) ($filters['sort_direction'] ?? ''), $sortColumn); + $limit = max(1, (int) ($filters['limit'] ?? 20)); + $pageSize = max(1, (int) ($filters['page_size'] ?? 20)); + + if ($searchTerm !== '') { + $allRows = fetch_sales_order_overview_rows($pdo, $sortColumn, $sortDirection, null); + $matchedRows = array_values(array_filter( + $allRows, + static fn (array $row): bool => sales_order_row_matches_search_term($row, $searchTerm) + )); + $totalCount = count($matchedRows); + $rows = array_slice($matchedRows, 0, $limit); + } else { + $countStmt = $pdo->prepare('SELECT COUNT(*) FROM sales_order'); + $countStmt->execute(); + $totalCount = (int) $countStmt->fetchColumn(); + $rows = fetch_sales_order_overview_rows($pdo, $sortColumn, $sortDirection, $limit); + } + return [ 'rows' => $rows, 'search' => $searchTerm,