basic saving and loading of consultation sessions

This commit is contained in:
2026-07-10 11:52:49 +02:00
parent 6f7593ac9d
commit 7c79bf8e91
2 changed files with 346 additions and 122 deletions
+143 -44
View File
@@ -6,10 +6,11 @@ from typing import TYPE_CHECKING, Any, cast
import polars as pl
import sqlalchemy as sql
from dopt_basics.result_pattern import wrap_result
from wce_crm import db
from wce_crm.constants import TIMEZONE_CEST
from wce_crm.data_models import Beratungsgespraech_Vorgang
from wce_crm.data_models import Beratungsgespraech_Einzelgespraech, Beratungsgespraech_Vorgang
from wce_crm.logging import logger_back as logger
from wce_crm.types import CompanyInfo, ContactPersonInfo, InitRecType, MainPageEntry
@@ -140,16 +141,19 @@ def initrec_company_get_initial_recording(
stmt = db.grunderfassung_unternehmen.select().where(
db.grunderfassung_unternehmen.c.un_id == id_
)
with db.ENGINE.begin() as conn:
with db.ENGINE.connect() as conn:
ret = conn.execute(stmt)
if ret.rowcount == 0:
raise KeyError(f"Database ID {id_} not found")
results = ret.mappings().all()
if not results:
raise KeyError(f"Database ID {id_} not found")
row = ret.fetchone()
assert len(results) == 1, "more than one company initial recording obtained"
row = results[0]
assert row, "row was not obtained"
return row._asdict() # type: ignore
return dict(row)
def initrec_company_delete_initial_recording(
@@ -202,16 +206,19 @@ def initrec_person_get_initial_recording(
stmt = db.grunderfassung_personen.select().where(
db.grunderfassung_personen.c.pers_id == id_
)
with db.ENGINE.begin() as conn:
with db.ENGINE.connect() as conn:
ret = conn.execute(stmt)
if ret.rowcount == 0:
raise KeyError(f"Database ID {id_} not found")
results = ret.mappings().all()
if not results:
raise KeyError(f"Database ID {id_} not found")
row = ret.fetchone()
assert len(results) == 1, "more than one person initial recording obtained"
row = results[0]
assert row, "row was not obtained"
return row._asdict() # type: ignore
return dict(row)
def initrec_person_delete_initial_recording(
@@ -228,50 +235,142 @@ def initrec_person_delete_initial_recording(
raise KeyError(f"Database ID {id_} not found for deletion")
@wrap_result(10)
def page_consulting_to_db(
data: Beratungsgespraech_Vorgang,
) -> None:
logger.debug("[Consulting Page] Call Database Routine...")
fk_vorgang_id: int
if data.vorgang_id is None:
# insert new "Vorgang"
insert_data = data.model_dump(exclude={"vorgang_id", "beratungen"})
logger.debug("[Consulting Page] Call insert with data:\n%s", pformat(insert_data))
fk_vorgang_id = 42 # TODO replace for real inserted PK
else:
fk_vorgang_id = data.vorgang_id
logger.debug("[Consulting Page] VorgangID already set. ID: %d", fk_vorgang_id)
consultation_data: Beratungsgespraech_Vorgang,
) -> Beratungsgespraech_Vorgang:
logger.debug("[Consulting Page] Call database saving routine...")
rows_for_db_insert: list[dict[str, Any]] = []
rows_for_db_update: list[dict[str, Any]] = []
with db.ENGINE.begin() as conn:
if consultation_data.vorgang_id is None:
# insert new "Vorgang"
insert_data = consultation_data.model_dump(exclude={"vorgang_id", "beratungen"})
logger.debug(
"[Consulting Page] Call insert 'Vorgang' with data:\n%s", pformat(insert_data)
)
stmt = db.beratung_vorgang.insert()
ret = conn.execute(stmt, insert_data)
if ret.rowcount == 0:
raise IOError("Entry was not inserted correctly")
prim_keys = ret.inserted_primary_key
assert prim_keys
consultation_data.vorgang_id = cast("ConsId", prim_keys[0])
logger.debug("[Consulting Page] Inserted 'Vorgang' successfully")
for cons_session in data.beratungen:
cons_session.vorgang_id = fk_vorgang_id
if cons_session.beratung_id is None:
row_data = cons_session.model_dump(exclude={"beratung_id"})
rows_for_db_insert.append(row_data)
else:
row_data = cons_session.model_dump()
rows_for_db_update.append(row_data)
logger.debug(
"[Consulting Page] VorgangID already set. ID: %d",
consultation_data.vorgang_id,
)
if rows_for_db_update:
# ... update
logger.debug(
"[Consulting Page] Call update for sessions:\n%s", pformat(rows_for_db_update)
)
if rows_for_db_insert:
# ... insert
logger.debug(
"[Consulting Page] Call insert for sessions:\n%s", pformat(rows_for_db_insert)
)
rows_for_db_insert: list[dict[str, Any]] = []
rows_for_db_update: list[dict[str, Any]] = []
cons_sessions_inserted: list[Beratungsgespraech_Einzelgespraech] = []
for cons_session in consultation_data.beratungen:
cons_session.vorgang_id = consultation_data.vorgang_id
if cons_session.beratung_id is None:
row_data = cons_session.model_dump(exclude={"beratung_id"})
rows_for_db_insert.append(row_data)
cons_sessions_inserted.append(cons_session)
else:
row_data = cons_session.model_dump()
# new bind param to avoid name clashes
row_data["b_beratung_id"] = row_data["beratung_id"]
del row_data["beratung_id"]
rows_for_db_update.append(row_data)
if rows_for_db_update:
# ... update
logger.debug(
"[Consulting Page] Call update for sessions:\n%s", pformat(rows_for_db_update)
)
stmt = db.beratung_einzelberatung.update().where(
db.beratung_einzelberatung.c.beratung_id == sql.bindparam("b_beratung_id")
)
conn.execute(stmt, rows_for_db_update)
if rows_for_db_insert:
# ... insert
logger.debug(
"[Consulting Page] Call insert for sessions:\n%s", pformat(rows_for_db_insert)
)
stmt = db.beratung_einzelberatung.insert().returning(
db.beratung_einzelberatung.c.beratung_id
)
res = conn.execute(stmt, rows_for_db_insert)
new_cons_session_ids = cast(list[int], [row[0] for row in res.fetchall()])
assert len(cons_sessions_inserted) == len(new_cons_session_ids)
for cons_session, new_id in zip(cons_sessions_inserted, new_cons_session_ids):
cons_session.beratung_id = new_id
return consultation_data
@wrap_result(11)
def page_consulting_from_db(
cons_id: ConsId,
) -> Beratungsgespraech_Vorgang:
# TODO add Routine
# get "Vorgang" and all associated sessions to instantiate Pydantic data model
...
logger.debug("[Consulting Page] Call database reading routine...")
with db.ENGINE.connect() as conn:
# get the consultation process
stmt = db.beratung_vorgang.select().where(db.beratung_vorgang.c.vorgang_id == cons_id)
ret = conn.execute(stmt)
results = ret.mappings().all()
if not results:
raise KeyError(f"Database ID {cons_id} not found")
assert len(results) == 1, "more than one consulting process obtained"
consultation_data_db = results[0]
consultation_data = Beratungsgespraech_Vorgang(
vorgang_id=consultation_data_db["vorgang_id"],
un_id=consultation_data_db["un_id"],
pers_id=consultation_data_db["pers_id"],
titel=consultation_data_db["titel"],
beratungs_typ=consultation_data_db["beratungs_typ"],
erstellt=consultation_data_db["erstellt"],
aktualisiert=consultation_data_db["aktualisiert"],
beratungen=[],
)
# get all consultation sessions of this process
stmt = db.beratung_einzelberatung.select().where(
db.beratung_einzelberatung.c.vorgang_id == cons_id
)
ret = conn.execute(stmt)
# empty results possible
if ret.rowcount == 0:
logger.debug("[Consulting Page] No sessions, return directly...")
return consultation_data
cons_sessions = ret.mappings()
for session in cons_sessions:
cons_session_pydantic = Beratungsgespraech_Einzelgespraech(
beratung_id=session["beratung_id"],
vorgang_id=session["vorgang_id"],
nutzer_id=session["nutzer_id"],
nutzer_name=session["nutzer_name"],
zeitstempel=session["zeitstempel"],
ansprechpartner=session["ansprechpartner"],
kommunikationsweg=session["kommunikationsweg"],
thema_crm_matrix=session["thema_crm_matrix"],
anmerkungen=session["anmerkungen"],
rueckmeldung=session["rueckmeldung"],
erstellt=session["erstellt"],
aktualisiert=session["aktualisiert"],
)
consultation_data.beratungen.append(cons_session_pydantic)
logger.debug("[Consulting Page] Returning with sessions attached...")
return consultation_data
# // main page interaction