mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2026-01-31 11:54:24 +01:00
Allow listeners to retrieve invoices with nonActivated prompts
This commit is contained in:
@@ -23,5 +23,6 @@
|
||||
<None Remove="DBScripts\003.RefactorPendingInvoicesPayments.sql" />
|
||||
<None Remove="DBScripts\004.MonitoredInvoices.sql" />
|
||||
<None Remove="DBScripts\005.PaymentsRenaming.sql" />
|
||||
<None Remove="DBScripts\006.PaymentsRenaming.sql" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
18
BTCPayServer.Data/DBScripts/006.PaymentsRenaming.sql
Normal file
18
BTCPayServer.Data/DBScripts/006.PaymentsRenaming.sql
Normal file
@@ -0,0 +1,18 @@
|
||||
DROP FUNCTION get_monitored_invoices;
|
||||
CREATE OR REPLACE FUNCTION get_monitored_invoices(payment_method_id TEXT, include_non_activated BOOLEAN)
|
||||
RETURNS TABLE (invoice_id TEXT, payment_id TEXT, payment_method_id TEXT) AS $$
|
||||
WITH cte AS (
|
||||
-- Get all the invoices which are pending. Even if no payments.
|
||||
SELECT i."Id" invoice_id, p."Id" payment_id, p."PaymentMethodId" payment_method_id FROM "Invoices" i LEFT JOIN "Payments" p ON i."Id" = p."InvoiceDataId"
|
||||
WHERE is_pending(i."Status")
|
||||
UNION ALL
|
||||
-- For invoices not pending, take all of those which have pending payments
|
||||
SELECT i."Id", p."Id", p."PaymentMethodId" payment_method_id FROM "Invoices" i INNER JOIN "Payments" p ON i."Id" = p."InvoiceDataId"
|
||||
WHERE is_pending(p."Status") AND NOT is_pending(i."Status"))
|
||||
SELECT cte.* FROM cte
|
||||
LEFT JOIN "Payments" p ON cte.payment_id=p."Id" AND cte.payment_id=p."PaymentMethodId"
|
||||
LEFT JOIN "Invoices" i ON cte.invoice_id=i."Id"
|
||||
WHERE (p."PaymentMethodId" IS NOT NULL AND p."PaymentMethodId" = payment_method_id) OR
|
||||
(p."PaymentMethodId" IS NULL AND get_prompt(i."Blob2", payment_method_id) IS NOT NULL AND
|
||||
(include_non_activated IS TRUE OR (get_prompt(i."Blob2", payment_method_id)->'activated')::BOOLEAN IS NOT FALSE));
|
||||
$$ LANGUAGE SQL STABLE;
|
||||
15
BTCPayServer.Data/Migrations/20240924071444_temprefactor3.cs
Normal file
15
BTCPayServer.Data/Migrations/20240924071444_temprefactor3.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using BTCPayServer.Data;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace BTCPayServer.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
[Migration("20240924071444_temprefactor3")]
|
||||
[DBScript("006.PaymentsRenaming.sql")]
|
||||
public partial class temprefactor3 : DBScriptsMigration
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ using BTCPayServer.Events;
|
||||
using BTCPayServer.Lightning;
|
||||
using BTCPayServer.Models.InvoicingModels;
|
||||
using BTCPayServer.NTag424;
|
||||
using BTCPayServer.Payments;
|
||||
using BTCPayServer.Payments.Lightning;
|
||||
using BTCPayServer.PayoutProcessors;
|
||||
using BTCPayServer.Plugins.PointOfSale.Controllers;
|
||||
@@ -2711,6 +2712,14 @@ namespace BTCPayServer.Tests
|
||||
invoiceObject = await client.GetOnChainWalletObject(user.StoreId, "BTC", new OnChainWalletObjectId("invoice", invoice.Id), false);
|
||||
Assert.DoesNotContain(invoiceObject.Links.Select(l => l.Type), t => t == "address");
|
||||
|
||||
// Check if we can get the monitored invoice
|
||||
var invoiceRepo = tester.PayTester.GetService<InvoiceRepository>();
|
||||
var includeNonActivated = true;
|
||||
Assert.Single(await invoiceRepo.GetMonitoredInvoices(PaymentMethodId.Parse("BTC-CHAIN"), includeNonActivated), i => i.Id == invoice.Id);
|
||||
includeNonActivated = false;
|
||||
Assert.Single(await invoiceRepo.GetMonitoredInvoices(PaymentMethodId.Parse("BTC-CHAIN"), includeNonActivated), i => i.Id == invoice.Id);
|
||||
Assert.Single(await invoiceRepo.GetMonitoredInvoices(PaymentMethodId.Parse("BTC-CHAIN")), i => i.Id == invoice.Id);
|
||||
//
|
||||
|
||||
paymentMethods = await client.GetInvoicePaymentMethods(store.Id, invoice.Id);
|
||||
Assert.Single(paymentMethods);
|
||||
|
||||
@@ -3161,9 +3161,11 @@ namespace BTCPayServer.Tests
|
||||
var invoiceRepo = tester.PayTester.GetService<InvoiceRepository>();
|
||||
var monitored = Assert.Single(await invoiceRepo.GetMonitoredInvoices(PaymentMethodId.Parse("BTC-CHAIN")), i => i.Id == invoiceId);
|
||||
Assert.Single(monitored.Payments);
|
||||
//
|
||||
monitored = Assert.Single(await invoiceRepo.GetMonitoredInvoices(PaymentMethodId.Parse("BTC-CHAIN"), true), i => i.Id == invoiceId);
|
||||
Assert.Single(monitored.Payments);
|
||||
//
|
||||
|
||||
app = await client.CreatePointOfSaleApp(acc.StoreId, new PointOfSaleAppRequest
|
||||
app = await client.CreatePointOfSaleApp(acc.StoreId, new PointOfSaleAppRequest
|
||||
{
|
||||
AppName = "Cart",
|
||||
DefaultView = PosViewType.Cart,
|
||||
|
||||
@@ -88,11 +88,30 @@ namespace BTCPayServer.Services.Invoices
|
||||
/// <param name="paymentMethodId">The payment method id</param>
|
||||
/// <param name="cancellationToken">Cancellation token</param>
|
||||
/// <returns></returns>
|
||||
public async Task<InvoiceEntity[]> GetMonitoredInvoices(PaymentMethodId paymentMethodId, CancellationToken cancellationToken = default)
|
||||
public Task<InvoiceEntity[]> GetMonitoredInvoices(PaymentMethodId paymentMethodId, CancellationToken cancellationToken = default)
|
||||
=> GetMonitoredInvoices(paymentMethodId, false, cancellationToken: cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Returns all invoices which either:
|
||||
/// * Have the <paramref name="paymentMethodId"/> activated and are pending
|
||||
/// * Aren't pending but have a payment from the <paramref name="paymentMethodId"/> that is pending
|
||||
/// <see cref="InvoiceData.AddressInvoices"/> is filled with the monitored addresses of the <paramref name="paymentMethodId"/> for this invoice.
|
||||
/// <see cref="InvoiceData.Payments"/> include the <paramref name="paymentMethodId"/> payments for this invoice.
|
||||
/// </summary>
|
||||
/// <param name="paymentMethodId">The payment method id</param>
|
||||
/// <param name="includeNonActivated">If true, include pending invoice with non activated payment methods</param>
|
||||
/// <param name="cancellationToken">Cancellation token</param>
|
||||
/// <returns></returns>
|
||||
public async Task<InvoiceEntity[]> GetMonitoredInvoices(PaymentMethodId paymentMethodId, bool includeNonActivated, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var pmi = paymentMethodId.ToString();
|
||||
using var ctx = _applicationDbContextFactory.CreateContext();
|
||||
var conn = ctx.Database.GetDbConnection();
|
||||
|
||||
string includeNonActivateQuery = String.Empty;
|
||||
if (includeNonActivated)
|
||||
includeNonActivateQuery = " AND (get_prompt(i.\"Blob2\", @pmi)->'activated')::BOOLEAN IS NOT FALSE)";
|
||||
|
||||
var rows = await conn.QueryAsync<(string Id, uint xmin, string[] addresses, string[] payments, string invoice)>(new("""
|
||||
SELECT
|
||||
i."Id",
|
||||
@@ -100,14 +119,14 @@ namespace BTCPayServer.Services.Invoices
|
||||
array_agg(ai."Address") addresses,
|
||||
COALESCE(array_agg(to_jsonb(p)) FILTER (WHERE p."Id" IS NOT NULL), '{}') as payments,
|
||||
(array_agg(to_jsonb(i)))[1] as invoice
|
||||
FROM get_monitored_invoices(@pmi) m
|
||||
FROM get_monitored_invoices(@pmi, @includeNonActivated) m
|
||||
LEFT JOIN "Payments" p ON p."Id" = m.payment_id AND p."PaymentMethodId" = m.payment_method_id
|
||||
LEFT JOIN "Invoices" i ON i."Id" = m.invoice_id
|
||||
LEFT JOIN "AddressInvoices" ai ON i."Id" = ai."InvoiceDataId"
|
||||
WHERE ai."PaymentMethodId" = @pmi
|
||||
GROUP BY i."Id";
|
||||
"""
|
||||
, new { pmi = paymentMethodId.ToString() }));
|
||||
, new { pmi = paymentMethodId.ToString(), includeNonActivated }));
|
||||
if (Enumerable.TryGetNonEnumeratedCount(rows, out var c) && c == 0)
|
||||
return Array.Empty<InvoiceEntity>();
|
||||
List<InvoiceEntity> invoices = new List<InvoiceEntity>();
|
||||
|
||||
Reference in New Issue
Block a user