Overview
Spree provides a flexible reporting system that allows you to generate data exports for sales analytics, product performance, and custom business metrics. Reports are generated asynchronously and delivered as downloadable CSV files.Report System Diagram
Key relationships:- Report is the base model for all report types using Single Table Inheritance (STI)
- ReportLineItem transforms raw database records into formatted report rows
- Reports are scoped to a Store and optionally track the AdminUser who created them
- GenerateJob handles asynchronous CSV generation via the events system
Architecture
The reporting system uses several design patterns:- Single Table Inheritance (STI): All report types inherit from
Spree::Reportand are stored in the same database table with atypecolumn - Presenter Pattern:
Spree::ReportLineItemsubclasses transform raw records into formatted output - Event-Driven Processing: Report generation is triggered asynchronously via Spree’s events system
- Registry Pattern: Reports are registered in
Spree.reportsfor discovery and validation
Built-in Reports
Spree ships with two built-in reports:Sales Total Report
The Sales Total report provides line-item level detail for all completed orders within a date range. Columns:date- Order completion dateorder- Order numberproduct- Variant descriptive namequantity- Line item quantitypre_tax_amount- Amount before taxespromo_total- Promotion discounts appliedshipment_total- Shipping coststax_total- Tax amounttotal- Final amount including all adjustments
Products Performance Report
The Products Performance report aggregates sales metrics by product for the specified period. Columns:sku- Product SKUname- Product namevendor- Vendor name (if multi-vendor enabled)brand- Brand namecategory_lvl0/1/2- Category hierarchy from main taxonprice- Current product priceweeks_online- Weeks since product became availablepre_tax_amount- Total pre-tax salestax_total- Total taxes collectedquantity- Total units soldpromo_total- Total promotion discountstotal- Total revenue
How Reports Work Internally
Generation Flow
- User creates report via admin UI with date range, currency, and optional vendor
- Report is saved to database with status tracking
report.createdevent fires viapublishes_lifecycle_eventsconcernSpree::ReportSubscribercatches event and enqueuesGenerateJob- Background job runs
report.generate:- Iterates through
line_items_scopein batches - Transforms each record via
ReportLineItem - Writes CSV to temp file
- Attaches CSV to report via ActiveStorage
- Sends notification email to user
- Iterates through
Key Files
| File | Purpose |
|---|---|
core/app/models/spree/report.rb | Base report model |
core/app/models/spree/report_line_item.rb | Base line item presenter |
core/app/models/spree/reports/*.rb | Built-in report implementations |
core/app/models/spree/report_line_items/*.rb | Built-in line item formatters |
core/app/subscribers/spree/report_subscriber.rb | Event subscriber for async generation |
core/app/jobs/spree/reports/generate_job.rb | Background job for CSV creation |
core/app/mailers/spree/report_mailer.rb | Notification emails |
admin/app/controllers/spree/admin/reports_controller.rb | Admin UI controller |
Report Base Class Methods
ReportLineItem Base Class Methods
Configuration
Report Preview Limit
Configure the number of preview rows shown in the admin UI:config/initializers/spree.rb
Background Job Queue
Reports use a dedicated queue. Configure your job processor:Permissions
Report access is controlled by CanCanCan. By default, only users with the:manage ability on Spree::Report can access reports. Configure permissions in your permission sets.
Related Documentation
- Build a Custom Report - Step-by-step guide to creating custom reports
- Events - How report generation uses the events system

