Auswählbare Mitarbeitermonate in separater Multiselektliste hinzugefügt

This commit is contained in:
Rob committed 2026-08-10 19:37:03 +02:00
1 parent eb1dd45e57
commit d027bedcb8
2 files changed
+116 -10

No files matched your search

+3 -2
View File
@@ -15,9 +15,10 @@ Um das Programm zu starten: Doppelklick auf `Tätigkeitsnachweis-Generator.exe`
- Nach Auswahl wird das Template sofort validiert - Nach Auswahl wird das Template sofort validiert
- Angezeigt wird: Anzahl gefundener Zielfelder - Angezeigt wird: Anzahl gefundener Zielfelder
3. **Mitarbeiter auswählen** – Multiselect-Liste aller gefundenen Mitarbeiter 3. **Mitarbeiter auswählen** – Multiselect-Liste aller gefundenen Mitarbeiter
- Standardmäßig sind alle ausgewählt - Standardmäßig ist keiner ausgewählt
- Nicht selektierte Mitarbeiter werden bei der Generierung übersprungen - Nicht selektierte Mitarbeiter werden bei der Generierung übersprungen
4. **"Tätigkeitsnachweise generieren"** klicken 4. **Mitarbeitermonate auswählen** – Multiselect-Liste aller verfügbaren Monate im Dokument. Vorselektiert sind die aktuell letzten beiden Monate.
5. **"Tätigkeitsnachweise generieren"** klicken
- Die generierten Dateien werden im `output/`-Ordner abgelegt - Die generierten Dateien werden im `output/`-Ordner abgelegt
## Konfiguration ## Konfiguration
+113 -8
View File
@@ -30,6 +30,26 @@ from src.parser import parse_input_file, group_by_employee, get_unique_antragsnu
from src.validator import validate_input_file, validate_template from src.validator import validate_input_file, validate_template
from src.writer import generate_activity_reports from src.writer import generate_activity_reports
def set_active_employee(employee_name: str):
"""Merkt die zuletzt angeklickte Person für die Monatsliste."""
st.session_state.active_month_employee = employee_name
def sync_employee_months(employee_name: str, months: list[str]):
"""Übernimmt Monats-Checkboxen vor dem nächsten UI-Rendern."""
st.session_state.employee_months[employee_name] = {
month for month in months
if st.session_state.get(f"month_{employee_name}_{month}", False)
}
def set_all_employee_months(employee_name: str, months: list[str], selected: bool):
"""Setzt alle Monats-Checkboxen einer Person gesammelt."""
st.session_state.employee_months[employee_name] = set(months) if selected else set()
for month in months:
st.session_state[f"month_{employee_name}_{month}"] = selected
# --- Seite konfigurieren --- # --- Seite konfigurieren ---
st.set_page_config( st.set_page_config(
page_title="Tätigkeitsnachweis-Generator", page_title="Tätigkeitsnachweis-Generator",
@@ -72,6 +92,8 @@ if "cached_val_result" not in st.session_state:
st.session_state.cached_val_result = None st.session_state.cached_val_result = None
if "cached_tpl_result" not in st.session_state: if "cached_tpl_result" not in st.session_state:
st.session_state.cached_tpl_result = None st.session_state.cached_tpl_result = None
if "employee_months" not in st.session_state:
st.session_state.employee_months = {}
# --- Layout: zwei Spalten --- # --- Layout: zwei Spalten ---
col1, col2 = st.columns(2) col1, col2 = st.columns(2)
@@ -230,25 +252,95 @@ if st.session_state.input_validated and st.session_state.parsed_records:
employees = get_unique_employees(st.session_state.parsed_records) employees = get_unique_employees(st.session_state.parsed_records)
st.caption(f"{len(employees)} Mitarbeiter gefunden – wähle aus, für wen Tätigkeitsnachweise erstellt werden sollen:") st.caption(f"{len(employees)} Mitarbeiter gefunden – wähle aus, für wen Tätigkeitsnachweise erstellt werden sollen:")
# "Alle" / "Keine" Buttons # Monatsbezeichnungen für die kompakte Anzeige hinter dem Namen
btn_col1, btn_col2 = st.columns(2) month_labels = {
if btn_col1.button("☑ Alle auswählen", use_container_width=True): "01": "Jan", "02": "Feb", "03": "Mär", "04": "Apr",
"05": "Mai", "06": "Jun", "07": "Jul", "08": "Aug",
"09": "Sep", "10": "Okt", "11": "Nov", "12": "Dez",
}
all_groups = group_by_employee(st.session_state.parsed_records)
available_months = {}
for emp in employees:
months = sorted({
record.monat.split(".", 1)[0].zfill(2)
for record in all_groups.get(emp, [])
if record.monat and record.monat.split(".", 1)[0].isdigit()
}, key=lambda value: int(value))
available_months[emp] = months
if emp not in st.session_state.employee_months:
st.session_state.employee_months[emp] = set(months[-2:])
# Mitarbeiter- und Monatsliste teilen sich die verfügbare Breite.
employee_col, month_col = st.columns(2)
with employee_col:
employee_btn_col1, employee_btn_col2 = st.columns(2)
if employee_btn_col1.button("☑ Alle auswählen", use_container_width=True):
for emp in employees: for emp in employees:
st.session_state[f"sel_{emp}"] = True st.session_state[f"sel_{emp}"] = True
if btn_col2.button("☐ Keine auswählen", use_container_width=True): if employee_btn_col2.button("☐ Keine auswählen", use_container_width=True):
for emp in employees: for emp in employees:
st.session_state[f"sel_{emp}"] = False st.session_state[f"sel_{emp}"] = False
# Mitarbeiter-Liste mit Rahmen
with st.container(border=True): with st.container(border=True):
selected_employees = [] selected_employees = []
for emp in employees: for emp in employees:
key = f"sel_{emp}" key = f"sel_{emp}"
if key not in st.session_state: if key not in st.session_state:
st.session_state[key] = True st.session_state[key] = False
if st.checkbox(emp, key=key): selected_months = st.session_state.employee_months.get(emp, set())
short_months = ", ".join(month_labels[m] for m in available_months[emp] if m in selected_months)
label = f"{emp} ({short_months})" if short_months else f"{emp} (**keine Monate**)"
if st.checkbox(
label,
key=key,
on_change=set_active_employee,
args=(emp,),
):
selected_employees.append(emp) selected_employees.append(emp)
with month_col:
selected_for_months = st.session_state.get("active_month_employee")
if selected_for_months not in employees:
selected_for_months = None
month_btn_col1, month_btn_col2 = st.columns(2)
month_btn_col1.button(
"☑ Alle Monate",
use_container_width=True,
disabled=not selected_for_months,
on_click=set_all_employee_months,
args=(selected_for_months, available_months[selected_for_months], True) if selected_for_months else ("", [], True),
)
month_btn_col2.button(
"☐ Keine Monate",
use_container_width=True,
disabled=not selected_for_months,
on_click=set_all_employee_months,
args=(selected_for_months, available_months[selected_for_months], False) if selected_for_months else ("", [], False),
)
with st.container(border=True):
st.caption("Monate für den angeklickten Mitarbeiter")
if selected_for_months:
st.write(selected_for_months)
month_values = {}
for month in available_months[selected_for_months]:
month_key = f"month_{selected_for_months}_{month}"
if month_key not in st.session_state:
st.session_state[month_key] = month in st.session_state.employee_months[selected_for_months]
month_values[month] = st.checkbox(
f"{month_labels[month]} ({month})",
key=month_key,
on_change=sync_employee_months,
args=(selected_for_months, available_months[selected_for_months]),
)
st.session_state.employee_months[selected_for_months] = {
month for month, checked in month_values.items() if checked
}
else:
st.info("Einen Mitarbeiter links auswählen, um seine Monate festzulegen.")
st.caption(f"{len(selected_employees)} von {len(employees)} Mitarbeitern ausgewählt") st.caption(f"{len(selected_employees)} von {len(employees)} Mitarbeitern ausgewählt")
else: else:
selected_employees = [] selected_employees = []
@@ -283,7 +375,20 @@ if generate_clicked:
else: else:
# Filtere Records auf selektierte Mitarbeiter # Filtere Records auf selektierte Mitarbeiter
all_groups = group_by_employee(st.session_state.parsed_records) all_groups = group_by_employee(st.session_state.parsed_records)
selected_groups = {name: all_groups[name] for name in selected_employees if name in all_groups} selected_groups = {
name: [
record for record in all_groups[name]
if record.monat.split(".", 1)[0].zfill(2)
in st.session_state.employee_months.get(name, set())
]
for name in selected_employees
if name in all_groups
}
selected_groups = {name: records for name, records in selected_groups.items() if records}
if not selected_groups:
st.error("Für die ausgewählten Mitarbeiter sind keine Monate ausgewählt.")
st.stop()
template_path = Path(app_config.template_dir) / selected_template template_path = Path(app_config.template_dir) / selected_template
output_dir = Path(app_config.output_dir) output_dir = Path(app_config.output_dir)