improved dynamic dropdown behaviour

This commit is contained in:
2026-05-28 09:21:53 +02:00
parent 5289579d93
commit c83c201a13

View File

@@ -5,7 +5,6 @@ import dataclasses as dc
import datetime
import enum
import json
import logging
import pickle
import re
import sys
@@ -18,7 +17,6 @@ from typing import Annotated, Any, Final, Protocol, TypeAlias, TypedDict, TypeVa
from typing_extensions import override
import babel
from dopt_basics.logging import BASE_LOGGER, setup_logging
from pydantic import (
AwareDatetime,
BaseModel,
@@ -62,26 +60,38 @@ from PySide6.QtWidgets import (
QWidget,
)
import wce_crm.constants
from wce_crm.backend import backend as be_init_rec
from wce_crm.logging import (
logger_auto_form,
logger_get_data,
logger_gui,
)
K = TypeVar("K")
V = TypeVar("V")
setup_logging(enable_stderr=True)
DEBUG: Final[bool] = True
DEBUG_SEARCH_WIDGET: Final[bool] = False
DEBUG_NO_DATABASE: Final[bool] = True
DEBUG_GET_SET: Final[bool] = True
DEBUG: bool = True
DEBUG_SEARCH_WIDGET: bool = False
DEBUG_NO_DATABASE: bool = False
DEBUG_GET_SET: bool = False
logger = BASE_LOGGER.getChild("wce")
logger.setLevel(logging.DEBUG)
logger_search_widget = logger.getChild("search_widget")
logger_search_widget.setLevel(logging.DEBUG)
logger_get_data = logger.getChild("get_data")
logger_get_data.setLevel(logging.DEBUG)
logger_auto_form = logger.getChild("get_data_auto_form")
logger_auto_form.setLevel(logging.DEBUG)
if not wce_crm.constants.Config.DEVELOPMENT_STATE:
DEBUG = False
DEBUG_SEARCH_WIDGET = False
DEBUG_NO_DATABASE = False
DEBUG_GET_SET = False
# TODO remove
# logger_gui = BASE_LOGGER.getChild("wce")
# logger_gui.setLevel(logging.DEBUG)
# logger_search_widget = logger_gui.getChild("search_widget")
# logger_search_widget.setLevel(logging.DEBUG)
# logger_get_data = logger_gui.getChild("get_data")
# logger_get_data.setLevel(logging.DEBUG)
# logger_auto_form = logger_gui.getChild("get_data_auto_form")
# logger_auto_form.setLevel(logging.DEBUG)
QSS = """
*[styleClass="stempel"] {
@@ -422,12 +432,13 @@ class FormField:
init_label: str = dc.field(init=False)
ignore_get_data: bool = False
trigger_value: str = ""
enable_uuid_key: bool = False
def __post_init__(
self,
options: Sequence[tuple[str, Any]],
) -> None:
if not self.key:
if not self.key and self.enable_uuid_key:
self.key = str(uuid.uuid4())
self.label = self.label.strip()
@@ -546,7 +557,13 @@ def _build_ui_recursively(
no_scroll_filter = NoScrollFilter(parent_layout)
keys: list[str] = []
for field in schema:
full_key = f"{prefix}{COLUMN_SEP}{field.key}" if prefix else field.key
if prefix and field.key:
full_key = f"{prefix}{COLUMN_SEP}{field.key}" if prefix else field.key
elif prefix and not field.key:
full_key = f"{prefix}"
else:
full_key = field.key
widget: QWidget
match field.type:
@@ -1095,8 +1112,13 @@ def set_form_data(
):
value = data
else:
if key not in data:
logger_gui.debug("---- Key not in data: %s")
logger_gui.debug("-------- Data: %s", pformat(data))
value = data[key]
logger_gui.debug("---- Key set: %s", key)
set_widget_value(widget, value)
@@ -1184,7 +1206,7 @@ class Grunderfassung_Unternehmen(FlatBaseModel):
Grunderfassung_notiz: str | None
Partnersuche: Grunderfassung_PartnerSuche
Projektrelevanz: Grunderfassung_ProjektrelevanzStatus
Projektrelevanz: Grunderfassung_Projektrelevanz
Kontaktperson: Grunderfassung_Kontaktperson
Stammdaten: Grunderfassung_Stammdaten
WeitereInfos: Grunderfassung_WeitereInfos
@@ -1202,32 +1224,49 @@ class Grunderfassung_PartnerSuche(BaseModel):
kanal_aufmerksamkeit: str | None
class Grunderfassung_ProjektrelevanzStatus(BaseModel):
class Grunderfassung_Projektrelevanz(BaseModel):
model_config = ConfigDict(str_strip_whitespace=True)
status: Grunderfassung_ProjektrelevanzStatus_Status
relevanz: str
foerderperiode: str | None = None
# @field_validator("relevanz", mode="before")
# @classmethod
# def str_to_bool(cls, value: Any) -> Any:
# if isinstance(value, str):
# value = value.strip().lower()
# if value == "ja":
# return True
# elif value == "nein":
# return False
# raise ValueError("Wert muss 'ja', 'nein', True oder False sein.")
# return value
class Grunderfassung_ProjektrelevanzStatus_Status(BaseModel):
model_config = ConfigDict(str_strip_whitespace=True)
# TODO remove
# class Grunderfassung_ProjektrelevanzStatus_Status(BaseModel):
# model_config = ConfigDict(str_strip_whitespace=True)
relevanz: bool
foerderperiode: list[str | None] | None = None
# relevanz: bool
# foerderperiode: list[str | None] | None = None
@field_validator("relevanz", mode="before")
@classmethod
def str_to_bool(cls, value: Any) -> Any:
if isinstance(value, str):
value = value.strip().lower()
# @field_validator("relevanz", mode="before")
# @classmethod
# def str_to_bool(cls, value: Any) -> Any:
# if isinstance(value, str):
# value = value.strip().lower()
if value == "ja":
return True
elif value == "nein":
return False
# if value == "ja":
# return True
# elif value == "nein":
# return False
raise ValueError("Wert muss 'ja', 'nein', True oder False sein.")
# raise ValueError("Wert muss 'ja', 'nein', True oder False sein.")
return value
# return value
class Grunderfassung_Kontaktperson(BaseModel):
@@ -1350,8 +1389,8 @@ class Grunderfassung_Sprachen(BaseModel):
SP_sprache: str | None
SP_niveau: str | None
SP_nachweis: str | None
SP_art_nachweis: str | None
SP_datum_nachweis: datetime.date | None
SP_art_nachweis: str | None = None
SP_datum_nachweis: datetime.date | None = None
class Grunderfassung_SuchWidget(CustomWidget):
@@ -1764,7 +1803,7 @@ class AutoForm(QWidget):
except ValueError:
index = -1
self.current_id = index
logger.debug("Set index to %d", self.current_id)
logger_gui.debug("Set index to %d", self.current_id)
def _disable_save(self) -> None:
self.save_btn.setEnabled(False)
@@ -1808,7 +1847,7 @@ class AutoForm(QWidget):
logger_auto_form.debug("Convert to GUI structure...")
form_data = model.to_gui()
logger_auto_form.debug("Set form data...")
# logger_get_data_auto_form.debug("Form data:\n%s", pformat(form_data))
logger_auto_form.debug("Form data:\n%s", pformat(form_data))
self.set_form_data(form_data)
self.current_id = lookup_id
@@ -1845,7 +1884,7 @@ class AutoForm(QWidget):
# Pydantic detailed error list
for error in e.errors():
logger.error("Error during validation phase:\n%s", pformat(error))
logger_gui.error("Error during validation phase:\n%s", pformat(error))
error_field = str(error["loc"][0])
reason = error["msg"]
@@ -1882,7 +1921,7 @@ class AutoForm(QWidget):
logger_auto_form.info("Data saved successfully")
self.save_clicked_form.emit()
self.reset_form()
# self.reset_form() # TODO check if this behaviour is expected
finally:
# always re-enable save, even if error occurred
self._enable_save()
@@ -2421,6 +2460,7 @@ class DynamicDropdownWidgetOption(QWidget):
value = data[key]
set_widget_value(widget, value)
# TODO need to get the correct index
logger_get_data.debug("Value: %s", value)
if value is None or value != self.trigger_value:
num_subforms = 0
else:
@@ -2435,7 +2475,7 @@ class DynamicDropdownWidgetOption(QWidget):
logger_get_data.debug(">>>>>>>>> Call set_form_data for DynamicDropdown")
logger_get_data.debug("Data before set of subforms:%s", pformat(data))
assert len(self.sub_forms) == num_subforms
assert len(self.sub_forms) == num_subforms, f"{len(self.sub_forms)=}"
if not self.sub_forms:
return
@@ -3223,72 +3263,101 @@ FORM_FIELDS_LANGUAGES = [
),
FormField(
"Nachweis",
FormFieldType.DROPDOWN,
required=False,
key="SP_nachweis",
options=[
("vorhanden", None),
("nicht vorhanden", None),
FormFieldType.DYNAMIC_DROPDOWN_OPTION,
key="",
trigger_value="vorhanden",
children=[
FormField(
"Nachweis",
FormFieldType.DROPDOWN,
required=False,
options=[("vorhanden", None), ("nicht vorhanden", None)],
key="SP_nachweis",
children=[
FormField(
"Art des Nachweises",
FormFieldType.TEXT,
required=False,
key="SP_art_nachweis",
),
FormField(
"Datum des Nachweises",
FormFieldType.DATE,
required=False,
key="SP_datum_nachweis",
),
],
),
],
),
FormField(
"Art des Nachweises (NUR WENN VORHANDEN)",
FormFieldType.TEXT,
required=False,
key="SP_art_nachweis",
),
FormField(
"Datum des Nachweises (NUR WENN VORHANDEN)",
FormFieldType.DATE,
required=False,
key="SP_datum_nachweis",
),
# FormField(
# "Nachweis",
# FormFieldType.DROPDOWN,
# required=False,
# key="SP_nachweis",
# options=[
# ("vorhanden", None),
# ("nicht vorhanden", None),
# ],
# ),
# FormField(
# "Art des Nachweises (NUR WENN VORHANDEN)",
# FormFieldType.TEXT,
# required=False,
# key="SP_art_nachweis",
# ),
# FormField(
# "Datum des Nachweises (NUR WENN VORHANDEN)",
# FormFieldType.DATE,
# required=False,
# key="SP_datum_nachweis",
# ),
]
FORM_FIELDS = [
# FormField(
# "Ersteintrag Datum",
# FormFieldType.TEXT_DATETIME,
# required=False,
# key="Metadaten_erstellung",
# readonly=True,
# ignore_get_data=True,
# ),
# FormField(
# "Aktualisierung Datum",
# FormFieldType.TEXT_DATETIME,
# required=False,
# key="Metadaten_aktualisierung",
# readonly=True,
# ignore_get_data=True,
# ),
# FormField(
# "Aktualisierung Nutzer",
# FormFieldType.TEXT,
# required=False,
# key="Metadaten_nutzer",
# readonly=True,
# ),
# FormField(
# "Fallnummer",
# FormFieldType.TEXT,
# required=True,
# key="Grunderfassung_fallnummer",
# ),
# FormField(
# "Notizen",
# FormFieldType.LONGTEXT,
# required=False,
# key="Grunderfassung_notiz",
# ),
# FormField(
# "Suche",
# FormFieldType.CUSTOM,
# custom_widget="grunderfassung_suche",
# key="Partnersuche",
# children=FORM_FIELDS_SEARCH_HEAD,
# ),
FormField(
"Ersteintrag Datum",
FormFieldType.TEXT_DATETIME,
required=False,
key="Metadaten_erstellung",
readonly=True,
ignore_get_data=True,
),
FormField(
"Aktualisierung Datum",
FormFieldType.TEXT_DATETIME,
required=False,
key="Metadaten_aktualisierung",
readonly=True,
ignore_get_data=True,
),
FormField(
"Aktualisierung Nutzer",
FormFieldType.TEXT,
required=False,
key="Metadaten_nutzer",
readonly=True,
),
FormField(
"Fallnummer",
FormFieldType.TEXT,
required=True,
key="Grunderfassung_fallnummer",
),
FormField(
"Notizen",
FormFieldType.LONGTEXT,
required=False,
key="Grunderfassung_notiz",
),
FormField(
"Suche",
FormFieldType.CUSTOM,
custom_widget="grunderfassung_suche",
key="Partnersuche",
children=FORM_FIELDS_SEARCH_HEAD,
),
FormField(
"Status && Projektrelevanz",
FormFieldType.GROUP,
@@ -3297,7 +3366,7 @@ FORM_FIELDS = [
FormField(
"Projektrelevanz",
FormFieldType.DYNAMIC_DROPDOWN_OPTION,
key="status",
key="",
trigger_value="ja",
children=[
FormField(
@@ -3310,56 +3379,54 @@ FORM_FIELDS = [
FormField(
"Förderperiode", FormFieldType.TEXT, key="foerderperiode"
),
FormField("Feld 2", FormFieldType.TEXT, key="feld_2"),
FormField("Feld 3", FormFieldType.TEXT, key="feld_3"),
],
),
],
),
],
),
# FormField(
# "Daten Kontaktperson",
# FormFieldType.GROUP,
# key="Kontaktperson",
# children=FORM_FIELDS_CONTACT_PERSON,
# ),
# FormField(
# "Stammdaten",
# FormFieldType.GROUP,
# key="Stammdaten",
# children=FORM_FIELDS_MASTER_DATA,
# ),
# FormField(
# "Weitere Informationen",
# FormFieldType.GROUP,
# key="WeitereInfos",
# children=FORM_FIELDS_ADDITIONAL_DATA,
# ),
# FormField(
# "Schulbildung",
# FormFieldType.DYNAMIC_LIST,
# children=FORM_FIELDS_SCHOOL,
# key="Schulbildung",
# ),
# FormField(
# "Studium/Ausbildung",
# FormFieldType.DYNAMIC_LIST,
# children=FORM_FIELDS_HIGHER_EDUCATION,
# key="HoehereBildung",
# ),
# FormField(
# "Arbeitserfahrung",
# FormFieldType.DYNAMIC_LIST,
# children=FORM_FIELDS_WORK_EXPERIENCE,
# key="Arbeitserfahrung",
# ),
# FormField(
# "Sprachkenntnisse",
# FormFieldType.DYNAMIC_LIST,
# children=FORM_FIELDS_LANGUAGES,
# key="Sprachkenntnisse",
# ),
FormField(
"Daten Kontaktperson",
FormFieldType.GROUP,
key="Kontaktperson",
children=FORM_FIELDS_CONTACT_PERSON,
),
FormField(
"Stammdaten",
FormFieldType.GROUP,
key="Stammdaten",
children=FORM_FIELDS_MASTER_DATA,
),
FormField(
"Weitere Informationen",
FormFieldType.GROUP,
key="WeitereInfos",
children=FORM_FIELDS_ADDITIONAL_DATA,
),
FormField(
"Schulbildung",
FormFieldType.DYNAMIC_LIST,
children=FORM_FIELDS_SCHOOL,
key="Schulbildung",
),
FormField(
"Studium/Ausbildung",
FormFieldType.DYNAMIC_LIST,
children=FORM_FIELDS_HIGHER_EDUCATION,
key="HoehereBildung",
),
FormField(
"Arbeitserfahrung",
FormFieldType.DYNAMIC_LIST,
children=FORM_FIELDS_WORK_EXPERIENCE,
key="Arbeitserfahrung",
),
FormField(
"Sprachkenntnisse",
FormFieldType.DYNAMIC_LIST,
children=FORM_FIELDS_LANGUAGES,
key="Sprachkenntnisse",
),
]
CONFIG_GRUNDERFASSUNG_UNTERNEHMEN: Final[AutoFormConfig] = AutoFormConfig(