diff --git a/BTCPayServer/Controllers/UIStorePullPaymentsController.PullPayments.cs b/BTCPayServer/Controllers/UIStorePullPaymentsController.PullPayments.cs index 0575684db..8ad6ebb64 100644 --- a/BTCPayServer/Controllers/UIStorePullPaymentsController.PullPayments.cs +++ b/BTCPayServer/Controllers/UIStorePullPaymentsController.PullPayments.cs @@ -448,15 +448,14 @@ namespace BTCPayServer.Controllers ApplicationDbContext ctx, string[] payoutIds, string storeId, CancellationToken cancellationToken) { - var payouts = (await ctx.Payouts - .Include(p => p.PullPaymentData) - .Include(p => p.StoreData) - .Where(p => payoutIds.Contains(p.Id)) - .Where(p => p.StoreDataId == storeId && (p.PullPaymentDataId == null || !p.PullPaymentData.Archived)) - .ToListAsync(cancellationToken)) - .Where(p => p.GetPaymentMethodId() == paymentMethodId) - .ToList(); - return payouts; + return await PullPaymentHostedService.GetPayouts(new PullPaymentHostedService.PayoutQuery() + { + IncludeArchived = false, + IncludeStoreData = true, + Stores = new[] {storeId}, + PayoutIds = payoutIds, + PaymentMethods = new[] {paymentMethodId.ToString()} + }, ctx, cancellationToken); } [HttpGet("stores/{storeId}/pull-payments/{pullPaymentId}/payouts")] diff --git a/BTCPayServer/Data/Payouts/BitcoinLike/BitcoinLikePayoutHandler.cs b/BTCPayServer/Data/Payouts/BitcoinLike/BitcoinLikePayoutHandler.cs index b5955b7c3..959dac081 100644 --- a/BTCPayServer/Data/Payouts/BitcoinLike/BitcoinLikePayoutHandler.cs +++ b/BTCPayServer/Data/Payouts/BitcoinLike/BitcoinLikePayoutHandler.cs @@ -202,12 +202,10 @@ public class BitcoinLikePayoutHandler : IPayoutHandler case "mark-paid": await using (var context = _dbContextFactory.CreateContext()) { - var payouts = (await context.Payouts - .Include(p => p.PullPaymentData) - .Include(p => p.PullPaymentData.StoreData) - .Where(p => payoutIds.Contains(p.Id)) - .Where(p => p.PullPaymentData.StoreId == storeId && !p.PullPaymentData.Archived && p.State == PayoutState.AwaitingPayment) - .ToListAsync()).Where(data => + var payouts = (await PullPaymentHostedService.GetPayouts(new PullPaymentHostedService.PayoutQuery() + { + States = new[] {PayoutState.AwaitingPayment}, Stores = new[] {storeId}, PayoutIds = payoutIds + }, context)).Where(data => PaymentMethodId.TryParse(data.PaymentMethodId, out var paymentMethodId) && CanHandle(paymentMethodId)) .Select(data => (data, ParseProof(data) as PayoutTransactionOnChainBlob)).Where(tuple => tuple.Item2 != null && tuple.Item2.TransactionId != null && tuple.Item2.Accounted == false); @@ -217,24 +215,20 @@ public class BitcoinLikePayoutHandler : IPayoutHandler valueTuple.data.State = PayoutState.InProgress; SetProofBlob(valueTuple.data, valueTuple.Item2); } - await context.SaveChangesAsync(); } - return new StatusMessageModel() { Message = "Payout payments have been marked confirmed", Severity = StatusMessageModel.StatusSeverity.Success }; case "reject-payment": - await using (var context = _dbContextFactory.CreateContext()) + await using (var context = _dbContextFactory.CreateContext()) { - var payouts = (await context.Payouts - .Include(p => p.PullPaymentData) - .Include(p => p.PullPaymentData.StoreData) - .Where(p => payoutIds.Contains(p.Id)) - .Where(p => p.PullPaymentData.StoreId == storeId && !p.PullPaymentData.Archived && p.State == PayoutState.AwaitingPayment) - .ToListAsync()).Where(data => + var payouts = (await PullPaymentHostedService.GetPayouts(new PullPaymentHostedService.PayoutQuery() + { + States = new[] {PayoutState.AwaitingPayment}, Stores = new[] {storeId}, PayoutIds = payoutIds + }, context)).Where(data => PaymentMethodId.TryParse(data.PaymentMethodId, out var paymentMethodId) && CanHandle(paymentMethodId)) .Select(data => (data, ParseProof(data) as PayoutTransactionOnChainBlob)).Where(tuple => tuple.Item2 != null && tuple.Item2.TransactionId != null && tuple.Item2.Accounted == true); diff --git a/BTCPayServer/HostedServices/PullPaymentHostedService.cs b/BTCPayServer/HostedServices/PullPaymentHostedService.cs index 0eedf3116..d7e0d2648 100644 --- a/BTCPayServer/HostedServices/PullPaymentHostedService.cs +++ b/BTCPayServer/HostedServices/PullPaymentHostedService.cs @@ -151,6 +151,9 @@ namespace BTCPayServer.HostedServices public string[] PayoutIds { get; set; } public string[] PaymentMethods { get; set; } public string[] Stores { get; set; } + public bool IncludeArchived { get; set; } + public bool IncludeStoreData { get; set; } + public bool IncludePullPaymentData { get; set; } } public async Task> GetPayouts(PayoutQuery payoutQuery) @@ -159,7 +162,8 @@ namespace BTCPayServer.HostedServices return await GetPayouts(payoutQuery, ctx); } - public async Task> GetPayouts(PayoutQuery payoutQuery, ApplicationDbContext ctx) + public static async Task> GetPayouts(PayoutQuery payoutQuery, ApplicationDbContext ctx, + CancellationToken cancellationToken = default) { var query = ctx.Payouts.AsQueryable(); if (payoutQuery.States is not null) @@ -186,8 +190,23 @@ namespace BTCPayServer.HostedServices { query = query.Where(data => payoutQuery.Stores.Contains(data.StoreDataId)); } + if (payoutQuery.IncludeStoreData) + { + query = query.Include(data => data.StoreData); + } + + if (payoutQuery.IncludePullPaymentData || !payoutQuery.IncludeArchived) + { + query = query.Include(data => data.PullPaymentData); + } - return await query.ToListAsync(); + if (!payoutQuery.IncludeArchived) + { + query = query.Where(data => + data.PullPaymentData == null || !data.PullPaymentData.Archived); + } + + return await query.ToListAsync(cancellationToken); } public async Task GetPullPayment(string pullPaymentId, bool includePayouts) @@ -769,7 +788,7 @@ namespace BTCPayServer.HostedServices public string PayoutId { get; set; } public JObject Proof { get; set; } - public PayoutState State { get; set; } + public PayoutState State { get; set; } = PayoutState.Completed; public static string GetErrorMessage(PayoutPaidResult result) { diff --git a/BTCPayServer/Payments/Lightning/LightningPendingPayoutListener.cs b/BTCPayServer/Payments/Lightning/LightningPendingPayoutListener.cs index 584d4b977..50e641765 100644 --- a/BTCPayServer/Payments/Lightning/LightningPendingPayoutListener.cs +++ b/BTCPayServer/Payments/Lightning/LightningPendingPayoutListener.cs @@ -56,7 +56,7 @@ public class LightningPendingPayoutListener : BaseAsyncService .ToDictionary(network => new PaymentMethodId(network.CryptoCode, PaymentTypes.LightningLike)); - var payouts = await _pullPaymentHostedService.GetPayouts( + var payouts = await PullPaymentHostedService.GetPayouts( new PullPaymentHostedService.PayoutQuery() { States = new PayoutState[] { PayoutState.InProgress }, diff --git a/BTCPayServer/PayoutProcessors/BaseAutomatedPayoutProcessor.cs b/BTCPayServer/PayoutProcessors/BaseAutomatedPayoutProcessor.cs index 19c3960b5..1205c8ce5 100644 --- a/BTCPayServer/PayoutProcessors/BaseAutomatedPayoutProcessor.cs +++ b/BTCPayServer/PayoutProcessors/BaseAutomatedPayoutProcessor.cs @@ -62,7 +62,7 @@ public abstract class BaseAutomatedPayoutProcessor : BaseAsyncService where T { await using var context = _applicationDbContextFactory.CreateContext(); - var payouts = await _pullPaymentHostedService.GetPayouts( + var payouts = await PullPaymentHostedService.GetPayouts( new PullPaymentHostedService.PayoutQuery() { States = new[] { PayoutState.AwaitingPayment },