From 7e0f0117e6164aed73ae6c89dd410a8522013695 Mon Sep 17 00:00:00 2001 From: Dotty Dotter Date: Tue, 28 Apr 2026 08:04:32 +0200 Subject: [PATCH] feat(#106): UI-Block 'Abstimmungsergebnis' auf Antrag-Detail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Antrag-Detail-Endpoint liest plenum_votes via get_plenum_votes() und reicht sie an antrag_detail.html durch. Block rendert pro Plenum-Abstimmung eine Karte: - Ergebnis (angenommen/abgelehnt/...) farb-kodiert - 'einstimmig'-Annotation falls gesetzt - Quelle (Protokoll-ID, mit URL als Tooltip) - Fraktions-Chips fuer Ja/Nein/Enthaltung Mehrfach-Abstimmungen einer Drucksache (Ueberweisung + finale Beschlussfassung) erzeugen mehrere Karten — chronologisch via parsed_at DESC im Repository sortiert. Block erscheint nur, wenn Eintraege existieren (kein leerer Header). --- app/main.py | 7 +++ app/templates/v2/screens/antrag_detail.html | 47 +++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/app/main.py b/app/main.py index 1c4fd51..eac356f 100644 --- a/app/main.py +++ b/app/main.py @@ -304,6 +304,13 @@ async def antrag_detail(request: Request, drucksache: str, current_user: Optiona except Exception: logger.exception("Fehler beim Laden von Abstimmungsverhalten für %s", drucksache) antrag["abstimmungsverhalten"] = None + # #106 Phase 2: fraktions-aggregierte Plenum-Abstimmungen aus Plenarprotokollen + try: + from .database import get_plenum_votes as _gpv + antrag["plenum_votes"] = await _gpv(antrag.get("bundesland") or "NRW", drucksache) + except Exception: + logger.exception("Fehler beim Laden plenum_vote_results für %s", drucksache) + antrag["plenum_votes"] = [] from .models import MATRIX_LABELS return templates.TemplateResponse("v2/screens/antrag_detail.html", { "request": request, diff --git a/app/templates/v2/screens/antrag_detail.html b/app/templates/v2/screens/antrag_detail.html index a5e2eee..9fde609 100644 --- a/app/templates/v2/screens/antrag_detail.html +++ b/app/templates/v2/screens/antrag_detail.html @@ -264,6 +264,53 @@ {% endfor %} {% endif %}{# abstimmungsverhalten #} + {# ── Fraktions-aggregierte Plenum-Abstimmung aus Plenarprotokoll (#106) ── #} + {% if antrag.plenum_votes %} +

Abstimmungsergebnis

+ {% set ergebnis_color = { + "angenommen": "#2da44e", + "abgelehnt": "#cf222e", + "überwiesen": "#0969da", + "zurückgezogen": "#8250df", + "bestätigt": "#2da44e", + "sammel": "#0969da", + } %} + {% for v in antrag.plenum_votes %} +
+
+ + {{ v.ergebnis | capitalize }}{% if v.einstimmig %} · einstimmig{% endif %} + + + {{ v.quelle_protokoll }}{% if v.quelle_url %} ↗{% endif %} + +
+ {% if v.fraktionen_ja or v.fraktionen_nein or v.fraktionen_enthaltung %} +
+ {% if v.fraktionen_ja %} +
Ja: + {% for f in v.fraktionen_ja %}{{ f }}{% endfor %} +
+ {% endif %} + {% if v.fraktionen_nein %} +
Nein: + {% for f in v.fraktionen_nein %}{{ f }}{% endfor %} +
+ {% endif %} + {% if v.fraktionen_enthaltung %} +
Enth.: + {% for f in v.fraktionen_enthaltung %}{{ f }}{% endfor %} +
+ {% endif %} +
+ {% endif %} +
+ {% endfor %} +
+ Quelle: Plenarprotokoll · automatisch extrahiert +
+ {% endif %}{# plenum_votes #} + {% if antrag.matrix %}

Matrix 2.0 · 25 Felder

{{ matrix_mini(antrag.matrix) }}