dak.c2s/backend/app/models/report.py
CCS Admin e9eb98119f feat: migrate database driver from MariaDB to PostgreSQL
Switch from pymysql to psycopg2-binary, update connection string to
postgresql+psycopg2, replace MySQL-specific JSON imports with generic
SQLAlchemy JSON, convert MySQL prefix index to PostgreSQL left() function,
and remove FetchedValue() (unnecessary with PostgreSQL).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 08:25:05 +00:00

192 lines
5.8 KiB
Python

"""Weekly report and yearly summary models."""
from __future__ import annotations
import datetime as dt
from typing import Optional
from sqlalchemy import (
Date,
DateTime,
ForeignKey,
Index,
Integer,
JSON,
SmallInteger,
String,
UniqueConstraint,
func,
)
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.database import Base
class WeeklyReport(Base):
__tablename__ = "weekly_reports"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
jahr: Mapped[int] = mapped_column(SmallInteger, nullable=False)
kw: Mapped[int] = mapped_column(SmallInteger, nullable=False)
report_type: Mapped[str] = mapped_column(
String(50), nullable=False, server_default="gesamt"
)
report_date: Mapped[dt.date] = mapped_column(Date, nullable=False)
report_file_path: Mapped[Optional[str]] = mapped_column(
String(500), nullable=True
)
report_data: Mapped[Optional[dict]] = mapped_column(JSON, nullable=True)
generated_by: Mapped[Optional[int]] = mapped_column(
Integer, ForeignKey("users.id"), nullable=True
)
generated_at: Mapped[dt.datetime] = mapped_column(
DateTime, nullable=False, server_default=func.now()
)
# Relationships
generated_by_user: Mapped[Optional["User"]] = relationship(
foreign_keys=[generated_by]
)
__table_args__ = (
UniqueConstraint("jahr", "kw", "report_type", name="uk_jahr_kw_type"),
)
class YearlySummary(Base):
__tablename__ = "yearly_summary"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
jahr: Mapped[int] = mapped_column(SmallInteger, nullable=False)
kw: Mapped[int] = mapped_column(SmallInteger, nullable=False)
# Overall counts
erstberatungen: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
ablehnungen: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
unterlagen: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
keine_rueckmeldung: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
gutachten_gesamt: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
gutachten_alternative: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
gutachten_bestaetigung: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
# Per-Fallgruppe counts: onko
onko_anzahl: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
onko_gutachten: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
onko_keine_rm: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
# Per-Fallgruppe counts: kardio
kardio_anzahl: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
kardio_gutachten: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
kardio_keine_rm: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
# Per-Fallgruppe counts: intensiv
intensiv_anzahl: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
intensiv_gutachten: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
intensiv_keine_rm: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
# Per-Fallgruppe counts: galle
galle_anzahl: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
galle_gutachten: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
galle_keine_rm: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
# Per-Fallgruppe counts: sd
sd_anzahl: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
sd_gutachten: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
sd_keine_rm: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
# Gutachten-Typ per Fallgruppe
onko_alternative: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
onko_bestaetigung: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
kardio_alternative: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
kardio_bestaetigung: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
intensiv_alternative: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
intensiv_bestaetigung: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
galle_alternative: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
galle_bestaetigung: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
sd_alternative: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
sd_bestaetigung: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
# Therapieaenderung counts
ta_ja: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
ta_nein: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
ta_diagnosekorrektur: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
ta_unterversorgung: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
ta_uebertherapie: Mapped[Optional[int]] = mapped_column(
Integer, server_default="0"
)
__table_args__ = (
UniqueConstraint("jahr", "kw", name="uk_jahr_kw"),
)