Add pull payment grouping options (#3177)

* Add grouping by payment methods

* Add filtering by pull payment state

* Hide "Archive" button for archived pull payments

* Don't show payment methods bar if there is only one

* Add "All" payment method option

* Remove filtering by payment method

* Update state queries to not run on the client

* Add filtering by future pull payments
This commit is contained in:
Umar Bolatov
2022-02-17 01:13:28 -08:00
committed by GitHub
parent 5c8ca15ee2
commit 9a3a7a3444
4 changed files with 87 additions and 18 deletions

View File

@@ -5,6 +5,13 @@ using Newtonsoft.Json;
namespace BTCPayServer.Client.Models
{
public enum PullPaymentState
{
Active,
Expired,
Archived,
Future
}
public class PullPaymentData
{
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]

View File

@@ -147,15 +147,19 @@ namespace BTCPayServer.Controllers
}
[HttpGet("")]
public async Task<IActionResult> PullPayments(string storeId, int skip = 0, int count = 50,
string sortOrder = "desc")
public async Task<IActionResult> PullPayments(
string storeId,
PullPaymentState pullPaymentState,
int skip = 0,
int count = 50,
string sortOrder = "desc"
)
{
await using var ctx = _dbContextFactory.CreateContext();
var now = DateTimeOffset.UtcNow;
var ppsQuery = ctx.PullPayments
.Include(data => data.Payouts)
.Where(p => p.StoreId == storeId && !p.Archived);
.Where(p => p.StoreId == storeId);
if (sortOrder != null)
{
@@ -172,12 +176,45 @@ namespace BTCPayServer.Controllers
}
}
var paymentMethods = await _payoutHandlers.GetSupportedPaymentMethods(HttpContext.GetStoreData());
if (!paymentMethods.Any())
{
TempData.SetStatusMessageModel(new StatusMessageModel
{
Message = "You must enable at least one payment method before creating a pull payment.",
Severity = StatusMessageModel.StatusSeverity.Error
});
return RedirectToAction("PaymentMethods", "Stores", new { storeId });
}
var vm = this.ParseListQuery(new PullPaymentsModel()
{
Skip = skip,
Count = count,
Total = await ppsQuery.CountAsync()
Total = await ppsQuery.CountAsync(),
ActiveState = pullPaymentState
});
switch (pullPaymentState) {
case PullPaymentState.Active:
ppsQuery = ppsQuery
.Where(
p => !p.Archived &&
(p.EndDate != null ? p.EndDate > DateTimeOffset.UtcNow : true) &&
p.StartDate <= DateTimeOffset.UtcNow
);
break;
case PullPaymentState.Archived:
ppsQuery = ppsQuery.Where(p => p.Archived);
break;
case PullPaymentState.Expired:
ppsQuery = ppsQuery.Where(p => DateTimeOffset.UtcNow > p.EndDate);
break;
case PullPaymentState.Future:
ppsQuery = ppsQuery.Where(p => p.StartDate > DateTimeOffset.UtcNow);
break;
}
var pps = (await ppsQuery
.Skip(vm.Skip)
.Take(vm.Count)
@@ -210,8 +247,9 @@ namespace BTCPayServer.Controllers
Completed = totalCompleted.RoundToSignificant(ni.Divisibility).ToString("C", nfi),
Limit = _currencyNameTable.DisplayFormatCurrency(ppBlob.Limit, ppBlob.Currency),
ResetIn = period?.End is DateTimeOffset nr ? ZeroIfNegative(nr - now).TimeString() : null,
EndIn = pp.EndDate is DateTimeOffset end ? ZeroIfNegative(end - now).TimeString() : null
}
EndIn = pp.EndDate is DateTimeOffset end ? ZeroIfNegative(end - now).TimeString() : null,
},
Archived = pp.Archived
});
}
return View(vm);

View File

@@ -3,6 +3,8 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc.Rendering;
using BTCPayServer.Payments;
using BTCPayServer.Client.Models;
namespace BTCPayServer.Models.WalletViewModels
{
@@ -26,9 +28,13 @@ namespace BTCPayServer.Models.WalletViewModels
public ProgressModel Progress { get; set; }
public DateTimeOffset StartDate { get; set; }
public DateTimeOffset? EndDate { get; set; }
public bool Archived { get; set; } = false;
}
public List<PullPaymentModel> PullPayments { get; set; } = new List<PullPaymentModel>();
public string PaymentMethodId { get; set; }
public IEnumerable<PaymentMethodId> PaymentMethods { get; set; }
public PullPaymentState ActiveState { get; set; } = PullPaymentState.Active;
}
public class NewPullPaymentModel

View File

@@ -1,6 +1,7 @@
@using BTCPayServer.Views.Stores
@using BTCPayServer.Views.Stores
@using BTCPayServer.Abstractions.Extensions
@using BTCPayServer.Client
@using BTCPayServer.Client.Models
@model BTCPayServer.Models.WalletViewModels.PullPaymentsModel
@{
ViewData.SetActivePage(StoreNavPages.PullPayments, "Pull Payments", Context.GetStoreData().Id);
@@ -50,6 +51,19 @@
</a>
</div>
<ul class="nav nav-pills border bg-tile" style="border-radius: 4px;">
@foreach (var state in Enum.GetValues(typeof(PullPaymentState)).Cast<PullPaymentState>())
{
<li class="nav-item py-0">
<a id="@state-view"
asp-action="PullPayments"
asp-route-storeId="@Context.GetRouteValue("storeId")"
asp-route-pullPaymentState="@state"
class="nav-link me-1 @(state == Model.ActiveState ? "active" : "")" role="tab">@state</a>
</li>
}
</ul>
@if (Model.PullPayments.Any())
{
<div class="row">
@@ -81,6 +95,7 @@
<a
asp-action="PullPayments"
asp-route-sortOrder="@(nextStartDateSortOrder ?? "asc")"
asp-route-pullPaymentState="@Model.ActiveState"
class="text-nowrap"
title="@(nextStartDateSortOrder == "desc" ? sortByAsc : sortByDesc)">
Start
@@ -120,6 +135,8 @@
asp-route-pullPaymentId="@pp.Id">
Payouts
</a>
@if (!pp.Archived)
{
<span permission="@Policies.CanModifyStoreSettings"> - </span>
<a asp-action="ArchivePullPayment"
permission="@Policies.CanModifyStoreSettings"
@@ -130,6 +147,7 @@
data-description="Do you really want to archive the pull payment <strong>@pp.Name</strong>?">
Archive
</a>
}
</td>
</tr>
}