Skip to content

Reports

Verified against source (13)

  • report/Report.cs
  • report/ReportQuery.cs
  • report/ReportRequest.cs
  • Config/Report.config
  • Config/ReportRequest.config
  • Properties/Settings.settings
  • Report/Standard.Prompt.xslt
  • Extensions/ReportExtensions.cs
  • qbo4.AI.Bridge/SqlAgentOrchestrator.cs
  • qbo4.AI.Bridge/ReadOnlySqlGuard.cs
  • qbo4.AI.Bridge/AiBridgeOptions.cs
  • qbo4.AI/README.md
  • Extensions/ReportExtensions.cs

Reports use three classes, each with the standard routes:

  • /api/{module}/{operation} runs synchronously on the web server.
  • /api/{module}/queue/{operation} queues the operation for an app server. Use it for report runs; they can be long.
Class Module Purpose
ReportObject report The report. Queries is its ReportQueryCollection.
ReportQueryObject reportquery One query. Method holds a method signature ({Class}/{Operation}?{parameters}); Json holds dashboard chart options.
ReportRequestObject reportrequest A user’s run, with Parameters, ScheduleID, DeliveryContactID, QueueName, and the timestamps RequestQueued, RequestStarted, RequestCompleted, RequestDelivered.
GET /api/report/queue/run?ID=12&StartDate=2026-09-01&EndDate=2026-09-30

Run loads the report and runs each query with the parameters you pass:

  • If the query’s method is Attachment/Generate, it generates a document from that template, bound to the report.
  • Otherwise it invokes the statement as a data reader and writes the rows to an .xlsx file using the generator named by the ExcelGeneratorName setting (default ExcelGenerator). Files are stored at ReportQueryExcelPath (default {Object}/{ObjectID}/{Guid}/{FileName}).

Without ID, Run selects reports with ListWhere using your parameters and runs each one.

Parameter Effect
DeliveryTo, DeliveryCc, DeliveryBcc Comma-separated email addresses. If any are present (or the report has a DeliveryContactID), QBO sends a message bound to the report, listing a download link for each file.
DeliverySubject, From Override the message subject and sender.
BaseUrl Base URL for the download links, when running outside a web request.
CopyTo Comma-separated storage (file object) names to copy each output file to.
PathURL Relative path for CopyTo; supports the same substitutions as document copies.
AttachmentName Output file name for Excel queries; supports {…} substitutions from the parameters.
GET /api/report/queue/run?ID=12&CopyTo=ClientSftp&PathURL=/outbound/{Guid}.xlsx

SubmitRequest saves a ReportRequest and queues ProcessRequest. Any parameter that isn’t a ReportRequest field is stored in Parameters and passed to the report when it runs.

POST /api/reportrequest/submitrequest
?ReportID=12
&ReportRequest=September activity
&RequestedPersonID=7
&ScheduleName=Weekly on Mon, Thu @ 3:00am
&DeliveryContact_Contact=Report Recipients
&DeliveryContact_Methods_0_ContactValue=ops@example.com
&StartDate=2026-09-01
  • ScheduleName is optional. QBO finds or creates the schedule and calculates the first run. The request form builds names such as Weekly on Mon, Thu @ 3:00am and Monthly on the 1st Mon every 1 month @ 3:00am.
  • QueueName (or ReportRequestQueueName) chooses the queue; the default comes from the ReportRequestQueue setting.

ProcessRequest runs the report, moves the output files onto the request (so they inherit the request’s security), emails the delivery contact, and, for scheduled requests, queues the next run. It skips requests whose status is final.

With the QueuePendingRequests setting on, scheduled runs aren’t queued ahead of time; call /api/reportrequest/queuependingrequests on a schedule to queue the requests that are due.

AdHocInsert is what the ad hoc builder calls on Save:

POST /api/report/adhocinsert
?Report=Contacts by state
&BaseObject=Contact
&Name=ContactsByState
&Query=SELECT State, COUNT(*) AS Contacts FROM Contact … GROUP BY State

It saves Query as a statement named Name on the BaseObject module, creates the report, and adds a query pointing at {BaseObject}/{Name}. Pass BaseStatement instead of Name/Query to reuse an existing statement. To run against another database, pass ConnectionStringName (an existing connection) or ConnectionStringNew plus ConnectionString; QBO registers a SQL service for the statement on that connection.

GET /api/report/aitoquery?Prompt=Active contacts created in the last 30 days, by state&Output=Json

The response is an envelope with a Query, a Message, or both:

{ "Root": { "AiToQuery": { "Query": "SELECT ..." } } }

How it works:

  1. The prompt goes to the SQL agent named by AiBridgeOptions.SqlAgent (default qbo-sql), or by an AiName parameter. The agent’s instructions carry the QBO domain prompt and the schema, so it works with any configured model provider.
  2. A reply without a fenced SQL block is returned as Message (for example, a clarifying question), with no retry.
  3. SQL is checked by ReadOnlySqlGuard: it must parse as T-SQL and be a single SELECT, not SELECT … INTO.
  4. It is then validated with sys.sp_describe_first_result_set on the ConnectionStringName connection (default qbo.AdHoc). This parses and binds the query without executing it, so unknown tables and columns are caught.
  5. On a validation error the agent gets the error and up to two corrective retries. If it still fails, you get the best-effort Query plus a warning Message.

AiToQuery never runs the SQL. The ad hoc builder places it in the editor for the user to review and run. The builder shows the prompt only to users with the ReportAiToQuery permission.

  • DashboardChartSave saves a chart’s options (ChartType, Dimension, Pivot, Fact, titles, axes, legend) as JSON on a ReportQuery, by ReportQueryID or by ReportID plus ReportQuery.
  • With the Aspose integration, /api/report/createexceltemplate?ID=12 builds a starter Excel document template for the report: one worksheet per query with its column headings and a named range, plus a Charts sheet.
Operation What it does
/api/report/copy Copies a report, its queries, and its links (FromReportID, optional ToReport; the default name is “Copy of …”).
/api/report/email Renders the report’s queries as an HTML email to its delivery contact.
/api/report/rollback Restores a report’s definition as of RollbackDate.
/api/reportrequest/attachmentlist Lists a request’s output files.