generated from dopt-python/py311
data loading of company profiles
This commit is contained in:
@@ -2,7 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import dataclasses as dc
|
||||
import datetime
|
||||
from typing import Any, TypeAlias, TypedDict, cast
|
||||
from typing import TYPE_CHECKING, Any, TypedDict, cast
|
||||
|
||||
import polars as pl
|
||||
import sqlalchemy as sql
|
||||
@@ -10,9 +10,11 @@ import sqlalchemy as sql
|
||||
from wce_crm import db
|
||||
from wce_crm.logging import logger_back as logger
|
||||
|
||||
InitRecId: TypeAlias = int
|
||||
if TYPE_CHECKING:
|
||||
from wce_crm.types import ExtAnId, ExtMaId, InitRecId
|
||||
|
||||
|
||||
# // externals
|
||||
class CompanyInfo(TypedDict):
|
||||
ma_id: str
|
||||
wce_id: str
|
||||
@@ -100,7 +102,7 @@ def initrec_comp_search_choices() -> tuple[tuple[str, int], ...]:
|
||||
|
||||
|
||||
def initrec_comp_search_get_info(
|
||||
ma_id: int,
|
||||
ma_id: ExtMaId,
|
||||
) -> CompanyInfo:
|
||||
logger.debug("[Call backend] comp_search_get_info")
|
||||
df = db.DF_CRM_MASTER.filter(pl.col.ma_id == ma_id)
|
||||
@@ -112,7 +114,7 @@ def initrec_comp_search_get_info(
|
||||
|
||||
|
||||
def initrec_comp_contact_person_search_choices(
|
||||
ma_id: int | None,
|
||||
ma_id: ExtMaId | None,
|
||||
use_both_names: bool,
|
||||
) -> tuple[tuple[str, int], ...]:
|
||||
# TODO no reload functionality
|
||||
@@ -140,7 +142,7 @@ def initrec_comp_contact_person_search_choices(
|
||||
|
||||
|
||||
def initrec_comp_contact_person_search_get_info(
|
||||
an_id: int,
|
||||
an_id: ExtAnId,
|
||||
) -> ContactPersonInfo:
|
||||
logger.debug("[Call backend] contact_person_search_get_info")
|
||||
df = db.DF_CONTACT_PERSON.filter(pl.col.an_id == an_id)
|
||||
@@ -151,6 +153,7 @@ def initrec_comp_contact_person_search_get_info(
|
||||
return cast(ContactPersonInfo, df.row(0, named=True))
|
||||
|
||||
|
||||
# // internals
|
||||
def initrec_insert_initial_recording(
|
||||
data: dict[str, Any],
|
||||
) -> InitRecId:
|
||||
@@ -210,7 +213,6 @@ def initrec_delete_initial_recording(
|
||||
@dc.dataclass(slots=True)
|
||||
class FrontpageCompany:
|
||||
erfassung_id: InitRecId
|
||||
# ma_id: int
|
||||
name: str
|
||||
Metadaten_aktualisierung: datetime.datetime
|
||||
is_company: bool
|
||||
|
||||
+132
-38
@@ -11,7 +11,7 @@ from collections import defaultdict
|
||||
from collections.abc import Container, Iterable, Sequence
|
||||
from pathlib import Path
|
||||
from pprint import pformat
|
||||
from typing import Any, Final, Protocol, TypeAlias, TypedDict, TypeVar, cast
|
||||
from typing import TYPE_CHECKING, Any, Final, Protocol, TypeAlias, TypedDict, TypeVar, cast
|
||||
from typing_extensions import override
|
||||
|
||||
from pydantic import (
|
||||
@@ -70,6 +70,10 @@ from wce_crm.logging import (
|
||||
logger_get_data,
|
||||
logger_gui,
|
||||
)
|
||||
from wce_crm.types import ExtMaId, InitRecId
|
||||
|
||||
if TYPE_CHECKING:
|
||||
...
|
||||
|
||||
K = TypeVar("K")
|
||||
V = TypeVar("V")
|
||||
@@ -1315,7 +1319,7 @@ class AutoForm(QWidget):
|
||||
self.delete_btn.clicked.connect(self.delete_data)
|
||||
self.layout_btn.addWidget(self.delete_btn)
|
||||
|
||||
self.current_id: int = -1
|
||||
self.current_id: InitRecId = -1
|
||||
|
||||
logger_auto_form.debug(
|
||||
"Initialised Auto Form Widget. Registry:%s",
|
||||
@@ -2072,7 +2076,7 @@ class NewEntrySelect_view(QWidget):
|
||||
"""view for new entry for initial recording ("Grunderfassung")"""
|
||||
|
||||
back_requested = Signal() # Signal back button
|
||||
company_requested = Signal() # Signal "Unternehmen"
|
||||
company_requested = Signal(bool) # Signal "Unternehmen" (bool: reset yes/no)
|
||||
person_requested = Signal() # Signal "Individualperson"
|
||||
|
||||
def __init__(self):
|
||||
@@ -2094,7 +2098,7 @@ class NewEntrySelect_view(QWidget):
|
||||
btn_company = QPushButton("Unternehmen →")
|
||||
btn_company.setFixedWidth(300)
|
||||
btn_company.setFixedHeight(40)
|
||||
btn_company.clicked.connect(lambda: self.company_requested.emit())
|
||||
btn_company.clicked.connect(lambda: self.company_requested.emit(True))
|
||||
|
||||
btn_person = QPushButton("Individualperson →")
|
||||
btn_person.setFixedWidth(300)
|
||||
@@ -2148,7 +2152,7 @@ class Page_InitRecCompany(QWidget):
|
||||
back_main_requested = Signal() # back to main page
|
||||
back_requested = Signal() # back button
|
||||
update_triggered = Signal() # form saved (data changed for front page)
|
||||
company_profile_requested = Signal()
|
||||
company_profile_requested = Signal(InitRecId)
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
@@ -2172,7 +2176,9 @@ class Page_InitRecCompany(QWidget):
|
||||
header_layout.setContentsMargins(0, 0, 0, 10)
|
||||
|
||||
comp_profile_btn = QPushButton("Unternehmensprofil")
|
||||
comp_profile_btn.clicked.connect(lambda: self.company_profile_requested.emit())
|
||||
comp_profile_btn.clicked.connect(
|
||||
lambda: self.company_profile_requested.emit(self.current_id)
|
||||
)
|
||||
comp_profile_btn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
|
||||
comp_profile_btn.setMinimumWidth(250)
|
||||
# comp_profile_btn.setMaximumWidth(200)
|
||||
@@ -2281,6 +2287,10 @@ class Page_InitRecCompany(QWidget):
|
||||
def reset_form(self) -> None:
|
||||
self.auto_form.reset_form()
|
||||
|
||||
@property
|
||||
def current_id(self) -> InitRecId:
|
||||
return self.auto_form.current_id
|
||||
|
||||
|
||||
class Page_InitRecPerson(QWidget):
|
||||
back_main_requested = Signal() # back to main page
|
||||
@@ -2413,12 +2423,27 @@ class Page_InitRecPerson(QWidget):
|
||||
|
||||
class Page_CompanyProfile(QWidget):
|
||||
back_main_requested = Signal() # back to main page
|
||||
back_requested = Signal() # back button
|
||||
back_requested = Signal(bool) # back to init rec (bool: reset yes/no)
|
||||
# TODO update should trigger something else
|
||||
update_triggered = Signal() # form saved (data changed for front page)
|
||||
# update_triggered = Signal() # form saved (data changed for front page)
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
# state management
|
||||
self.current_id: InitRecId = -1
|
||||
self.COMPANY_FETAURES_MASTER_DATA: dict[str, str] = {
|
||||
"ma_unternehmensname": "Name:",
|
||||
"ma_branche": "Branche:",
|
||||
"ma_strasse": "Straße:",
|
||||
"ma_hausnummer": "Hausnummer:",
|
||||
"ma_plz": "PLZ:",
|
||||
"ma_ort": "Ort:",
|
||||
"ma_website": "Webseite:",
|
||||
"ma_mail": "E-Mail:",
|
||||
"ma_telefonnummer": "Telefon:",
|
||||
}
|
||||
|
||||
# Hauptlayout der Seite
|
||||
outer_layout = QHBoxLayout(self)
|
||||
vert_layout = QVBoxLayout()
|
||||
@@ -2444,7 +2469,7 @@ class Page_CompanyProfile(QWidget):
|
||||
back_btn_main.setMinimumWidth(200)
|
||||
back_btn_main.setMaximumWidth(200)
|
||||
back_btn_step = QPushButton("← Zurück")
|
||||
back_btn_step.clicked.connect(lambda: self.back_requested.emit())
|
||||
back_btn_step.clicked.connect(lambda: self.back_requested.emit(False))
|
||||
back_btn_step.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
|
||||
back_btn_step.setMinimumWidth(200)
|
||||
back_btn_step.setMaximumWidth(200)
|
||||
@@ -2521,7 +2546,8 @@ class Page_CompanyProfile(QWidget):
|
||||
)
|
||||
left_layout.addWidget(master_data_label)
|
||||
# self.table_master_data = MasterDataTable()
|
||||
self.table_master_data = MasterDataFormWidget()
|
||||
default_labels = tuple(self.COMPANY_FETAURES_MASTER_DATA.values())
|
||||
self.table_master_data = MasterDataFormWidget(default_labels)
|
||||
left_layout.addWidget(self.table_master_data)
|
||||
left_layout.addWidget(QLabel("PLATZHALTER Vermerke: Welche Notizen?"))
|
||||
|
||||
@@ -2575,6 +2601,7 @@ class Page_CompanyProfile(QWidget):
|
||||
container_layout.addLayout(main_hor_layout)
|
||||
container_layout.addStretch()
|
||||
|
||||
# --- STYLE ---
|
||||
self.setStyleSheet("""
|
||||
QFrame#Segment {
|
||||
background-color: #ffffff;
|
||||
@@ -2606,7 +2633,7 @@ class Page_CompanyProfile(QWidget):
|
||||
# }
|
||||
# """)
|
||||
|
||||
def set_company_name(self, name: str = "") -> None:
|
||||
def set_company_name(self, name: str) -> None:
|
||||
if not name:
|
||||
name = self.change_title_text.text()
|
||||
if not name:
|
||||
@@ -2615,6 +2642,42 @@ class Page_CompanyProfile(QWidget):
|
||||
txt = f"Unternehmen: {name}"
|
||||
self.title_company_name.setText(txt)
|
||||
|
||||
def load_from_id(
|
||||
self,
|
||||
id_: InitRecId,
|
||||
) -> None:
|
||||
assert id_ is not None, "tried to load with InitRecId None"
|
||||
logger_gui.debug(f"Called function to load with ID: {id_}")
|
||||
|
||||
if id_ < 0:
|
||||
# just clear and do nothing else
|
||||
logger_gui.debug("just reset with ID < 0")
|
||||
self.table_master_data.reset()
|
||||
self.set_company_name("")
|
||||
self.current_id = id_
|
||||
return
|
||||
|
||||
if id_ == self.current_id:
|
||||
logger_gui.debug("ID did not change. Do nothing")
|
||||
self.current_id = id_
|
||||
return
|
||||
|
||||
# TODO retrieve and process data to load
|
||||
init_rec = backend.initrec_get_initial_recording(id_)
|
||||
ma_id = cast(ExtMaId, init_rec["Partnersuche__un_suche"])
|
||||
assert ma_id is not None, "no ma_id obtained"
|
||||
comp_info = backend.initrec_comp_search_get_info(ma_id)
|
||||
|
||||
data: dict[str, Any] = {}
|
||||
|
||||
for feature, value in comp_info.items():
|
||||
if feature in self.COMPANY_FETAURES_MASTER_DATA:
|
||||
data[self.COMPANY_FETAURES_MASTER_DATA[feature]] = value
|
||||
|
||||
self.table_master_data.load_data(data)
|
||||
self.set_company_name(data["Name:"])
|
||||
self.current_id = id_
|
||||
|
||||
|
||||
class MasterDataTable(QWidget):
|
||||
def __init__(self):
|
||||
@@ -2705,8 +2768,13 @@ class MasterDataTable(QWidget):
|
||||
|
||||
|
||||
class MasterDataFormWidget(QWidget):
|
||||
def __init__(self):
|
||||
def __init__(
|
||||
self,
|
||||
default_labels: Sequence[str],
|
||||
):
|
||||
super().__init__()
|
||||
self.default_labels = default_labels
|
||||
self.default_data = {label: None for label in self.default_labels}
|
||||
|
||||
# main layout
|
||||
main_layout = QVBoxLayout(self)
|
||||
@@ -2716,37 +2784,55 @@ class MasterDataFormWidget(QWidget):
|
||||
segment_frame = QFrame()
|
||||
segment_frame.setObjectName("Segment")
|
||||
# form layout
|
||||
form_layout = QFormLayout(segment_frame)
|
||||
form_layout.setSpacing(15) # Vertikaler Abstand zwischen den Zeilen
|
||||
form_layout.setLabelAlignment(Qt.AlignmentFlag.AlignLeft) # Merkmale linksbündig
|
||||
self.form_layout = QFormLayout(segment_frame)
|
||||
self.form_layout.setSpacing(15)
|
||||
self.form_layout.setLabelAlignment(Qt.AlignmentFlag.AlignLeft)
|
||||
|
||||
# load data
|
||||
self.load_data(form_layout)
|
||||
# self.load_data()
|
||||
|
||||
main_layout.addWidget(segment_frame)n
|
||||
main_layout.addWidget(segment_frame)
|
||||
self.style_ui()
|
||||
self.reset()
|
||||
|
||||
def load_data(self, form_layout):
|
||||
daten = [
|
||||
("Anwendungsname", "MyQtApp Pro"),
|
||||
("Version", "2.4.1-beta"),
|
||||
("Datenbank-Pfad", "/var/lib/sqlite/data.db"),
|
||||
("Letzter Login", "2026-06-25 09:30"),
|
||||
("Benutzer-ID", "USR-88291"),
|
||||
("Verschlüsselung", "AES-256-GCM"),
|
||||
]
|
||||
simulated_retrieved_data = {x[0]: x[1] for x in daten}
|
||||
def load_data(
|
||||
self,
|
||||
data: dict[str, Any],
|
||||
) -> None:
|
||||
self.clear_current_layout()
|
||||
# daten = [
|
||||
# ("Anwendungsname", "MyQtApp Pro"),
|
||||
# ("Version", "2.4.1-beta"),
|
||||
# ("Datenbank-Pfad", "/var/lib/sqlite/data.db"),
|
||||
# ("Letzter Login", "2026-06-25 09:30"),
|
||||
# ("Benutzer-ID", "USR-88291"),
|
||||
# ("Verschlüsselung", "AES-256-GCM"),
|
||||
# ]
|
||||
# simulated_retrieved_data = {x[0]: x[1] for x in daten}
|
||||
|
||||
for merkmal, wert in simulated_retrieved_data.items():
|
||||
lbl_merkmal = QLabel(f"{merkmal}")
|
||||
lbl_merkmal.setObjectName("Merkmal")
|
||||
for feature, value in data.items():
|
||||
label_feature = QLabel(f"{feature}")
|
||||
label_feature.setObjectName("Merkmal")
|
||||
|
||||
lbl_wert = QLabel(str(wert))
|
||||
lbl_wert.setObjectName("Wert")
|
||||
if value is None:
|
||||
value = ""
|
||||
|
||||
lbl_wert.setTextInteractionFlags(Qt.TextInteractionFlag.TextSelectableByMouse)
|
||||
label_value = QLabel(str(value))
|
||||
label_value.setObjectName("Wert")
|
||||
label_value.setTextInteractionFlags(Qt.TextInteractionFlag.TextSelectableByMouse)
|
||||
|
||||
form_layout.addRow(lbl_merkmal, lbl_wert)
|
||||
self.form_layout.addRow(label_feature, label_value)
|
||||
|
||||
def clear_current_layout(self):
|
||||
while self.form_layout.count() > 0:
|
||||
item = self.form_layout.takeAt(0)
|
||||
assert item is not None
|
||||
widget = item.widget()
|
||||
if widget is not None:
|
||||
widget.deleteLater()
|
||||
|
||||
def reset(self) -> None:
|
||||
self.load_data(self.default_data)
|
||||
|
||||
def style_ui(self):
|
||||
self.setStyleSheet("""
|
||||
@@ -2771,7 +2857,8 @@ class MasterDataFormWidget(QWidget):
|
||||
/* Linke Spalte (Merkmale): Grau und Fett */
|
||||
QLabel#Merkmal {
|
||||
font-weight: bold;
|
||||
color: #64748b;
|
||||
/* color: #64748b; */
|
||||
color: #475569;
|
||||
}
|
||||
|
||||
/* Rechte Spalte (Werte): Dunkel und gut lesbar */
|
||||
@@ -2999,15 +3086,22 @@ class MainWindow(QMainWindow):
|
||||
def show_new_entry_select(self):
|
||||
self.stack.setCurrentWidget(self.new_entry_select)
|
||||
|
||||
def show_page_initrec_company(self):
|
||||
self.initrec_company.reset_form()
|
||||
def show_page_initrec_company(self, reset: bool):
|
||||
# TODO: allow for "back" on profile to sustain current view
|
||||
# TODO: reset if approached from "other side" by "new entry"
|
||||
if reset:
|
||||
self.initrec_company.reset_form()
|
||||
self.stack.setCurrentWidget(self.initrec_company)
|
||||
|
||||
def show_page_initrec_person(self):
|
||||
self.initrec_person.reset_form()
|
||||
self.stack.setCurrentWidget(self.initrec_person)
|
||||
|
||||
def show_page_company_profile(self) -> None:
|
||||
def show_page_company_profile(
|
||||
self,
|
||||
id_: InitRecId,
|
||||
) -> None:
|
||||
self.company_profile.load_from_id(id_)
|
||||
self.stack.setCurrentWidget(self.company_profile)
|
||||
|
||||
# --- MENÜ LOGIK ---
|
||||
|
||||
@@ -5,5 +5,8 @@ from typing import TYPE_CHECKING, TypeAlias
|
||||
if TYPE_CHECKING:
|
||||
import polars as pl
|
||||
|
||||
InitRecId: TypeAlias = int
|
||||
ExtMaId: TypeAlias = int
|
||||
ExtAnId: TypeAlias = int
|
||||
|
||||
PolarsSchema: TypeAlias = dict[str, type["pl.DataType"]]
|
||||
|
||||
Reference in New Issue
Block a user