fix: filter report data by max KW when generating reports

Previously, generate_full_report() ignored the kw parameter for data
filtering — it was only stored as metadata. This caused all reports to
contain data up to the latest available KW, making historical reports
(e.g., for KW 8) identical to the current one.

Now all 5 sheet calculation functions accept an optional max_kw parameter.
When generating a report for a specific KW, only cases with kw <= max_kw
are included. Dashboard and vorjahr callers are unaffected (max_kw=None).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
CCS Admin 2026-02-26 23:16:20 +00:00
parent 4cd52dd0b2
commit 95e84a6978

View file

@ -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),
}