@using Newtonsoft.Json @using BTCPayServer.Services @using BTCPayServer.Services.Reporting @using BTCPayServer.Abstractions.Extensions @using BTCPayServer.Abstractions.Contracts @using BTCPayServer.Plugins.DynamicReports @model BTCPayServer.Plugins.DynamicReports.DynamicReportViewModel @inject IScopeProvider ScopeProvider @inject ReportService ReportService @inject DynamicReportService DynamicReportService @{ var storeId = ScopeProvider.GetCurrentStoreId(); var reportName = Context.Request.Query["reportName"].ToString(); reportName = string.IsNullOrEmpty(reportName) ? null : reportName; var existingReports = ReportService.ReportProviders.Where(pair => pair.Value is PostgresReportProvider).Select(pair => pair.Key).ToList(); ViewData.SetActivePage("DynamicReports", reportName is null ? "Create dynamic report" : $"Edit {reportName} dynamic report", reportName); }

@ViewData["Title"]

@if (reportName is null) { } else { @if (storeId is not null) { View } } @if (storeId is not null) { } @if (existingReports.Count > 0) { }
@if (reportName is null) {
} else { }
If unchecked, only admins will be able to use this report. Executing raw SQL is very powerful. Executing queries without proper filtering may expose sensitive data to unrelated users.
You can use @@StoreId to reference the current store id, @@From and @@To for the specified date range filters. The queries are sandboxed inside a SQL transaction, which never gets committed, ensuring reports are read-only.
@if (TempData.TryGetValue("Data", out var dataV) && dataV is string dataS) { var queryContext = JsonConvert.DeserializeObject(dataS);
.
@foreach (var column in queryContext.ViewDefinition.Fields) { } @foreach (var row in queryContext.Data) { @foreach (var column in row) { } }
@column.Name
@column
}