mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-17 22:14:26 +01:00
Add payouts report (#5320)
This commit is contained in:
@@ -538,7 +538,8 @@ namespace BTCPayServer.Controllers
|
|||||||
{
|
{
|
||||||
var ppBlob = item.PullPayment?.GetBlob();
|
var ppBlob = item.PullPayment?.GetBlob();
|
||||||
var payoutBlob = item.Payout.GetBlob(_jsonSerializerSettings);
|
var payoutBlob = item.Payout.GetBlob(_jsonSerializerSettings);
|
||||||
string payoutSource;
|
item.Payout.PullPaymentData = item.PullPayment;
|
||||||
|
string payoutSource = item.Payout.GetPayoutSource(_jsonSerializerSettings);
|
||||||
if (payoutBlob.Metadata?.TryGetValue("source", StringComparison.InvariantCultureIgnoreCase,
|
if (payoutBlob.Metadata?.TryGetValue("source", StringComparison.InvariantCultureIgnoreCase,
|
||||||
out var source) is true)
|
out var source) is true)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,6 +33,22 @@ namespace BTCPayServer.Data
|
|||||||
return PaymentMethodId.TryParse(data.PaymentMethodId, out var paymentMethodId) ? paymentMethodId : null;
|
return PaymentMethodId.TryParse(data.PaymentMethodId, out var paymentMethodId) ? paymentMethodId : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string GetPayoutSource(this PayoutData data, BTCPayNetworkJsonSerializerSettings jsonSerializerSettings)
|
||||||
|
{
|
||||||
|
var ppBlob = data.PullPaymentData?.GetBlob();
|
||||||
|
var payoutBlob = data.GetBlob(jsonSerializerSettings);
|
||||||
|
string payoutSource;
|
||||||
|
if (payoutBlob.Metadata?.TryGetValue("source", StringComparison.InvariantCultureIgnoreCase,
|
||||||
|
out var source) is true)
|
||||||
|
{
|
||||||
|
return source.Value<string>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ppBlob?.Name ?? data.PullPaymentDataId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static PayoutBlob GetBlob(this PayoutData data, BTCPayNetworkJsonSerializerSettings serializers)
|
public static PayoutBlob GetBlob(this PayoutData data, BTCPayNetworkJsonSerializerSettings serializers)
|
||||||
{
|
{
|
||||||
var result = JsonConvert.DeserializeObject<PayoutBlob>(Encoding.UTF8.GetString(data.Blob), serializers.GetSerializer(data.GetPaymentMethodId().CryptoCode));
|
var result = JsonConvert.DeserializeObject<PayoutBlob>(Encoding.UTF8.GetString(data.Blob), serializers.GetSerializer(data.GetPaymentMethodId().CryptoCode));
|
||||||
|
|||||||
@@ -157,6 +157,8 @@ namespace BTCPayServer.HostedServices
|
|||||||
public bool IncludeArchived { get; set; }
|
public bool IncludeArchived { get; set; }
|
||||||
public bool IncludeStoreData { get; set; }
|
public bool IncludeStoreData { get; set; }
|
||||||
public bool IncludePullPaymentData { get; set; }
|
public bool IncludePullPaymentData { get; set; }
|
||||||
|
public DateTimeOffset? From { get; set; }
|
||||||
|
public DateTimeOffset? To { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<PayoutData>> GetPayouts(PayoutQuery payoutQuery)
|
public async Task<List<PayoutData>> GetPayouts(PayoutQuery payoutQuery)
|
||||||
@@ -217,6 +219,14 @@ namespace BTCPayServer.HostedServices
|
|||||||
data.PullPaymentData == null || !data.PullPaymentData.Archived);
|
data.PullPaymentData == null || !data.PullPaymentData.Archived);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (payoutQuery.From is not null)
|
||||||
|
{
|
||||||
|
query = query.Where(data => data.Date >= payoutQuery.From);
|
||||||
|
}
|
||||||
|
if (payoutQuery.To is not null)
|
||||||
|
{
|
||||||
|
query = query.Where(data => data.Date <= payoutQuery.To);
|
||||||
|
}
|
||||||
return await query.ToListAsync(cancellationToken);
|
return await query.ToListAsync(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -359,6 +359,7 @@ namespace BTCPayServer.Hosting
|
|||||||
services.AddReportProvider<PaymentsReportProvider>();
|
services.AddReportProvider<PaymentsReportProvider>();
|
||||||
services.AddReportProvider<OnChainWalletReportProvider>();
|
services.AddReportProvider<OnChainWalletReportProvider>();
|
||||||
services.AddReportProvider<ProductsReportProvider>();
|
services.AddReportProvider<ProductsReportProvider>();
|
||||||
|
services.AddReportProvider<PayoutsReportProvider>();
|
||||||
|
|
||||||
services.AddHttpClient(WebhookSender.OnionNamedClient)
|
services.AddHttpClient(WebhookSender.OnionNamedClient)
|
||||||
.ConfigurePrimaryHttpMessageHandler<Socks5HttpClientHandler>();
|
.ConfigurePrimaryHttpMessageHandler<Socks5HttpClientHandler>();
|
||||||
|
|||||||
109
BTCPayServer/Services/Reporting/PayoutsReportProvider.cs
Normal file
109
BTCPayServer/Services/Reporting/PayoutsReportProvider.cs
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using BTCPayServer.Client.Models;
|
||||||
|
using BTCPayServer.Data;
|
||||||
|
using BTCPayServer.HostedServices;
|
||||||
|
using BTCPayServer.Payments;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Services.Reporting;
|
||||||
|
|
||||||
|
public class PayoutsReportProvider:ReportProvider
|
||||||
|
{
|
||||||
|
private readonly PullPaymentHostedService _pullPaymentHostedService;
|
||||||
|
private readonly BTCPayNetworkJsonSerializerSettings _btcPayNetworkJsonSerializerSettings;
|
||||||
|
|
||||||
|
public PayoutsReportProvider(PullPaymentHostedService pullPaymentHostedService, BTCPayNetworkJsonSerializerSettings btcPayNetworkJsonSerializerSettings)
|
||||||
|
{
|
||||||
|
_pullPaymentHostedService = pullPaymentHostedService;
|
||||||
|
_btcPayNetworkJsonSerializerSettings = btcPayNetworkJsonSerializerSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Name => "Payouts";
|
||||||
|
public override async Task Query(QueryContext queryContext, CancellationToken cancellation)
|
||||||
|
{
|
||||||
|
queryContext.ViewDefinition = CreateDefinition();
|
||||||
|
foreach (var payout in (await _pullPaymentHostedService.GetPayouts(new PullPaymentHostedService.PayoutQuery()
|
||||||
|
{
|
||||||
|
Stores = new[] {queryContext.StoreId},
|
||||||
|
From = queryContext.From,
|
||||||
|
To = queryContext.To,
|
||||||
|
IncludeArchived = true,
|
||||||
|
IncludePullPaymentData = true,
|
||||||
|
|
||||||
|
|
||||||
|
})).OrderBy(data => data.Date))
|
||||||
|
{
|
||||||
|
var blob = payout.GetBlob(_btcPayNetworkJsonSerializerSettings);
|
||||||
|
var data = queryContext.CreateData();
|
||||||
|
data.Add(payout.Date);
|
||||||
|
data.Add(payout.GetPayoutSource(_btcPayNetworkJsonSerializerSettings));
|
||||||
|
data.Add(payout.State.ToString());
|
||||||
|
if (PaymentMethodId.TryParse(payout.PaymentMethodId, out var paymentType))
|
||||||
|
{
|
||||||
|
if (paymentType.PaymentType == PaymentTypes.LightningLike || paymentType.PaymentType == PaymentTypes.LNURLPay)
|
||||||
|
data.Add("Lightning");
|
||||||
|
else if (paymentType.PaymentType == PaymentTypes.BTCLike)
|
||||||
|
data.Add("On-Chain");
|
||||||
|
else
|
||||||
|
data.Add(paymentType.PaymentType.ToStringNormalized());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
data.Add(paymentType.CryptoCode);
|
||||||
|
data.Add(blob.CryptoAmount);
|
||||||
|
var ppBlob = payout.PullPaymentData?.GetBlob();
|
||||||
|
data.Add(ppBlob?.Currency??paymentType.CryptoCode);
|
||||||
|
data.Add(blob.Amount);
|
||||||
|
data.Add(blob.Destination);
|
||||||
|
queryContext.Data.Add(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private ViewDefinition CreateDefinition()
|
||||||
|
{
|
||||||
|
return new ViewDefinition()
|
||||||
|
{
|
||||||
|
Fields = new List<StoreReportResponse.Field>()
|
||||||
|
{
|
||||||
|
new("Date", "datetime"),
|
||||||
|
new("Source", "string"),
|
||||||
|
new("State", "string"),
|
||||||
|
new("PaymentType", "string"),
|
||||||
|
new("Crypto", "string"),
|
||||||
|
new("CryptoAmount", "decimal"),
|
||||||
|
new("Currency", "string"),
|
||||||
|
new("CurrencyAmount", "decimal"),
|
||||||
|
new("Destination", "string")
|
||||||
|
},
|
||||||
|
Charts =
|
||||||
|
{
|
||||||
|
new ()
|
||||||
|
{
|
||||||
|
Name = "Aggregated crypto amount",
|
||||||
|
Groups = { "Crypto", "PaymentType", "State" },
|
||||||
|
Totals = { "Crypto" },
|
||||||
|
HasGrandTotal = false,
|
||||||
|
Aggregates = { "CryptoAmount" }
|
||||||
|
},new ()
|
||||||
|
{
|
||||||
|
Name = "Aggregated amount",
|
||||||
|
Groups = { "Currency", "State" },
|
||||||
|
Totals = { "CurrencyAmount" },
|
||||||
|
HasGrandTotal = false,
|
||||||
|
Aggregates = { "CurrencyAmount" }
|
||||||
|
},new ()
|
||||||
|
{
|
||||||
|
Name = "Aggregated amount by Source",
|
||||||
|
Groups = { "Currency", "State", "Source" },
|
||||||
|
Totals = { "CurrencyAmount" },
|
||||||
|
HasGrandTotal = false,
|
||||||
|
Aggregates = { "CurrencyAmount" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,18 +1,10 @@
|
|||||||
using System;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Data;
|
|
||||||
using BTCPayServer.Rating;
|
using BTCPayServer.Rating;
|
||||||
using BTCPayServer.Services.Apps;
|
using BTCPayServer.Services.Apps;
|
||||||
using BTCPayServer.Services.Invoices;
|
using BTCPayServer.Services.Invoices;
|
||||||
using BTCPayServer.Services.Rates;
|
using BTCPayServer.Services.Rates;
|
||||||
using Dapper;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Internal;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace BTCPayServer.Services.Reporting;
|
namespace BTCPayServer.Services.Reporting;
|
||||||
|
|
||||||
public class ProductsReportProvider : ReportProvider
|
public class ProductsReportProvider : ReportProvider
|
||||||
|
|||||||
Reference in New Issue
Block a user