generated from dopt-python/py311
better automatic export, prepare data validation for backend export
This commit is contained in:
44
pdm.lock
generated
44
pdm.lock
generated
@@ -5,7 +5,7 @@
|
|||||||
groups = ["default", "dev", "lint", "nb", "tests"]
|
groups = ["default", "dev", "lint", "nb", "tests"]
|
||||||
strategy = ["inherit_metadata"]
|
strategy = ["inherit_metadata"]
|
||||||
lock_version = "4.5.0"
|
lock_version = "4.5.0"
|
||||||
content_hash = "sha256:ae1cefda69bbf1f63d7c5d8c8b19f5dae8525f42c8550e9a44b186d7f57fe7bc"
|
content_hash = "sha256:611d8f56a617297efdc1daedd4a2cd7c21e58bc0a57288a8f230db9015a6adef"
|
||||||
|
|
||||||
[[metadata.targets]]
|
[[metadata.targets]]
|
||||||
requires_python = ">=3.11,<3.14"
|
requires_python = ">=3.11,<3.14"
|
||||||
@@ -951,6 +951,17 @@ files = [
|
|||||||
{file = "distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d"},
|
{file = "distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dnspython"
|
||||||
|
version = "2.8.0"
|
||||||
|
requires_python = ">=3.10"
|
||||||
|
summary = "DNS toolkit"
|
||||||
|
groups = ["default"]
|
||||||
|
files = [
|
||||||
|
{file = "dnspython-2.8.0-py3-none-any.whl", hash = "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af"},
|
||||||
|
{file = "dnspython-2.8.0.tar.gz", hash = "sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "docutils"
|
name = "docutils"
|
||||||
version = "0.22.4"
|
version = "0.22.4"
|
||||||
@@ -976,6 +987,21 @@ files = [
|
|||||||
{file = "dopt_basics-0.2.4.tar.gz", hash = "sha256:c21fbe183bec5eab4cfd1404e10baca670035801596960822d0019e6e885983f"},
|
{file = "dopt_basics-0.2.4.tar.gz", hash = "sha256:c21fbe183bec5eab4cfd1404e10baca670035801596960822d0019e6e885983f"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "email-validator"
|
||||||
|
version = "2.3.0"
|
||||||
|
requires_python = ">=3.8"
|
||||||
|
summary = "A robust email address syntax and deliverability validation library."
|
||||||
|
groups = ["default"]
|
||||||
|
dependencies = [
|
||||||
|
"dnspython>=2.0.0",
|
||||||
|
"idna>=2.0.0",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "email_validator-2.3.0-py3-none-any.whl", hash = "sha256:80f13f623413e6b197ae73bb10bf4eb0908faf509ad8362c5edeb0be7fd450b4"},
|
||||||
|
{file = "email_validator-2.3.0.tar.gz", hash = "sha256:9fc05c37f2f6cf439ff414f8fc46d917929974a82244c20eb10231ba60c54426"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "execnet"
|
name = "execnet"
|
||||||
version = "2.1.2"
|
version = "2.1.2"
|
||||||
@@ -2781,6 +2807,22 @@ files = [
|
|||||||
{file = "pydantic_settings-2.13.1.tar.gz", hash = "sha256:b4c11847b15237fb0171e1462bf540e294affb9b86db4d9aa5c01730bdbe4025"},
|
{file = "pydantic_settings-2.13.1.tar.gz", hash = "sha256:b4c11847b15237fb0171e1462bf540e294affb9b86db4d9aa5c01730bdbe4025"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pydantic"
|
||||||
|
version = "2.13.4"
|
||||||
|
extras = ["email"]
|
||||||
|
requires_python = ">=3.9"
|
||||||
|
summary = "Data validation using Python type hints"
|
||||||
|
groups = ["default"]
|
||||||
|
dependencies = [
|
||||||
|
"email-validator>=2.0.0",
|
||||||
|
"pydantic==2.13.4",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba"},
|
||||||
|
{file = "pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pygments"
|
name = "pygments"
|
||||||
version = "2.20.0"
|
version = "2.20.0"
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import copy
|
||||||
import dataclasses as dc
|
import dataclasses as dc
|
||||||
|
import datetime
|
||||||
import enum
|
import enum
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
@@ -8,9 +10,10 @@ import time
|
|||||||
import uuid
|
import uuid
|
||||||
from collections.abc import Sequence
|
from collections.abc import Sequence
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
from typing import Any, Protocol, TypeAlias, TypedDict
|
from typing import Annotated, Any, Protocol, TypeAlias, TypedDict
|
||||||
|
|
||||||
import babel
|
import babel
|
||||||
|
from pydantic import BaseModel, ConfigDict, EmailStr, Field, ValidationError, field_validator
|
||||||
from PySide6.QtCore import QDate, QModelIndex, QStringListModel, Qt, QTimer, Signal
|
from PySide6.QtCore import QDate, QModelIndex, QStringListModel, Qt, QTimer, Signal
|
||||||
from PySide6.QtGui import QAction, QStandardItem, QStandardItemModel
|
from PySide6.QtGui import QAction, QStandardItem, QStandardItemModel
|
||||||
from PySide6.QtWidgets import (
|
from PySide6.QtWidgets import (
|
||||||
@@ -83,7 +86,137 @@ def get_country_list_german() -> CountryList:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_list_germany_states() -> CountryList:
|
||||||
|
states: list[tuple[str, str]] = []
|
||||||
|
short_code_to_name: dict[str, str] = {}
|
||||||
|
|
||||||
|
STATE_LIST: list[tuple[str, str]] = [
|
||||||
|
("Bayern", "BY"),
|
||||||
|
("Niedersachen", "NI"),
|
||||||
|
("Baden-Württemberg", "BW"),
|
||||||
|
("Berlin", "BE"),
|
||||||
|
("Brandenburg", "BB"),
|
||||||
|
("Bremen", "HB"),
|
||||||
|
("Hamburg", "HH"),
|
||||||
|
("Hessen", "HE"),
|
||||||
|
("Mecklenburg", "MV"),
|
||||||
|
("Nordrhein-Westfalen", "NW"),
|
||||||
|
("Rheinland-Pfalz", "RP"),
|
||||||
|
("Saarland", "SL"),
|
||||||
|
("Sachsen", "SN"),
|
||||||
|
("Sachsen-Anhalt", "ST"),
|
||||||
|
("Schleswig-Holstein", "SH"),
|
||||||
|
("Thüringen", "TH"),
|
||||||
|
]
|
||||||
|
STATE_LIST.sort(key=lambda x: x[1])
|
||||||
|
|
||||||
|
for iso_code, country_name in STATE_LIST:
|
||||||
|
states.append((country_name, iso_code))
|
||||||
|
short_code_to_name[iso_code] = country_name
|
||||||
|
|
||||||
|
return CountryList(
|
||||||
|
iso_to_country=short_code_to_name,
|
||||||
|
for_dropdown=tuple(states),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
COUNTRY_LIST = get_country_list_german()
|
COUNTRY_LIST = get_country_list_german()
|
||||||
|
GERMAN_STATE_LIST = get_country_list_german()
|
||||||
|
|
||||||
|
|
||||||
|
def pprint_registry(widget_registry: WidgetRegistry) -> None:
|
||||||
|
print("---\n\n>>> Widget registry:")
|
||||||
|
for key, entry in widget_registry.items():
|
||||||
|
print(f"Key: {key}")
|
||||||
|
print(f"\twidget: {entry['widget']}")
|
||||||
|
print(f"\tfield key: {entry['form_field'].key}")
|
||||||
|
print(f"\tfield type: {entry['form_field'].type}")
|
||||||
|
|
||||||
|
|
||||||
|
class Grunderfassung_Unternehmen(BaseModel):
|
||||||
|
Projektrelevanz: Grunderfassung_Projektrelevanz
|
||||||
|
Kontaktperson: Grunderfassung_Kontaktperson
|
||||||
|
Stammdaten: Grunderfassung_Stammdaten
|
||||||
|
|
||||||
|
|
||||||
|
class Grunderfassung_Projektrelevanz(BaseModel):
|
||||||
|
model_config = ConfigDict(str_strip_whitespace=True)
|
||||||
|
|
||||||
|
Projektrelevanz_relevanz: bool
|
||||||
|
|
||||||
|
@field_validator("Projektrelevanz_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_Kontaktperson(BaseModel):
|
||||||
|
model_config = ConfigDict(str_strip_whitespace=True)
|
||||||
|
|
||||||
|
KP_name_partner: str | None
|
||||||
|
KP_titel: str | None
|
||||||
|
KP_anrede_anschrift: str | None
|
||||||
|
KP_name: str | None
|
||||||
|
KP_vorname: str | None
|
||||||
|
KP_festnetznummer: str | None
|
||||||
|
KP_mobilfunknummer: str | None
|
||||||
|
KP_email: EmailStr | None
|
||||||
|
KP_funktion_beziehung: str | None
|
||||||
|
KP_adresse: str | None
|
||||||
|
|
||||||
|
|
||||||
|
ValidAge = Annotated[int, Field(ge=0, le=99)]
|
||||||
|
|
||||||
|
|
||||||
|
class Grunderfassung_Stammdaten(BaseModel):
|
||||||
|
model_config = ConfigDict(str_strip_whitespace=True)
|
||||||
|
|
||||||
|
Stammdaten_titel: str | None
|
||||||
|
Stammdaten_anrede_anschrift: str
|
||||||
|
Stammdaten_name: str
|
||||||
|
Stammdaten_vorname: str | None
|
||||||
|
Stammdaten_geburtsdatum: datetime.date | None
|
||||||
|
Stammdaten_herkunftsland: str
|
||||||
|
Stammdaten_staatsangehoerigkeit: str | None
|
||||||
|
Stammdaten_rueckkehrer: bool | None
|
||||||
|
Stammdaten_aufenthaltsort: str | None
|
||||||
|
Stammdaten_strasse: str | None
|
||||||
|
Stammdaten_hausnummer: str | None
|
||||||
|
Stammdaten_PLZ: str | None
|
||||||
|
Stammdaten_ort: str | None
|
||||||
|
Stammdaten_bundesland: str | None
|
||||||
|
Stammdaten_land: str | None
|
||||||
|
Stammdaten_festnetznummer: str | None
|
||||||
|
Stammdaten_mobilfunknummer: str | None
|
||||||
|
Stammdaten_email: EmailStr | None
|
||||||
|
Stammdaten_familienstand: str | None
|
||||||
|
Stammdaten_anzahl_kinder: int | None
|
||||||
|
Stammdaten_alter_kinder: list[ValidAge] = Field(default_factory=list)
|
||||||
|
|
||||||
|
@field_validator("Stammdaten_rueckkehrer", 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 CompanyForm_Search(QWidget):
|
class CompanyForm_Search(QWidget):
|
||||||
@@ -302,6 +435,7 @@ class FormFieldType(enum.StrEnum):
|
|||||||
DROPDOWN = enum.auto()
|
DROPDOWN = enum.auto()
|
||||||
EXTENDED_DROPDOWN = enum.auto()
|
EXTENDED_DROPDOWN = enum.auto()
|
||||||
DYNAMIC_LIST = enum.auto()
|
DYNAMIC_LIST = enum.auto()
|
||||||
|
DYNAMIC_DROPDOWN = enum.auto()
|
||||||
|
|
||||||
|
|
||||||
@dc.dataclass(slots=True)
|
@dc.dataclass(slots=True)
|
||||||
@@ -334,6 +468,7 @@ class FormField:
|
|||||||
dropdown_options: Sequence[DropdownOption] = dc.field(default=tuple(), init=False)
|
dropdown_options: Sequence[DropdownOption] = dc.field(default=tuple(), init=False)
|
||||||
key: str = ""
|
key: str = ""
|
||||||
tooltip: str = ""
|
tooltip: str = ""
|
||||||
|
init_label: str = dc.field(init=False)
|
||||||
|
|
||||||
def __post_init__(
|
def __post_init__(
|
||||||
self,
|
self,
|
||||||
@@ -343,6 +478,7 @@ class FormField:
|
|||||||
self.key = str(uuid.uuid4())
|
self.key = str(uuid.uuid4())
|
||||||
|
|
||||||
self.label = self.label.strip()
|
self.label = self.label.strip()
|
||||||
|
self.init_label = self.label.replace("*", "").replace(":", "")
|
||||||
if not self.label.endswith(":") and self.type is not FormFieldType.GROUP:
|
if not self.label.endswith(":") and self.type is not FormFieldType.GROUP:
|
||||||
self.label += ":"
|
self.label += ":"
|
||||||
if self.required:
|
if self.required:
|
||||||
@@ -361,6 +497,32 @@ class FormField:
|
|||||||
for child in self.children:
|
for child in self.children:
|
||||||
child.parent = self
|
child.parent = self
|
||||||
|
|
||||||
|
def enhanced_label(
|
||||||
|
self,
|
||||||
|
add_text: str,
|
||||||
|
) -> str:
|
||||||
|
enhanced_label = self.init_label + f" {add_text}"
|
||||||
|
if not enhanced_label.endswith(":") and self.type is not FormFieldType.GROUP:
|
||||||
|
enhanced_label += ":"
|
||||||
|
if self.required:
|
||||||
|
enhanced_label += "*"
|
||||||
|
|
||||||
|
return enhanced_label
|
||||||
|
|
||||||
|
|
||||||
|
def enhanced_label(
|
||||||
|
base_label: str,
|
||||||
|
add_text: str,
|
||||||
|
add_colon: bool = False,
|
||||||
|
) -> str:
|
||||||
|
label = base_label.strip().replace("*", "").replace(":", "")
|
||||||
|
if add_text:
|
||||||
|
label = label + f" {add_text}"
|
||||||
|
if add_colon and not label.endswith(":"):
|
||||||
|
label += ":"
|
||||||
|
|
||||||
|
return label
|
||||||
|
|
||||||
|
|
||||||
class WidgetRegistryEntry(TypedDict):
|
class WidgetRegistryEntry(TypedDict):
|
||||||
widget: QWidget
|
widget: QWidget
|
||||||
@@ -475,7 +637,7 @@ FORM_FIELDS_CONTACT_PERSON = [
|
|||||||
FormField(
|
FormField(
|
||||||
"Name Unternehmen/Netzwerkpartner (pre-filled von Suche)",
|
"Name Unternehmen/Netzwerkpartner (pre-filled von Suche)",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
key="t1",
|
key="KP_name_partner",
|
||||||
required=False,
|
required=False,
|
||||||
placeholder="Text wird nach gewähltem Unternehmen angezeigt",
|
placeholder="Text wird nach gewähltem Unternehmen angezeigt",
|
||||||
readonly=True,
|
readonly=True,
|
||||||
@@ -483,7 +645,7 @@ FORM_FIELDS_CONTACT_PERSON = [
|
|||||||
FormField(
|
FormField(
|
||||||
"Titel",
|
"Titel",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
key="t2",
|
key="KP_titel",
|
||||||
required=False,
|
required=False,
|
||||||
tooltip=(
|
tooltip=(
|
||||||
"* nur wenn anrufende Person oder kontaktaufnehmende Person "
|
"* nur wenn anrufende Person oder kontaktaufnehmende Person "
|
||||||
@@ -493,49 +655,49 @@ FORM_FIELDS_CONTACT_PERSON = [
|
|||||||
FormField(
|
FormField(
|
||||||
"Anrede_Anschrift",
|
"Anrede_Anschrift",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
key="t3",
|
key="KP_anrede_anschrift",
|
||||||
required=True,
|
required=True,
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"Name",
|
"Name",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
key="t4",
|
key="KP_name",
|
||||||
required=True,
|
required=True,
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"Vorname",
|
"Vorname",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
key="t5",
|
key="KP_vorname",
|
||||||
required=False,
|
required=False,
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"Festnetznummer",
|
"Festnetznummer",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
key="t6",
|
key="KP_festnetznummer",
|
||||||
required=False,
|
required=False,
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"Mobilfunknummer",
|
"Mobilfunknummer",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
key="t7",
|
key="KP_mobilfunknummer",
|
||||||
required=False,
|
required=False,
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"E-Mail",
|
"E-Mail",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
key="t8",
|
key="KP_email",
|
||||||
required=False,
|
required=False,
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"Funktion/Beziehung zur beratenden Person",
|
"Funktion/Beziehung zur beratenden Person",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
key="t9",
|
key="KP_funktion_beziehung",
|
||||||
required=False,
|
required=False,
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"Adresse",
|
"Adresse",
|
||||||
FormFieldType.LONGTEXT,
|
FormFieldType.LONGTEXT,
|
||||||
key="t10",
|
key="KP_adresse",
|
||||||
required=False,
|
required=False,
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
@@ -544,6 +706,7 @@ FORM_FIELDS_MASTER_DATA = [
|
|||||||
FormField(
|
FormField(
|
||||||
"Titel",
|
"Titel",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
|
key="Stammdaten_titel",
|
||||||
required=False,
|
required=False,
|
||||||
tooltip=(
|
tooltip=(
|
||||||
"* nur wenn anrufende Person oder kontaktaufnehmende Person "
|
"* nur wenn anrufende Person oder kontaktaufnehmende Person "
|
||||||
@@ -553,21 +716,25 @@ FORM_FIELDS_MASTER_DATA = [
|
|||||||
FormField(
|
FormField(
|
||||||
"Anrede",
|
"Anrede",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
|
key="Stammdaten_anrede_anschrift",
|
||||||
required=True,
|
required=True,
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"Name",
|
"Name",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
|
key="Stammdaten_name",
|
||||||
required=True,
|
required=True,
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"Vorname",
|
"Vorname",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
|
key="Stammdaten_vorname",
|
||||||
required=False,
|
required=False,
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"Geburtsdatum",
|
"Geburtsdatum",
|
||||||
FormFieldType.DATE,
|
FormFieldType.DATE,
|
||||||
|
key="Stammdaten_geburtsdatum",
|
||||||
required=False,
|
required=False,
|
||||||
tooltip=(
|
tooltip=(
|
||||||
"* Wichtig zu erfragen, da u.a. Mindestgehaltsschwelle davon abhängt "
|
"* Wichtig zu erfragen, da u.a. Mindestgehaltsschwelle davon abhängt "
|
||||||
@@ -576,21 +743,26 @@ FORM_FIELDS_MASTER_DATA = [
|
|||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"Herkunftsland",
|
"Herkunftsland",
|
||||||
FormFieldType.DROPDOWN,
|
FormFieldType.EXTENDED_DROPDOWN,
|
||||||
|
key="Stammdaten_herkunftsland",
|
||||||
required=True,
|
required=True,
|
||||||
options=[("LÄNDERLISTE NOCH ZU ERGÄNZEN", None)],
|
placeholder="Suche...",
|
||||||
|
options=COUNTRY_LIST.for_dropdown,
|
||||||
tooltip=("* Wichtig zu erfragen aufgrund eventueller EU-Freizügigkeitsregelung"),
|
tooltip=("* Wichtig zu erfragen aufgrund eventueller EU-Freizügigkeitsregelung"),
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"Staatsangehörigkeit",
|
"Staatsangehörigkeit",
|
||||||
FormFieldType.DROPDOWN,
|
FormFieldType.EXTENDED_DROPDOWN,
|
||||||
|
key="Stammdaten_herkunftsland",
|
||||||
required=False,
|
required=False,
|
||||||
options=[("LÄNDERLISTE NOCH ZU ERGÄNZEN", None)],
|
placeholder="Suche...",
|
||||||
|
options=COUNTRY_LIST.for_dropdown,
|
||||||
tooltip=("* Wichtig zu erfragen aufgrund eventueller EU-Freizügigkeitsregelung"),
|
tooltip=("* Wichtig zu erfragen aufgrund eventueller EU-Freizügigkeitsregelung"),
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"Rückkehrer",
|
"Rückkehrer",
|
||||||
FormFieldType.DROPDOWN,
|
FormFieldType.DROPDOWN,
|
||||||
|
key="Stammdaten_rueckkehrer",
|
||||||
required=False,
|
required=False,
|
||||||
options=[("ja", None), ("nein", None)],
|
options=[("ja", None), ("nein", None)],
|
||||||
tooltip=("* Wichtig zu erfragen aufgrund eventueller EU-Freizügigkeitsregelung"),
|
tooltip=("* Wichtig zu erfragen aufgrund eventueller EU-Freizügigkeitsregelung"),
|
||||||
@@ -598,34 +770,40 @@ FORM_FIELDS_MASTER_DATA = [
|
|||||||
FormField(
|
FormField(
|
||||||
"Wo befindet sich die Person?",
|
"Wo befindet sich die Person?",
|
||||||
FormFieldType.DROPDOWN,
|
FormFieldType.DROPDOWN,
|
||||||
|
key="Stammdaten_aufenthaltsort",
|
||||||
required=True,
|
required=True,
|
||||||
options=[("Inland", None), ("Ausland EU/EWR", None), ("Ausland Drittstaat", None)],
|
options=[("Inland", None), ("Ausland EU/EWR", None), ("Ausland Drittstaat", None)],
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"Straße",
|
"Straße",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
|
key="Stammdaten_strasse",
|
||||||
required=False,
|
required=False,
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"Hausnummer",
|
"Hausnummer",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
|
key="Stammdaten_hausnummer",
|
||||||
required=False,
|
required=False,
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"PLZ",
|
"PLZ",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
|
key="Stammdaten_PLZ",
|
||||||
required=False,
|
required=False,
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"Ort",
|
"Ort",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
|
key="Stammdaten_ort",
|
||||||
required=False,
|
required=False,
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"Bundesland",
|
"Bundesland",
|
||||||
FormFieldType.DROPDOWN,
|
FormFieldType.DROPDOWN,
|
||||||
|
key="Stammdaten_bundesland",
|
||||||
required=False,
|
required=False,
|
||||||
options=[("BUNDESLÄNDER NOCH ZU ERGÄNZEN", None)],
|
options=GERMAN_STATE_LIST.for_dropdown,
|
||||||
tooltip=(
|
tooltip=(
|
||||||
"nur wenn Inland angegeben und die Angabe zieht es in keine Dokumente "
|
"nur wenn Inland angegeben und die Angabe zieht es in keine Dokumente "
|
||||||
"rüber! Liste Bundesländer verwenden"
|
"rüber! Liste Bundesländer verwenden"
|
||||||
@@ -634,35 +812,63 @@ FORM_FIELDS_MASTER_DATA = [
|
|||||||
FormField(
|
FormField(
|
||||||
"Land",
|
"Land",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
|
key="Stammdaten_land",
|
||||||
required=False,
|
required=False,
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"Festnetznummer",
|
"Festnetznummer",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
|
key="Stammdaten_festnetznummer",
|
||||||
required=False,
|
required=False,
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"Mobilfunknummer",
|
"Mobilfunknummer",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
|
key="Stammdaten_mobilfunknummer",
|
||||||
required=False,
|
required=False,
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"E-Mail",
|
"E-Mail",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
|
key="Stammdaten_email",
|
||||||
required=False,
|
required=False,
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"Familienstand",
|
"Familienstand",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
|
key="Stammdaten_familienstand",
|
||||||
required=False,
|
required=False,
|
||||||
tooltip="* Wichtig zu erfragen aufgrund Lebensunterhaltssicherung",
|
tooltip="* Wichtig zu erfragen aufgrund Lebensunterhaltssicherung",
|
||||||
),
|
),
|
||||||
|
# FormField(
|
||||||
|
# "Anzahl Kinder",
|
||||||
|
# FormFieldType.DYNAMIC_DROPDOWN,
|
||||||
|
# key="Stammdaten_anzahl_kinder",
|
||||||
|
# required=False,
|
||||||
|
# options=[(str(x), None) for x in range(11)],
|
||||||
|
# tooltip="* Wichtig zu erfragen aufgrund Lebensunterhaltssicherung",
|
||||||
|
# ),
|
||||||
|
FormField(
|
||||||
|
"Anzahl Kinder",
|
||||||
|
FormFieldType.DYNAMIC_DROPDOWN,
|
||||||
|
required=False,
|
||||||
|
tooltip="* Wichtig zu erfragen aufgrund Lebensunterhaltssicherung",
|
||||||
|
key="Stammdaten_anzahl_kinder",
|
||||||
|
children=[
|
||||||
FormField(
|
FormField(
|
||||||
"Anzahl Kinder",
|
"Anzahl Kinder",
|
||||||
FormFieldType.DROPDOWN,
|
FormFieldType.DROPDOWN,
|
||||||
required=False,
|
required=False,
|
||||||
options=[(str(x), None) for x in range(11)],
|
options=[(str(x), None) for x in range(11)],
|
||||||
tooltip="* Wichtig zu erfragen aufgrund Lebensunterhaltssicherung",
|
tooltip="* Wichtig zu erfragen aufgrund Lebensunterhaltssicherung",
|
||||||
|
key="Stammdaten_anzahl_kinder",
|
||||||
|
children=[
|
||||||
|
FormField(
|
||||||
|
"Alter Kind", FormFieldType.TEXT, key="Stammdaten_alter_kinder"
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -736,25 +942,21 @@ FORM_FIELDS_ADDITIONAL_DATA = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
FORM_FIELDS_SCHOOL = [
|
FORM_FIELDS_SCHOOL = [
|
||||||
|
FormField("Abschluss", FormFieldType.TEXT, required=False, key="abschluss"),
|
||||||
FormField(
|
FormField(
|
||||||
"Abschluss",
|
"Abschlussgrad laut Dokument", FormFieldType.TEXT, required=False, key="abschlussgrad"
|
||||||
FormFieldType.TEXT,
|
|
||||||
required=True,
|
|
||||||
),
|
|
||||||
FormField(
|
|
||||||
"Abschlussgrad laut Dokument",
|
|
||||||
FormFieldType.TEXT,
|
|
||||||
required=False,
|
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"Schule",
|
"Schule",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
required=False,
|
required=False,
|
||||||
|
key="schule",
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"Ort",
|
"Ort",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
required=False,
|
required=False,
|
||||||
|
key="ort",
|
||||||
),
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"Land",
|
"Land",
|
||||||
@@ -764,15 +966,12 @@ FORM_FIELDS_SCHOOL = [
|
|||||||
placeholder="Suche...",
|
placeholder="Suche...",
|
||||||
options=COUNTRY_LIST.for_dropdown,
|
options=COUNTRY_LIST.for_dropdown,
|
||||||
),
|
),
|
||||||
FormField(
|
FormField("Abschlussjahr", FormFieldType.TEXT, required=False, key="abschlussjahr"),
|
||||||
"Abschlussjahr",
|
|
||||||
FormFieldType.TEXT,
|
|
||||||
required=False,
|
|
||||||
),
|
|
||||||
FormField(
|
FormField(
|
||||||
"Bemerkungsfeld",
|
"Bemerkungsfeld",
|
||||||
FormFieldType.TEXT,
|
FormFieldType.TEXT,
|
||||||
required=False,
|
required=False,
|
||||||
|
key="bemerkung",
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -946,12 +1145,12 @@ FORM_FIELDS = [
|
|||||||
FormField(
|
FormField(
|
||||||
"Status && Projektrelevanz",
|
"Status && Projektrelevanz",
|
||||||
FormFieldType.GROUP,
|
FormFieldType.GROUP,
|
||||||
key="state_relevance",
|
key="Projektrelevanz",
|
||||||
children=[
|
children=[
|
||||||
FormField(
|
FormField(
|
||||||
"Projektrelevanz",
|
"Projektrelevanz",
|
||||||
FormFieldType.DROPDOWN,
|
FormFieldType.DROPDOWN,
|
||||||
key="projektrelevanz",
|
key="Projektrelevanz_relevanz",
|
||||||
required=True,
|
required=True,
|
||||||
options=[("ja", None), ("nein", None)],
|
options=[("ja", None), ("nein", None)],
|
||||||
),
|
),
|
||||||
@@ -960,30 +1159,57 @@ FORM_FIELDS = [
|
|||||||
FormField(
|
FormField(
|
||||||
"Daten Kontaktperson",
|
"Daten Kontaktperson",
|
||||||
FormFieldType.GROUP,
|
FormFieldType.GROUP,
|
||||||
key="data_contact_person",
|
key="Kontaktperson",
|
||||||
children=FORM_FIELDS_CONTACT_PERSON,
|
children=FORM_FIELDS_CONTACT_PERSON,
|
||||||
),
|
),
|
||||||
|
FormField(
|
||||||
|
"Stammdaten",
|
||||||
|
FormFieldType.GROUP,
|
||||||
|
key="Stammdaten",
|
||||||
|
children=FORM_FIELDS_MASTER_DATA,
|
||||||
|
),
|
||||||
FormField(
|
FormField(
|
||||||
"Schulbildung",
|
"Schulbildung",
|
||||||
FormFieldType.DYNAMIC_LIST,
|
FormFieldType.DYNAMIC_LIST,
|
||||||
children=FORM_FIELDS_SCHOOL,
|
children=FORM_FIELDS_SCHOOL,
|
||||||
key="Schulbildung",
|
key="Schulbildung",
|
||||||
),
|
),
|
||||||
FormField(
|
# FormField(
|
||||||
"Test Länderauswahl",
|
# "Test Länderauswahl",
|
||||||
FormFieldType.GROUP,
|
# FormFieldType.GROUP,
|
||||||
key="countries",
|
# key="countries",
|
||||||
children=[
|
# children=[
|
||||||
FormField(
|
# FormField(
|
||||||
"Länderauswahl",
|
# "Länderauswahl",
|
||||||
FormFieldType.EXTENDED_DROPDOWN,
|
# FormFieldType.EXTENDED_DROPDOWN,
|
||||||
key="country",
|
# key="country",
|
||||||
required=True,
|
# required=True,
|
||||||
placeholder="Suche...",
|
# placeholder="Suche...",
|
||||||
options=COUNTRY_LIST.for_dropdown,
|
# options=COUNTRY_LIST.for_dropdown,
|
||||||
),
|
# ),
|
||||||
],
|
# ],
|
||||||
),
|
# ),
|
||||||
|
# FormField(
|
||||||
|
# "Anzahl Kinder (dynamischer Dropdown)",
|
||||||
|
# FormFieldType.DYNAMIC_DROPDOWN,
|
||||||
|
# required=False,
|
||||||
|
# options=[(str(x), None) for x in range(11)],
|
||||||
|
# tooltip="* Wichtig zu erfragen aufgrund Lebensunterhaltssicherung",
|
||||||
|
# key="DynamicDropdown",
|
||||||
|
# children=[
|
||||||
|
# FormField(
|
||||||
|
# "Anzahl Kinder",
|
||||||
|
# FormFieldType.DROPDOWN,
|
||||||
|
# required=False,
|
||||||
|
# options=[(str(x), None) for x in range(11)],
|
||||||
|
# tooltip="* Wichtig zu erfragen aufgrund Lebensunterhaltssicherung",
|
||||||
|
# key="MainDropdown",
|
||||||
|
# children=[
|
||||||
|
# FormField("Alter Kind", FormFieldType.TEXT),
|
||||||
|
# ],
|
||||||
|
# ),
|
||||||
|
# ],
|
||||||
|
# ),
|
||||||
# FormFieldGroup("Daten Kontaktperson", FORM_FIELDS_CONTACT_PERSON),
|
# FormFieldGroup("Daten Kontaktperson", FORM_FIELDS_CONTACT_PERSON),
|
||||||
# FormFieldGroup("Stammdaten (ERGÄNZUNG KINDERALTER DYNAMISCH)", FORM_FIELDS_MASTER_DATA),
|
# FormFieldGroup("Stammdaten (ERGÄNZUNG KINDERALTER DYNAMISCH)", FORM_FIELDS_MASTER_DATA),
|
||||||
# FormFieldGroup("weitere Informationen", FORM_FIELDS_ADDITIONAL_DATA),
|
# FormFieldGroup("weitere Informationen", FORM_FIELDS_ADDITIONAL_DATA),
|
||||||
@@ -1184,6 +1410,18 @@ def _build_ui_recursively(
|
|||||||
}
|
}
|
||||||
parent_layout.addRow(widget)
|
parent_layout.addRow(widget)
|
||||||
|
|
||||||
|
case FormFieldType.DYNAMIC_DROPDOWN:
|
||||||
|
widget = DynamicDropdownWidget(
|
||||||
|
field.children,
|
||||||
|
field.label,
|
||||||
|
prefix=f"{full_key}",
|
||||||
|
)
|
||||||
|
widget_registry[full_key] = {
|
||||||
|
"widget": widget,
|
||||||
|
"form_field": field,
|
||||||
|
}
|
||||||
|
parent_layout.addRow(widget)
|
||||||
|
|
||||||
case _:
|
case _:
|
||||||
raise NotImplementedError(f"Not supported field type: {field.type.value}")
|
raise NotImplementedError(f"Not supported field type: {field.type.value}")
|
||||||
|
|
||||||
@@ -1240,6 +1478,9 @@ def reset_form(
|
|||||||
elif isinstance(widget, DynamicListWidget):
|
elif isinstance(widget, DynamicListWidget):
|
||||||
# dynamic list widget manages its widgets by itself
|
# dynamic list widget manages its widgets by itself
|
||||||
widget.reset_form()
|
widget.reset_form()
|
||||||
|
elif isinstance(widget, DynamicDropdownWidget):
|
||||||
|
# dynamic list widget manages its widgets by itself
|
||||||
|
widget.reset_form()
|
||||||
|
|
||||||
widget.setStyleSheet("")
|
widget.setStyleSheet("")
|
||||||
|
|
||||||
@@ -1255,6 +1496,31 @@ def _insert_nested(
|
|||||||
target_dict[key_path[-1]] = value
|
target_dict[key_path[-1]] = value
|
||||||
|
|
||||||
|
|
||||||
|
def update_sub_forms(
|
||||||
|
widget_registry: WidgetRegistry,
|
||||||
|
sub_forms: Sequence[SubForm],
|
||||||
|
base_label: str = "",
|
||||||
|
):
|
||||||
|
total_num_sub_forms = len(sub_forms)
|
||||||
|
for index, sub_form in enumerate(sub_forms, start=1):
|
||||||
|
if isinstance(sub_form.entry_box, QGroupBox) and base_label:
|
||||||
|
sub_form.entry_box.setTitle(f"{base_label} {index}")
|
||||||
|
change_sub_form_widget_registry(
|
||||||
|
widget_registry,
|
||||||
|
sub_form,
|
||||||
|
index,
|
||||||
|
)
|
||||||
|
|
||||||
|
for key in tuple(widget_registry.keys()):
|
||||||
|
matches = DYNAMIC_LIST_KEY_PATTERN.search(key)
|
||||||
|
if not matches:
|
||||||
|
continue
|
||||||
|
|
||||||
|
counter_sub_form = int(matches.group(1))
|
||||||
|
if counter_sub_form > total_num_sub_forms:
|
||||||
|
del widget_registry[key]
|
||||||
|
|
||||||
|
|
||||||
def get_form_data(
|
def get_form_data(
|
||||||
widget_registry: WidgetRegistry,
|
widget_registry: WidgetRegistry,
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
@@ -1277,6 +1543,15 @@ def get_form_data(
|
|||||||
# of such dictionaries
|
# of such dictionaries
|
||||||
form_data = widget.get_form_data()
|
form_data = widget.get_form_data()
|
||||||
value = [val for val in form_data.values()]
|
value = [val for val in form_data.values()]
|
||||||
|
# print(">>>>>>>>> Form Data:")
|
||||||
|
# pprint(form_data)
|
||||||
|
elif isinstance(widget, DynamicDropdownWidget):
|
||||||
|
# this should be a list: each dynamic list contains a list
|
||||||
|
# of such dictionaries
|
||||||
|
form_data = widget.get_form_data()
|
||||||
|
value = [val for val in form_data.values()]
|
||||||
|
# print(">>>>>>>>> Form Data:")
|
||||||
|
# pprint(form_data)
|
||||||
|
|
||||||
_insert_nested(raw_data, key.split("."), value)
|
_insert_nested(raw_data, key.split("."), value)
|
||||||
|
|
||||||
@@ -1459,6 +1734,16 @@ class AutoForm(QWidget):
|
|||||||
print("Erfolg! Alle Daten sind valide.")
|
print("Erfolg! Alle Daten sind valide.")
|
||||||
print("Get form data call...")
|
print("Get form data call...")
|
||||||
form_data = self.get_form_data()
|
form_data = self.get_form_data()
|
||||||
|
post_proc_1 = form_data["Stammdaten"]["Stammdaten_anzahl_kinder"]
|
||||||
|
|
||||||
|
Stammdaten_anzahl_kinder = post_proc_1[0]["Stammdaten_anzahl_kinder-[0]"][
|
||||||
|
"'Stammdaten_anzahl_kinder'"
|
||||||
|
]
|
||||||
|
Stammdaten_alter_kinder: list[str] = []
|
||||||
|
if len(post_proc_1) > 1:
|
||||||
|
for i in range(1, len(post_proc_1)):
|
||||||
|
content = post_proc_1[i]
|
||||||
|
|
||||||
print("------------>>>>>>>>> Get form data")
|
print("------------>>>>>>>>> Get form data")
|
||||||
pprint(form_data)
|
pprint(form_data)
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
@@ -1478,7 +1763,7 @@ class AutoForm(QWidget):
|
|||||||
|
|
||||||
@dc.dataclass(slots=True)
|
@dc.dataclass(slots=True)
|
||||||
class SubForm:
|
class SubForm:
|
||||||
entry_box: QGroupBox
|
entry_box: QWidget
|
||||||
prefix_parent: str
|
prefix_parent: str
|
||||||
index: int
|
index: int
|
||||||
prefix: str = ""
|
prefix: str = ""
|
||||||
@@ -1529,6 +1814,7 @@ class DynamicListWidget(QWidget):
|
|||||||
super().__init__()
|
super().__init__()
|
||||||
self.form_fields = form_fields
|
self.form_fields = form_fields
|
||||||
self.label = label
|
self.label = label
|
||||||
|
self.base_label = enhanced_label(label, add_text="")
|
||||||
self.prefix = prefix
|
self.prefix = prefix
|
||||||
self.widget_registry: WidgetRegistry = {}
|
self.widget_registry: WidgetRegistry = {}
|
||||||
|
|
||||||
@@ -1551,6 +1837,8 @@ class DynamicListWidget(QWidget):
|
|||||||
|
|
||||||
self.inner_layout.addWidget(self.add_btn)
|
self.inner_layout.addWidget(self.add_btn)
|
||||||
|
|
||||||
|
self.widget_registry_base_size = len(self.widget_registry)
|
||||||
|
|
||||||
# add empty sub form as initial value
|
# add empty sub form as initial value
|
||||||
self.add_entry()
|
self.add_entry()
|
||||||
|
|
||||||
@@ -1590,14 +1878,14 @@ class DynamicListWidget(QWidget):
|
|||||||
self.update_sub_forms()
|
self.update_sub_forms()
|
||||||
|
|
||||||
def update_sub_forms(self):
|
def update_sub_forms(self):
|
||||||
for index, sub_form in enumerate(self.sub_forms, start=1):
|
update_sub_forms(
|
||||||
sub_form.entry_box.setTitle(f"{self.label} {index}")
|
|
||||||
change_sub_form_widget_registry(
|
|
||||||
self.widget_registry,
|
self.widget_registry,
|
||||||
sub_form,
|
sub_forms=self.sub_forms,
|
||||||
index,
|
base_label=self.base_label,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# pprint_registry(self.widget_registry)
|
||||||
|
|
||||||
def reset_form(self) -> None:
|
def reset_form(self) -> None:
|
||||||
reset_form(self.widget_registry)
|
reset_form(self.widget_registry)
|
||||||
|
|
||||||
@@ -1614,6 +1902,146 @@ class DynamicListWidget(QWidget):
|
|||||||
return raw_data
|
return raw_data
|
||||||
|
|
||||||
|
|
||||||
|
class DynamicDropdownWidget(QWidget):
|
||||||
|
"""
|
||||||
|
A Widget, which can generate and manage an arbitrary number of sub forms with additional
|
||||||
|
information on a combobox selection (integer in combobox).
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
form_fields: Sequence[FormField],
|
||||||
|
label_add_info: str = "Eintrag",
|
||||||
|
prefix: str = "",
|
||||||
|
):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
# form_fields = form_fields.children
|
||||||
|
if len(form_fields) == 0 or len(form_fields) > 1:
|
||||||
|
raise ValueError(
|
||||||
|
"Dynamic Dropdown Widget must have only one child, which is a dropdown widget"
|
||||||
|
)
|
||||||
|
|
||||||
|
self.combobox_field = form_fields[0]
|
||||||
|
assigned_form_fields = self.combobox_field.children
|
||||||
|
if len(assigned_form_fields) == 0 or len(assigned_form_fields) > 1:
|
||||||
|
raise ValueError(
|
||||||
|
(
|
||||||
|
"Dynamic Dropdown Widget's dropdown element must have only one "
|
||||||
|
"child, which is a single field definition"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assigned_form_field = assigned_form_fields[0]
|
||||||
|
|
||||||
|
self.label_add_info = label_add_info
|
||||||
|
self.prefix = prefix
|
||||||
|
self.widget_registry: WidgetRegistry = {}
|
||||||
|
|
||||||
|
# layout for group component
|
||||||
|
# self.group_box = QGroupBox(label)
|
||||||
|
self.main_layout = QVBoxLayout(self)
|
||||||
|
self.main_layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
self.form_layout = QFormLayout()
|
||||||
|
self.main_layout.addLayout(self.form_layout)
|
||||||
|
|
||||||
|
_build_ui_recursively(
|
||||||
|
[self.combobox_field],
|
||||||
|
self.form_layout,
|
||||||
|
self.widget_registry,
|
||||||
|
prefix=f"{self.prefix}-[0]",
|
||||||
|
)
|
||||||
|
dropdown_widget_entry = tuple(self.widget_registry.values())[0]
|
||||||
|
dropdown_widget = dropdown_widget_entry["widget"]
|
||||||
|
assert isinstance(dropdown_widget, QComboBox)
|
||||||
|
self.dropdown_widget = dropdown_widget
|
||||||
|
|
||||||
|
self.rows_container = QWidget()
|
||||||
|
self.rows_layout = QVBoxLayout(self.rows_container)
|
||||||
|
self.rows_layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
self.main_layout.addWidget(self.rows_container)
|
||||||
|
|
||||||
|
self.sub_forms: list[SubForm] = []
|
||||||
|
|
||||||
|
self.dropdown_widget.currentTextChanged.connect(self.on_anzahl_changed)
|
||||||
|
self.widget_registry_base_size = len(self.widget_registry)
|
||||||
|
|
||||||
|
def on_anzahl_changed(
|
||||||
|
self,
|
||||||
|
text: str,
|
||||||
|
) -> None:
|
||||||
|
target_count: int
|
||||||
|
if text == DROPDOWN_DEFAULT:
|
||||||
|
target_count = 0
|
||||||
|
else:
|
||||||
|
target_count = int(text)
|
||||||
|
current_count = len(self.sub_forms)
|
||||||
|
|
||||||
|
if target_count > current_count:
|
||||||
|
differenz = target_count - current_count
|
||||||
|
for _ in range(differenz):
|
||||||
|
self._add_row()
|
||||||
|
|
||||||
|
elif target_count < current_count:
|
||||||
|
differenz = current_count - target_count
|
||||||
|
for _ in range(differenz):
|
||||||
|
self._remove_row()
|
||||||
|
|
||||||
|
def _add_row(self) -> None:
|
||||||
|
number_form = len(self.sub_forms) + 1
|
||||||
|
container = QWidget()
|
||||||
|
container.setContentsMargins(0, 0, 0, 0)
|
||||||
|
form_layout = QFormLayout(container)
|
||||||
|
form_layout.setContentsMargins(10, 0, 0, 0)
|
||||||
|
sub_form = SubForm(container, prefix_parent=self.prefix, index=number_form)
|
||||||
|
|
||||||
|
form_field_def = copy.copy(self.assigned_form_field)
|
||||||
|
form_field_def.label = form_field_def.enhanced_label(f"{number_form}")
|
||||||
|
|
||||||
|
_build_ui_recursively(
|
||||||
|
schema=[form_field_def],
|
||||||
|
parent_layout=form_layout,
|
||||||
|
widget_registry=self.widget_registry,
|
||||||
|
prefix=f"{self.prefix}-[{number_form}]",
|
||||||
|
)
|
||||||
|
self.rows_layout.addWidget(container)
|
||||||
|
|
||||||
|
self.sub_forms.append(sub_form)
|
||||||
|
self.update_sub_forms()
|
||||||
|
|
||||||
|
def _remove_row(self) -> None:
|
||||||
|
last_form = self.sub_forms.pop()
|
||||||
|
box_to_remove = last_form.entry_box
|
||||||
|
|
||||||
|
self.rows_layout.removeWidget(box_to_remove)
|
||||||
|
box_to_remove.deleteLater()
|
||||||
|
self.update_sub_forms()
|
||||||
|
|
||||||
|
def update_sub_forms(self) -> None:
|
||||||
|
update_sub_forms(
|
||||||
|
self.widget_registry,
|
||||||
|
sub_forms=self.sub_forms,
|
||||||
|
)
|
||||||
|
|
||||||
|
# pprint_registry(self.widget_registry)
|
||||||
|
|
||||||
|
def reset_form(self) -> None:
|
||||||
|
# resets dynamic content when dropdown is set back to default value
|
||||||
|
self.dropdown_widget.setCurrentIndex(0)
|
||||||
|
|
||||||
|
def validate_form_data(self) -> list[str]:
|
||||||
|
return validate_form_data(self.widget_registry)
|
||||||
|
|
||||||
|
def load_form_data(self) -> None:
|
||||||
|
# TODO add way to load data when initialised (probably with click)
|
||||||
|
...
|
||||||
|
|
||||||
|
def get_form_data(self):
|
||||||
|
raw_data = get_form_data(self.widget_registry)
|
||||||
|
|
||||||
|
return raw_data
|
||||||
|
|
||||||
|
|
||||||
class ClickableCell(QFrame):
|
class ClickableCell(QFrame):
|
||||||
"""cell in the table on the startup screen"""
|
"""cell in the table on the startup screen"""
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,74 @@ import dataclasses as dc
|
|||||||
import enum
|
import enum
|
||||||
import re
|
import re
|
||||||
from collections.abc import Sequence
|
from collections.abc import Sequence
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import babel
|
import babel
|
||||||
from PySide6.QtCore import QDate, Qt
|
from PySide6.QtCore import QDate, Qt
|
||||||
|
|
||||||
|
# %%
|
||||||
|
DYNAMIC_LIST_KEY_PATTERN = re.compile(r"-\[(\d+)\]")
|
||||||
|
|
||||||
|
dynamic_content = {
|
||||||
|
"Stammdaten_anzahl_kinder-[0]": {"Stammdaten_anzahl_kinder": "5"},
|
||||||
|
"Stammdaten_anzahl_kinder-[1]": {"Stammdaten_alter_kinder": "23213"},
|
||||||
|
"Stammdaten_anzahl_kinder-[2]": {"Stammdaten_alter_kinder": "123123"},
|
||||||
|
"Stammdaten_anzahl_kinder-[3]": {"Stammdaten_alter_kinder": "123213"},
|
||||||
|
"Stammdaten_anzahl_kinder-[4]": {"Stammdaten_alter_kinder": "123123"},
|
||||||
|
"Stammdaten_anzahl_kinder-[5]": {"Stammdaten_alter_kinder": "123123"},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def find_dynamic_content(content: dict[str, Any]) -> dict[str, Any] | None:
|
||||||
|
|
||||||
|
found = None
|
||||||
|
for key in dynamic_content.keys():
|
||||||
|
if DYNAMIC_LIST_KEY_PATTERN.search(key):
|
||||||
|
# found an match: this is dynamic content dictionary
|
||||||
|
print("found")
|
||||||
|
found = dynamic_content
|
||||||
|
break
|
||||||
|
|
||||||
|
return found
|
||||||
|
|
||||||
|
|
||||||
|
# %%
|
||||||
|
new_content = {
|
||||||
|
"Stammdaten": {
|
||||||
|
"Stammdaten_PLZ": "",
|
||||||
|
"Stammdaten_anrede_anschrift": "asdasdas",
|
||||||
|
"Stammdaten_anzahl_kinder": [
|
||||||
|
{
|
||||||
|
"Stammdaten_anzahl_kinder-[0]": {"Stammdaten_anzahl_kinder": "5"},
|
||||||
|
"Stammdaten_anzahl_kinder-[1]": {"Stammdaten_alter_kinder": "23213"},
|
||||||
|
"Stammdaten_anzahl_kinder-[2]": {"Stammdaten_alter_kinder": "123123"},
|
||||||
|
"Stammdaten_anzahl_kinder-[3]": {"Stammdaten_alter_kinder": "123213"},
|
||||||
|
"Stammdaten_anzahl_kinder-[4]": {"Stammdaten_alter_kinder": "123123"},
|
||||||
|
"Stammdaten_anzahl_kinder-[5]": {"Stammdaten_alter_kinder": "123123"},
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def flat_dict(contents):
|
||||||
|
for x in contents:
|
||||||
|
if isinstance(contents, dict):
|
||||||
|
yield from flat_dict(tuple(contents[x]))
|
||||||
|
elif isinstance(x, (list, tuple, set)):
|
||||||
|
yield from flat_dict(x)
|
||||||
|
else:
|
||||||
|
yield x
|
||||||
|
|
||||||
|
|
||||||
|
# %%
|
||||||
|
for x in flat_dict(new_content):
|
||||||
|
print(x)
|
||||||
|
|
||||||
|
|
||||||
|
# %%
|
||||||
|
find_dynamic_content(dynamic_content)
|
||||||
|
|
||||||
|
|
||||||
# %%
|
# %%
|
||||||
@dc.dataclass(slots=True)
|
@dc.dataclass(slots=True)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ description = "GUI for CRM of NAFKA project with WCE"
|
|||||||
authors = [
|
authors = [
|
||||||
{name = "d-opt GmbH, resp. Florian Förster", email = "f.foerster@d-opt.com"},
|
{name = "d-opt GmbH, resp. Florian Förster", email = "f.foerster@d-opt.com"},
|
||||||
]
|
]
|
||||||
dependencies = ["nicegui>=3.10.0", "pyside6>=6.11.0", "sqlalchemy>=2.0.49", "polars>=1.40.1", "dopt-basics>=0.2.4", "pydantic>=2.13.4", "babel>=2.18.0"]
|
dependencies = ["nicegui>=3.10.0", "pyside6>=6.11.0", "sqlalchemy>=2.0.49", "polars>=1.40.1", "dopt-basics>=0.2.4", "pydantic[email]>=2.13.4", "babel>=2.18.0"]
|
||||||
requires-python = "<3.14,>=3.11"
|
requires-python = "<3.14,>=3.11"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
license = {text = "LicenseRef-Proprietary"}
|
license = {text = "LicenseRef-Proprietary"}
|
||||||
|
|||||||
Reference in New Issue
Block a user