Reports
Genie offers two distinct kinds of report, for two different needs:
- Code-defined reports — a C# class that loads data, formats it, and returns a downloadable file (typically a PDF). Use these for pixel-formatted, printable documents (invoices, statements).
- SQL-view report grids — an ordinary read-only
*.view.xmlover a SQL view. Use these for interactive, filterable, on-screen reporting tables.
Code-defined reports
Section titled “Code-defined reports”A report is a class deriving from ReportBase (implementing IReportBuilder). It has full access
to dependency injection (DbContext, session parameters, configuration) and owns its own data loading,
formatting and styling. It implements BuildAsync() to return an IReport (content bytes + file name +
content type + size).
[Report(Key = "sales.invoice", DisplayName = "Invoice", Category = "Sales")]public class InvoiceReport( ILogger logger, ISessionParametersService sessionParams, IServiceProvider services) : ReportBase(logger, sessionParams, services){ public override async Task<IReport> BuildAsync() { var invoiceId = GetParameter<long>("invoiceId"); // load data, render a PDF, return an IReport … }}Registration
Section titled “Registration”Reports are discovered by reflection over the [Report] attribute — no manual wiring:
AddReportsFromAssemblies(...)/AddReportsFromCurrentDomain(...)register each report type in the DI container (scoped, so it gets aDbContext).RegisterReportsFromAssemblies(...)/RegisterReportsFromCurrentDomain(...)register them in theReportRegistryby theirKey.
At request time ReportService looks the key up in the registry, resolves a fresh scoped instance,
passes the parameters via WithParameters(...), and calls BuildAsync().
| Method | Route | Returns |
|---|---|---|
GET |
/api/v1/genie/report/{reportName} |
the generated file (FileResult) |
Any query-string values (except reportName) are passed through as report parameters. Read them in the
builder with the typed helper GetParameter<T>("key").
GET /api/v1/genie/report/sales.invoice?invoiceId=42SQL-view report grids
Section titled “SQL-view report grids”Many “reports” need no code at all — they are just a read-only grid over a database view. Author a
normal object view whose <Sql> selects from a SQL view, and turn off CRUD:
<Table Name="LowStockReport" Slug="low-stock-report" Label="Low Stock" DisableActions="true" DisableControls="true"> <ParentView Name="catalog" /> <Sql PrimaryKey="ProductId" SortBy="Shortfall" SortDirection="DESC" PageSize="25"> <![CDATA[ SELECT v.ProductId, v.Sku, v.Name, v.OnHand, v.ReorderLevel, v.Shortfall FROM [Inventory].[vw_LowStock] v WHERE v.CompanyId = @SessionCompanyId ]]> </Sql> <Columns> <Column Name="Shortfall" Label="Shortfall" StyleClassesExpression="If(Shortfall > 10, 'badge bg-danger', 'badge bg-warning')" /> </Columns></Table>DisableActions/DisableControls make it a pure report — no create/edit/delete. It still gets
paging, sorting, per-column search, lookups and expression-driven styling from the standard
object pipeline, and it is permission-filtered and tenant-scoped
like any other view. The same SQL view can also back a navbar
counts badge.
See sample/Inventory/models/views/LowStockReport.view.xml and CategoryStockReport.view.xml.
Which to use
Section titled “Which to use”| Need | Use |
|---|---|
| Printable/downloadable document, precise layout | Code-defined report (ReportBase + PDF) |
| Interactive on-screen table, filter/sort/search | SQL-view report grid (*.view.xml) |