From f2d944b1171f7cbca2ef7256a41da7628d39d670 Mon Sep 17 00:00:00 2001 From: Jacek Pyziak Date: Mon, 6 Jul 2026 22:17:16 +0200 Subject: [PATCH] Operacje: nowrap dla daty/kwoty, ucinanie opisu i stronicowanie 10/str Co-Authored-By: Claude Opus 4.8 (1M context) --- app/Controllers/Operations.php | 10 ++++++- app/Models/OperationModel.php | 31 +++++++++++++++++++--- app/Views/operations/index.php | 48 ++++++++++++++++++++++++++++------ 3 files changed, 76 insertions(+), 13 deletions(-) diff --git a/app/Controllers/Operations.php b/app/Controllers/Operations.php index 98bd8e2..500f765 100644 --- a/app/Controllers/Operations.php +++ b/app/Controllers/Operations.php @@ -21,12 +21,20 @@ class Operations extends BaseController 'type' => $this->request->getGet('type'), ]; + $perPage = 10; + $total = $this->model()->countFiltered($f); + $pages = max(1, (int) ceil($total / $perPage)); + $page = min($pages, max(1, (int) $this->request->getGet('page'))); + return view('operations/index', [ 'title' => 'Operacje', - 'operations' => $this->model()->filtered($f), + 'operations' => $this->model()->filtered($f, $perPage, $page), 'totals' => $this->model()->totals($f), 'categories' => model(CategoryModel::class)->tree(), 'filter' => $f, + 'page' => $page, + 'pages' => $pages, + 'total' => $total, ]); } diff --git a/app/Models/OperationModel.php b/app/Models/OperationModel.php index 99d755b..0e260be 100644 --- a/app/Models/OperationModel.php +++ b/app/Models/OperationModel.php @@ -10,7 +10,7 @@ class OperationModel extends Model protected $primaryKey = 'id'; protected $returnType = 'array'; protected $useTimestamps = true; - protected $allowedFields = ['date', 'amount', 'type', 'category_id', 'description']; + protected $allowedFields = ['date', 'amount', 'type', 'category_id', 'receipt_id', 'description']; protected $validationRules = [ 'date' => 'required|valid_date[Y-m-d]', @@ -23,14 +23,39 @@ class OperationModel extends Model /** * Lista operacji z nazwa kategorii, z filtrami. * $f: from, to, category_id, type (wszystkie opcjonalne). + * Gdy $perPage > 0, zwraca tylko jedna strone (LIMIT/OFFSET). */ - public function filtered(array $f): array + public function filtered(array $f, int $perPage = 0, int $page = 1): array { $b = $this->db->table('operations o') ->select('o.*, c.name AS category_name, p.name AS parent_name') ->join('categories c', 'c.id = o.category_id', 'left') ->join('categories p', 'p.id = c.parent_id', 'left'); + $this->applyFilters($b, $f); + + $b->orderBy('o.date', 'DESC')->orderBy('o.id', 'DESC'); + + if ($perPage > 0) { + $b->limit($perPage, max(0, ($page - 1) * $perPage)); + } + + return $b->get()->getResultArray(); + } + + /** + * Liczba operacji pasujacych do filtrow (do stronicowania). + */ + public function countFiltered(array $f): int + { + $b = $this->db->table('operations o'); + $this->applyFilters($b, $f); + + return $b->countAllResults(); + } + + private function applyFilters($b, array $f): void + { if (! empty($f['from'])) { $b->where('o.date >=', $f['from']); } @@ -43,8 +68,6 @@ class OperationModel extends Model if (! empty($f['type'])) { $b->where('o.type', $f['type']); } - - return $b->orderBy('o.date', 'DESC')->orderBy('o.id', 'DESC')->get()->getResultArray(); } /** diff --git a/app/Views/operations/index.php b/app/Views/operations/index.php index b45b37f..e426488 100644 --- a/app/Views/operations/index.php +++ b/app/Views/operations/index.php @@ -2,6 +2,9 @@ section('content') ?> number_format((float) $v, 2, ',', ' ') . ' zł'; ?> +

Operacje

@@ -65,10 +68,10 @@ - - + + - + @@ -77,8 +80,8 @@ - - + - - + -
DataKategoriaDataKategoria OpisKwotaKwota Akcje
Brak operacji dla wybranych filtrów.
+ + + Edytuj Usuń @@ -103,5 +106,34 @@
+ 1): ?> + $filter['from'] ?? '', + 'to' => $filter['to'] ?? '', + 'category_id' => $filter['category_id'] ?? '', + 'type' => $filter['type'] ?? '', + ], static fn ($v) => $v !== '' && $v !== null); + $link = static fn (int $p) => site_url('operations') . '?' . http_build_query($qs + ['page' => $p]); + ?> + + endSection() ?>