fix: correct capacity time-off handling and centralise quarter/revenue computations#158
Merged
Conversation
…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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Review of all computation logic (revenue, sessions, capacity, tax, working days) for correctness, plus centralisation of duplicated calculation code.
Correctness fixes
capacity_helpers._calculate_weighted_capacity): for periods spanning the 2023-08-01 capacity change, theavailable_working_daysparameter 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.tax_quarter_overviewandTaxQuarterWidgetBuilderfiltered strictly onpaid_date__range, while the year summary usesbuild_paid_date_filterwith an invoice-date fallback for paid invoices without apaid_date. Such invoices appeared in the yearly total but in no quarter. Quarters now useRevenueCalculator.build_paid_date_range_filterand sum exactly to the year total.count_working_daysdocstring example claimed 2025-11-15 is a Friday (it's a Saturday).Centralisation
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 incalculate_quarter_trends— the latter carried a wrongyear % 4leap rule in dead code).practice_days.py: three identical_timeoff_dates()methods collapsed into one module-level_timeoff_dates_for_year().CapacityMonitoringWidgetBuilder._get_month_statsnow reusescount_session_hours()andRevenueCalculator.get_month_revenue()instead of hand-rolled formulas.tax_viewsJSON 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_hoursnormalisation and group-size handlingRevenueCalculatoraggregations,apply_remainder_distributionpractice_daysget_days_to_payment_trendsDateField subtraction works correctly on PostgreSQL (exercised at runtime)Tests
test_capacity_helpers.py: capacity period boundaries, weighted capacity with/without time off (regression), integration test across the capacity changetest_date_helpers.pytest_views_tax.py🤖 Generated with Claude Code