diff --git a/README.md b/README.md index 54a8ac4..311b88c 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,10 @@ Dokumentiere Ausgaben on-the-go als Webapp - [ ] Zusammenfassen von mehreren Einträgen zu einer Aktie - [ ] Prüfen ob APIKEYS leer sind und ggfs die Aktualisierung ausblenden +## V.2.3 + +- [X] Listen mit Spaltenfiltern (Dashboard) zeigen unterhalb eine optisch abgesetzte Summenzeile, die die Beträge der aktuell sichtbaren (gefilterten) Einträge in der Spalte "Betrag" aufsummiert. + ## V.2.2 - [X] Unit-Tests (PHPUnit) für die wichtigsten Funktionen, gebündelt in `html/lib/fscash.php`: Monatsnavigation, Admin-/Aktien-Rollenprüfung, Aktien-GuV-Berechnung, OpenFIGI-/Alpha-Vantage-Antwortauswertung, Eingabevalidierung, CSV-Export und Migrations-Logik (siehe Abschnitt "Tests" unten). diff --git a/html/assets/css/style.css b/html/assets/css/style.css index 56574e4..a40dabc 100644 --- a/html/assets/css/style.css +++ b/html/assets/css/style.css @@ -351,6 +351,14 @@ tr.filter-row th { border-color: var(--primary-color); } +/* Summenzeile unterhalb gefilterter Listen */ +tr.sum-row td { + background: #eef3f8; + font-weight: 700; + border-top: 2px solid var(--primary-color); + border-bottom: none; +} + /* Button */ .btn-xr { diff --git a/html/dashboard.php b/html/dashboard.php index 123e0b1..88b6d09 100644 --- a/html/dashboard.php +++ b/html/dashboard.php @@ -198,7 +198,7 @@ sort($filterZahlweise, SORT_STRING | SORT_FLAG_CASE); - + @@ -208,6 +208,19 @@ sort($filterZahlweise, SORT_STRING | SORT_FLAG_CASE); + + +Summe + + + + + +0,00 + + + + @@ -224,6 +237,7 @@ document.querySelector('.hamburger').addEventListener('click', function() { (function() { const filters = document.querySelectorAll('.column-filter'); const rows = document.querySelectorAll('#entries-body tr'); + const sumValue = document.getElementById('sum-value'); // Mehrfach-Kategorie-Vorauswahl, z. B. per Link aus dem Personenreport (Kategorie-Select kann nur einen Wert anzeigen) const presetKategorien = ; @@ -232,6 +246,7 @@ document.querySelector('.hamburger').addEventListener('click', function() { .map(f => ({ col: parseInt(f.dataset.col, 10), value: f.value.trim().toLowerCase() })) .filter(f => f.value !== ''); + let sum = 0; rows.forEach(row => { const cells = row.children; const visible = activeFilters.every(f => { @@ -240,7 +255,17 @@ document.querySelector('.hamburger').addEventListener('click', function() { return cell.textContent.trim().toLowerCase().includes(f.value); }) && (presetKategorien.length === 0 || (cells[3] && presetKategorien.includes(cells[3].textContent.trim().toLowerCase()))); row.style.display = visible ? '' : 'none'; + if (visible) { + const amountCell = cells[6]; + if (amountCell) { + sum += parseFloat(amountCell.dataset.amount) || 0; + } + } }); + + if (sumValue) { + sumValue.textContent = sum.toLocaleString('de-DE', { minimumFractionDigits: 2, maximumFractionDigits: 2 }); + } } filters.forEach(f => {