Skip to content

fix: resolve review issues #181-#187#188

Merged
dholbach merged 6 commits into
mainfrom
fix/review-issues-181-187
Jul 6, 2026
Merged

fix: resolve review issues #181-#187#188
dholbach merged 6 commits into
mainfrom
fix/review-issues-181-187

Conversation

@dholbach

@dholbach dholbach commented Jul 6, 2026

Copy link
Copy Markdown
Owner

Resolves all seven issues filed during the 2026-07-06 codebase review. Four commits, each closing one group of issues.

Commit 1 — #181, #182, #183: Billing helpers + duplicate-guard fixes

New utils/billing_helpers.py with four functions shared across all session→InvoiceItem call sites:

  • build_service_type_map(practice){default_duration: ServiceType} dict, deterministic ordering
  • resolve_session_rate(client, service_type) — handles therapy_free zero-rating, previously missing in the batch-billing path
  • is_session_already_billed(session) — excludes cancelled invoices (was missing this in two places)
  • create_invoice_item_for_session(invoice, session, map, fallback) — full helper with all guards

invoice_views.py: both add_sessions_to_invoice and create_invoice_with_sessions now use the helper. create_invoice_with_sessions gains the already-billed guard it was missing (#181). Message count now reflects actually-added items, not the original request list.

calendar_views.py: approval-flow duplicate guard now excludes cancelled invoices (#182); inline rate logic replaced with resolve_session_rate; Decimal("1.00") and total= field set consistently.

19 unit tests in test_billing_helpers.py.

Commit 2 — #184: bank_import_views cleanup

  • Invoice.calculate_total() (a DB aggregate) replaced with stored invoice.total in both matching loops
  • New _fetch_invoice_maps(practice, numbers, statuses) static method eliminates the duplicated batch-fetch + split loop in get_queryset and _handle_bulk_ignore_paid
  • Amount tolerance changed from float 0.01 to Decimal("0.01")

Commit 3 — #185: available_data_years() helper

available_data_years(practice, include_expenses=True) added to tax_context_builder.py. Replaces three hand-rolled set-union expressions in:

  • TaxYearContextBuilder._build_available_years (was 10 lines, now 1)
  • tax_workday_audit (Invoice ∪ Expense years)
  • tax_quarter_overview (Invoice-only, include_expenses=False)

Commit 4 — #186: dead template deletion

Deleted client_detail_sidebar.html (224 lines) and client_detail_tabs.html (334 lines) — both unreferenced since the P-094 cockpit migration. Ran ./dev.py i18n to remove ~30 stale msgids from the .po files.

Commit 5 — #187: CODE_STRUCTURE.md rewrite

Replaced a doc that described the January 2026 state with an accurate description of the current codebase:

  • Dashboard section now describes the real 22-line dispatcher + 9 widget builders (not a 166-line monolith)
  • Adds billing_helpers.py, available_data_years(), CapacityPeriod
  • Stale per-module line counts replaced with a views quick-reference table

Test plan

  • test_billing_helpers — 19 tests (all new, all pass)
  • test_bank_import_views — 20 tests pass
  • test_tax_views + test_views_tax — 35 tests pass
  • test_views_invoice, test_signals, test_models — 135 total pass

dholbach and others added 6 commits July 6, 2026 13:25
… cancelled-invoice exclusion

- New utils/billing_helpers.py: build_service_type_map(), resolve_session_rate(),
  is_session_already_billed(), create_invoice_item_for_session()
- invoice_views: both add_sessions_to_invoice and create_invoice_with_sessions now
  use the helper, giving create_invoice_with_sessions the already-billed guard it
  was missing (#181) and consistent therapy_free zero-rating
- calendar_views: approval-flow duplicate guard now excludes cancelled invoices
  (#182); inline rate logic replaced with resolve_session_rate(); Decimal("1.00")
  and total= field set consistently
- 19 unit tests in test_billing_helpers.py

Closes #181, #182, #183

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…helper, Decimal tolerance

- Replace calculate_total() (DB aggregate per call) with stored invoice.total
- Extract _fetch_invoice_maps(practice, numbers, statuses) → eliminates the
  duplicated batch-fetch + split loop in get_queryset and _handle_bulk_ignore_paid
- Amount comparison tolerance changed from float 0.01 to Decimal("0.01")

Closes #184

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…and-rolled copies

Add available_data_years(practice, include_expenses=True) to tax_context_builder.py.
Use it in:
- TaxYearContextBuilder._build_available_years (was 10 lines, now 1)
- tax_workday_audit (Invoice ∪ Expense years, with practice guard)
- tax_quarter_overview (Invoice-only years, include_expenses=False)

Closes #185

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…bs templates

Both templates have been unreferenced since the P-094 cockpit migration.
client_detail_tabs.html was fully i18n-wrapped (v0.2.4), so its ~30 msgids
inflated the P-039 translation surface. Ran ./dev.py i18n to drop the stale
references from both .po files.

Closes #186

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Updated directory tree: 18 models (adds capacity.py), 35 utils (adds billing_helpers.py)
- Dashboard section replaced with current reality: 22-line dispatcher + 9 widget builders
- Replaced stale per-module line counts with a views quick-reference table
- Documents billing_helpers.py, available_data_years(), CapacityPeriod (all v0.2.9)
- Migration history table removed (see CHANGELOG.md for that)
- Last updated: 2026-07-06

Closes #187

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ews (English msgids)

Per CLAUDE.md: any Python file touched for any reason must have user-facing
strings wrapped. Both files were touched for the code-quality fixes in this
branch and were previously missing gettext coverage.

- bank_import_views.py: 28 messages/JsonResponse strings wrapped; all four view
  classes covered (BankImportView, BankReviewView, BankExpenseReviewView,
  BankWithdrawalReviewView); ngettext used for plurals
- calendar_views.py: 21 messages/JsonResponse strings wrapped; gettext import
  added to module

All msgids use English; German translations added to locale/de/django.po.
locale/en/django.po: pass-through msgstr = msgid for all new entries.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@dholbach dholbach merged commit dbff14a into main Jul 6, 2026
1 check passed
@dholbach dholbach deleted the fix/review-issues-181-187 branch July 6, 2026 13:01
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