Introduce Server paging for Payouts List (#2564)

* Introduce Server paging for Payouts List

* Add paging params

* Minor code and formatting improvements

* View updates

* Apply suggestions from code review

Co-authored-by: Zaxounette <51208677+Zaxounette@users.noreply.github.com>

* fix tests

Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
Co-authored-by: Zaxounette <51208677+Zaxounette@users.noreply.github.com>
This commit is contained in:
Andrew Camilleri
2021-06-30 08:59:01 +01:00
committed by GitHub
parent 33de4cccfc
commit 6c856aba48
5 changed files with 267 additions and 270 deletions

View File

@@ -24,8 +24,7 @@ namespace BTCPayServer.Controllers
{
public partial class WalletsController
{
[HttpGet]
[Route("{walletId}/pull-payments/new")]
[HttpGet("{walletId}/pull-payments/new")]
public IActionResult NewPullPayment([ModelBinder(typeof(WalletIdModelBinder))]
WalletId walletId)
{
@@ -40,9 +39,8 @@ namespace BTCPayServer.Controllers
EmbeddedCSS = "",
});
}
[HttpPost]
[Route("{walletId}/pull-payments/new")]
[HttpPost("{walletId}/pull-payments/new")]
public async Task<IActionResult> NewPullPayment([ModelBinder(typeof(WalletIdModelBinder))]
WalletId walletId, NewPullPaymentModel model)
{
@@ -86,9 +84,8 @@ namespace BTCPayServer.Controllers
});
return RedirectToAction(nameof(PullPayments), new { walletId = walletId.ToString() });
}
[HttpGet]
[Route("{walletId}/pull-payments")]
[HttpGet("{walletId}/pull-payments")]
public async Task<IActionResult> PullPayments(
[ModelBinder(typeof(WalletIdModelBinder))]
WalletId walletId)
@@ -149,8 +146,7 @@ namespace BTCPayServer.Controllers
return time;
}
[HttpGet]
[Route("{walletId}/pull-payments/{pullPaymentId}/archive")]
[HttpGet("{walletId}/pull-payments/{pullPaymentId}/archive")]
public IActionResult ArchivePullPayment(
[ModelBinder(typeof(WalletIdModelBinder))]
WalletId walletId,
@@ -164,8 +160,8 @@ namespace BTCPayServer.Controllers
Action = "Archive"
});
}
[HttpPost]
[Route("{walletId}/pull-payments/{pullPaymentId}/archive")]
[HttpPost("{walletId}/pull-payments/{pullPaymentId}/archive")]
public async Task<IActionResult> ArchivePullPaymentPost(
[ModelBinder(typeof(WalletIdModelBinder))]
WalletId walletId,
@@ -180,8 +176,7 @@ namespace BTCPayServer.Controllers
return RedirectToAction(nameof(PullPayments), new { walletId = walletId.ToString() });
}
[HttpPost]
[Route("{walletId}/payouts")]
[HttpPost("{walletId}/payouts")]
public async Task<IActionResult> PayoutsPost(
[ModelBinder(typeof(WalletIdModelBinder))]
WalletId walletId, PayoutsModel vm, CancellationToken cancellationToken)
@@ -312,7 +307,7 @@ namespace BTCPayServer.Controllers
});
if (result != PayoutPaidRequest.PayoutPaidResult.Ok)
{
this.TempData.SetStatusMessageModel(new StatusMessageModel()
TempData.SetStatusMessageModel(new StatusMessageModel()
{
Message = PayoutPaidRequest.GetErrorMessage(result),
Severity = StatusMessageModel.StatusSeverity.Error
@@ -362,65 +357,77 @@ namespace BTCPayServer.Controllers
return payouts;
}
[HttpGet]
[Route("{walletId}/payouts")]
[HttpGet("{walletId}/payouts")]
public async Task<IActionResult> Payouts(
[ModelBinder(typeof(WalletIdModelBinder))]
WalletId walletId, PayoutsModel vm = null)
WalletId walletId, string pullPaymentId, PayoutState payoutState,
int skip = 0, int count = 50)
{
vm ??= new PayoutsModel();
vm.PayoutStateSets ??= ((PayoutState[]) Enum.GetValues(typeof(PayoutState))).Select(state =>
new PayoutsModel.PayoutStateSet() {State = state, Payouts = new List<PayoutsModel.PayoutModel>()}).ToList();
using var ctx = this._dbContextFactory.CreateContext();
var vm = this.ParseListQuery(new PayoutsModel
{
PaymentMethodId = new PaymentMethodId(walletId.CryptoCode, PaymentTypes.BTCLike),
PullPaymentId = pullPaymentId,
PayoutState = payoutState,
Skip = skip,
Count = count
});
vm.Payouts = new List<PayoutsModel.PayoutModel>();
await using var ctx = _dbContextFactory.CreateContext();
var storeId = walletId.StoreId;
vm.PaymentMethodId = new PaymentMethodId(walletId.CryptoCode, PaymentTypes.BTCLike);
var payoutRequest = ctx.Payouts.Where(p => p.PullPaymentData.StoreId == storeId && !p.PullPaymentData.Archived);
if (vm.PullPaymentId != null)
{
payoutRequest = payoutRequest.Where(p => p.PullPaymentDataId == vm.PullPaymentId);
vm.PullPaymentName = (await ctx.PullPayments.FindAsync(pullPaymentId)).GetBlob().Name;
}
if (vm.PaymentMethodId != null)
{
var pmiStr = vm.PaymentMethodId.ToString();
payoutRequest = payoutRequest.Where(p => p.PaymentMethodId == pmiStr);
}
vm.PayoutStateCount = payoutRequest.GroupBy(data => data.State)
.Select(e => new {e.Key, Count = e.Count()})
.ToDictionary(arg => arg.Key, arg => arg.Count);
foreach (PayoutState value in Enum.GetValues(typeof(PayoutState)))
{
if(vm.PayoutStateCount.ContainsKey(value))
continue;
vm.PayoutStateCount.Add(value, 0);
}
vm.PayoutStateCount = vm.PayoutStateCount.OrderBy(pair => pair.Key)
.ToDictionary(pair => pair.Key, pair => pair.Value);
payoutRequest = payoutRequest.Where(p => p.State == vm.PayoutState);
vm.Total = await payoutRequest.CountAsync();
payoutRequest = payoutRequest.Skip(vm.Skip).Take(vm.Count);
var payouts = await payoutRequest.OrderByDescending(p => p.Date)
.Select(o => new
{
Payout = o,
PullPayment = o.PullPaymentData
}).ToListAsync();
foreach (var stateSet in payouts.GroupBy(arg => arg.Payout.State))
foreach (var item in payouts)
{
var state = vm.PayoutStateSets.SingleOrDefault(set => set.State == stateSet.Key);
if (state == null)
var ppBlob = item.PullPayment.GetBlob();
var payoutBlob = item.Payout.GetBlob(_jsonSerializerSettings);
var m = new PayoutsModel.PayoutModel
{
state = new PayoutsModel.PayoutStateSet()
{
Payouts = new List<PayoutsModel.PayoutModel>(), State = stateSet.Key
};
vm.PayoutStateSets.Add(state);
}
foreach (var item in stateSet)
{
if (item.Payout.GetPaymentMethodId() != vm.PaymentMethodId)
continue;
var ppBlob = item.PullPayment.GetBlob();
var payoutBlob = item.Payout.GetBlob(_jsonSerializerSettings);
var m = new PayoutsModel.PayoutModel();
m.PullPaymentId = item.PullPayment.Id;
m.PullPaymentName = ppBlob.Name ?? item.PullPayment.Id;
m.Date = item.Payout.Date;
m.PayoutId = item.Payout.Id;
m.Amount = _currencyTable.DisplayFormatCurrency(payoutBlob.Amount, ppBlob.Currency);
m.Destination = payoutBlob.Destination;
var handler = _payoutHandlers
.FirstOrDefault(handler => handler.CanHandle(item.Payout.GetPaymentMethodId()));
var proofBlob = handler?.ParseProof(item.Payout);
m.ProofLink = proofBlob?.Link;
state.Payouts.Add(m);
}
PullPaymentId = item.PullPayment.Id,
PullPaymentName = ppBlob.Name ?? item.PullPayment.Id,
Date = item.Payout.Date,
PayoutId = item.Payout.Id,
Amount = _currencyTable.DisplayFormatCurrency(payoutBlob.Amount, ppBlob.Currency),
Destination = payoutBlob.Destination
};
var handler = _payoutHandlers
.FirstOrDefault(handler => handler.CanHandle(item.Payout.GetPaymentMethodId()));
var proofBlob = handler?.ParseProof(item.Payout);
m.ProofLink = proofBlob?.Link;
vm.Payouts.Add(m);
}
vm.PayoutStateSets = vm.PayoutStateSets.Where(set => set.Payouts?.Any() is true).ToList();
return View(vm);
}
}