btcpayserver/BTCPayServer/Controllers/GreenField/GreenfieldReportsController.cs
Nicolas Dorier dc986959fd
Add reporting feature (#5155)
* Add reporting feature

* Remove nodatime

* Add summaries

* work...

* Add chart title

* Fix error

* Allow to set hour in the field

* UI updates

* Fix fake data

* ViewDefinitions can be dynamic

* Add items sold

* Sticky table headers

* Update JS and remove jQuery usages

* JS click fix

* Handle tag all invoices for app

* fix dup row in items report

* Can cancel invoice request

* Add tests

* Fake data for items sold

* Rename Items to Products, improve navigation F5

* Use bordered table for summaries

---------

Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
2023-07-24 09:24:32 +09:00

80 lines
2.9 KiB
C#

#nullable enable
using BTCPayServer.Lightning;
using BTCPayServer.Models.StoreViewModels;
using BTCPayServer.Services.Invoices;
using System.Collections.Generic;
using System.Threading.Tasks;
using System;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore.Internal;
using NBitcoin;
using Newtonsoft.Json.Linq;
using BTCPayServer.Data;
using Microsoft.EntityFrameworkCore;
using Dapper;
using Microsoft.AspNetCore.Authorization;
using BTCPayServer.Abstractions.Constants;
using BTCPayServer.Client;
using BTCPayServer.Abstractions.Extensions;
using BTCPayServer.Client.Models;
using BTCPayServer.Services;
using System.Linq;
using System.Threading;
namespace BTCPayServer.Controllers.GreenField;
[ApiController]
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
[EnableCors(CorsPolicies.All)]
public class GreenfieldReportsController : Controller
{
public GreenfieldReportsController(
ApplicationDbContextFactory dbContextFactory,
ReportService reportService)
{
DBContextFactory = dbContextFactory;
ReportService = reportService;
}
public ApplicationDbContextFactory DBContextFactory { get; }
public ReportService ReportService { get; }
[Authorize(Policy = Policies.CanViewStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
[HttpPost("~/api/v1/stores/{storeId}/reports")]
[NonAction] // Disabling this endpoint as we still need to figure out the request/response model
public async Task<IActionResult> StoreReports(string storeId, [FromBody] StoreReportRequest? vm = null, CancellationToken cancellationToken = default)
{
vm ??= new StoreReportRequest();
vm.ViewName ??= "Payments";
vm.TimePeriod ??= new TimePeriod();
vm.TimePeriod.To ??= DateTime.UtcNow;
vm.TimePeriod.From ??= vm.TimePeriod.To.Value.AddMonths(-1);
var from = vm.TimePeriod.From.Value;
var to = vm.TimePeriod.To.Value;
if (ReportService.ReportProviders.TryGetValue(vm.ViewName, out var report))
{
if (!report.IsAvailable())
return this.CreateAPIError(503, "view-unavailable", $"This view is unavailable at this moment");
var ctx = new Services.Reporting.QueryContext(storeId, from, to);
await report.Query(ctx, cancellationToken);
var result = new StoreReportResponse()
{
Fields = ctx.ViewDefinition?.Fields ?? new List<StoreReportResponse.Field>(),
Charts = ctx.ViewDefinition?.Charts ?? new List<ChartDefinition>(),
Data = ctx.Data.Select(d => new JArray(d)).ToList(),
From = from,
To = to
};
return Json(result);
}
else
{
ModelState.AddModelError(nameof(vm.ViewName), "View doesn't exist");
return this.CreateValidationError(ModelState);
}
}
}