Refactoring: Invoice UI Controller cleanups

Simple and IDE proposed changes and cleanups I came across while working on #3092.
This commit is contained in:
Dennis Reimann
2021-11-15 09:35:03 +01:00
committed by Andrew Camilleri
parent 4cd18a1b28
commit 6813a6ea63

View File

@@ -15,7 +15,6 @@ using BTCPayServer.Client.Models;
using BTCPayServer.Data;
using BTCPayServer.Filters;
using BTCPayServer.HostedServices;
using BTCPayServer.Logging;
using BTCPayServer.Models.InvoicingModels;
using BTCPayServer.Payments;
using BTCPayServer.Rating;
@@ -26,9 +25,7 @@ using BTCPayServer.Services.Rates;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Routing;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using NBitcoin;
using NBitpayClient;
using NBXplorer;
@@ -40,9 +37,7 @@ namespace BTCPayServer.Controllers
{
public partial class InvoiceController
{
[HttpGet]
[Route("invoices/{invoiceId}/deliveries/{deliveryId}/request")]
[HttpGet("invoices/{invoiceId}/deliveries/{deliveryId}/request")]
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie)]
public async Task<IActionResult> WebhookDelivery(string invoiceId, string deliveryId)
{
@@ -56,10 +51,10 @@ namespace BTCPayServer.Controllers
var delivery = await _InvoiceRepository.GetWebhookDelivery(invoiceId, deliveryId);
if (delivery is null)
return NotFound();
return this.File(delivery.GetBlob().Request, "application/json");
return File(delivery.GetBlob().Request, "application/json");
}
[HttpPost]
[Route("invoices/{invoiceId}/deliveries/{deliveryId}/redeliver")]
[HttpPost("invoices/{invoiceId}/deliveries/{deliveryId}/redeliver")]
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
public async Task<IActionResult> RedeliverWebhook(string storeId, string invoiceId, string deliveryId)
{
@@ -85,8 +80,7 @@ namespace BTCPayServer.Controllers
});
}
[HttpGet]
[Route("invoices/{invoiceId}")]
[HttpGet("invoices/{invoiceId}")]
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie)]
public async Task<IActionResult> Invoice(string invoiceId)
{
@@ -162,13 +156,12 @@ namespace BTCPayServer.Controllers
invoiceState.Status == InvoiceStatusLegacy.Invalid;
}
[HttpGet]
[Route("invoices/{invoiceId}/refund")]
[HttpGet("invoices/{invoiceId}/refund")]
[AllowAnonymous]
public async Task<IActionResult> Refund([FromServices]IEnumerable<IPayoutHandler> payoutHandlers, string invoiceId, CancellationToken cancellationToken)
{
await using var ctx = _dbContextFactory.CreateContext();
ctx.ChangeTracker.QueryTrackingBehavior = Microsoft.EntityFrameworkCore.QueryTrackingBehavior.NoTracking;
ctx.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
var invoice = await ctx.Invoices.Include(i => i.Payments)
.Include(i => i.CurrentRefund)
.Include(i => i.StoreData)
@@ -189,8 +182,7 @@ namespace BTCPayServer.Controllers
"PullPayment",
new { pullPaymentId = ppId });
}
else
{
var paymentMethods = invoice.GetBlob(_NetworkProvider).GetPaymentMethods();
var pmis = paymentMethods.Select(method => method.GetId()).ToList();
var options = (await payoutHandlers.GetSupportedPaymentMethods(invoice.StoreData)).Where(id => pmis.Contains(id)).ToList();
@@ -222,9 +214,8 @@ namespace BTCPayServer.Controllers
}
return View(refund);
}
}
[HttpPost]
[Route("invoices/{invoiceId}/refund")]
[HttpPost("invoices/{invoiceId}/refund")]
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie)]
public async Task<IActionResult> Refund(string invoiceId, RefundModel model, CancellationToken cancellationToken)
{
@@ -256,6 +247,9 @@ namespace BTCPayServer.Controllers
{
paymentMethod = pms[new PaymentMethodId(paymentMethodId.CryptoCode, PaymentTypes.LNURLPay)];
}
if (paymentMethod != null)
{
var cryptoPaid = paymentMethod.Calculate().Paid.ToDecimal(MoneyUnit.BTC);
var paidCurrency =
Math.Round(cryptoPaid * paymentMethod.Rate,
@@ -279,6 +273,8 @@ namespace BTCPayServer.Controllers
model.CurrentRateText =
_CurrencyNameTable.DisplayFormatCurrency(model.CryptoAmountNow, paymentMethodId.CryptoCode);
model.FiatAmount = paidCurrency;
}
model.FiatText = _CurrencyNameTable.DisplayFormatCurrency(model.FiatAmount, invoice.Currency);
return View(model);
case RefundSteps.SelectRate:
@@ -330,7 +326,7 @@ namespace BTCPayServer.Controllers
}
rules = store.GetStoreBlob().GetRateRules(_NetworkProvider);
rateResult = await _RateProvider.FetchRate(
new Rating.CurrencyPair(paymentMethodId.CryptoCode, model.CustomCurrency), rules,
new CurrencyPair(paymentMethodId.CryptoCode, model.CustomCurrency), rules,
cancellationToken);
//TODO: What if fetching rate failed?
if (rateResult.BidAsk is null)
@@ -340,7 +336,7 @@ namespace BTCPayServer.Controllers
return View(model);
}
createPullPayment = new HostedServices.CreatePullPayment();
createPullPayment = new CreatePullPayment();
createPullPayment.Name = $"Refund {invoice.Id}";
createPullPayment.PaymentMethodIds = new[] { paymentMethodId };
createPullPayment.StoreId = invoice.StoreId;
@@ -352,12 +348,12 @@ namespace BTCPayServer.Controllers
}
var ppId = await _paymentHostedService.CreatePullPayment(createPullPayment);
this.TempData.SetStatusMessageModel(new StatusMessageModel()
TempData.SetStatusMessageModel(new StatusMessageModel()
{
Html = "Refund successfully created!<br />Share the link to this page with a customer.<br />The customer needs to enter their address and claim the refund.<br />Once a customer claims the refund, you will get a notification and would need to approve and initiate it from your Store > Payouts.",
Severity = StatusMessageModel.StatusSeverity.Success
});
(await ctx.Invoices.FindAsync(new[] { invoice.Id }, cancellationToken: cancellationToken)).CurrentRefundId = ppId;
(await ctx.Invoices.FindAsync(new[] { invoice.Id }, cancellationToken)).CurrentRefundId = ppId;
ctx.Refunds.Add(new RefundData()
{
InvoiceDataId = invoice.Id,
@@ -442,10 +438,9 @@ namespace BTCPayServer.Controllers
return RedirectToAction(nameof(ListInvoices));
}
[HttpGet]
[Route("i/{invoiceId}")]
[Route("i/{invoiceId}/{paymentMethodId}")]
[Route("invoice")]
[HttpGet("i/{invoiceId}")]
[HttpGet("i/{invoiceId}/{paymentMethodId}")]
[HttpGet("invoice")]
[AcceptMediaTypeConstraint("application/bitcoin-paymentrequest", false)]
[XFrameOptionsAttribute(null)]
[ReferrerPolicyAttribute("origin")]
@@ -466,8 +461,7 @@ namespace BTCPayServer.Controllers
return View(nameof(Checkout), model);
}
[HttpGet]
[Route("invoice-noscript")]
[HttpGet("invoice-noscript")]
public async Task<IActionResult> CheckoutNoScript(string? invoiceId, string? id = null, string? paymentMethodId = null, [FromQuery] string? lang = null)
{
//Keep compatibility with Bitpay
@@ -491,7 +485,7 @@ namespace BTCPayServer.Controllers
bool isDefaultPaymentId = false;
if (paymentMethodId is null)
{
var enabledPaymentIds = store.GetEnabledPaymentIds(_NetworkProvider) ?? Array.Empty<PaymentMethodId>();
var enabledPaymentIds = store.GetEnabledPaymentIds(_NetworkProvider);
PaymentMethodId? invoicePaymentId = invoice.GetDefaultPaymentMethod();
PaymentMethodId? storePaymentId = store.GetDefaultPaymentId();
if (invoicePaymentId is PaymentMethodId)
@@ -570,11 +564,11 @@ namespace BTCPayServer.Controllers
}
lang ??= storeBlob.DefaultLang;
var model = new PaymentModel()
var model = new PaymentModel
{
Activated = paymentMethodDetails.Activated,
CryptoCode = network.CryptoCode,
RootPath = this.Request.PathBase.Value.WithTrailingSlash(),
RootPath = Request.PathBase.Value.WithTrailingSlash(),
OrderId = invoice.Metadata.OrderId,
InvoiceId = invoice.Id,
DefaultLang = lang ?? invoice.DefaultLanguage ?? storeBlob.DefaultLang ?? "en",
@@ -630,7 +624,7 @@ namespace BTCPayServer.Controllers
Link = Url.Action(nameof(Checkout),
new
{
invoiceId = invoiceId,
invoiceId,
paymentMethodId = kv.GetId().ToString()
})
};
@@ -660,12 +654,11 @@ namespace BTCPayServer.Controllers
return _CurrencyNameTable.DisplayFormatCurrency(paymentMethod.Rate, currency);
}
[HttpGet]
[Route("i/{invoiceId}/status")]
[Route("i/{invoiceId}/{implicitPaymentMethodId}/status")]
[Route("invoice/{invoiceId}/status")]
[Route("invoice/{invoiceId}/{implicitPaymentMethodId}/status")]
[Route("invoice/status")]
[HttpGet("i/{invoiceId}/status")]
[HttpGet("i/{invoiceId}/{implicitPaymentMethodId}/status")]
[HttpGet("invoice/{invoiceId}/status")]
[HttpGet("invoice/{invoiceId}/{implicitPaymentMethodId}/status")]
[HttpGet("invoice/status")]
public async Task<IActionResult> GetStatus(string invoiceId, string? paymentMethodId = null, string? implicitPaymentMethodId = null, [FromQuery] string? lang = null)
{
if (string.IsNullOrEmpty(paymentMethodId))
@@ -676,12 +669,11 @@ namespace BTCPayServer.Controllers
return Json(model);
}
[HttpGet]
[Route("i/{invoiceId}/status/ws")]
[Route("i/{invoiceId}/{paymentMethodId}/status/ws")]
[Route("invoice/{invoiceId}/status/ws")]
[Route("invoice/{invoiceId}/{paymentMethodId}/status")]
[Route("invoice/status/ws")]
[HttpGet("i/{invoiceId}/status/ws")]
[HttpGet("i/{invoiceId}/{paymentMethodId}/status/ws")]
[HttpGet("invoice/{invoiceId}/status/ws")]
[HttpGet("invoice/{invoiceId}/{paymentMethodId}/status")]
[HttpGet("invoice/status/ws")]
public async Task<IActionResult> GetStatusWebSocket(string invoiceId, CancellationToken cancellationToken)
{
if (!HttpContext.WebSockets.IsWebSocketRequest)
@@ -698,7 +690,7 @@ namespace BTCPayServer.Controllers
leases.Add(_EventAggregator.SubscribeAsync<Events.InvoiceEvent>(async o => await NotifySocket(webSocket, o.Invoice.Id, invoiceId)));
while (true)
{
var message = await webSocket.ReceiveAndPingAsync(DummyBuffer, default(CancellationToken));
var message = await webSocket.ReceiveAndPingAsync(DummyBuffer);
if (message.MessageType == WebSocketMessageType.Close)
break;
}
@@ -728,9 +720,8 @@ namespace BTCPayServer.Controllers
catch { try { webSocket.Dispose(); } catch { } }
}
[HttpPost]
[Route("i/{invoiceId}/UpdateCustomer")]
[Route("invoice/UpdateCustomer")]
[HttpPost("i/{invoiceId}/UpdateCustomer")]
[HttpPost("invoice/UpdateCustomer")]
public async Task<IActionResult> UpdateCustomer(string invoiceId, [FromBody] UpdateCustomerModel data)
{
if (!ModelState.IsValid)
@@ -741,8 +732,7 @@ namespace BTCPayServer.Controllers
return Ok("{}");
}
[HttpGet]
[Route("invoices")]
[HttpGet("invoices")]
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie)]
[BitpayAPIConstraint(false)]
public async Task<IActionResult> ListInvoices(InvoicesModel? model = null)
@@ -824,7 +814,6 @@ namespace BTCPayServer.Controllers
return Content(res, "application/" + format);
}
private SelectList GetPaymentMethodsSelectList()
{
return new SelectList(_paymentMethodHandlerDictionary.Distinct().SelectMany(handler =>
@@ -834,8 +823,7 @@ namespace BTCPayServer.Controllers
nameof(SelectListItem.Text));
}
[HttpGet]
[Route("invoices/create")]
[HttpGet("invoices/create")]
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie)]
[BitpayAPIConstraint(false)]
public async Task<IActionResult> CreateInvoice(InvoicesModel? model = null)
@@ -852,11 +840,16 @@ namespace BTCPayServer.Controllers
return RedirectToAction(nameof(UserStoresController.ListStores), "UserStores");
}
return View(new CreateInvoiceModel() { Stores = stores, AvailablePaymentMethods = GetPaymentMethodsSelectList() });
var vm = new CreateInvoiceModel
{
Stores = stores,
AvailablePaymentMethods = GetPaymentMethodsSelectList()
};
return View(vm);
}
[HttpPost]
[Route("invoices/create")]
[HttpPost("invoices/create")]
[Authorize(Policy = Policies.CanCreateInvoice, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
[BitpayAPIConstraint(false)]
public async Task<IActionResult> CreateInvoice(CreateInvoiceModel model, CancellationToken cancellationToken)
@@ -912,7 +905,7 @@ namespace BTCPayServer.Controllers
}
catch (BitpayHttpException ex)
{
this.TempData.SetStatusMessageModel(new StatusMessageModel()
TempData.SetStatusMessageModel(new StatusMessageModel()
{
Severity = StatusMessageModel.StatusSeverity.Error,
Message = ex.Message