diff --git a/backend/app/services/report_service.py b/backend/app/services/report_service.py index 0bebf86..599ec14 100644 --- a/backend/app/services/report_service.py +++ b/backend/app/services/report_service.py @@ -223,9 +223,22 @@ async def _recalculate_overtime_balance( return float(sa.factor) return 1.0 - expected = _expected_hours(schedule, date_from_all, date_to_all) - worked = sum((e.worked_hours or 0.0) * _fza_factor(e.date) for e in entries) - overtime = max(0.0, worked - expected) + # Tages-weise Berechnung: nur Tage mit Eintrag werden verglichen. + # Hintergrund: Fehl- und Urlaubstage sollen das Überstunden-Konto nicht + # senken – nur an Arbeitstagen wo tatsächlich gestempelt wurde, wird + # geprüft ob mehr als das Soll gearbeitet wurde. + daily_schedule = _schedule_daily(schedule) + + # Einträge nach Datum gruppieren (mehrere Einträge am gleichen Tag summieren) + hours_by_date: dict[date, float] = {} + for e in entries: + fac = _fza_factor(e.date) + hours_by_date[e.date] = hours_by_date.get(e.date, 0.0) + (e.worked_hours or 0.0) * fac + + overtime = 0.0 + for entry_date, worked_on_day in hours_by_date.items(): + expected_on_day = daily_schedule.get(entry_date.weekday(), 0.0) + overtime += max(0.0, worked_on_day - expected_on_day) bal.total_hours = Decimal(str(round(overtime, 2))) bal.last_calculated = datetime.utcnow()