Skip to content

Report Builder: group-band repetition (group_by, per-group totals) #597

Description

@nielsdrost7

Parent: #130 (Report Builder) · Hanging item from #608

Story
As a company admin, I want the Group Header / Group Footer bands to repeat per group of line items (e.g. per project, per product category), so long invoices read as grouped sections with per-group subtotals instead of one flat item table.

Current state (as of PR #608)
Modules/Core/Services/ReportRenderer.php renders every band exactly once, in ReportBand::ordered() order. The group_header and group_footer bands exist in the five-band model and are editable in the builder, but nothing ever repeats them — grouping is not configurable anywhere.

Spec to settle in this issue

  • A group_by setting — either in the template manifest or as per-details-band config (decide: manifest band_options.details.group_by fits the existing band-options pattern used by keep_together).
  • The whitelist of valid group keys: which item attributes may be grouped on (candidates from ReportDataMapper::itemData(): none today — grouping keys like project_id/category must first be added to the item data array; enumerate them explicitly, never accept arbitrary strings).
  • Per-group data exposure: Group Header bricks receive the current group key/label; Group Footer bricks receive per-group totals (subtotal, tax, total computed over the group's items) alongside the document-level totals.
  • Renderer loop: for each group — group_header bands → details (group's items only) → group_footer bands; header/footer bands stay document-level.

Acceptance criteria

  • bands.json/manifest carry an optional, enum-validated group_by (unknown keys rejected on load, same pattern as ReportTemplateStorage::sanitizeBands())
  • With group_by unset, rendering is byte-identical to today (golden fixtures unchanged)
  • With group_by set, Group Header/Footer bands repeat per group and the details band iterates only that group's items
  • Group Footer bricks can render per-group totals; document totals remain correct
  • PHPUnit: renderer unit tests for grouped vs ungrouped output; golden fixture for one grouped template

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