From 9dc26e36b51b6752903e7a1abce84870f9cf2b16 Mon Sep 17 00:00:00 2001 From: foefl Date: Tue, 30 Jun 2026 12:36:29 +0200 Subject: [PATCH] session management and prepare component interaction scheme for consultations --- src/wce_crm/gui.py | 122 ++++++++++++++++++++++++++++++++++++++----- src/wce_crm/types.py | 1 + 2 files changed, 110 insertions(+), 13 deletions(-) diff --git a/src/wce_crm/gui.py b/src/wce_crm/gui.py index 86b2e9e..aeed011 100644 --- a/src/wce_crm/gui.py +++ b/src/wce_crm/gui.py @@ -32,6 +32,7 @@ from PySide6.QtGui import QAction from PySide6.QtWidgets import ( QAbstractItemView, QApplication, + QButtonGroup, QComboBox, QCompleter, QDateEdit, @@ -48,6 +49,7 @@ from PySide6.QtWidgets import ( QMessageBox, QPlainTextEdit, QPushButton, + QRadioButton, QScrollArea, QSizePolicy, QStackedWidget, @@ -76,7 +78,7 @@ from wce_crm.logging import ( logger_get_data, logger_gui, ) -from wce_crm.types import ExtMaId, InitRecId +from wce_crm.types import ExtMaId, InitRecId, UserId if TYPE_CHECKING: ... @@ -1151,9 +1153,11 @@ class AutoForm(QWidget): def __init__( self, + session: Session, cfg: AutoFormConfig, ) -> None: super().__init__() + self.session = session self.cfg = cfg self.setStyleSheet(""" QGroupBox { @@ -2050,8 +2054,13 @@ class NewEntrySelect_view(QWidget): company_requested = Signal(bool) # Signal "Unternehmen" (bool: reset yes/no) person_requested = Signal() # Signal "Individualperson" - def __init__(self): + def __init__( + self, + session: Session, + ): super().__init__() + self.session = session + layout = QVBoxLayout(self) layout.setAlignment(Qt.AlignmentFlag.AlignTop | Qt.AlignmentFlag.AlignLeft) @@ -2123,8 +2132,13 @@ class Page_InitRecCompany(QWidget): update_triggered = Signal() # form saved (data changed for front page) company_profile_requested = Signal(InitRecId) - def __init__(self): + def __init__( + self, + session: Session, + ): super().__init__() + self.session = session + # Hauptlayout der Seite outer_layout = QHBoxLayout(self) vert_layout = QVBoxLayout() @@ -2193,7 +2207,7 @@ class Page_InitRecCompany(QWidget): # --- AUTO FORM LAYOUT --- container_layout.addSpacing(20) - self.auto_form = AutoForm(cfg=CONFIG_GRUNDERFASSUNG_UNTERNEHMEN) + self.auto_form = AutoForm(self.session, cfg=CONFIG_GRUNDERFASSUNG_UNTERNEHMEN) container_layout.addWidget(self.auto_form) self.auto_form.update_triggered.connect(lambda: self.update_triggered.emit()) @@ -2268,8 +2282,12 @@ class Page_InitRecPerson(QWidget): back_requested = Signal() # back button update_triggered = Signal() # form saved (data changed for front page) - def __init__(self): + def __init__( + self, + session: Session, + ): super().__init__() + self.session = session # Hauptlayout der Seite outer_layout = QHBoxLayout(self) vert_layout = QVBoxLayout() @@ -2328,7 +2346,7 @@ class Page_InitRecPerson(QWidget): # --- AUTO FORM LAYOUT --- container_layout.addSpacing(20) - self.auto_form = AutoForm(cfg=CONFIG_GRUNDERFASSUNG_PERSONEN) + self.auto_form = AutoForm(self.session, cfg=CONFIG_GRUNDERFASSUNG_PERSONEN) container_layout.addWidget(self.auto_form) self.auto_form.update_triggered.connect(lambda: self.update_triggered.emit()) @@ -2413,8 +2431,12 @@ class Page_CompanyProfile(QWidget): # update_triggered = Signal() # form saved (data changed for front page) consulting_requested = Signal(ConsultingRequest) - def __init__(self): + def __init__( + self, + session: Session, + ): super().__init__() + self.session = session # state management self.current_id: InitRecId = -1 @@ -2632,6 +2654,7 @@ class Page_CompanyProfile(QWidget): assert self.current_id > -1, ( "tried to call consulting from comp profile without set ID" ) + # TODO req = ConsultingRequest(cons_type=cons_type, un_id=self.current_id) self.consulting_requested.emit(req) @@ -2858,6 +2881,32 @@ class MasterDataFormWidget(QWidget): """) +@dc.dataclass(slots=True) +class Session: + user_id: UserId | None = None + user_name: str | None = None + + +@dc.dataclass(slots=True) +class Page_Consulting_State: + session: Session | None = None + un_id: InitRecId | None = None + pers_id: InitRecId | None = None + cons_type: ConsultingType | None = None + + +@dc.dataclass(slots=True) +class ConsultingSession: + user_id: UserId + user_name: str + timestamp: datetime.datetime + partner: str + interaction_scheme: str + topic: str # TODO should be linked to something, target unclear (need specification by customer) + notes: str + response: str + + class Page_Consulting(QWidget): back_main_requested = Signal() # back to main page back_requested = Signal(bool) # back to init rec (bool: reset yes/no) @@ -2865,10 +2914,16 @@ class Page_Consulting(QWidget): # more like listening to 'child' ("Beratungen") # update_triggered = Signal() # form saved (data changed for front page) - def __init__(self): + def __init__( + self, + session: Session, + ): super().__init__() + self.session = session # state management + self.STATE = Page_Consulting_State() + # self.current_id: InitRecId = -1 # self.COMPANY_FETAURES_MASTER_DATA: dict[str, str] = { # "ma_unternehmensname": "Name:", @@ -2965,6 +3020,19 @@ class Page_Consulting(QWidget): # container_layout.addWidget(self.title_company_name) container_layout.addWidget(QLabel("PLATZHALTER")) + self.type_pauschal_btn = QRadioButton("Pauschalberatung") + self.type_individual_btn = QRadioButton("Individualberatung") + + self.type_pauschal_btn.setChecked(True) + + self.type_group = QButtonGroup() + self.type_group.addButton(self.type_pauschal_btn, 0) + self.type_group.addButton(self.type_individual_btn, 1) + self.type_group.idClicked.connect(self.type_consulting_changed) + + container_layout.addWidget(self.type_pauschal_btn) + container_layout.addWidget(self.type_individual_btn) + container_layout.addSpacing(20) # separation in left and right @@ -3071,12 +3139,38 @@ class Page_Consulting(QWidget): # } # """) + # TODO placeholder, check if needed + def _sync_state_to_ui(self) -> None: ... + + def _sync_ui_to_state(self) -> None: ... + + def type_consulting_changed( + self, + button_id: int, + ) -> None: + logger_gui.debug("[Consultin Page] Trigger type buttons...") + + cons_type: ConsultingType + if button_id == 0: + cons_type = ConsultingType.PAUSCHAL + elif button_id == 1: + cons_type = ConsultingType.INDIVIUAL + else: + raise RuntimeError(f"No consulting type defined for button id: {button_id}") + + logger_gui.debug("[Consulting Page] Selected cons_type: %s", cons_type) + self.STATE.cons_type = cons_type + def load_from_request( self, req: ConsultingRequest, ) -> None: # TODO add correct loading behaviour + # TODO add validation (correct type with necessary information) logger_gui.debug("[Consulting] Loading with request:\n%s", req) + self.STATE.un_id = req.un_id + self.STATE.pers_id = req.pers_id + self.STATE.cons_type = req.cons_type # def set_company_name(self, name: str) -> None: # if not name: @@ -3148,6 +3242,7 @@ class MainWindow(QMainWindow): super().__init__() # STATE MANAGEMENT + self.session = Session(user_id=42, user_name="TEST-USER") self._history_stack: list[int] = [] self.setWindowTitle("Master") @@ -3165,32 +3260,32 @@ class MainWindow(QMainWindow): self.stack.addWidget(self.main_page) # SITE: add new entries for 'Grunderfassung' - self.new_entry_select = NewEntrySelect_view() + self.new_entry_select = NewEntrySelect_view(self.session) self.new_entry_select.back_requested.connect(self.show_main_page) self.new_entry_select.company_requested.connect(self.show_page_initrec_company) self.new_entry_select.person_requested.connect(self.show_page_initrec_person) self.stack.addWidget(self.new_entry_select) # SITE: 'Grunderfassung Unternehmen' - self.initrec_company = Page_InitRecCompany() + self.initrec_company = Page_InitRecCompany(self.session) self.initrec_company.back_main_requested.connect(self.show_main_page) self.initrec_company.back_requested.connect(self.show_new_entry_select) self.initrec_company.update_triggered.connect(self.update_grid) self.initrec_company.company_profile_requested.connect(self.show_page_company_profile) self.stack.addWidget(self.initrec_company) # SITE: 'Grunderfassung Person' - self.initrec_person = Page_InitRecPerson() + self.initrec_person = Page_InitRecPerson(self.session) self.initrec_person.back_main_requested.connect(self.show_main_page) self.initrec_person.back_requested.connect(self.show_new_entry_select) self.initrec_person.update_triggered.connect(self.update_grid) self.stack.addWidget(self.initrec_person) # SITE: 'Unternehmensprofil' - self.company_profile = Page_CompanyProfile() + self.company_profile = Page_CompanyProfile(self.session) self.company_profile.back_main_requested.connect(self.show_main_page) self.company_profile.back_requested.connect(self.show_page_initrec_company) self.company_profile.consulting_requested.connect(self.show_page_consulting) self.stack.addWidget(self.company_profile) # SITE: 'Beratungsgespräch' - self.consulting_page = Page_Consulting() + self.consulting_page = Page_Consulting(self.session) self.consulting_page.back_main_requested.connect(self.show_main_page) # self.consulting_page.back_requested.connect( # self.show_page_company_profile_without_load @@ -3366,6 +3461,7 @@ class MainWindow(QMainWindow): self.stack.setCurrentIndex(prev_idx) def show_main_page(self): + self._history_stack.clear() self._navigate_to_target(self.main_page) def show_new_entry_select(self): diff --git a/src/wce_crm/types.py b/src/wce_crm/types.py index edec434..38575a7 100644 --- a/src/wce_crm/types.py +++ b/src/wce_crm/types.py @@ -5,6 +5,7 @@ from typing import TYPE_CHECKING, TypeAlias if TYPE_CHECKING: import polars as pl +UserId: TypeAlias = int InitRecId: TypeAlias = int ExtMaId: TypeAlias = int ExtAnId: TypeAlias = int