From ee288a47dc873eb39e698f3aa6ae265c6d2ab2f6 Mon Sep 17 00:00:00 2001 From: foefl Date: Tue, 26 May 2026 13:29:38 +0200 Subject: [PATCH] config based auto-generated form --- prototypes/t_qt_2.py | 87 ++++++++++++++++-------- src/wce_crm/backend/initial_recording.py | 10 +-- 2 files changed, 65 insertions(+), 32 deletions(-) diff --git a/prototypes/t_qt_2.py b/prototypes/t_qt_2.py index 1d42d4b..c0878d6 100644 --- a/prototypes/t_qt_2.py +++ b/prototypes/t_qt_2.py @@ -481,6 +481,39 @@ class CustomForm(Protocol): def validate_form_data(self) -> list[str]: ... +class AutoFormInsert(Protocol): + def __call__( + self, + data: dict[str, Any], + ) -> None: ... + + +class AutoFormUpdate(Protocol): + def __call__( + self, + id_: int, + data: dict[str, Any], + ) -> None: ... + + +class AutoFormGet(Protocol): + def __call__( + self, + id_: int, + ) -> dict[str, Any]: ... + + +@dc.dataclass(slots=True) +class AutoFormConfig: + model: type[FlatBaseModel] + data_insert: AutoFormInsert + data_update: AutoFormUpdate + data_get: AutoFormGet + form_fields: Sequence[FormField] + ignored_keys: Iterable[str] = tuple() + add_buttons: bool = True + + class CustomWidget(QWidget): def __init__( self, @@ -904,12 +937,6 @@ def update_sub_forms( del widget_registry[key] -@dc.dataclass(slots=True) -class FormData: - data: dict[str, Any] - ignored_keys: Iterable[str] - - def get_form_data( widget_registry: WidgetRegistry, filter_keys: Container[str] = tuple(), @@ -1682,11 +1709,10 @@ def search_widgets_by_key( class AutoForm(QWidget): def __init__( self, - form_fields: Sequence[FormField], - add_buttons: bool = True, - ignored_keys: Iterable[str] = tuple(), + cfg: AutoFormConfig, ) -> None: super().__init__() + self.cfg = cfg self.setStyleSheet(""" QGroupBox { font-size: 16px; @@ -1754,7 +1780,7 @@ class AutoForm(QWidget): self.main_layout.addLayout(self.top_level_form_layout) self.top_level_form_layout.setSpacing(10) - self.form_fields = form_fields + self.form_fields = self.cfg.form_fields self.widget_registry: WidgetRegistry = {} _build_ui_recursively( @@ -1764,7 +1790,7 @@ class AutoForm(QWidget): ) # buttons (save and reset) - self.add_buttons = add_buttons + self.add_buttons = self.cfg.add_buttons if self.add_buttons: self.layout_btn = QHBoxLayout() self.main_layout.addLayout(self.layout_btn) @@ -1787,7 +1813,7 @@ class AutoForm(QWidget): self.reset_btn.clicked.connect(self.reset_form) self.layout_btn.addWidget(self.reset_btn) - self.ignored_keys = ignored_keys + # self.ignored_keys = ignored_keys self.current_id: int = -1 # test button # self.main_layout.addSpacing(10) @@ -1824,7 +1850,8 @@ class AutoForm(QWidget): if lookup_id > 0: logger_get_data_auto_form.debug("Load from DB:") - loaded_data = be_init_rec.get_initial_recording(lookup_id) + loaded_data = self.cfg.data_get(lookup_id) + # loaded_data = be_init_rec.get_initial_recording(lookup_id) else: logger_get_data_auto_form.debug("Load from pickled object:") loaded_data = load_pydantic_model_dict_db() @@ -1865,7 +1892,7 @@ class AutoForm(QWidget): logger.debug("------------>>>>>>>>> Call Pydantic") try: - validated_data = Grunderfassung_Unternehmen(**form_data) + validated_data = self.cfg.model(**form_data) # # TODO add user? # logger.debug("%s", pformat(validated_data.model_dump())) except ValidationError as e: @@ -1905,15 +1932,17 @@ class AutoForm(QWidget): "\n\n>>>>>>>>>>>>> Form data with 'exlude' " "(must be saved in the database):\n%s" ), - pformat(validated_data.to_db(exclude=self.ignored_keys)), + pformat(validated_data.to_db(exclude=self.cfg.ignored_keys)), ) - db_data = validated_data.to_db(exclude=self.ignored_keys) + db_data = validated_data.to_db(exclude=self.cfg.ignored_keys) if self.current_id < 0: logger.debug("Insert triggered") - be_init_rec.insert_initial_recording(db_data) + self.cfg.data_insert(db_data) + # be_init_rec.insert_initial_recording(db_data) else: logger.debug("Update triggered") - be_init_rec.update_initial_recording(self.current_id, db_data) + self.cfg.data_update(self.current_id, db_data) + # be_init_rec.update_initial_recording(self.current_id, db_data) logger_get_data.info("Data saved successfully") self.reset_form() @@ -3283,6 +3312,18 @@ FORM_FIELDS = [ ), ] +CONFIG_GRUNDERFASSUNG_UNTERNEHMEN: Final[AutoFormConfig] = AutoFormConfig( + model=Grunderfassung_Unternehmen, + data_insert=be_init_rec.insert_initial_recording, + data_update=be_init_rec.update_initial_recording, + data_get=be_init_rec.get_initial_recording, + ignored_keys=( + "Metadaten_erstellung", + "Metadaten_aktualisierung", + ), + form_fields=FORM_FIELDS, +) + class SearchFormPage(QWidget): back_main_requested = Signal() # Signal für den Zurück-Button @@ -3427,15 +3468,7 @@ class SearchFormPage(QWidget): title.setStyleSheet("font-size: 14px; font-style: italic;") # font-weight: bold; container_layout.addWidget(title) # container_layout.addWidget(MyFormPart(FORM_FIELD_DEF, "Test-Gruppe")) - container_layout.addWidget( - AutoForm( - FORM_FIELDS, - ignored_keys=( - "Metadaten_erstellung", - "Metadaten_aktualisierung", - ), - ) - ) + container_layout.addWidget(AutoForm(cfg=CONFIG_GRUNDERFASSUNG_UNTERNEHMEN)) container_layout.addSpacing(30) diff --git a/src/wce_crm/backend/initial_recording.py b/src/wce_crm/backend/initial_recording.py index 4b8a225..3caceac 100644 --- a/src/wce_crm/backend/initial_recording.py +++ b/src/wce_crm/backend/initial_recording.py @@ -150,12 +150,12 @@ def insert_initial_recording( def update_initial_recording( - erfassung_id: int, + id_: int, data: dict[str, Any], ) -> None: stmt = ( db.grunderfassung_unternehmen.update() - .where(db.grunderfassung_unternehmen.c.erfassung_id == erfassung_id) + .where(db.grunderfassung_unternehmen.c.erfassung_id == id_) .values(data) ) with db.ENGINE.begin() as conn: @@ -163,16 +163,16 @@ def update_initial_recording( def get_initial_recording( - erfassung_id: int, + id_: int, ) -> dict[str, Any]: stmt = db.grunderfassung_unternehmen.select().where( - db.grunderfassung_unternehmen.c.erfassung_id == erfassung_id + db.grunderfassung_unternehmen.c.erfassung_id == id_ ) with db.ENGINE.begin() as conn: ret = conn.execute(stmt) row = ret.fetchone() if row is None: - raise KeyError(f"Database ID {erfassung_id} not found") + raise KeyError(f"Database ID {id_} not found") return row._asdict()