generated from dopt-python/py311
prepare document selection widget
This commit is contained in:
@@ -19,7 +19,7 @@ assert BASE_PATH
|
||||
|
||||
class Config:
|
||||
DEVELOPMENT_STATE: bool = bool(os.getenv("DOPT_DEVELOPMENT", None))
|
||||
DB_PATH_CRM: Path = BASE_PATH / os.getenv("DOPT_DB_CRM", "data/db/wce_crm.db")
|
||||
DB_PATH_KONTAKTLISTE: Path = BASE_PATH / os.getenv("DOPT_DB_CRM", "data/db/wce_crm.db")
|
||||
DB_PATH_MAIN: Path = BASE_PATH / os.getenv(
|
||||
"DOPT_DB_MAIN", "data/db/wce_grunderfassung.db"
|
||||
)
|
||||
|
||||
@@ -5,6 +5,7 @@ import dataclasses as dc
|
||||
import datetime
|
||||
import json
|
||||
from collections.abc import Iterable, Sequence
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Annotated, Any, Final, Generic, Protocol, TypeVar
|
||||
|
||||
from dopt_basics.datastructures import DualDict
|
||||
@@ -265,6 +266,34 @@ class Page_InitRec_Form_State(PageState[Module]):
|
||||
geloescht: bool = False
|
||||
|
||||
|
||||
@dc.dataclass(slots=True, kw_only=True)
|
||||
class Page_InitRec_DocumentSection_State:
|
||||
session: Session
|
||||
pers_id: int | None
|
||||
docs: list[Page_InitRec_DocumentSection_Doc_State] = dc.field(default_factory=list)
|
||||
locked: bool
|
||||
geloescht: bool = False
|
||||
|
||||
@property
|
||||
def doc_count(self) -> int:
|
||||
return len(self.docs)
|
||||
|
||||
|
||||
@dc.dataclass(slots=True, kw_only=True)
|
||||
class Page_InitRec_DocumentSection_Doc_State:
|
||||
id: int | None
|
||||
pers_id: int | None
|
||||
datum_erstellt_utc: datetime.datetime = dc.field(
|
||||
default_factory=lambda: datetime.datetime.now(datetime.UTC)
|
||||
)
|
||||
|
||||
speicher_pfad: Path
|
||||
dateiname_original: str
|
||||
dateigroesse: int | None
|
||||
locked: bool
|
||||
geloescht: bool = False
|
||||
|
||||
|
||||
@dc.dataclass(slots=True, kw_only=True)
|
||||
class Page_Consulting_State(PageState[Module]):
|
||||
session: Session
|
||||
|
||||
+19
-8
@@ -45,29 +45,40 @@ class UTCDateTime(TypeDecorator):
|
||||
if value is not None:
|
||||
# Ensure it's converted to UTC before saving
|
||||
if value.tzinfo is None:
|
||||
value = value.replace(tzinfo=datetime.timezone.utc)
|
||||
value = value.replace(tzinfo=datetime.UTC)
|
||||
else:
|
||||
value = value.astimezone(datetime.timezone.utc)
|
||||
value = value.astimezone(datetime.UTC)
|
||||
return value
|
||||
|
||||
def process_result_value(self, value, dialect):
|
||||
"""Runs when fetching from the database."""
|
||||
if value is not None and value.tzinfo is None:
|
||||
# Explicitly tell Python this data *is* UTC
|
||||
value = value.replace(tzinfo=datetime.timezone.utc)
|
||||
value = value.replace(tzinfo=datetime.UTC)
|
||||
return value
|
||||
|
||||
|
||||
MD_CRM = sa.MetaData()
|
||||
MD_MAIN = sa.MetaData()
|
||||
ENGINE = sa.create_engine(f"sqlite:///{constants.Config.DB_PATH_MAIN}")
|
||||
URL_MAIN = sa.engine.URL.create(
|
||||
"sqlite+pysqlite",
|
||||
database=str(constants.Config.DB_PATH_MAIN),
|
||||
)
|
||||
ENGINE = sa.create_engine(
|
||||
URL_MAIN,
|
||||
connect_args={"uri": True, "timeout": 0.5},
|
||||
)
|
||||
|
||||
KONTAKTLISTE_URI = constants.Config.DB_PATH_KONTAKTLISTE.as_uri() + "?mode=ro"
|
||||
|
||||
|
||||
@event.listens_for(ENGINE, "connect")
|
||||
def attach_second_db(dbapi_connection, connection_record):
|
||||
def _db_conn_event(dbapi_connection, connection_record):
|
||||
cursor = dbapi_connection.cursor()
|
||||
# 'kontaktliste' is the alias for the second DB
|
||||
cursor.execute(f"ATTACH DATABASE '{constants.Config.DB_PATH_CRM}' AS kontaktliste")
|
||||
cursor.execute("ATTACH DATABASE ? AS kontaktliste", (KONTAKTLISTE_URI,))
|
||||
# enable foreign keys
|
||||
cursor.execute("PRAGMA foreign_keys=ON")
|
||||
cursor.close()
|
||||
|
||||
|
||||
@@ -146,7 +157,7 @@ def get_ext_crm_master(
|
||||
return pl.read_database(stmt, engine, schema_overrides=ext_crm_master_schema)
|
||||
|
||||
|
||||
DF_CRM_MASTER = get_ext_crm_master(constants.Config.DB_PATH_CRM)
|
||||
DF_CRM_MASTER = get_ext_crm_master(constants.Config.DB_PATH_KONTAKTLISTE)
|
||||
|
||||
ext_crm_nutzer: Table = Table(
|
||||
"Nutzer",
|
||||
@@ -253,7 +264,7 @@ def get_ext_crm_contact_person(
|
||||
|
||||
|
||||
# df_contact_person = get_ext_crm_contact_person(None)
|
||||
DF_CONTACT_PERSON = get_ext_crm_contact_person(constants.Config.DB_PATH_CRM)
|
||||
DF_CONTACT_PERSON = get_ext_crm_contact_person(constants.Config.DB_PATH_KONTAKTLISTE)
|
||||
|
||||
t_ext_crm_master_attach: Table = Table(
|
||||
"Master",
|
||||
|
||||
@@ -132,7 +132,7 @@ class CountryList:
|
||||
|
||||
|
||||
def get_country_list_german() -> CountryList:
|
||||
locale = babel.Locale("de", "DE")
|
||||
locale = babel.Locale("en", "GB")
|
||||
countries: list[tuple[str, str]] = []
|
||||
iso_to_country: dict[str, str] = {}
|
||||
|
||||
@@ -938,7 +938,7 @@ INITREC_PERSON = [
|
||||
trigger_value="ja",
|
||||
children=[
|
||||
FormField(
|
||||
"Relevanz",
|
||||
"Relevant perspektivERZ",
|
||||
FormFieldType.DROPDOWN,
|
||||
required=True,
|
||||
options=[("ja", None), ("nein", None)],
|
||||
|
||||
+21
-6
@@ -3256,7 +3256,7 @@ class Page_InitRec(QWidget):
|
||||
self.modify_btn.modify_activated.connect(self.unlock)
|
||||
self.modify_btn.modify_deactivated.connect(self.lock)
|
||||
self.save_btn.clicked.connect(self.save_data)
|
||||
self.reset_btn.clicked.connect(self._reset)
|
||||
self.reset_btn.clicked.connect(self._trigger_reset_btn)
|
||||
self.delete_btn.clicked.connect(self._delete_data)
|
||||
header_layout.addSpacing(5)
|
||||
header_layout.addWidget(self.edit_buttons)
|
||||
@@ -3477,6 +3477,21 @@ class Page_InitRec(QWidget):
|
||||
)
|
||||
return all(valid_id_states)
|
||||
|
||||
def _trigger_reset_btn(self) -> None:
|
||||
assert not self.STATE.locked, "reset initialised, even though form is locked"
|
||||
confirm = get_user_confirmation(
|
||||
self,
|
||||
"Zurücksetzen bestätigen",
|
||||
(
|
||||
"Soll der Eintrag wirklich zurückgesetzt werden? Alle nicht "
|
||||
"gespeicherten Änderungen gehen verloren."
|
||||
),
|
||||
)
|
||||
if not confirm:
|
||||
return
|
||||
|
||||
self._sync_state_to_GUI(None)
|
||||
|
||||
def _delete_data(self) -> None:
|
||||
assert self._deletion_valid(), "deletion initialised despite IDs are not properly set"
|
||||
confirm = get_user_confirmation(
|
||||
@@ -3525,7 +3540,6 @@ class Page_InitRec(QWidget):
|
||||
return
|
||||
|
||||
# TODO add loading logic with backend call
|
||||
# !! just a dummy
|
||||
initrec = backend.page_initrec_from_db(ids)
|
||||
|
||||
# TODO re-enable later
|
||||
@@ -4589,6 +4603,7 @@ class Page_Consulting(QWidget):
|
||||
container_layout.addWidget(self.info_banners_container)
|
||||
|
||||
# --- BUTTONS ---
|
||||
# TODO check if no reset button is correct
|
||||
self.edit_buttons = EditButtons(add_modify_btn=True, add_reset_btn=False)
|
||||
modify_btn = self.edit_buttons.modify_button
|
||||
assert modify_btn
|
||||
@@ -6165,7 +6180,7 @@ class EditButtons(QWidget):
|
||||
self.save_btn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
|
||||
layout_btn.addWidget(self.save_btn)
|
||||
# reset
|
||||
self.reset_button: QPushButton | None = None
|
||||
self.reset_btn: QPushButton | None = None
|
||||
if add_reset_btn:
|
||||
self.reset_btn = QPushButton("Zurücksetzen (Strg + Z)")
|
||||
self.reset_btn.setShortcut("Ctrl+Z")
|
||||
@@ -6185,12 +6200,15 @@ class EditButtons(QWidget):
|
||||
self,
|
||||
enable_modification: bool,
|
||||
set_delete_btn: bool = True,
|
||||
set_reset_btn: bool = True,
|
||||
) -> None:
|
||||
if self.modify_button is not None:
|
||||
self.modify_button.set_modify_state(enable_modification)
|
||||
self.save_btn.setEnabled(enable_modification)
|
||||
if set_delete_btn:
|
||||
self.delete_btn.setEnabled(enable_modification)
|
||||
if self.reset_btn is not None and set_reset_btn:
|
||||
self.reset_btn.setEnabled(enable_modification)
|
||||
|
||||
|
||||
class MainWindow(QMainWindow):
|
||||
@@ -6220,8 +6238,6 @@ class MainWindow(QMainWindow):
|
||||
new_initrec_select_state = Page_NewEntry_State(session=self.STATE.session)
|
||||
self.new_entry_select = Page_NewEntry(new_initrec_select_state)
|
||||
self.new_entry_select.back_requested.connect(self.show_main_page)
|
||||
# self.new_initrec_select.company_requested.connect(self.show_page_initrec_company)
|
||||
# self.new_initrec_select.person_requested.connect(self.show_page_initrec_person)
|
||||
self.new_entry_select.new_consulting_requested.connect(self.show_page_consulting)
|
||||
self.new_entry_select.new_initrec_requested.connect(self.show_page_initrec)
|
||||
self.stack.addWidget(self.new_entry_select)
|
||||
@@ -6504,7 +6520,6 @@ def qt_message_handler(mode, context, message):
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
# TODO add all relevant modules
|
||||
# enable static type checking for the protocol
|
||||
_m1: type[Module] = Page_Consulting
|
||||
_m2: type[Module] = Page_Consulting_Table
|
||||
|
||||
Reference in New Issue
Block a user