Skip to content

[Reports]: Invoice aging report (v1 parity) #679

Description

@nielsdrost7

The one v1 report missing from #145's five sub-reports. v1's Invoice Aging shows, per client, the open balance bucketed by days past due — the standard collections tool.

Behavioral spec: v1 application/modules/reports/models/Mdl_reports.php:125-181, controllers/Reports.php:86-101, views/invoice_aging_index.php.


Specific

An Invoice Aging report page in the company panel Reports group (same pattern as #145 / PR #609): one row per client with open balances, columns:

  • 1–15 days — sum of open invoice balances due 1–15 days ago (v1 range_1)
  • 16–30 days — due 16–30 days ago (range_2)
  • 31+ days — due 31+ days ago (range_3)
  • Total balance — all past-due balance (total_balance)

Only clients with any bucket > 0 appear (v1 HAVING clause :175-178). No date-range picker — aging is always relative to today.

Measurable

  • Report reachable from the Reports navigation group; read-only.
  • Bucket math matches the v1 definitions above against a seeded fixture.
  • Summary/totals line across all clients at the bottom.
  • Export CSV action downloads header + one row per client + totals.
  • Company-scoped; other tenants' invoices never counted.

Achievable

One Filament page + custom query following the #145 page pattern: Invoice::forCompany()->whereDate('due_at', '<', today()) with conditional SUM aggregates per bucket, grouped by relation. CSV export reuses the #145 CSV action.

Relevant

Track B of epic #506 (v1 parity required before launch). Collections/aging is the report accountants ask for first.

Time-Bound

Half a sprint once PR #609 merges (pattern + CSV plumbing exist then).


Arrange

  • Client A: open invoices due 5 days ago (balance 100) and 20 days ago (balance 200).
  • Client B: open invoice due 45 days ago (balance 300).
  • Client C: only a fully paid past-due invoice (balance 0) and a future-due invoice.
  • Another company with an overdue invoice (leak check).

Act

  • Open the Invoice Aging report page; trigger Export CSV.

Assert

  • Client A row: 1–15 = 100, 16–30 = 200, 31+ = 0, total = 300.
  • Client B row: 31+ = 300, total = 300.
  • Client C does not appear.
  • Grand totals line: 100 / 200 / 300 / 600.
  • Other company's invoice affects nothing.
  • CSV contains exactly the displayed rows + header.
  • PHPUnit + Livewire feature tests cover buckets, exclusion rule, scoping, CSV.

Metadata

Metadata

Assignees

No one assigned

    Labels

    refinedRefined with SMART plan / test suggestions

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions