"""Case and ICD code models.""" from __future__ import annotations import datetime as dt from typing import Optional from sqlalchemy import ( Boolean, CheckConstraint, Date, DateTime, ForeignKey, Index, Integer, SmallInteger, String, Text, UniqueConstraint, func, text, ) from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.schema import FetchedValue from app.database import Base class Case(Base): __tablename__ = "cases" id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) fall_id: Mapped[Optional[str]] = mapped_column(String(100), nullable=True) crm_ticket_id: Mapped[Optional[str]] = mapped_column(String(20), nullable=True) jahr: Mapped[int] = mapped_column(SmallInteger, nullable=False) kw: Mapped[int] = mapped_column(SmallInteger, nullable=False) datum: Mapped[dt.date] = mapped_column(Date, nullable=False) anrede: Mapped[Optional[str]] = mapped_column(String(20), nullable=True) vorname: Mapped[Optional[str]] = mapped_column(String(100), nullable=True) nachname: Mapped[str] = mapped_column(String(100), nullable=False) geburtsdatum: Mapped[Optional[dt.date]] = mapped_column(Date, nullable=True) kvnr: Mapped[Optional[str]] = mapped_column(String(20), nullable=True) versicherung: Mapped[str] = mapped_column( String(50), nullable=False, server_default="DAK" ) icd: Mapped[Optional[str]] = mapped_column(Text, nullable=True) fallgruppe: Mapped[str] = mapped_column(String(20), nullable=False) strasse: Mapped[Optional[str]] = mapped_column(String(255), nullable=True) plz: Mapped[Optional[str]] = mapped_column(String(10), nullable=True) ort: Mapped[Optional[str]] = mapped_column(String(100), nullable=True) email: Mapped[Optional[str]] = mapped_column(String(255), nullable=True) ansprechpartner: Mapped[Optional[str]] = mapped_column(String(200), nullable=True) telefonnummer: Mapped[Optional[str]] = mapped_column(String(50), nullable=True) mobiltelefon: Mapped[Optional[str]] = mapped_column(String(50), nullable=True) email2: Mapped[Optional[str]] = mapped_column(String(255), nullable=True) telefon2: Mapped[Optional[str]] = mapped_column(String(50), nullable=True) unterlagen: Mapped[bool] = mapped_column( Boolean, nullable=False, server_default="0" ) unterlagen_verschickt: Mapped[Optional[dt.date]] = mapped_column( Date, nullable=True ) erhalten: Mapped[Optional[bool]] = mapped_column(Boolean, nullable=True) unterlagen_erhalten: Mapped[Optional[dt.date]] = mapped_column( Date, nullable=True ) unterlagen_an_gutachter: Mapped[Optional[dt.date]] = mapped_column( Date, nullable=True ) gutachten: Mapped[bool] = mapped_column( Boolean, nullable=False, server_default="0" ) gutachter: Mapped[Optional[str]] = mapped_column(String(100), nullable=True) gutachten_erstellt: Mapped[Optional[dt.date]] = mapped_column( Date, nullable=True ) gutachten_versendet: Mapped[Optional[dt.date]] = mapped_column( Date, nullable=True ) schweigepflicht: Mapped[bool] = mapped_column( Boolean, nullable=False, server_default="0" ) ablehnung: Mapped[bool] = mapped_column( Boolean, nullable=False, server_default="0" ) abbruch: Mapped[bool] = mapped_column( Boolean, nullable=False, server_default="0" ) abbruch_datum: Mapped[Optional[dt.date]] = mapped_column(Date, nullable=True) gutachten_typ: Mapped[Optional[str]] = mapped_column(String(20), nullable=True) therapieaenderung: Mapped[Optional[str]] = mapped_column(String(5), nullable=True) ta_diagnosekorrektur: Mapped[bool] = mapped_column( Boolean, nullable=False, server_default="0" ) ta_unterversorgung: Mapped[bool] = mapped_column( Boolean, nullable=False, server_default="0" ) ta_uebertherapie: Mapped[bool] = mapped_column( Boolean, nullable=False, server_default="0" ) kurzbeschreibung: Mapped[Optional[str]] = mapped_column(Text, nullable=True) fragestellung: Mapped[Optional[str]] = mapped_column(Text, nullable=True) kommentar: Mapped[Optional[str]] = mapped_column(Text, nullable=True) sonstiges: Mapped[Optional[str]] = mapped_column(Text, nullable=True) abgerechnet: Mapped[bool] = mapped_column( Boolean, nullable=False, server_default="0" ) abrechnung_datum: Mapped[Optional[dt.date]] = mapped_column(Date, nullable=True) import_source: Mapped[Optional[str]] = mapped_column(String(255), nullable=True) imported_at: Mapped[dt.datetime] = mapped_column( DateTime, nullable=False, server_default=func.now() ) updated_at: Mapped[dt.datetime] = mapped_column( DateTime, nullable=False, server_default=func.now(), onupdate=func.now(), server_onupdate=FetchedValue(), ) updated_by: Mapped[Optional[int]] = mapped_column( Integer, ForeignKey("users.id"), nullable=True ) icd_entered_by: Mapped[Optional[int]] = mapped_column( Integer, ForeignKey("users.id"), nullable=True ) icd_entered_at: Mapped[Optional[dt.datetime]] = mapped_column( DateTime, nullable=True ) coding_completed_by: Mapped[Optional[int]] = mapped_column( Integer, ForeignKey("users.id"), nullable=True ) coding_completed_at: Mapped[Optional[dt.datetime]] = mapped_column( DateTime, nullable=True ) # Relationships icd_codes: Mapped[list[CaseICDCode]] = relationship( back_populates="case", cascade="all, delete-orphan" ) updated_by_user: Mapped[Optional["User"]] = relationship( foreign_keys=[updated_by] ) icd_entered_by_user: Mapped[Optional["User"]] = relationship( foreign_keys=[icd_entered_by] ) coding_completed_by_user: Mapped[Optional["User"]] = relationship( foreign_keys=[coding_completed_by] ) __table_args__ = ( UniqueConstraint("fall_id", name="uk_fall_id"), Index("idx_jahr_kw", "jahr", "kw"), Index("idx_kvnr", "kvnr"), Index("idx_fallgruppe", "fallgruppe"), Index("idx_datum", "datum"), Index("idx_nachname_vorname", "nachname", "vorname"), # Note: idx_pending_icd uses a prefix length icd(20) which SQLAlchemy # does not support natively. We use text() for the prefix column. Index("idx_pending_icd", "jahr", "kw", "fallgruppe", text("icd(20)")), Index("idx_pending_coding", "gutachten", "gutachten_typ"), CheckConstraint( "fallgruppe IN ('onko','kardio','intensiv','galle','sd')", name="chk_fallgruppe", ), CheckConstraint( "gutachten_typ IS NULL OR gutachten_typ IN ('Bestätigung','Alternative')", name="chk_gutachten_typ", ), CheckConstraint( "therapieaenderung IS NULL OR therapieaenderung IN ('Ja','Nein')", name="chk_ta", ), ) class CaseICDCode(Base): __tablename__ = "case_icd_codes" id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) case_id: Mapped[int] = mapped_column( Integer, ForeignKey("cases.id", ondelete="CASCADE"), nullable=False, ) icd_code: Mapped[str] = mapped_column(String(20), nullable=False) icd_hauptgruppe: Mapped[Optional[str]] = mapped_column(String(10), nullable=True) created_at: Mapped[dt.datetime] = mapped_column( DateTime, nullable=False, server_default=func.now() ) # Relationships case: Mapped[Case] = relationship(back_populates="icd_codes") __table_args__ = ( Index("idx_case", "case_id"), Index("idx_code", "icd_code"), Index("idx_haupt", "icd_hauptgruppe"), )