Reports
Frappe has three report types, in order of complexity.
1. Report Builder
Click Reports → Report Builder, pick a DocType, choose fields and filters, save as a named report. Anyone with access can run it and export to CSV/XLSX.
Strengths: no code, fast to iterate, end-user friendly. Limits: single DocType, no joins, no SQL.
2. Query Report
For multi-DocType joins or computed columns, developers create Query Reports — a Python function returning columns and rows, plus a JSON config. Defined in code, shipped with apps.
Example structure:
my_app/my_app/report/sales_summary/
├── sales_summary.json
├── sales_summary.py # def execute(filters): return columns, data
└── sales_summary.js # Filter form
End users see them in the same Reports list and run them like Report Builder reports.
3. Script Report
Similar to Query Report but with more flexibility — you can run arbitrary Python, call APIs, do anything before returning data. Use sparingly; SQL via Query Report is usually enough.
Dashboards
Reports can be added to a Dashboard with charts (number cards, bar/line, pie). Dashboards live on Workspaces and can be the landing page for a role.
Scheduling
Any report can email itself to users on a schedule: Report → Set "Send to Users" → frequency. Saves you logging in every Monday for the weekly sales summary.
Exporting
All reports export to CSV and XLSX from the toolbar. For programmatic access, hit the API or use a Query Report's underlying execute() function via frappe.get_attr().