diff --git a/backend/app/services/report_service.py b/backend/app/services/report_service.py index 9ea1923..88a63fc 100644 --- a/backend/app/services/report_service.py +++ b/backend/app/services/report_service.py @@ -94,7 +94,7 @@ def _empty_ta_weekly_row(kw: int) -> dict: # Sheet 1: Auswertung KW gesamt # --------------------------------------------------------------------------- -def calculate_sheet1_data(db: Session, jahr: int) -> dict: +def calculate_sheet1_data(db: Session, jahr: int, max_kw: int | None = None) -> dict: """Calculate *Auswertung KW gesamt*. Returns:: @@ -121,8 +121,13 @@ def calculate_sheet1_data(db: Session, jahr: int) -> dict: * Ablehnungen = cases where ablehnung == True * Gutachten = cases where gutachten == True * Keine RM = Unterlagen - Gutachten (derived, per KW row) + + If *max_kw* is given, only data up to and including that KW is included. """ # One query: group by kw, count the four flags + filters = [Case.versicherung == settings.VERSICHERUNG_FILTER, Case.jahr == jahr] + if max_kw is not None: + filters.append(Case.kw <= max_kw) rows = ( db.query( Case.kw, @@ -131,7 +136,7 @@ def calculate_sheet1_data(db: Session, jahr: int) -> dict: func.sum(Case.ablehnung.cast(Integer)).label("ablehnungen"), func.sum(Case.gutachten.cast(Integer)).label("gutachten"), ) - .filter(Case.versicherung == settings.VERSICHERUNG_FILTER, Case.jahr == jahr) + .filter(*filters) .group_by(Case.kw) .all() ) @@ -178,7 +183,7 @@ def calculate_sheet1_data(db: Session, jahr: int) -> dict: # Sheet 2: Auswertung nach Fachgebieten # --------------------------------------------------------------------------- -def calculate_sheet2_data(db: Session, jahr: int) -> dict: +def calculate_sheet2_data(db: Session, jahr: int, max_kw: int | None = None) -> dict: """Calculate *Auswertung nach Fachgebieten*. Per KW, per Fallgruppe: Anzahl, Gutachten, Keine RM/Ablehnung. @@ -200,7 +205,12 @@ def calculate_sheet2_data(db: Session, jahr: int) -> dict: } Keine RM/Ablehnung = Anzahl - Gutachten (per the Excel formula). + + If *max_kw* is given, only data up to and including that KW is included. """ + filters = [Case.versicherung == settings.VERSICHERUNG_FILTER, Case.jahr == jahr] + if max_kw is not None: + filters.append(Case.kw <= max_kw) rows = ( db.query( Case.kw, @@ -208,7 +218,7 @@ def calculate_sheet2_data(db: Session, jahr: int) -> dict: func.count(Case.id).label("anzahl"), func.sum(Case.gutachten.cast(Integer)).label("gutachten"), ) - .filter(Case.versicherung == settings.VERSICHERUNG_FILTER, Case.jahr == jahr) + .filter(*filters) .group_by(Case.kw, Case.fallgruppe) .all() ) @@ -242,7 +252,7 @@ def calculate_sheet2_data(db: Session, jahr: int) -> dict: # Sheet 3: Auswertung Gutachten # --------------------------------------------------------------------------- -def calculate_sheet3_data(db: Session, jahr: int) -> dict: +def calculate_sheet3_data(db: Session, jahr: int, max_kw: int | None = None) -> dict: """Calculate *Auswertung Gutachten*. Per KW, per group (gesamt + 5 Fallgruppen): @@ -269,7 +279,16 @@ def calculate_sheet3_data(db: Session, jahr: int) -> dict: - Per Fallgruppe: Gutachten = count, Alternative = count where typ='Alternative', Bestaetigung = Gutachten - Alternative - Gesamt = sum across all Fallgruppen + + If *max_kw* is given, only data up to and including that KW is included. """ + filters = [ + Case.versicherung == settings.VERSICHERUNG_FILTER, + Case.jahr == jahr, + Case.gutachten == True, # noqa: E712 + ] + if max_kw is not None: + filters.append(Case.kw <= max_kw) rows = ( db.query( Case.kw, @@ -279,7 +298,7 @@ def calculate_sheet3_data(db: Session, jahr: int) -> dict: (Case.gutachten_typ == "Alternative").cast(Integer) ).label("alternative"), ) - .filter(Case.versicherung == settings.VERSICHERUNG_FILTER, Case.jahr == jahr, Case.gutachten == True) # noqa: E712 + .filter(*filters) .group_by(Case.kw, Case.fallgruppe) .all() ) @@ -322,7 +341,7 @@ def calculate_sheet3_data(db: Session, jahr: int) -> dict: # Sheet 4: Auswertung Therapieaenderungen # --------------------------------------------------------------------------- -def calculate_sheet4_data(db: Session, jahr: int) -> dict: +def calculate_sheet4_data(db: Session, jahr: int, max_kw: int | None = None) -> dict: """Calculate *Auswertung Therapieaenderungen*. Per KW: Gutachten count, TA Ja, TA Nein, Diagnosekorrektur, @@ -344,7 +363,16 @@ def calculate_sheet4_data(db: Session, jahr: int) -> dict: ... ] } + + If *max_kw* is given, only data up to and including that KW is included. """ + filters = [ + Case.versicherung == settings.VERSICHERUNG_FILTER, + Case.jahr == jahr, + Case.gutachten == True, # noqa: E712 + ] + if max_kw is not None: + filters.append(Case.kw <= max_kw) rows = ( db.query( Case.kw, @@ -359,7 +387,7 @@ def calculate_sheet4_data(db: Session, jahr: int) -> dict: func.sum(Case.ta_unterversorgung.cast(Integer)).label("unterversorgung"), func.sum(Case.ta_uebertherapie.cast(Integer)).label("uebertherapie"), ) - .filter(Case.versicherung == settings.VERSICHERUNG_FILTER, Case.jahr == jahr, Case.gutachten == True) # noqa: E712 + .filter(*filters) .group_by(Case.kw) .all() ) @@ -388,7 +416,7 @@ def calculate_sheet4_data(db: Session, jahr: int) -> dict: # Sheet 5: Auswertung ICD onko # --------------------------------------------------------------------------- -def calculate_sheet5_data(db: Session, jahr: int) -> dict: +def calculate_sheet5_data(db: Session, jahr: int, max_kw: int | None = None) -> dict: """Calculate *Auswertung ICD onko*. Returns sorted list of ICD codes from onko cases with counts. @@ -407,20 +435,23 @@ def calculate_sheet5_data(db: Session, jahr: int) -> dict: ... ] } + + If *max_kw* is given, only data up to and including that KW is included. """ + filter_conditions = [ + Case.versicherung == settings.VERSICHERUNG_FILTER, + Case.fallgruppe == "onko", + Case.jahr == jahr, + ] + if max_kw is not None: + filter_conditions.append(Case.kw <= max_kw) rows = ( db.query( func.upper(CaseICDCode.icd_code).label("icd"), func.count(CaseICDCode.id).label("cnt"), ) .join(Case, CaseICDCode.case_id == Case.id) - .filter( - and_( - Case.versicherung == settings.VERSICHERUNG_FILTER, - Case.fallgruppe == "onko", - Case.jahr == jahr, - ) - ) + .filter(and_(*filter_conditions)) .group_by(func.upper(CaseICDCode.icd_code)) .order_by(func.count(CaseICDCode.id).desc(), func.upper(CaseICDCode.icd_code)) .all() @@ -550,8 +581,9 @@ def calculate_dashboard_kpis(db: Session, jahr: int) -> dict: def generate_full_report(db: Session, jahr: int, kw: int | None = None) -> dict: """Generate complete report data for all 5 sheets. - The *kw* parameter is recorded for metadata but does not filter the data - -- all sheets always contain the full year up to the latest available KW. + If *kw* is given, only data up to and including that calendar week is + included in the report. This allows generating historical reports + that reflect the state at a specific point in the year. Returns:: @@ -570,9 +602,9 @@ def generate_full_report(db: Session, jahr: int, kw: int | None = None) -> dict: return { "jahr": jahr, "kw": kw, - "sheet1": calculate_sheet1_data(db, jahr), - "sheet2": calculate_sheet2_data(db, jahr), - "sheet3": calculate_sheet3_data(db, jahr), - "sheet4": calculate_sheet4_data(db, jahr), - "sheet5": calculate_sheet5_data(db, jahr), + "sheet1": calculate_sheet1_data(db, jahr, max_kw=kw), + "sheet2": calculate_sheet2_data(db, jahr, max_kw=kw), + "sheet3": calculate_sheet3_data(db, jahr, max_kw=kw), + "sheet4": calculate_sheet4_data(db, jahr, max_kw=kw), + "sheet5": calculate_sheet5_data(db, jahr, max_kw=kw), }