Dev #7

Merged
foefl merged 74 commits from dev into main 2026-07-31 14:19:01 +00:00
3 changed files with 114 additions and 157 deletions
Showing only changes of commit ba26baa225 - Show all commits
+13 -11
View File
@@ -75,7 +75,8 @@ def initrec_comp_search_choices() -> tuple[tuple[str, int], ...]:
return tuple(zip(df["dedupl"], df["ma_id"]))
def initrec_comp_search_get_info(
# TODO change to direct SQL interaction
def external_company_get_info(
ma_id: ExtMaId,
) -> CompanyInfo:
logger.debug("[Call backend] comp_search_get_info")
@@ -858,11 +859,11 @@ def page_consulting_linking_companies(
with db.ENGINE.connect() as conn:
q_relevant_companies = sa.select(
db.grunderfassung_unternehmen.c.un_id,
db.grunderfassung_unternehmen.c.Partnersuche__un_suche,
db.t_unternehmen.c.un_id,
db.t_unternehmen.c.Partnersuche__un_suche,
).where(
db.grunderfassung_unternehmen.c.geloescht.is_(None),
db.grunderfassung_unternehmen.c.Partnersuche__un_suche.is_not(None),
db.t_unternehmen.c.geloescht.is_(None),
db.t_unternehmen.c.Partnersuche__un_suche.is_not(None),
)
if un_id is not None:
q_relevant_companies = q_relevant_companies.where(
@@ -904,6 +905,8 @@ def page_consulting_linking_companies(
def page_consulting_linking_persons(
un_id: RecId | None,
) -> list[LinkingConsultationsEntryPerson]:
raise RuntimeError("TODOs to implement")
with db.ENGINE.connect() as conn:
# if un_id None: list all persons
# else: list just the persons associated with the company
@@ -958,6 +961,7 @@ def page_consulting_eastablish_link(
un_id: RecId | None,
pers_id: RecId | None,
) -> None:
raise RuntimeError("TODOs to implement")
stmt = (
sa.update(db.t_beratung_vorgang)
@@ -969,6 +973,7 @@ def page_consulting_eastablish_link(
conn.execute(stmt)
# // company profile interaction
def companyprofile_page_get_consultations(
un_id: RecId,
) -> CompanyProfileConsultations:
@@ -994,11 +999,8 @@ def companyprofile_page_get_consultations(
datetime_updated = cast(datetime.datetime, entry["aktualisiert"])
datetime_updated = datetime_updated.astimezone(TIMEZONE_CEST)
base_title = entry["titel"]
_cons_type = entry["beratungs_typ"]
cons_type = ConsultingType(_cons_type)
cons_type = ConsultingType(entry["beratungs_typ"])
con_entry = CompanyProfileConsultationEntry(
cons_id=cons_id,
@@ -1012,7 +1014,7 @@ def companyprofile_page_get_consultations(
elif cons_type is ConsultingType.INDIVIDUAL:
cons_entries_individual.append(con_entry)
else:
raise TypeError(f"Unknown consulting type: {_cons_type}")
raise TypeError(f"Unknown consulting type: {cons_type}")
cons_entries_pauschal.sort(key=lambda x: x.date_updated, reverse=True)
cons_entries_individual.sort(key=lambda x: x.date_updated, reverse=True)
@@ -1081,7 +1083,7 @@ def _main_page_get_company_list() -> list[MainPageEntry]:
datetime_akt = cast(datetime.datetime, entry["Metadaten_aktualisierung"])
datetime_akt = datetime_akt.astimezone(TIMEZONE_CEST)
comp_info = initrec_comp_search_get_info(ma_id_external)
comp_info = external_company_get_info(ma_id_external)
display_name = comp_info["ma_unternehmensname"]
main_page_companies.append(
+3 -4
View File
@@ -20,11 +20,11 @@ from pydantic import (
from pydantic_core import ErrorDetails
from wce_crm.form_defs import INITREC_COMP, INITREC_PERSON, FormField
from wce_crm.types import EntityIds, EntityType, RecordingType
from wce_crm.types import ConsultingType, EntityIds, EntityType, RecordingType
if TYPE_CHECKING:
from wce_crm.gui import InitRecForm, Page_Consulting_ConsultingSession # noqa: F401
from wce_crm.types import ConsId, ConsultingType, EntityType, RecId, UserId
from wce_crm.types import ConsId, EntityType, RecId, UserId
ValidAge = Annotated[int, Field(ge=0, le=99)]
COLUMN_SEP: Final[str] = "__"
@@ -354,8 +354,7 @@ class Page_Consulting_Table_State(PageState["Page_Consulting_ConsultingSession"]
@dc.dataclass(slots=True, kw_only=True)
class Page_CompanyProfile_State(PageState[Module]):
session: Session
ids: EntityIds
# rec_id: RecId | None = None
un_id: RecId | None = None
# // Pydantic models
+98 -142
View File
@@ -85,7 +85,6 @@ from wce_crm.backend import backend
from wce_crm.constants import TIMEZONE_CEST
from wce_crm.data_models import (
COLUMN_SEP,
INITREC_CONFIGS,
Beratungsgespraech_Einzelgespraech,
Beratungsgespraech_Vorgang,
InitRec,
@@ -128,7 +127,6 @@ if TYPE_CHECKING:
from wce_crm.data_models import (
Module,
Page_InitRec_Form_State,
WrapperModule,
)
from wce_crm.types import (
ConsId,
@@ -1273,7 +1271,7 @@ class Grunderfassung_SuchWidget(CustomFormWidget):
if ma_id is None or index == (-1):
self._clear_company_fields()
return
data = backend.initrec_comp_search_get_info(
data = backend.external_company_get_info(
ma_id=ma_id,
)
self.fill_out_company(data)
@@ -1378,7 +1376,7 @@ def search_widgets_by_key(
class InitRecForm(QWidget):
"""a widget, which is managed by a code-defined field definition collection"""
update_triggered = Signal() # formular saved (data changed for front page)
# update_triggered = Signal() # formular saved (data changed for front page)
def __init__(
self,
@@ -1425,54 +1423,54 @@ class InitRecForm(QWidget):
self.main_layout = QVBoxLayout(self)
self.main_layout.setContentsMargins(0, 0, 0, 0)
if DEBUG:
separator1 = QFrame()
separator1.setFrameShape(QFrame.Shape.HLine)
separator1.setFrameShadow(QFrame.Shadow.Sunken)
self.main_layout.addWidget(separator1)
# if DEBUG:
# separator1 = QFrame()
# separator1.setFrameShape(QFrame.Shape.HLine)
# separator1.setFrameShadow(QFrame.Shadow.Sunken)
# self.main_layout.addWidget(separator1)
self.registry_button = QPushButton("Ausgabe Widget Registry")
self.registry_button.clicked.connect(self._print_registry)
self.registry_button.setFixedHeight(35)
self.main_layout.addWidget(self.registry_button)
# self.registry_button = QPushButton("Ausgabe Widget Registry")
# self.registry_button.clicked.connect(self._print_registry)
# self.registry_button.setFixedHeight(35)
# self.main_layout.addWidget(self.registry_button)
# self.test_button = QPushButton("Initialisiere Laden")
# self.test_button.clicked.connect(self.load_from_ids)
# self.test_button.setFixedHeight(35)
# self.test_button.setSizePolicy(
# QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed
# )
# self.main_layout.addWidget(self.test_button)
# # self.test_button = QPushButton("Initialisiere Laden")
# # self.test_button.clicked.connect(self.load_from_ids)
# # self.test_button.setFixedHeight(35)
# # self.test_button.setSizePolicy(
# # QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed
# # )
# # self.main_layout.addWidget(self.test_button)
button_get = QPushButton("GET DATA")
button_get.setFixedHeight(35)
button_get.clicked.connect(self._get_data)
self.main_layout.addWidget(button_get)
button_set = QPushButton("SET DATA")
button_set.setFixedHeight(35)
button_set.clicked.connect(self._set_data)
self.main_layout.addWidget(button_set)
# button_get = QPushButton("GET DATA")
# button_get.setFixedHeight(35)
# button_get.clicked.connect(self._get_data)
# self.main_layout.addWidget(button_get)
# button_set = QPushButton("SET DATA")
# button_set.setFixedHeight(35)
# button_set.clicked.connect(self._set_data)
# self.main_layout.addWidget(button_set)
id_field_layout = QHBoxLayout()
id_field_layout.setContentsMargins(0, 0, 0, 0)
id_field_layout.setSpacing(5)
id_field_label = QLabel("ID Datenbank:")
self.id_field_input = QLineEdit()
id_field_layout.addWidget(id_field_label)
id_field_layout.addWidget(self.id_field_input)
self.main_layout.addLayout(id_field_layout)
button_db_index = QPushButton("Setze DB Index")
button_db_index.setFixedHeight(35)
button_db_index.clicked.connect(self._set_db_index)
self.main_layout.addWidget(button_db_index)
# id_field_layout = QHBoxLayout()
# id_field_layout.setContentsMargins(0, 0, 0, 0)
# id_field_layout.setSpacing(5)
# id_field_label = QLabel("ID Datenbank:")
# self.id_field_input = QLineEdit()
# id_field_layout.addWidget(id_field_label)
# id_field_layout.addWidget(self.id_field_input)
# self.main_layout.addLayout(id_field_layout)
# button_db_index = QPushButton("Setze DB Index")
# button_db_index.setFixedHeight(35)
# button_db_index.clicked.connect(self._set_db_index)
# self.main_layout.addWidget(button_db_index)
separator2 = QFrame()
separator2.setFrameShape(QFrame.Shape.HLine)
separator2.setFrameShadow(QFrame.Shadow.Sunken)
self.main_layout.addWidget(separator2)
self.main_layout.addSpacing(5)
# separator2 = QFrame()
# separator2.setFrameShape(QFrame.Shape.HLine)
# separator2.setFrameShadow(QFrame.Shadow.Sunken)
# self.main_layout.addWidget(separator2)
# self.main_layout.addSpacing(5)
self.main_layout.addSpacing(10)
# self.main_layout.addSpacing(10)
# buttons (save and reset)
self.add_buttons = self.cfg.add_buttons
@@ -1519,14 +1517,14 @@ class InitRecForm(QWidget):
def _print_registry(self) -> None:
pprint_registry(self.widget_registry)
def _set_db_index(self) -> None:
try:
index = int(self.id_field_input.text())
except ValueError:
index = None
self.STATE.ids.un_id = index
self.STATE.ids.pers_id = index
logger_gui.debug("[InitRecForm] Set index to %s, new state: %s", index, self.STATE)
# def _set_db_index(self) -> None:
# try:
# index = int(self.id_field_input.text())
# except ValueError:
# index = None
# self.STATE.ids.un_id = index
# self.STATE.ids.pers_id = index
# logger_gui.debug("[InitRecForm] Set index to %s, new state: %s", index, self.STATE)
# def _disable_save(self) -> None:
# assert self.save_btn is not None
@@ -3104,6 +3102,7 @@ class Page_InitRec(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(Page_CompanyProfile_State)
def __init__(
self,
@@ -3153,6 +3152,15 @@ class Page_InitRec(QWidget):
header_layout.addWidget(back_btn_step)
header_layout.addWidget(back_btn_main)
header_layout.addWidget(title)
self.comp_profile_btn = QPushButton("Unternehmensprofil")
self.comp_profile_btn.clicked.connect(self._request_company_profile)
self.comp_profile_btn.setSizePolicy(
QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed
)
self.comp_profile_btn.setFixedHeight(50)
header_layout.addWidget(self.comp_profile_btn)
vert_layout.addWidget(header_container)
if DEBUG:
@@ -3185,36 +3193,6 @@ class Page_InitRec(QWidget):
)
header_layout.addWidget(btn_print_state)
# self.test_button = QPushButton("Initialisiere Laden")
# self.test_button.clicked.connect(self._load_from_id)
# self.test_button.setFixedHeight(35)
# self.test_button.setSizePolicy(
# QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed
# )
# header_layout.addWidget(self.test_button)
# button_get = QPushButton("GET DATA")
# button_get.setFixedHeight(35)
# button_get.clicked.connect(self._get_form_data)
# header_layout.addWidget(button_get)
# button_set = QPushButton("SET DATA")
# button_set.setFixedHeight(35)
# button_set.clicked.connect(self._set_form_data)
# header_layout.addWidget(button_set)
# id_field_layout = QHBoxLayout()
# id_field_layout.setContentsMargins(0, 0, 0, 0)
# id_field_layout.setSpacing(5)
# id_field_label = QLabel("ID Datenbank:")
# self.id_field_input = QLineEdit()
# id_field_layout.addWidget(id_field_label)
# id_field_layout.addWidget(self.id_field_input)
# header_layout.addLayout(id_field_layout)
# button_db_index = QPushButton("Setze DB Index")
# button_db_index.setFixedHeight(35)
# button_db_index.clicked.connect(self._set_db_index)
# header_layout.addWidget(button_db_index)
separator2 = QFrame()
separator2.setFrameShape(QFrame.Shape.HLine)
separator2.setFrameShadow(QFrame.Shadow.Sunken)
@@ -3279,12 +3257,6 @@ class Page_InitRec(QWidget):
self.STATE.child_modules.append(self.initrec_form_person)
self.initrec_form_person_box.setContentWidget(self.initrec_form_person)
self.container_layout.addWidget(self.initrec_form_person_box)
# container_layout.addSpacing(15)
# TODO trigger needed?
# self.initrec_form_person.update_triggered.connect(
# lambda: self.update_triggered.emit()
# )
# self.initrec_form_person.update_triggered.connect(self._auto_form_updated)
# --- CUSTOM LOGIC ---
# ** 'Bundesland' only if 'Inland' selected in 'Stammdaten'
@@ -3318,13 +3290,6 @@ class Page_InitRec(QWidget):
self.initrec_form_company_box.setContentWidget(self.initrec_form_company)
self.container_layout.insertWidget(target_idx, self.initrec_form_company_box)
# container_layout.addSpacing(15)
# TODO trigger needed?
# self.initrec_form_person.update_triggered.connect(
# lambda: self.update_triggered.emit()
# )
# self.initrec_form_person.update_triggered.connect(self._auto_form_updated)
# --- CUSTOM LOGIC ---
# ** fill 'Kontaktperson -> Namen Unternehmen'
search_res = search_widgets_by_key(
@@ -3344,35 +3309,31 @@ class Page_InitRec(QWidget):
"[Page -- InitRec] Printing state IDs:\n%s", pformat(self.STATE.ids)
)
def _request_company_profile(self) -> None:
assert self.STATE.ids.un_id is not None, (
"requested company profile for a company which is not known (no ID)"
)
req_state = Page_CompanyProfile_State(
session=self.STATE.session,
un_id=self.STATE.ids.un_id,
)
logger_gui.debug("[Page -- InitRec Company] State to call: %s", req_state)
self.company_profile_requested.emit(req_state)
def _update_layout(self) -> None:
if self.STATE.recording_type is RecordingType.WITH_COMPANY:
# add company
self.initrec_form_company_box.setVisible(True)
self.comp_profile_btn.setVisible(True)
if self.STATE.ids.valid(EntityType.COMPANY):
self.comp_profile_btn.setEnabled(True)
else:
self.comp_profile_btn.setEnabled(False)
else:
self.initrec_form_company_box.setVisible(False)
# elif self.initrec_form_company_box is not None:
# self.container_layout.removeWidget(self.initrec_form_company_box)
# # ** state
# assert self.initrec_form_company
# self.STATE.child_modules.remove(self.initrec_form_company)
# del self.STATE.initrec_form_states[EntityType.COMPANY]
# self.initrec_form_company_box = None
# self.initrec_form_company = None
# def _set_new_initrec_state(
# self,
# ent_type: EntityType,
# ) -> None:
# initrec_form_state = Page_InitRec_Form_State(
# session=self.STATE.session,
# cfg=INITREC_CONFIGS[ent_type],
# ids=self.STATE.ids,
# ent_type=ent_type,
# locked=False,
# )
# self.STATE.initrec_form_states[ent_type] = initrec_form_state
self.comp_profile_btn.setVisible(False)
self.comp_profile_btn.setEnabled(False)
# ** custom logic
def _custom_county_selection(self, idx: int) -> None:
@@ -4099,13 +4060,13 @@ class Page_CompanyProfile(QWidget):
self,
cons_type: ConsultingType,
) -> None:
assert self.STATE.ids.un_id is not None, (
assert self.STATE.un_id is not None, (
"tried to call consulting from comp profile without set ID"
)
new_state = Page_Consulting_State(
session=self.STATE.session,
vorgang_id=None,
un_id=self.STATE.ids.un_id,
un_id=self.STATE.un_id,
beratungs_typ=cons_type,
locked=False,
)
@@ -4115,13 +4076,13 @@ class Page_CompanyProfile(QWidget):
self,
data: CompanyProfileConsultationEntry,
) -> None:
assert self.STATE.ids.un_id is not None, (
assert self.STATE.un_id is not None, (
"tried to call consulting from comp profile without set ID"
)
new_state = Page_Consulting_State(
session=self.STATE.session,
vorgang_id=data.cons_id,
un_id=self.STATE.ids.un_id,
un_id=self.STATE.un_id,
beratungs_typ=data.cons_type,
locked=True,
)
@@ -4143,11 +4104,9 @@ class Page_CompanyProfile(QWidget):
widget.deleteLater()
def _update_consultations(self) -> None:
if self.STATE.ids.un_id is None:
if self.STATE.un_id is None:
return
consultations = backend.companyprofile_page_get_consultations(
un_id=self.STATE.ids.un_id
)
consultations = backend.companyprofile_page_get_consultations(un_id=self.STATE.un_id)
logger_gui.debug(
"[Page -- Company Profile] Consultations: %s", pformat(consultations)
@@ -4185,7 +4144,7 @@ class Page_CompanyProfile(QWidget):
self.add_btn_individual.setEnabled(True)
def _sync_state_to_GUI(self) -> None:
if self.STATE.ids.un_id is None:
if self.STATE.un_id is None:
# just clear and do nothing else
logger_gui.debug("just reset, ID is None")
self.table_master_data.reset()
@@ -4195,11 +4154,11 @@ class Page_CompanyProfile(QWidget):
self._enable_add_btns()
# TODO change to correct backend function
raise RuntimeError("TODOs to implement")
init_rec = backend.initrec_company_get_initial_recording(self.STATE.ids.un_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)
# raise RuntimeError("TODOs to implement")
# init_rec = backend.initrec_company_get_initial_recording(self.STATE.un_id)
# ma_id = cast("ExtMaId", init_rec["Partnersuche__un_suche"])
# assert ma_id is not None, "no ma_id obtained"
comp_info = backend.external_company_get_info(self.STATE.un_id)
data: dict[str, Any] = {}
@@ -4221,8 +4180,8 @@ class Page_CompanyProfile(QWidget):
self,
new_state: Page_CompanyProfile_State,
) -> None:
logger_gui.debug("Called function to load with IDs: %s", pformat(new_state.ids))
self.STATE.ids = new_state.ids
logger_gui.debug("Called function to load with ID: %s", pformat(new_state.un_id))
self.STATE.un_id = new_state.un_id
self._sync_state_to_GUI()
@@ -6213,7 +6172,8 @@ class MainWindow(QMainWindow):
self.newinitrec = Page_InitRec(newinitrec_state)
self.newinitrec.back_main_requested.connect(self.show_main_page)
self.newinitrec.back_requested.connect(self.simple_go_back)
# self.newinitrec.update_main_page.connect(self.update_grid)
self.newinitrec.company_profile_requested.connect(self.show_page_company_profile)
# self.newinitrec.update_triggered.connect(self.update_grid)
self.stack.addWidget(self.newinitrec)
# SITE: 'Grunderfassung Unternehmen'
@@ -6239,9 +6199,7 @@ class MainWindow(QMainWindow):
# self.initrec_person.update_triggered.connect(self.update_grid)
# self.stack.addWidget(self.initrec_person)
# SITE: 'Unternehmensprofil'
comp_profile_state = Page_CompanyProfile_State(
session=self.STATE.session, ids=EntityIds()
)
comp_profile_state = Page_CompanyProfile_State(session=self.STATE.session)
self.company_profile = Page_CompanyProfile(comp_profile_state)
self.company_profile.back_main_requested.connect(self.show_main_page)
# TODO remove
@@ -6526,8 +6484,6 @@ if TYPE_CHECKING:
_m3: type[Module] = Page_Consulting_ConsultingSession
_m4: type[Module] = Page_InitRec
_m5: type[Module] = InitRecForm
# _w1: type[WrapperModule] = Page_InitRecCompany
# _w2: type[WrapperModule] = Page_InitRecPerson
_f1: type[CustomForm] = DynamicListWidget
_f2: type[CustomForm] = DynamicDropdownWidgetNumeric
_f3: type[CustomForm] = DynamicDropdownWidgetOption