Ist-Stand mit 2 Nachkommastellen formatieren, Dropdown-Anzeige via NeedAppearances korrigieren

This commit is contained in:
Rob committed 2026-03-27 14:51:51 +01:00
1 parent 6a06a5f2a9
commit a1f229a502
3 files changed
+13 -9

No files matched your search

+2 -4
View File
@@ -40,12 +40,10 @@ class AttendanceDate:
return self.status == "X" return self.status == "X"
def hours_german(self) -> str: def hours_german(self) -> str:
"""Returns hours as a German-formatted string (comma decimal separator).""" """Returns hours as a German-formatted string (comma decimal separator, 2 decimal places)."""
if self.hours is None: if self.hours is None:
return "" return ""
if self.hours == int(self.hours): return f"{self.hours:.2f}".replace(".", ",")
return str(int(self.hours))
return str(self.hours).replace(".", ",")
@dataclass @dataclass
+7 -1
View File
@@ -11,7 +11,7 @@ from pathlib import Path
from typing import Any, Dict, Optional from typing import Any, Dict, Optional
from pypdf import PdfReader, PdfWriter from pypdf import PdfReader, PdfWriter
from pypdf.generic import NameObject, NumberObject from pypdf.generic import BooleanObject, NameObject, NumberObject
from .config_loader import load_config from .config_loader import load_config
from .exceptions import PdfTemplateError from .exceptions import PdfTemplateError
@@ -153,6 +153,12 @@ def fill_pdf(
_update_widget_visibility(writer, fields) _update_widget_visibility(writer, fields)
# Tell the PDF viewer to regenerate appearance streams from field values.
# Without this flag, dropdown fields (plan, pauschale) display stale text
# instead of their actual selected option (e.g. "8,60" for pauschale).
if "/AcroForm" in writer._root_object:
writer._root_object["/AcroForm"][NameObject("/NeedAppearances")] = BooleanObject(True)
output_path.parent.mkdir(parents=True, exist_ok=True) output_path.parent.mkdir(parents=True, exist_ok=True)
with output_path.open("wb") as fh: with output_path.open("wb") as fh:
writer.write(fh) writer.write(fh)
+4 -4
View File
@@ -95,11 +95,11 @@ class TestPresentDay:
def test_ist_field_whole_hours(self, cfg): def test_ist_field_whole_hours(self, cfg):
fields = build_field_dict(_make_attendance(_present(3, 6.0)), cfg, date(2026, 2, 1)) fields = build_field_dict(_make_attendance(_present(3, 6.0)), cfg, date(2026, 2, 1))
assert fields["ist.0"] == "6" assert fields["ist.0"] == "6,00"
def test_ist_field_decimal_hours(self, cfg): def test_ist_field_decimal_hours(self, cfg):
fields = build_field_dict(_make_attendance(_present(3, 6.5)), cfg, date(2026, 2, 1)) fields = build_field_dict(_make_attendance(_present(3, 6.5)), cfg, date(2026, 2, 1))
assert fields["ist.0"] == "6,5" assert fields["ist.0"] == "6,50"
def test_plan_always_6(self, cfg): def test_plan_always_6(self, cfg):
fields = build_field_dict(_make_attendance(_present(3, 3.0)), cfg, date(2026, 2, 1)) fields = build_field_dict(_make_attendance(_present(3, 3.0)), cfg, date(2026, 2, 1))
@@ -164,11 +164,11 @@ class TestMultiRow:
class TestHoursFormatting: class TestHoursFormatting:
def test_whole_number_no_decimal(self): def test_whole_number_no_decimal(self):
entry = AttendanceDate(date=date(2026, 2, 1), status="X", hours=6.0) entry = AttendanceDate(date=date(2026, 2, 1), status="X", hours=6.0)
assert entry.hours_german() == "6" assert entry.hours_german() == "6,00"
def test_decimal_comma_separator(self): def test_decimal_comma_separator(self):
entry = AttendanceDate(date=date(2026, 2, 1), status="X", hours=6.5) entry = AttendanceDate(date=date(2026, 2, 1), status="X", hours=6.5)
assert entry.hours_german() == "6,5" assert entry.hours_german() == "6,50"
def test_none_returns_empty(self): def test_none_returns_empty(self):
entry = AttendanceDate(date=date(2026, 2, 1), status="K", hours=None) entry = AttendanceDate(date=date(2026, 2, 1), status="K", hours=None)