Skip to content

fix: correct capacity time-off handling and centralise quarter/revenue computations#158

Merged
dholbach merged 1 commit into
mainfrom
fix/computation-review
Jul 2, 2026
Merged

fix: correct capacity time-off handling and centralise quarter/revenue computations#158
dholbach merged 1 commit into
mainfrom
fix/computation-review

Conversation

@dholbach

@dholbach dholbach commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Summary

Review of all computation logic (revenue, sessions, capacity, tax, working days) for correctness, plus centralisation of duplicated calculation code.

Correctness fixes

  • Weighted capacity ignored time off across capacity changes (capacity_helpers._calculate_weighted_capacity): for periods spanning the 2023-08-01 capacity change, the available_working_days parameter was unused, so vacation/time off never reduced usable capacity — utilisation percentages for such periods were understated. Now the per-segment weighted hours/week is applied to the time-off-adjusted available days.
  • Quarterly tax revenue didn't match the year summary: tax_quarter_overview and TaxQuarterWidgetBuilder filtered strictly on paid_date__range, while the year summary uses build_paid_date_filter with an invoice-date fallback for paid invoices without a paid_date. Such invoices appeared in the yearly total but in no quarter. Quarters now use RevenueCalculator.build_paid_date_range_filter and sum exactly to the year total.
  • count_working_days docstring example claimed 2025-11-15 is a Friday (it's a Saturday).

Centralisation

  • New DateRangeHelper.get_quarter_range() / get_quarter_for_date() replace three independent quarter-boundary implementations (tax_views._quarter_date_range, TaxQuarterWidgetBuilder._quarter_of, and inline logic in calculate_quarter_trends — the latter carried a wrong year % 4 leap rule in dead code).
  • practice_days.py: three identical _timeoff_dates() methods collapsed into one module-level _timeoff_dates_for_year().
  • CapacityMonitoringWidgetBuilder._get_month_stats now reuses count_session_hours() and RevenueCalculator.get_month_revenue() instead of hand-rolled formulas.
  • tax_views JSON error strings wrapped with gettext (P-039); German translations added (fixed two fuzzy-matched msgstrs from makemessages).

Verified as correct (no change needed)

  • count_sessions / count_session_hours normalisation and group-size handling
  • RevenueCalculator aggregations, apply_remainder_distribution
  • Easter algorithm and Berlin holiday set in practice_days
  • Entfernungspauschale (0.30/0.38 €/km split at 20 km) and Home-Office-Pauschale (6 €/day, 210-day cap)
  • get_days_to_payment_trends DateField subtraction works correctly on PostgreSQL (exercised at runtime)

Tests

  • New test_capacity_helpers.py: capacity period boundaries, weighted capacity with/without time off (regression), integration test across the capacity change
  • Quarter helper tests in test_date_helpers.py
  • Quarter/year revenue consistency regression tests in test_views_tax.py
  • Full Django + JS suite passes

🤖 Generated with Claude Code

…e computations

Correctness:
- _calculate_weighted_capacity ignored available_working_days (time off)
  for periods spanning a capacity change, overstating usable capacity;
  now weights hours/week per segment and applies it to available days
- Quarterly tax revenue (tax_quarter_overview, TaxQuarterWidgetBuilder)
  used a strict paid_date range while the year summary falls back to
  invoice_date for null paid_date — quarters now use
  RevenueCalculator.build_paid_date_range_filter so they sum to the
  year total
- Fix count_working_days docstring example (2025-11-15 is a Saturday)

Centralisation:
- New DateRangeHelper.get_quarter_range / get_quarter_for_date replace
  three hand-rolled quarter-boundary implementations (one with a wrong
  year%4 leap rule in dead code)
- practice_days: one _timeoff_dates_for_year() instead of three
  identical private methods
- CapacityMonitoringWidgetBuilder reuses count_session_hours and
  RevenueCalculator.get_month_revenue instead of manual formulas
- Wrap tax_views JSON error strings with gettext (P-039 convention)

Tests: new test_capacity_helpers.py (capacity boundaries, weighted
capacity time-off regression), quarter helper tests, quarter/year
revenue consistency tests. Full suite passes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@dholbach dholbach merged commit 444e5b2 into main Jul 2, 2026
1 check passed
@dholbach dholbach deleted the fix/computation-review branch July 2, 2026 19:50
@dholbach dholbach mentioned this pull request Jul 3, 2026
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant