This commit is contained in:
2026-04-07 22:39:16 +02:00
parent 8fa9ca6439
commit 40644eb362
31 changed files with 4972 additions and 71 deletions

View File

@@ -47,6 +47,7 @@ final class OrdersController
'search' => trim((string) $request->input('search', '')),
'source' => trim((string) $request->input('source', '')),
'status' => trim((string) $request->input('status', '')),
'status_group' => trim((string) $request->input('status_group', '')),
'payment_status' => trim((string) $request->input('payment_status', '')),
'date_from' => trim((string) $request->input('date_from', '')),
'date_to' => trim((string) $request->input('date_to', '')),
@@ -66,7 +67,7 @@ final class OrdersController
$statusLabelMap = $this->statusLabelMap($statusConfig);
$statusColorMap = $this->statusColorMap($statusConfig);
$statusOptions = $this->buildStatusFilterOptions($this->orders->statusOptions(), $statusLabelMap);
$statusPanel = $this->buildStatusPanel($statusConfig, $statusCounts, $filters['status'], $filters);
$statusPanel = $this->buildStatusPanel($statusConfig, $statusCounts, $filters['status'], $filters, $filters['status_group']);
$tableRows = array_map(fn (array $row): array => $this->toTableRow($row, $statusLabelMap, $statusColorMap), (array) ($result['items'] ?? []));
@@ -438,7 +439,7 @@ final class OrdersController
* @param array<string, int> $counts
* @return array<int, array<string, mixed>>
*/
private function buildStatusPanel(array $config, array $counts, string $currentStatusCode, array $query = []): array
private function buildStatusPanel(array $config, array $counts, string $currentStatusCode, array $query = [], string $currentStatusGroup = ''): array
{
$allCount = 0;
foreach ($counts as $count) {
@@ -451,7 +452,7 @@ final class OrdersController
'code' => '',
'label' => 'Wszystkie',
'count' => $allCount,
'is_active' => trim($currentStatusCode) === '',
'is_active' => trim($currentStatusCode) === '' && trim($currentStatusGroup) === '',
'tone' => 'neutral',
'color_hex' => '#64748b',
'url' => $this->statusFilterUrl($query, ''),
@@ -461,17 +462,22 @@ final class OrdersController
foreach ($config as $group) {
$items = [];
$groupColor = StringHelper::normalizeColorHex((string) ($group['color_hex'] ?? '#64748b'));
$groupId = (string) ((int) ($group['id'] ?? 0));
$groupItems = is_array($group['items'] ?? null) ? $group['items'] : [];
$isActiveGroup = $currentStatusGroup !== '' && $currentStatusGroup === $groupId;
$groupCount = 0;
foreach ($groupItems as $status) {
$code = strtolower(trim((string) ($status['code'] ?? '')));
if ($code === '') {
continue;
}
$statusCount = (int) ($counts[$code] ?? 0);
$groupCount += $statusCount;
$items[] = [
'code' => $code,
'label' => (string) ($status['name'] ?? $code),
'count' => (int) ($counts[$code] ?? 0),
'is_active' => trim(strtolower($currentStatusCode)) === $code,
'count' => $statusCount,
'is_active' => !$isActiveGroup && trim(strtolower($currentStatusCode)) === $code,
'tone' => $this->statusTone($code),
'color_hex' => $groupColor,
'url' => $this->statusFilterUrl($query, $code),
@@ -483,6 +489,10 @@ final class OrdersController
$result[] = [
'name' => (string) ($group['name'] ?? ''),
'color_hex' => $groupColor,
'group_id' => $groupId,
'group_url' => $this->groupFilterUrl($query, $groupId),
'group_count' => $groupCount,
'is_active_group' => $isActiveGroup,
'items' => $items,
];
}
@@ -531,6 +541,7 @@ final class OrdersController
private function statusFilterUrl(array $query, string $statusCode): string
{
$params = $query;
unset($params['status_group']);
if ($statusCode === '') {
unset($params['status']);
} else {
@@ -550,6 +561,29 @@ final class OrdersController
return $qs === '' ? '/orders/list' : '/orders/list?' . $qs;
}
private function groupFilterUrl(array $query, string $groupId): string
{
$params = $query;
unset($params['status']);
if ($groupId === '' || $groupId === '0') {
unset($params['status_group']);
} else {
$params['status_group'] = $groupId;
}
$params['page'] = 1;
$clean = [];
foreach ($params as $key => $value) {
if ($value === '' || $value === null) {
continue;
}
$clean[(string) $key] = (string) $value;
}
$qs = http_build_query($clean);
return $qs === '' ? '/orders/list' : '/orders/list?' . $qs;
}
private function statusTone(string $statusCode): string
{
$code = strtolower(trim($statusCode));

View File

@@ -111,8 +111,20 @@ final class OrdersRepository
$params['source'] = $source;
}
$statusGroup = trim((string) ($filters['status_group'] ?? ''));
$status = trim((string) ($filters['status'] ?? ''));
if ($status !== '') {
if ($statusGroup !== '' && ctype_digit($statusGroup)) {
$groupCodes = $this->statusCodesByGroupId((int) $statusGroup);
if ($groupCodes !== []) {
$placeholders = [];
foreach ($groupCodes as $i => $code) {
$key = 'sg' . $i;
$placeholders[] = ':' . $key;
$params[$key] = $code;
}
$where[] = $effectiveStatusSql . ' IN (' . implode(', ', $placeholders) . ')';
}
} elseif ($status !== '') {
$where[] = $effectiveStatusSql . ' = :status';
$params['status'] = $status;
}
@@ -398,6 +410,7 @@ final class OrdersRepository
if (!isset($groupMap[$groupId])) {
$groupMap[$groupId] = [
'id' => $groupId,
'name' => trim((string) ($row['group_name'] ?? '')),
'color_hex' => StringHelper::normalizeColorHex((string) ($row['group_color_hex'] ?? '#64748b')),
'items' => [],
@@ -418,6 +431,35 @@ final class OrdersRepository
return array_values($groupMap);
}
/**
* @return list<string>
*/
private function statusCodesByGroupId(int $groupId): array
{
try {
$stmt = $this->pdo->prepare(
'SELECT code FROM order_statuses WHERE group_id = :gid AND is_active = 1 ORDER BY sort_order ASC'
);
$stmt->execute(['gid' => $groupId]);
$rows = $stmt->fetchAll(PDO::FETCH_COLUMN);
} catch (Throwable) {
return [];
}
if (!is_array($rows)) {
return [];
}
$codes = [];
foreach ($rows as $code) {
$trimmed = strtolower(trim((string) $code));
if ($trimmed !== '') {
$codes[] = $trimmed;
}
}
return $codes;
}
/**
* @return array<string, mixed>|null
*/