fix: show individual case data in Wochenübersicht preview instead of aggregated summaries

Preview now mirrors the Excel export content: KVNR, Datum, x-markers
for Erstgespräch/Abbruch/Unterlagen/Gutachten/FG, and ICD-10 per case,
grouped by KW blocks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
CCS Admin 2026-02-27 15:32:30 +00:00
parent 27b3810250
commit 899c125a62
2 changed files with 82 additions and 75 deletions

View file

@ -360,20 +360,26 @@ def generate_wochenuebersicht(
) )
.first() .first()
) )
# Build per-KW summary for frontend preview # Build per-KW case data for frontend preview (mirrors Excel content)
fg1, fg2 = fallgruppen fg1, fg2 = fallgruppen
fg1_label, fg2_label = type_cfg["fg_labels"] fg1_label, fg2_label = type_cfg["fg_labels"]
weeks_summary = [] weeks_data = []
for kw in sorted(cases_by_kw.keys(), reverse=True): for kw in sorted(cases_by_kw.keys(), reverse=True):
kw_cases = cases_by_kw[kw] kw_cases = sorted(cases_by_kw[kw], key=lambda c: (c.datum or date.min))
weeks_summary.append({ rows = []
"kw": kw, for c in kw_cases:
"count": len(kw_cases), rows.append({
"with_icd": sum(1 for c in kw_cases if c.icd), "kvnr": c.kvnr or "",
"fg1_count": sum(1 for c in kw_cases if c.fallgruppe == fg1), "datum": c.datum.strftime("%d.%m.%Y") if c.datum else "",
"fg2_count": sum(1 for c in kw_cases if c.fallgruppe == fg2), "erstgespraech": True,
"gutachten": sum(1 for c in kw_cases if c.gutachten), "abbruch": bool(c.ablehnung or c.abbruch),
"unterlagen": bool(c.unterlagen and not c.ablehnung and not c.abbruch),
"gutachten": bool(c.gutachten),
"fg1": c.fallgruppe == fg1,
"fg2": c.fallgruppe == fg2,
"icd": c.icd or "",
}) })
weeks_data.append({"kw": kw, "cases": rows})
report_data = { report_data = {
"export_type": export_type, "export_type": export_type,
@ -382,7 +388,7 @@ def generate_wochenuebersicht(
"case_count": len(cases), "case_count": len(cases),
"fg1_label": fg1_label, "fg1_label": fg1_label,
"fg2_label": fg2_label, "fg2_label": fg2_label,
"weeks": weeks_summary, "weeks": weeks_data,
} }
if report: if report:
report.report_date = date.today() report.report_date = date.today()

View file

@ -17,7 +17,7 @@ import {
Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Select, SelectContent, SelectItem, SelectTrigger, SelectValue,
} from '@/components/ui/select' } from '@/components/ui/select'
import { import {
Table, TableBody, TableCell, TableFooter, TableHead, TableHeader, TableRow, Table, TableBody, TableCell, TableHead, TableHeader, TableRow,
} from '@/components/ui/table' } from '@/components/ui/table'
import { Skeleton } from '@/components/ui/skeleton' import { Skeleton } from '@/components/ui/skeleton'
import { Alert, AlertDescription } from '@/components/ui/alert' import { Alert, AlertDescription } from '@/components/ui/alert'
@ -487,28 +487,33 @@ export function WochenuebersichtPage() {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Wochenübersicht Viewer (inline preview) // Wochenübersicht Viewer (inline preview — individual cases per KW)
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
interface WeekSummary { interface CaseRow {
kvnr: string
datum: string
erstgespraech: boolean
abbruch: boolean
unterlagen: boolean
gutachten: boolean
fg1: boolean
fg2: boolean
icd: string
}
interface WeekBlock {
kw: number kw: number
count: number cases: CaseRow[]
with_icd: number
fg1_count: number
fg2_count: number
gutachten: number
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
function WochenuebersichtViewer({ data }: { data: Record<string, any> }) { function WochenuebersichtViewer({ data }: { data: Record<string, any> }) {
const weeks: WeekSummary[] = data?.weeks ?? [] const weeks: WeekBlock[] = data?.weeks ?? []
const fg1Label: string = data?.fg1_label ?? 'FG1' const fg1Label: string = data?.fg1_label ?? 'FG1'
const fg2Label: string = data?.fg2_label ?? 'FG2' const fg2Label: string = data?.fg2_label ?? 'FG2'
const kwVon: number = data?.kw_von ?? '?'
const kwBis: number = data?.kw_bis ?? '?'
const totalCases: number = data?.case_count ?? 0
if (!weeks.length) { if (!weeks.length || weeks.every((w) => w.cases.length === 0)) {
return ( return (
<p className="py-4 text-center text-muted-foreground"> <p className="py-4 text-center text-muted-foreground">
Keine Vorschaudaten verfügbar. Keine Vorschaudaten verfügbar.
@ -516,62 +521,58 @@ function WochenuebersichtViewer({ data }: { data: Record<string, any> }) {
) )
} }
const totals = weeks.reduce( const totalCases = weeks.reduce((sum, w) => sum + w.cases.length, 0)
(acc, w) => ({ const totalIcd = weeks.reduce(
count: acc.count + w.count, (sum, w) => sum + w.cases.filter((c) => c.icd).length, 0,
with_icd: acc.with_icd + w.with_icd,
fg1: acc.fg1 + w.fg1_count,
fg2: acc.fg2 + w.fg2_count,
gutachten: acc.gutachten + w.gutachten,
}),
{ count: 0, with_icd: 0, fg1: 0, fg2: 0, gutachten: 0 },
) )
return ( return (
<div className="space-y-3"> <div className="space-y-4">
<div className="flex items-center gap-4 text-sm text-muted-foreground"> <div className="flex items-center gap-4 text-sm text-muted-foreground">
<span>KW {kwVon}{kwBis}</span>
<span>{totalCases} Fälle gesamt</span> <span>{totalCases} Fälle gesamt</span>
<span>{totals.with_icd} mit ICD</span> <span>{totalIcd} mit ICD</span>
</div> </div>
{weeks.map((week) => (
<div key={week.kw}>
<h4 className="text-sm font-semibold mb-1">
KW {week.kw} {week.cases.length} Fälle
</h4>
{week.cases.length > 0 ? (
<Table> <Table>
<TableHeader> <TableHeader>
<TableRow> <TableRow>
<TableHead>KW</TableHead> <TableHead>KVNR</TableHead>
<TableHead className="text-right">Fälle</TableHead> <TableHead>Datum</TableHead>
<TableHead className="text-right">{fg1Label}</TableHead> <TableHead className="text-center">Erstgespräch</TableHead>
<TableHead className="text-right">{fg2Label}</TableHead> <TableHead className="text-center">Abbruch</TableHead>
<TableHead className="text-right">Gutachten</TableHead> <TableHead className="text-center">Unterlagen</TableHead>
<TableHead className="text-right">mit ICD</TableHead> <TableHead className="text-center">Gutachten</TableHead>
<TableHead className="text-center">{fg1Label}</TableHead>
<TableHead className="text-center">{fg2Label}</TableHead>
<TableHead>ICD-10</TableHead>
</TableRow> </TableRow>
</TableHeader> </TableHeader>
<TableBody> <TableBody>
{weeks.map((w) => ( {week.cases.map((c, i) => (
<TableRow key={w.kw}> <TableRow key={i}>
<TableCell>KW {w.kw}</TableCell> <TableCell className="font-mono text-xs">{c.kvnr || '—'}</TableCell>
<TableCell className="text-right">{w.count}</TableCell> <TableCell className="text-xs">{c.datum}</TableCell>
<TableCell className="text-right">{w.fg1_count}</TableCell> <TableCell className="text-center">{c.erstgespraech ? 'x' : ''}</TableCell>
<TableCell className="text-right">{w.fg2_count}</TableCell> <TableCell className="text-center">{c.abbruch ? 'x' : ''}</TableCell>
<TableCell className="text-right">{w.gutachten}</TableCell> <TableCell className="text-center">{c.unterlagen ? 'x' : ''}</TableCell>
<TableCell className="text-right"> <TableCell className="text-center">{c.gutachten ? 'x' : ''}</TableCell>
{w.with_icd}/{w.count} <TableCell className="text-center">{c.fg1 ? 'x' : ''}</TableCell>
</TableCell> <TableCell className="text-center">{c.fg2 ? 'x' : ''}</TableCell>
<TableCell className="font-mono text-xs">{c.icd || ''}</TableCell>
</TableRow> </TableRow>
))} ))}
</TableBody> </TableBody>
<TableFooter>
<TableRow>
<TableCell className="font-bold">Gesamt</TableCell>
<TableCell className="text-right font-bold">{totals.count}</TableCell>
<TableCell className="text-right font-bold">{totals.fg1}</TableCell>
<TableCell className="text-right font-bold">{totals.fg2}</TableCell>
<TableCell className="text-right font-bold">{totals.gutachten}</TableCell>
<TableCell className="text-right font-bold">
{totals.with_icd}/{totals.count}
</TableCell>
</TableRow>
</TableFooter>
</Table> </Table>
) : (
<p className="text-xs text-muted-foreground">Keine Fälle in dieser KW.</p>
)}
</div>
))}
</div> </div>
) )
} }