generated from dopt-python/py311
exclude for auto-update fields
This commit is contained in:
@@ -183,8 +183,8 @@ class FlatBaseModel(BaseModel):
|
|||||||
# 1. Die aktuelle Ebene dieses Dictionaries ent-flachen
|
# 1. Die aktuelle Ebene dieses Dictionaries ent-flachen
|
||||||
unflattened_level = {}
|
unflattened_level = {}
|
||||||
for key, value in data.items():
|
for key, value in data.items():
|
||||||
if "__" in key:
|
if COLUMN_SEP in key:
|
||||||
parts = key.split("__")
|
parts = key.split(COLUMN_SEP)
|
||||||
aktuell = unflattened_level
|
aktuell = unflattened_level
|
||||||
for part in parts[:-1]:
|
for part in parts[:-1]:
|
||||||
if part not in aktuell or not isinstance(aktuell[part], dict):
|
if part not in aktuell or not isinstance(aktuell[part], dict):
|
||||||
@@ -219,14 +219,14 @@ class FlatBaseModel(BaseModel):
|
|||||||
|
|
||||||
return final_nested_data
|
return final_nested_data
|
||||||
|
|
||||||
def to_db(self) -> dict[str, Any]:
|
def to_db(self, *args, **kwargs) -> dict[str, Any]:
|
||||||
"""Ausgang für die DB: Flach, Listen sind JSON-Strings."""
|
"""Ausgang für die DB: Flach, Listen sind JSON-Strings."""
|
||||||
nested = super().model_dump()
|
nested = super().model_dump(*args, **kwargs)
|
||||||
return self.__flatten_dict(nested, serialize_lists=True)
|
return self.__flatten_dict(nested, serialize_lists=True)
|
||||||
|
|
||||||
def to_gui(self) -> dict[str, Any]:
|
def to_gui(self, *args, **kwargs) -> dict[str, Any]:
|
||||||
"""Ausgang für die GUI: Flach, aber Listen bleiben Python-Listen."""
|
"""Ausgang für die GUI: Flach, aber Listen bleiben Python-Listen."""
|
||||||
nested = super().model_dump()
|
nested = super().model_dump(*args, **kwargs)
|
||||||
return self.__flatten_dict(nested, serialize_lists=False)
|
return self.__flatten_dict(nested, serialize_lists=False)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -236,7 +236,7 @@ class FlatBaseModel(BaseModel):
|
|||||||
"""Rekursiver Helfer zum Abflachen von Strukturen."""
|
"""Rekursiver Helfer zum Abflachen von Strukturen."""
|
||||||
items = []
|
items = []
|
||||||
for k, v in nested_dict.items():
|
for k, v in nested_dict.items():
|
||||||
new_key = f"{parent_key}__{k}" if parent_key else k
|
new_key = f"{parent_key}{COLUMN_SEP}{k}" if parent_key else k
|
||||||
|
|
||||||
if isinstance(v, dict):
|
if isinstance(v, dict):
|
||||||
items.extend(cls.__flatten_dict(v, new_key, serialize_lists).items())
|
items.extend(cls.__flatten_dict(v, new_key, serialize_lists).items())
|
||||||
@@ -901,11 +901,18 @@ def update_sub_forms(
|
|||||||
del widget_registry[key]
|
del widget_registry[key]
|
||||||
|
|
||||||
|
|
||||||
|
@dc.dataclass(slots=True)
|
||||||
|
class FormData:
|
||||||
|
data: dict[str, Any]
|
||||||
|
ignored_keys: Iterable[str]
|
||||||
|
|
||||||
|
|
||||||
def get_form_data(
|
def get_form_data(
|
||||||
widget_registry: WidgetRegistry,
|
widget_registry: WidgetRegistry,
|
||||||
filter_keys: Container[str] = tuple(),
|
filter_keys: Container[str] = tuple(),
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
raw_data = {}
|
raw_data: dict[str, Any] = {}
|
||||||
|
ignored_keys: list[str] = []
|
||||||
for key, registry_entry in widget_registry.items():
|
for key, registry_entry in widget_registry.items():
|
||||||
value: Any | None = None
|
value: Any | None = None
|
||||||
|
|
||||||
@@ -917,6 +924,7 @@ def get_form_data(
|
|||||||
widget = registry_entry["widget"]
|
widget = registry_entry["widget"]
|
||||||
form_field = registry_entry["form_field"]
|
form_field = registry_entry["form_field"]
|
||||||
if form_field.ignore_get_data:
|
if form_field.ignore_get_data:
|
||||||
|
ignored_keys.append(key)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if isinstance(widget, QLineEdit):
|
if isinstance(widget, QLineEdit):
|
||||||
@@ -1672,6 +1680,7 @@ class AutoForm(QWidget):
|
|||||||
self,
|
self,
|
||||||
form_fields: Sequence[FormField],
|
form_fields: Sequence[FormField],
|
||||||
add_buttons: bool = True,
|
add_buttons: bool = True,
|
||||||
|
ignored_keys: Iterable[str] = tuple(),
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.setStyleSheet("""
|
self.setStyleSheet("""
|
||||||
@@ -1761,6 +1770,7 @@ class AutoForm(QWidget):
|
|||||||
self.reset_btn.clicked.connect(self.reset_form)
|
self.reset_btn.clicked.connect(self.reset_form)
|
||||||
self.layout_btn.addWidget(self.reset_btn)
|
self.layout_btn.addWidget(self.reset_btn)
|
||||||
|
|
||||||
|
self.ignored_keys = ignored_keys
|
||||||
# test button
|
# test button
|
||||||
# self.main_layout.addSpacing(10)
|
# self.main_layout.addSpacing(10)
|
||||||
# self.main_layout.addWidget(self.test_button)
|
# self.main_layout.addWidget(self.test_button)
|
||||||
@@ -1819,7 +1829,7 @@ class AutoForm(QWidget):
|
|||||||
validated_data = Grunderfassung_Unternehmen(**form_data)
|
validated_data = Grunderfassung_Unternehmen(**form_data)
|
||||||
# # TODO remove
|
# # TODO remove
|
||||||
# validated_data.Metadaten_erstellung = datetime.datetime.now()
|
# validated_data.Metadaten_erstellung = datetime.datetime.now()
|
||||||
logger.debug("%s", pformat(validated_data.model_dump()))
|
# logger.debug("%s", pformat(validated_data.model_dump()))
|
||||||
except ValidationError as e:
|
except ValidationError as e:
|
||||||
# catch errors and show them in GUI
|
# catch errors and show them in GUI
|
||||||
fehler_texte = []
|
fehler_texte = []
|
||||||
@@ -1848,9 +1858,17 @@ class AutoForm(QWidget):
|
|||||||
save_pydantic_model_dict_db(validated_data)
|
save_pydantic_model_dict_db(validated_data)
|
||||||
# TODO save data to database
|
# TODO save data to database
|
||||||
logger.info(
|
logger.info(
|
||||||
"\n\n>>>>>>>>>>>>> The following data muste be saved in the database:\n%s",
|
"\n\n>>>>>>>>>>>>> Form data without 'exlude':\n%s",
|
||||||
pformat(validated_data.to_db()),
|
pformat(validated_data.to_db()),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
(
|
||||||
|
"\n\n>>>>>>>>>>>>> Form data with 'exlude' "
|
||||||
|
"(must be saved in the database):\n%s"
|
||||||
|
),
|
||||||
|
pformat(validated_data.to_db(exclude=self.ignored_keys)),
|
||||||
|
)
|
||||||
logger_get_data.info("Data saved successfully")
|
logger_get_data.info("Data saved successfully")
|
||||||
finally:
|
finally:
|
||||||
# always re-enable save, even if error occurred
|
# always re-enable save, even if error occurred
|
||||||
@@ -1985,7 +2003,7 @@ class DynamicListWidget(QWidget):
|
|||||||
|
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
def get_form_data(self):
|
def get_form_data(self) -> list[dict[str, Any]]:
|
||||||
# raw_data = get_form_data(self.widget_registry)
|
# raw_data = get_form_data(self.widget_registry)
|
||||||
# form_data = get_form_data(self.widget_registry)
|
# form_data = get_form_data(self.widget_registry)
|
||||||
# logger_get_data.debug(
|
# logger_get_data.debug(
|
||||||
@@ -1997,6 +2015,10 @@ class DynamicListWidget(QWidget):
|
|||||||
# pprint_registry(sub_form.registry)
|
# pprint_registry(sub_form.registry)
|
||||||
|
|
||||||
form_data = [get_form_data(sub.registry) for sub in self.sub_forms]
|
form_data = [get_form_data(sub.registry) for sub in self.sub_forms]
|
||||||
|
# ignored_keys: list[str] = []
|
||||||
|
# for d in form_data:
|
||||||
|
# ignored_keys.extend(d.ignored_keys)
|
||||||
|
# data = [d.data for d in form_data]
|
||||||
logger_get_data.debug("##################")
|
logger_get_data.debug("##################")
|
||||||
logger_get_data.debug("Form data:\n%s", pformat(form_data))
|
logger_get_data.debug("Form data:\n%s", pformat(form_data))
|
||||||
|
|
||||||
@@ -2168,7 +2190,7 @@ class DynamicDropdownWidget(QWidget):
|
|||||||
|
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
def get_form_data(self):
|
def get_form_data(self) -> dict[str, Any]:
|
||||||
# raw_data = get_form_data(self.widget_registry)
|
# raw_data = get_form_data(self.widget_registry)
|
||||||
form_data = get_form_data(self.widget_registry)
|
form_data = get_form_data(self.widget_registry)
|
||||||
|
|
||||||
@@ -3357,7 +3379,15 @@ class SearchFormPage(QWidget):
|
|||||||
title.setStyleSheet("font-size: 14px; font-style: italic;") # font-weight: bold;
|
title.setStyleSheet("font-size: 14px; font-style: italic;") # font-weight: bold;
|
||||||
container_layout.addWidget(title)
|
container_layout.addWidget(title)
|
||||||
# container_layout.addWidget(MyFormPart(FORM_FIELD_DEF, "Test-Gruppe"))
|
# container_layout.addWidget(MyFormPart(FORM_FIELD_DEF, "Test-Gruppe"))
|
||||||
container_layout.addWidget(AutoForm(FORM_FIELDS))
|
container_layout.addWidget(
|
||||||
|
AutoForm(
|
||||||
|
FORM_FIELDS,
|
||||||
|
ignored_keys=(
|
||||||
|
"Metadaten_erstellung",
|
||||||
|
"Metadaten_aktualisierung",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
container_layout.addSpacing(30)
|
container_layout.addSpacing(30)
|
||||||
|
|
||||||
|
|||||||
6
src/wce_crm/constants.py
Normal file
6
src/wce_crm/constants.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Final
|
||||||
|
|
||||||
|
LIB_PATH: Final[Path] = Path(__file__).parent
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import datetime
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
from datetime import datetime
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import polars as pl
|
import polars as pl
|
||||||
@@ -26,7 +26,7 @@ class SafeDateTime(TypeDecorator):
|
|||||||
clean_value = re.sub(r"[a-zA-Z]+$", "", value).replace(",", ".")
|
clean_value = re.sub(r"[a-zA-Z]+$", "", value).replace(",", ".")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return datetime.fromisoformat(clean_value)
|
return datetime.datetime.fromisoformat(clean_value)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
# Fallback if it's still weird
|
# Fallback if it's still weird
|
||||||
return None
|
return None
|
||||||
@@ -302,6 +302,20 @@ grunderfassung_unternehmen: sql.Table = Table(
|
|||||||
"grunderfassung_unternehmen",
|
"grunderfassung_unternehmen",
|
||||||
md_main,
|
md_main,
|
||||||
Column("erfassung_id", sql.Integer, nullable=False, unique=True, autoincrement=True),
|
Column("erfassung_id", sql.Integer, nullable=False, unique=True, autoincrement=True),
|
||||||
|
Column(
|
||||||
|
"Metadaten_erstellung",
|
||||||
|
sql.DateTime(timezone=True),
|
||||||
|
nullable=True,
|
||||||
|
default=lambda: datetime.datetime.now(datetime.UTC),
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
"Metadaten_aktualisierung",
|
||||||
|
sql.DateTime(timezone=True),
|
||||||
|
nullable=True,
|
||||||
|
default=lambda: datetime.datetime.now(datetime.UTC),
|
||||||
|
onupdate=lambda: datetime.datetime.now(datetime.UTC),
|
||||||
|
),
|
||||||
|
Column("Metadaten_nutzer", sql.String(20), nullable=True),
|
||||||
Column("Arbeitserfahrung", sql.Text, nullable=True),
|
Column("Arbeitserfahrung", sql.Text, nullable=True),
|
||||||
Column("Grunderfassung_fallnummer", sql.Text, nullable=True),
|
Column("Grunderfassung_fallnummer", sql.Text, nullable=True),
|
||||||
Column("Grunderfassung_notiz", sql.Text, nullable=True),
|
Column("Grunderfassung_notiz", sql.Text, nullable=True),
|
||||||
@@ -316,9 +330,8 @@ grunderfassung_unternehmen: sql.Table = Table(
|
|||||||
Column("Kontaktperson__KP_name_partner", sql.Text, nullable=True),
|
Column("Kontaktperson__KP_name_partner", sql.Text, nullable=True),
|
||||||
Column("Kontaktperson__KP_titel", sql.Text, nullable=True),
|
Column("Kontaktperson__KP_titel", sql.Text, nullable=True),
|
||||||
Column("Kontaktperson__KP_vorname", sql.Text, nullable=True),
|
Column("Kontaktperson__KP_vorname", sql.Text, nullable=True),
|
||||||
Column("Metadaten_aktualisierung", sql.Text, nullable=True),
|
# Column("Metadaten_aktualisierung", sql.Text, nullable=True),
|
||||||
Column("Metadaten_erstellung", sql.Text, nullable=True),
|
# Column("Metadaten_erstellung", sql.Text, nullable=True),
|
||||||
Column("Metadaten_nutzer", sql.String(20), nullable=True),
|
|
||||||
Column("Partnersuche__kanal_aufmerksamkeit", sql.Text, nullable=True),
|
Column("Partnersuche__kanal_aufmerksamkeit", sql.Text, nullable=True),
|
||||||
Column("Partnersuche__person_suche", sql.Text, nullable=True),
|
Column("Partnersuche__person_suche", sql.Text, nullable=True),
|
||||||
Column("Partnersuche__un_suche", sql.Text, nullable=True),
|
Column("Partnersuche__un_suche", sql.Text, nullable=True),
|
||||||
|
|||||||
Reference in New Issue
Block a user