feat(109): checkbox multiselect filters

Phase 109 complete:
- Add checkbox dropdown enhancement for statistics multi-select filters
- Preserve GET contract for channels[] and status_groups[]
- Update PAUL plan context to read .paul/codebase docs

Co-Authored-By: Codex <noreply@openai.com>
This commit is contained in:
2026-04-28 22:13:52 +02:00
parent 1009957fff
commit 6d3dba89ed
13 changed files with 681 additions and 29 deletions

View File

@@ -26,6 +26,7 @@ HTTP Request
| Repositories | `src/Modules/*/Repository.php` | PDO data access (34+ repos) |
| Views | `resources/views/` | PHP templates with `$e()` / `$t()` |
| Components | `resources/views/components/` | Reusable UI blocks |
| Frontend modules | `public/assets/js/modules/` | Small vanilla JS enhancements loaded by layout |
## Module Inventory (`src/Modules/`)
@@ -44,6 +45,15 @@ HTTP Request
| **Statistics** | 2 | `OrdersStatisticsController`, `OrdersStatisticsRepository` | Dashboard aggregates |
| **Info** | 1 | `InfoController` | Health check |
## Frontend Enhancement Modules
### Checkbox Multiselect (`public/assets/js/modules/checkbox-multiselect.js`)
- Loaded globally from `resources/views/layouts/app.php`.
- Enhances native `<select multiple data-checkbox-multiselect>` controls after `DOMContentLoaded`.
- Keeps the original select in the form, synchronizes option `selected` state, and preserves native GET/POST names such as `channels[]` and `status_groups[]`.
- Used by `/statistics/orders` filters to display a compact trigger, checkbox dropdown, "Wszystkie" bulk toggle, and selected count.
- Progressive enhancement: if JavaScript fails, the native multi-select remains visible.
## Key Data Flows
### Order Lifecycle
@@ -124,3 +134,28 @@ tests/
Unit/ PHPUnit tests (7+ service test files)
bootstrap.php PSR-4 autoloader for tests
```
## Phase 108 — Delivery Status Management
### DeliveryStatusRepository (`src/Modules/Shipments/DeliveryStatusRepository.php`)
- CRUD dla tabeli `delivery_statuses`
- Per-request static cache (`private static ?array $cache`)
- Blokuje edycję/usunięcie statusów systemowych (`is_system=1`)
- Blokuje usunięcie statusów używanych w `delivery_status_mappings` lub `shipment_packages`
### DeliveryStatusesController (`src/Modules/Settings/DeliveryStatusesController.php`)
- Panel `/settings/delivery-statuses`
- Dwie zakładki via `?tab=` param: `statuses` (CRUD) i `mapping` (embed mapowania)
- Wstrzykuje `DeliveryStatusRepository` i `DeliveryStatusMappingRepository`
### DeliveryStatus::setRepository() (dynamic loading)
- Wywoływane raz w `routes/web.php` po bootstrap
- `label()`, `getAllOptions()`, `getAllStatuses()`, `getColor()` ładują z DB gdy repo ustawione
- Fallback na hardcoded stałe gdy repo niedostępne
### AutomationController + AutomationService (Phase 108 Plan 02)
- `AutomationController::buildShipmentStatusOptions()` — buduje listę opcji `[key => ['label' => ...]]` z `DeliveryStatus::getAllOptions()` (DB-driven)
- Walidacja `shipment_status` warunku i `update_shipment_status` akcji w `parseConditionValue()`/`parseActionConfig()` używa `DeliveryStatus::getAllStatuses()`
- `AutomationService::evaluateShipmentStatusCondition()` — bezpośrednie porównanie kluczy DB (usunięto mapping grupowy `SHIPMENT_STATUS_OPTION_MAP`)
- `AutomationService::resolveStatusFromActionKey()` — bezpośredni klucz statusu z DB jako target
- BREAKING: stare reguły z grupowymi kluczami (`registered`, `courier_pickup`, `dropped_at_point`, `unclaimed`, `picked_up_return`) nie matchują się — operator musi je odtworzyć przy użyciu nowych kluczy DB