Dev #7

Merged
foefl merged 74 commits from dev into main 2026-07-31 14:19:01 +00:00
Showing only changes of commit 04bfac8f53 - Show all commits
+340 -6
View File
@@ -3,6 +3,7 @@ from __future__ import annotations
import copy
import dataclasses as dc
import datetime
import enum
import pickle
import re
import sys
@@ -2392,12 +2393,25 @@ class Page_InitRecPerson(QWidget):
self.auto_form.reset_form()
class ConsultingType(enum.StrEnum):
PAUSCHAL = enum.auto()
INDIVIUAL = enum.auto()
@dc.dataclass(slots=True, kw_only=True)
class ConsultingRequest:
cons_type: ConsultingType
un_id: InitRecId | None = None
pers_id: InitRecId | None = None
class Page_CompanyProfile(QWidget):
back_main_requested = Signal() # back to main page
back_requested = Signal(bool) # back to init rec (bool: reset yes/no)
# TODO update should trigger something else
# more like listening to 'child' ("Beratungen")
# update_triggered = Signal() # form saved (data changed for front page)
consulting_requested = Signal(ConsultingRequest)
def __init__(self):
super().__init__()
@@ -2541,6 +2555,9 @@ class Page_CompanyProfile(QWidget):
)
top_right_layout.addWidget(common_consultancy_label)
top_right_new_btn = QPushButton("+ Hinzufügen")
top_right_new_btn.clicked.connect(
lambda: self._request_consulting(ConsultingType.PAUSCHAL)
)
top_right_new_btn.setSizePolicy(
QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed
)
@@ -2560,6 +2577,9 @@ class Page_CompanyProfile(QWidget):
)
bottom_right_layout.addWidget(individual_consultancy_label)
bottom_right_new_btn = QPushButton("+ Hinzufügen")
bottom_right_new_btn.clicked.connect(
lambda: self._request_consulting(ConsultingType.INDIVIUAL)
)
bottom_right_new_btn.setSizePolicy(
QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed
)
@@ -2605,6 +2625,16 @@ class Page_CompanyProfile(QWidget):
# }
# """)
def _request_consulting(
self,
cons_type: ConsultingType,
) -> None:
assert self.current_id > -1, (
"tried to call consulting from comp profile without set ID"
)
req = ConsultingRequest(cons_type=cons_type, un_id=self.current_id)
self.consulting_requested.emit(req)
def set_company_name(self, name: str) -> None:
if not name:
name = self.change_title_text.text()
@@ -2619,6 +2649,7 @@ class Page_CompanyProfile(QWidget):
id_: InitRecId,
) -> None:
assert id_ is not None, "tried to load with InitRecId None"
assert id_, "tried to load with invalid InitRecId"
logger_gui.debug(f"Called function to load with ID: {id_}")
if id_ < 0:
@@ -2827,6 +2858,271 @@ class MasterDataFormWidget(QWidget):
""")
class Page_Consulting(QWidget):
back_main_requested = Signal() # back to main page
back_requested = Signal(bool) # back to init rec (bool: reset yes/no)
# TODO update should trigger something else
# more like listening to 'child' ("Beratungen")
# 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()
# main_layout.setContentsMargins(0, 0, 0, 0)
outer_layout.addStretch(1)
outer_layout.addLayout(vert_layout, stretch=100)
outer_layout.addStretch(1)
# Optional: Damit der Container oben am Rand klebt
outer_layout.setAlignment(Qt.AlignmentFlag.AlignTop)
# --- HEADER ---
header_container = QWidget()
header_container.setMinimumWidth(700)
header_container.setMaximumWidth(1200)
header_container.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
header_layout = QVBoxLayout(header_container)
header_layout.setContentsMargins(0, 0, 0, 10)
back_btn_main = QPushButton("← Zurück zur Übersicht")
back_btn_main.clicked.connect(lambda: self.back_main_requested.emit())
back_btn_main.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
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(False))
back_btn_step.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
back_btn_step.setMinimumWidth(200)
back_btn_step.setMaximumWidth(200)
title = QLabel("Beratungsgespräch")
title.setStyleSheet("font-size: 20px; font-weight: bold;")
header_layout.setSpacing(5)
header_layout.addSpacing(15)
header_layout.addWidget(back_btn_step)
header_layout.addWidget(back_btn_main)
header_layout.addWidget(title)
vert_layout.addWidget(header_container)
# --- MAIN CONTENT ---
container = QWidget()
# SCROLL AREA
scroll_area = QScrollArea()
scroll_area.setWidgetResizable(True)
scroll_area.setMinimumWidth(700)
scroll_area.setMaximumWidth(1200)
scroll_area.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
# optional: remove frame to look more modern
scroll_area.setFrameShape(QFrame.Shape.NoFrame)
scroll_area.setWidget(container)
vert_layout.addWidget(scroll_area)
container_layout = QVBoxLayout(container)
container_layout.setContentsMargins(0, 0, 0, 0)
# --- MAIN LAYOUT ---
if DEBUG:
separator1 = QFrame()
separator1.setFrameShape(QFrame.Shape.HLine)
separator1.setFrameShadow(QFrame.Shadow.Sunken)
container_layout.addWidget(separator1)
# layout_change_title = QHBoxLayout()
# self.change_title_text = QLineEdit(placeholderText="Unternehmensname eingeben...")
# layout_change_title.addWidget(self.change_title_text)
# change_title_btn = QPushButton("ändern")
# layout_change_title.addWidget(change_title_btn)
# change_title_btn.clicked.connect(self.set_company_name)
# container_layout.addLayout(layout_change_title)
separator2 = QFrame()
separator2.setFrameShape(QFrame.Shape.HLine)
separator2.setFrameShadow(QFrame.Shadow.Sunken)
container_layout.addWidget(separator2)
container_layout.addSpacing(30)
# self.title_company_name = HeaderCell("Unternehmen: n.v.", font_size=16)
# container_layout.addWidget(self.title_company_name)
container_layout.addWidget(QLabel("PLATZHALTER"))
container_layout.addSpacing(20)
# separation in left and right
# main_hor_layout = QHBoxLayout()
# main_hor_layout.setSpacing(20)
# # main_hor_layout.setContentsMargins(20, 20, 20, 20)
# # left column
# left_frame = QFrame()
# left_frame.setObjectName("Segment")
# left_frame.setSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Maximum)
# left_layout = QVBoxLayout(left_frame)
# main_hor_layout.addWidget(left_frame, stretch=1, alignment=Qt.AlignmentFlag.AlignTop)
# master_data_label = HeaderCell("Stammdaten & Vermerke")
# master_data_label.setSizePolicy(
# QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed
# )
# left_layout.addWidget(master_data_label)
# # self.table_master_data = MasterDataTable()
# 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?"))
# # right column
# right_column_layout = QVBoxLayout()
# right_column_layout.setSpacing(20)
# main_hor_layout.addLayout(right_column_layout, stretch=1)
# # top right area
# top_right_frame = QFrame()
# top_right_frame.setObjectName("Segment")
# top_right_frame.setSizePolicy(
# QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Maximum
# )
# top_right_layout = QVBoxLayout(top_right_frame)
# common_consultancy_label = HeaderCell("Pauschalberatung")
# common_consultancy_label.setSizePolicy(
# QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed
# )
# top_right_layout.addWidget(common_consultancy_label)
# top_right_new_btn = QPushButton("+ Hinzufügen")
# top_right_new_btn.setSizePolicy(
# QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed
# )
# top_right_new_btn.setMinimumHeight(30)
# top_right_layout.addWidget(top_right_new_btn)
# # bottom right area
# bottom_right_frame = QFrame()
# bottom_right_frame.setObjectName("Segment")
# bottom_right_frame.setSizePolicy(
# QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Maximum
# )
# bottom_right_layout = QVBoxLayout(bottom_right_frame)
# individual_consultancy_label = HeaderCell("Individualberatung")
# individual_consultancy_label.setSizePolicy(
# QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed
# )
# bottom_right_layout.addWidget(individual_consultancy_label)
# bottom_right_new_btn = QPushButton("+ Hinzufügen")
# bottom_right_new_btn.setSizePolicy(
# QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed
# )
# bottom_right_new_btn.setMinimumHeight(30)
# bottom_right_layout.addWidget(bottom_right_new_btn)
# right_column_layout.addWidget(top_right_frame)
# right_column_layout.addWidget(bottom_right_frame)
# right_column_layout.addStretch(1)
# container_layout.addLayout(main_hor_layout)
container_layout.addStretch()
# --- STYLE ---
self.setStyleSheet("""
QFrame#Segment {
background-color: #ffffff;
border: 1px solid #e2e8f0;
border-radius: 12px;
padding: 3px;
}
""")
# self.setStyleSheet("""
# /* Hintergrund des Hauptfensters */
# QWidget {
# background-color: #f1f5f9;
# }
# /* Styling für unsere 3 Segmente */
# QFrame#Segment {
# background-color: #ffffff;
# border: 1px solid #e2e8f0;
# border-radius: 12px;
# padding: 15px;
# }
# /* Text-Styling */
# QLabel {
# color: #334155;
# font-size: 16px;
# font-weight: bold;
# }
# """)
def load_from_request(
self,
req: ConsultingRequest,
) -> None:
# TODO add correct loading behaviour
logger_gui.debug("[Consulting] Loading with request:\n%s", req)
# def set_company_name(self, name: str) -> None:
# if not name:
# name = self.change_title_text.text()
# if not name:
# name = "n.v."
# 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
# init_rec = backend.initrec_company_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_
def clear_layout(
layout: QLayout | None,
) -> None:
@@ -2850,6 +3146,10 @@ def clear_layout(
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
# STATE MANAGEMENT
self._history_stack: list[int] = []
self.setWindowTitle("Master")
self.resize(1800, 1000)
@@ -2887,7 +3187,16 @@ class MainWindow(QMainWindow):
self.company_profile = Page_CompanyProfile()
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.back_main_requested.connect(self.show_main_page)
# self.consulting_page.back_requested.connect(
# self.show_page_company_profile_without_load
# )
self.consulting_page.back_requested.connect(self.simple_go_back)
self.stack.addWidget(self.consulting_page)
def setup_main_page(self):
# QMainWindow defines frame --> container widget needed for the middle
@@ -3038,28 +3347,53 @@ class MainWindow(QMainWindow):
# 2. Auf die Detail-Seite umblättern
# self.stack.setCurrentWidget(self.detail_page)
def _navigate_to_target(
self,
widget: QWidget,
) -> None:
curr_idx = self.stack.currentIndex()
if curr_idx != -1:
self._history_stack.append(curr_idx)
self.stack.setCurrentWidget(widget)
def simple_go_back(self) -> None:
if not self._history_stack:
logger_gui.info("[main program] Called >back< on empty history")
prev_idx = self._history_stack.pop()
self.stack.setCurrentIndex(prev_idx)
def show_main_page(self):
# Zurück zur Tabelle blättern
self.stack.setCurrentWidget(self.main_page)
self._navigate_to_target(self.main_page)
def show_new_entry_select(self):
self.stack.setCurrentWidget(self.new_entry_select)
self._navigate_to_target(self.new_entry_select)
def show_page_initrec_company(self, reset: bool):
if reset:
self.initrec_company.reset_form()
self.stack.setCurrentWidget(self.initrec_company)
self._navigate_to_target(self.initrec_company)
def show_page_initrec_person(self):
# TODO: similar to company with reset?
self.initrec_person.reset_form()
self.stack.setCurrentWidget(self.initrec_person)
self._navigate_to_target(self.initrec_person)
def show_page_company_profile(
self,
id_: InitRecId,
) -> None:
self.company_profile.load_from_id(id_)
self.stack.setCurrentWidget(self.company_profile)
self._navigate_to_target(self.company_profile)
def show_page_consulting(
self,
req: ConsultingRequest,
) -> None:
self.consulting_page.load_from_request(req)
self._navigate_to_target(self.consulting_page)
# --- MENÜ LOGIK ---
def create_menu(self):