mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-01-18 13:26:47 +01:00
Generate unique order IDs for PoS and Crowdfund sales (#5127)
* Generate unique order IDs for PoS and Crowdfund sales Part of #5054. * Refactorings * Updates * Updates * Refactoring * Remove search by AdditionalSearchTerm * Implement appid --------- Co-authored-by: nicolas.dorier <nicolas.dorier@gmail.com>
This commit is contained in:
parent
0017f236a7
commit
b1c81b696f
@ -24,7 +24,7 @@ public class AppTopItems : ViewComponent
|
||||
public async Task<IViewComponentResult> InvokeAsync(string appId, string appType)
|
||||
{
|
||||
var type = _appService.GetAppType(appType);
|
||||
if (type is not IHasItemStatsAppType salesAppType || type is not AppBaseType appBaseType)
|
||||
if (type is not (IHasItemStatsAppType and AppBaseType appBaseType))
|
||||
return new HtmlContentViewComponentResult(new StringHtmlContent(string.Empty));
|
||||
|
||||
var vm = new AppTopItemsViewModel
|
||||
|
@ -1,6 +1,7 @@
|
||||
@model BTCPayServer.Components.TruncateCenter.TruncateCenterViewModel
|
||||
@{
|
||||
var classes = string.IsNullOrEmpty(Model.Classes) ? string.Empty : Model.Classes.Trim();
|
||||
var isTruncated = !string.IsNullOrEmpty(Model.Start) && !string.IsNullOrEmpty(Model.End);
|
||||
@if (Model.Copy) classes += " truncate-center--copy";
|
||||
@if (Model.Elastic) classes += " truncate-center--elastic";
|
||||
}
|
||||
@ -15,9 +16,12 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="truncate-center-truncated" @(!string.IsNullOrEmpty(Model.Start) ? $"data-bs-toggle=tooltip title={Model.Text}" : "")>
|
||||
<span class="truncate-center-start">@(Model.Elastic ? Model.Text : $"{Model.Start}…")</span>
|
||||
<span class="truncate-center-end">@Model.End</span>
|
||||
<span class="truncate-center-truncated" @(isTruncated ? $"data-bs-toggle=tooltip title={Model.Text}" : "")>
|
||||
<span class="truncate-center-start">@(Model.Elastic || !isTruncated ? Model.Text : $"{Model.Start}…")</span>
|
||||
@if (isTruncated)
|
||||
{
|
||||
<span class="truncate-center-end">@Model.End</span>
|
||||
}
|
||||
</span>
|
||||
<span class="truncate-center-text">@Model.Text</span>
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ using BTCPayServer.Data;
|
||||
using BTCPayServer.Filters;
|
||||
using BTCPayServer.HostedServices;
|
||||
using BTCPayServer.Models;
|
||||
using BTCPayServer.Models.AppViewModels;
|
||||
using BTCPayServer.Models.InvoicingModels;
|
||||
using BTCPayServer.Models.PaymentRequestViewModels;
|
||||
using BTCPayServer.Payments;
|
||||
@ -1084,22 +1085,22 @@ namespace BTCPayServer.Controllers
|
||||
}
|
||||
model.Search = fs;
|
||||
model.SearchText = fs.TextSearch;
|
||||
|
||||
InvoiceQuery invoiceQuery = GetInvoiceQuery(fs, timezoneOffset);
|
||||
|
||||
var apps = await _appService.GetAllApps(GetUserId(), false, storeId);
|
||||
InvoiceQuery invoiceQuery = GetInvoiceQuery(fs, apps, timezoneOffset);
|
||||
invoiceQuery.StoreId = storeIds.ToArray();
|
||||
invoiceQuery.Take = model.Count;
|
||||
invoiceQuery.Skip = model.Skip;
|
||||
invoiceQuery.IncludeRefunds = true;
|
||||
|
||||
var list = await _InvoiceRepository.GetInvoices(invoiceQuery);
|
||||
|
||||
// Apps
|
||||
var apps = await _appService.GetAllApps(GetUserId(), false, storeId);
|
||||
model.Apps = apps.Select(a => new InvoiceAppModel
|
||||
{
|
||||
Id = a.Id,
|
||||
AppName = a.AppName,
|
||||
AppType = a.AppType,
|
||||
AppOrderId = AppService.GetAppOrderId(a.AppType, a.Id)
|
||||
AppType = a.AppType
|
||||
}).ToList();
|
||||
|
||||
foreach (var invoice in list)
|
||||
@ -1124,11 +1125,21 @@ namespace BTCPayServer.Controllers
|
||||
return View(model);
|
||||
}
|
||||
|
||||
private InvoiceQuery GetInvoiceQuery(SearchString fs, int timezoneOffset = 0)
|
||||
private InvoiceQuery GetInvoiceQuery(SearchString fs, ListAppsViewModel.ListAppViewModel[] apps, int timezoneOffset = 0)
|
||||
{
|
||||
var textSearch = fs.TextSearch;
|
||||
if (fs.GetFilterArray("appid") is { } appIds)
|
||||
{
|
||||
var appsById = apps.ToDictionary(a => a.Id);
|
||||
var searchTexts = appIds.Select(a => appsById.TryGet(a)).Where(a => a != null)
|
||||
.Select(a => AppService.GetAppSearchTerm(a.AppType, a.Id))
|
||||
.ToList();
|
||||
searchTexts.Add(fs.TextSearch);
|
||||
textSearch = string.Join(' ', searchTexts.Where(t => !string.IsNullOrEmpty(t)).ToList());
|
||||
}
|
||||
return new InvoiceQuery
|
||||
{
|
||||
TextSearch = fs.TextSearch,
|
||||
TextSearch = textSearch,
|
||||
UserId = GetUserId(),
|
||||
Unusual = fs.GetFilterBool("unusual"),
|
||||
IncludeArchived = fs.GetFilterBool("includearchived") ?? false,
|
||||
@ -1160,7 +1171,8 @@ namespace BTCPayServer.Controllers
|
||||
storeIds.Add(i);
|
||||
}
|
||||
|
||||
InvoiceQuery invoiceQuery = GetInvoiceQuery(fs, timezoneOffset);
|
||||
var apps = await _appService.GetAllApps(GetUserId(), false, storeId);
|
||||
InvoiceQuery invoiceQuery = GetInvoiceQuery(fs, apps, timezoneOffset);
|
||||
invoiceQuery.StoreId = storeIds.ToArray();
|
||||
invoiceQuery.Skip = 0;
|
||||
invoiceQuery.Take = int.MaxValue;
|
||||
|
@ -297,7 +297,6 @@ namespace BTCPayServer
|
||||
var createInvoice = new CreateInvoiceRequest()
|
||||
{
|
||||
Amount = item?.PriceType == ViewPointOfSaleViewModel.ItemPriceType.Topup? null: item?.Price,
|
||||
|
||||
Currency = currencyCode,
|
||||
Checkout = new InvoiceDataBase.CheckoutOptions()
|
||||
{
|
||||
@ -307,11 +306,11 @@ namespace BTCPayServer
|
||||
HttpContext.Request.GetAbsoluteUri($"/apps/{app.Id}/pos"),
|
||||
_ => null
|
||||
}
|
||||
}
|
||||
},
|
||||
AdditionalSearchTerms = new[] { AppService.GetAppSearchTerm(app) }
|
||||
};
|
||||
|
||||
var invoiceMetadata = new InvoiceMetadata();
|
||||
invoiceMetadata.OrderId = AppService.GetAppOrderId(app);
|
||||
var invoiceMetadata = new InvoiceMetadata { OrderId = AppService.GetRandomOrderId() };
|
||||
if (item != null)
|
||||
{
|
||||
invoiceMetadata.ItemCode = item.Id;
|
||||
@ -319,7 +318,6 @@ namespace BTCPayServer
|
||||
}
|
||||
createInvoice.Metadata = invoiceMetadata.ToJObject();
|
||||
|
||||
|
||||
return await GetLNURLRequest(
|
||||
cryptoCode,
|
||||
store,
|
||||
|
@ -41,6 +41,5 @@ namespace BTCPayServer.Models.InvoicingModels
|
||||
public string Id { get; set; }
|
||||
public string AppName { get; set; }
|
||||
public string AppType { get; set; }
|
||||
public string AppOrderId { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
||||
using BTCPayServer.Abstractions.Constants;
|
||||
using BTCPayServer.Abstractions.Extensions;
|
||||
using BTCPayServer.Client;
|
||||
using BTCPayServer.Client.Models;
|
||||
using BTCPayServer.Controllers;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Filters;
|
||||
@ -13,6 +14,7 @@ using BTCPayServer.Models;
|
||||
using BTCPayServer.Plugins.Crowdfund.Models;
|
||||
using BTCPayServer.Plugins.PointOfSale.Models;
|
||||
using BTCPayServer.Services.Apps;
|
||||
using BTCPayServer.Services.Invoices;
|
||||
using BTCPayServer.Services.Rates;
|
||||
using BTCPayServer.Services.Stores;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
@ -21,6 +23,7 @@ using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NBitpayClient;
|
||||
using NicolasDorier.RateLimits;
|
||||
using CrowdfundResetEvery = BTCPayServer.Services.Apps.CrowdfundResetEvery;
|
||||
|
||||
namespace BTCPayServer.Plugins.Crowdfund.Controllers
|
||||
{
|
||||
@ -175,33 +178,41 @@ namespace BTCPayServer.Plugins.Crowdfund.Controllers
|
||||
{
|
||||
var appPath = await _appService.ViewLink(app);
|
||||
var appUrl = HttpContext.Request.GetAbsoluteUri(appPath);
|
||||
var invoice = await _invoiceController.CreateInvoiceCore(new BitpayCreateInvoiceRequest()
|
||||
var invoice = await _invoiceController.CreateInvoiceCoreRaw(new CreateInvoiceRequest()
|
||||
{
|
||||
OrderId = AppService.GetAppOrderId(app),
|
||||
Amount = price,
|
||||
Currency = settings.TargetCurrency,
|
||||
ItemCode = request.ChoiceKey ?? string.Empty,
|
||||
ItemDesc = title,
|
||||
BuyerEmail = request.Email,
|
||||
Price = price,
|
||||
NotificationURL = settings.NotificationUrl,
|
||||
FullNotifications = true,
|
||||
ExtendedNotifications = true,
|
||||
SupportedTransactionCurrencies = paymentMethods,
|
||||
RedirectURL = request.RedirectUrl ?? appUrl,
|
||||
Metadata = new InvoiceMetadata()
|
||||
{
|
||||
OrderId = AppService.GetRandomOrderId(),
|
||||
ItemCode = request.ChoiceKey ?? string.Empty,
|
||||
ItemDesc = title,
|
||||
BuyerEmail = request.Email
|
||||
}.ToJObject(),
|
||||
Checkout = new InvoiceDataBase.CheckoutOptions()
|
||||
{
|
||||
RedirectURL = request.RedirectUrl ?? appUrl,
|
||||
PaymentMethods = paymentMethods?.Where(p => p.Value.Enabled)
|
||||
.Select(p => p.Key).ToArray()
|
||||
},
|
||||
AdditionalSearchTerms = new[] { AppService.GetAppSearchTerm(app) }
|
||||
}, store, HttpContext.Request.GetAbsoluteRoot(),
|
||||
new List<string> { AppService.GetAppInternalTag(appId) },
|
||||
cancellationToken, entity =>
|
||||
{
|
||||
entity.NotificationURLTemplate = settings.NotificationUrl;
|
||||
entity.FullNotifications = true;
|
||||
entity.ExtendedNotifications = true;
|
||||
entity.Metadata.OrderUrl = appUrl;
|
||||
});
|
||||
|
||||
if (request.RedirectToCheckout)
|
||||
{
|
||||
return RedirectToAction(nameof(UIInvoiceController.Checkout), "UIInvoice",
|
||||
new { invoiceId = invoice.Data.Id });
|
||||
new { invoiceId = invoice.Id });
|
||||
}
|
||||
|
||||
return Ok(invoice.Data.Id);
|
||||
return Ok(invoice.Id);
|
||||
}
|
||||
catch (BitpayHttpException e)
|
||||
{
|
||||
@ -248,7 +259,7 @@ namespace BTCPayServer.Plugins.Crowdfund.Controllers
|
||||
IsRecurring = resetEvery != nameof(CrowdfundResetEvery.Never),
|
||||
UseAllStoreInvoices = app.TagAllInvoices,
|
||||
AppId = appId,
|
||||
SearchTerm = app.TagAllInvoices ? $"storeid:{app.StoreDataId}" : $"orderid:{AppService.GetAppOrderId(app)}",
|
||||
SearchTerm = app.TagAllInvoices ? $"storeid:{app.StoreDataId}" : $"appid:{app.Id}",
|
||||
DisplayPerksRanking = settings.DisplayPerksRanking,
|
||||
DisplayPerksValue = settings.DisplayPerksValue,
|
||||
SortPerksByPopularity = settings.SortPerksByPopularity,
|
||||
|
@ -12,6 +12,7 @@ using BTCPayServer.Abstractions.Extensions;
|
||||
using BTCPayServer.Abstractions.Form;
|
||||
using BTCPayServer.Abstractions.Models;
|
||||
using BTCPayServer.Client;
|
||||
using BTCPayServer.Client.Models;
|
||||
using BTCPayServer.Controllers;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Filters;
|
||||
@ -35,6 +36,7 @@ using NBitcoin.DataEncoders;
|
||||
using NBitpayClient;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NicolasDorier.RateLimits;
|
||||
using StoreData = BTCPayServer.Data.StoreData;
|
||||
|
||||
namespace BTCPayServer.Plugins.PointOfSale.Controllers
|
||||
{
|
||||
@ -304,30 +306,37 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers
|
||||
}
|
||||
try
|
||||
{
|
||||
var invoice = await _invoiceController.CreateInvoiceCore(new BitpayCreateInvoiceRequest
|
||||
var invoice = await _invoiceController.CreateInvoiceCoreRaw(new CreateInvoiceRequest
|
||||
{
|
||||
ItemCode = choice?.Id,
|
||||
ItemDesc = title,
|
||||
Amount = price,
|
||||
Currency = settings.Currency,
|
||||
Price = price,
|
||||
BuyerEmail = email,
|
||||
OrderId = orderId ?? AppService.GetAppOrderId(app),
|
||||
NotificationURL =
|
||||
string.IsNullOrEmpty(notificationUrl) ? settings.NotificationUrl : notificationUrl,
|
||||
RedirectURL = !string.IsNullOrEmpty(redirectUrl) ? redirectUrl
|
||||
: !string.IsNullOrEmpty(settings.RedirectUrl) ? settings.RedirectUrl
|
||||
: Request.GetAbsoluteUri(Url.Action(nameof(ViewPointOfSale), "UIPointOfSale", new { appId, viewType })),
|
||||
FullNotifications = true,
|
||||
ExtendedNotifications = true,
|
||||
RedirectAutomatically = settings.RedirectAutomatically,
|
||||
SupportedTransactionCurrencies = paymentMethods,
|
||||
RequiresRefundEmail = requiresRefundEmail == RequiresRefundEmail.InheritFromStore
|
||||
? storeBlob.RequiresRefundEmail
|
||||
: requiresRefundEmail == RequiresRefundEmail.On,
|
||||
Metadata = new InvoiceMetadata()
|
||||
{
|
||||
ItemCode = choice?.Id,
|
||||
ItemDesc = title,
|
||||
BuyerEmail = email,
|
||||
OrderId = orderId ?? AppService.GetRandomOrderId()
|
||||
}.ToJObject(),
|
||||
Checkout = new InvoiceDataBase.CheckoutOptions()
|
||||
{
|
||||
RedirectAutomatically = settings.RedirectAutomatically,
|
||||
RedirectURL = !string.IsNullOrEmpty(redirectUrl) ? redirectUrl
|
||||
: !string.IsNullOrEmpty(settings.RedirectUrl) ? settings.RedirectUrl
|
||||
: Request.GetAbsoluteUri(Url.Action(nameof(ViewPointOfSale), "UIPointOfSale", new { appId, viewType })),
|
||||
RequiresRefundEmail = requiresRefundEmail == RequiresRefundEmail.InheritFromStore
|
||||
? storeBlob.RequiresRefundEmail
|
||||
: requiresRefundEmail == RequiresRefundEmail.On,
|
||||
PaymentMethods = paymentMethods?.Where(p => p.Value.Enabled).Select(p => p.Key).ToArray()
|
||||
},
|
||||
AdditionalSearchTerms = new [] { AppService.GetAppSearchTerm(app) }
|
||||
}, store, HttpContext.Request.GetAbsoluteRoot(),
|
||||
new List<string> { AppService.GetAppInternalTag(appId) },
|
||||
cancellationToken, entity =>
|
||||
{
|
||||
entity.NotificationURLTemplate =
|
||||
string.IsNullOrEmpty(notificationUrl) ? settings.NotificationUrl : notificationUrl;
|
||||
entity.FullNotifications = true;
|
||||
entity.ExtendedNotifications = true;
|
||||
entity.Metadata.OrderUrl = Request.GetDisplayUrl();
|
||||
entity.Metadata.PosData = jposData;
|
||||
var receiptData = new JObject();
|
||||
@ -380,9 +389,9 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers
|
||||
});
|
||||
if (price is 0 && storeBlob.ReceiptOptions?.Enabled is true)
|
||||
{
|
||||
return RedirectToAction(nameof(UIInvoiceController.InvoiceReceipt), "UIInvoice", new { invoiceId = invoice.Data.Id });
|
||||
return RedirectToAction(nameof(UIInvoiceController.InvoiceReceipt), "UIInvoice", new { invoiceId = invoice.Id });
|
||||
}
|
||||
return RedirectToAction(nameof(UIInvoiceController.Checkout), "UIInvoice", new { invoiceId = invoice.Data.Id });
|
||||
return RedirectToAction(nameof(UIInvoiceController.Checkout), "UIInvoice", new { invoiceId = invoice.Id });
|
||||
}
|
||||
catch (BitpayHttpException e)
|
||||
{
|
||||
@ -537,7 +546,7 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers
|
||||
Description = settings.Description,
|
||||
NotificationUrl = settings.NotificationUrl,
|
||||
RedirectUrl = settings.RedirectUrl,
|
||||
SearchTerm = app.TagAllInvoices ? $"storeid:{app.StoreDataId}" : $"orderid:{AppService.GetAppOrderId(app)}",
|
||||
SearchTerm = app.TagAllInvoices ? $"storeid:{app.StoreDataId}" : $"appid:{app.Id}",
|
||||
RedirectAutomatically = settings.RedirectAutomatically.HasValue ? settings.RedirectAutomatically.Value ? "true" : "false" : "",
|
||||
FormId = settings.FormId
|
||||
};
|
||||
|
@ -2,8 +2,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using ExchangeSharp;
|
||||
|
||||
namespace BTCPayServer
|
||||
{
|
||||
|
@ -195,8 +195,8 @@ namespace BTCPayServer.Services.Apps
|
||||
};
|
||||
}
|
||||
|
||||
public static string GetAppOrderId(AppData app) => GetAppOrderId(app.AppType, app.Id);
|
||||
public static string GetAppOrderId(string appType, string appId) =>
|
||||
public static string GetAppSearchTerm(AppData app) => GetAppSearchTerm(app.AppType, app.Id);
|
||||
public static string GetAppSearchTerm(string appType, string appId) =>
|
||||
appType switch
|
||||
{
|
||||
CrowdfundAppType.AppType => $"crowdfund-app_{appId}",
|
||||
@ -209,13 +209,18 @@ namespace BTCPayServer.Services.Apps
|
||||
{
|
||||
return invoice.GetInternalTags("APP#");
|
||||
}
|
||||
|
||||
public static string GetRandomOrderId(int length = 16)
|
||||
{
|
||||
return Encoders.Base58.EncodeData(RandomUtils.GetBytes(length));
|
||||
}
|
||||
|
||||
public static async Task<InvoiceEntity[]> GetInvoicesForApp(InvoiceRepository invoiceRepository, AppData appData, DateTimeOffset? startDate = null, string[]? status = null)
|
||||
{
|
||||
var invoices = await invoiceRepository.GetInvoices(new InvoiceQuery
|
||||
{
|
||||
StoreId = new[] { appData.StoreDataId },
|
||||
OrderId = appData.TagAllInvoices ? null : new[] { GetAppOrderId(appData) },
|
||||
TextSearch = appData.TagAllInvoices ? null : GetAppSearchTerm(appData),
|
||||
Status = status ?? new[]{
|
||||
InvoiceState.ToString(InvoiceStatusLegacy.New),
|
||||
InvoiceState.ToString(InvoiceStatusLegacy.Paid),
|
||||
|
@ -180,7 +180,7 @@ namespace BTCPayServer.Services.Invoices
|
||||
var textSearch = new HashSet<string>();
|
||||
using (var context = _applicationDbContextFactory.CreateContext())
|
||||
{
|
||||
var invoiceData = new Data.InvoiceData()
|
||||
var invoiceData = new InvoiceData
|
||||
{
|
||||
StoreDataId = invoice.StoreId,
|
||||
Id = invoice.Id,
|
||||
@ -529,7 +529,7 @@ namespace BTCPayServer.Services.Invoices
|
||||
{
|
||||
var invoiceIdSet = invoiceIds.ToHashSet();
|
||||
using var context = _applicationDbContextFactory.CreateContext();
|
||||
IQueryable<Data.InvoiceData> query =
|
||||
IQueryable<InvoiceData> query =
|
||||
context
|
||||
.Invoices
|
||||
.Include(o => o.Payments)
|
||||
@ -540,7 +540,7 @@ namespace BTCPayServer.Services.Invoices
|
||||
|
||||
private async Task<InvoiceData> GetInvoiceRaw(string id, ApplicationDbContext dbContext, bool includeAddressData = false)
|
||||
{
|
||||
IQueryable<Data.InvoiceData> query =
|
||||
IQueryable<InvoiceData> query =
|
||||
dbContext
|
||||
.Invoices
|
||||
.Include(o => o.Payments);
|
||||
@ -549,13 +549,10 @@ namespace BTCPayServer.Services.Invoices
|
||||
query = query.Where(i => i.Id == id);
|
||||
|
||||
var invoice = (await query.ToListAsync()).FirstOrDefault();
|
||||
if (invoice == null)
|
||||
return null;
|
||||
|
||||
return invoice;
|
||||
}
|
||||
|
||||
public InvoiceEntity ToEntity(Data.InvoiceData invoice)
|
||||
public InvoiceEntity ToEntity(InvoiceData invoice)
|
||||
{
|
||||
var entity = invoice.GetBlob(_btcPayNetworkProvider);
|
||||
PaymentMethodDictionary paymentMethods = null;
|
||||
@ -606,9 +603,9 @@ namespace BTCPayServer.Services.Invoices
|
||||
return entity;
|
||||
}
|
||||
|
||||
private IQueryable<Data.InvoiceData> GetInvoiceQuery(ApplicationDbContext context, InvoiceQuery queryObject)
|
||||
private IQueryable<InvoiceData> GetInvoiceQuery(ApplicationDbContext context, InvoiceQuery queryObject)
|
||||
{
|
||||
IQueryable<Data.InvoiceData> query = queryObject.UserId is null
|
||||
IQueryable<InvoiceData> query = queryObject.UserId is null
|
||||
? context.Invoices
|
||||
: context.UserStore
|
||||
.Where(u => u.ApplicationUserId == queryObject.UserId)
|
||||
@ -619,7 +616,7 @@ namespace BTCPayServer.Services.Invoices
|
||||
query = query.Where(i => !i.Archived);
|
||||
}
|
||||
|
||||
if (queryObject.InvoiceId != null && queryObject.InvoiceId.Length > 0)
|
||||
if (queryObject.InvoiceId is { Length: > 0 })
|
||||
{
|
||||
if (queryObject.InvoiceId.Length > 1)
|
||||
{
|
||||
@ -633,7 +630,7 @@ namespace BTCPayServer.Services.Invoices
|
||||
}
|
||||
}
|
||||
|
||||
if (queryObject.StoreId != null && queryObject.StoreId.Length > 0)
|
||||
if (queryObject.StoreId is { Length: > 0 })
|
||||
{
|
||||
if (queryObject.StoreId.Length > 1)
|
||||
{
|
||||
@ -663,18 +660,18 @@ namespace BTCPayServer.Services.Invoices
|
||||
if (queryObject.EndDate != null)
|
||||
query = query.Where(i => i.Created <= queryObject.EndDate.Value);
|
||||
|
||||
if (queryObject.OrderId != null && queryObject.OrderId.Length > 0)
|
||||
if (queryObject.OrderId is { Length: > 0 })
|
||||
{
|
||||
var statusSet = queryObject.OrderId.ToHashSet().ToArray();
|
||||
query = query.Where(i => statusSet.Contains(i.OrderId));
|
||||
}
|
||||
if (queryObject.ItemCode != null && queryObject.ItemCode.Length > 0)
|
||||
if (queryObject.ItemCode is { Length: > 0 })
|
||||
{
|
||||
var statusSet = queryObject.ItemCode.ToHashSet().ToArray();
|
||||
query = query.Where(i => statusSet.Contains(i.ItemCode));
|
||||
}
|
||||
|
||||
if (queryObject.Status != null && queryObject.Status.Length > 0)
|
||||
if (queryObject.Status is { Length: > 0 })
|
||||
{
|
||||
var statusSet = queryObject.Status.ToHashSet();
|
||||
// We make sure here that the old filters still work
|
||||
@ -709,7 +706,7 @@ namespace BTCPayServer.Services.Invoices
|
||||
query = query.Where(i => unused == (i.Status == "invalid" || !string.IsNullOrEmpty(i.ExceptionStatus)));
|
||||
}
|
||||
|
||||
if (queryObject.ExceptionStatus != null && queryObject.ExceptionStatus.Length > 0)
|
||||
if (queryObject.ExceptionStatus is { Length: > 0 })
|
||||
{
|
||||
var exceptionStatusSet = queryObject.ExceptionStatus.Select(s => NormalizeExceptionStatus(s)).ToHashSet().ToArray();
|
||||
query = query.Where(i => exceptionStatusSet.Contains(i.ExceptionStatus));
|
||||
@ -727,7 +724,7 @@ namespace BTCPayServer.Services.Invoices
|
||||
|
||||
public async Task<InvoiceEntity[]> GetInvoices(InvoiceQuery queryObject)
|
||||
{
|
||||
using var context = _applicationDbContextFactory.CreateContext();
|
||||
await using var context = _applicationDbContextFactory.CreateContext();
|
||||
var query = GetInvoiceQuery(context, queryObject);
|
||||
query = query.Include(o => o.Payments);
|
||||
if (queryObject.IncludeAddresses)
|
||||
@ -775,7 +772,6 @@ namespace BTCPayServer.Services.Invoices
|
||||
return network == null ? JsonConvert.SerializeObject(data, DefaultSerializerSettings) : network.ToString(data);
|
||||
}
|
||||
|
||||
|
||||
public InvoiceStatistics GetContributionsByPaymentMethodId(string currency, InvoiceEntity[] invoices, bool softcap)
|
||||
{
|
||||
var contributions = invoices
|
||||
@ -807,7 +803,6 @@ namespace BTCPayServer.Services.Invoices
|
||||
p.Status == InvoiceStatusLegacy.Invalid)
|
||||
return new[] { contribution };
|
||||
|
||||
|
||||
// Else, we just sum the payments
|
||||
return payments
|
||||
.Select(pay =>
|
||||
|
@ -8,7 +8,7 @@
|
||||
ViewData.SetActivePage(InvoiceNavPages.Index, "Invoices");
|
||||
var statusFilterCount = CountArrayFilter("status") + CountArrayFilter("exceptionstatus") + (HasBooleanFilter("includearchived") ? 1 : 0) + (HasBooleanFilter("unusual") ? 1 : 0);
|
||||
var hasDateFilter = HasArrayFilter("startdate") || HasArrayFilter("enddate");
|
||||
var appFilterCount = Model.Apps.Count(app => HasArrayFilter("orderid", app.AppOrderId));
|
||||
var appFilterCount = Model.Apps.Count(app => HasArrayFilter("appid", app.Id));
|
||||
}
|
||||
|
||||
@functions
|
||||
@ -140,7 +140,7 @@
|
||||
})
|
||||
.on("click", ".invoice-row", function (e) {
|
||||
const $invoiceRow = $(e.currentTarget);
|
||||
if (!$(e.target).is("a,.badge,.selector")) {
|
||||
if ($(e.target).is("td")) {
|
||||
$invoiceRow.find(".selector").trigger("click");
|
||||
}
|
||||
});
|
||||
@ -279,7 +279,7 @@
|
||||
<div class="dropdown-menu" aria-labelledby="AppOptionsToggle">
|
||||
@foreach (var app in Model.Apps)
|
||||
{
|
||||
<a asp-action="ListInvoices" asp-route-storeId="@Model.StoreId" asp-route-count="@Model.Count" asp-route-searchTerm="@Model.Search.Toggle("orderid", app.AppOrderId)" class="dropdown-item @(HasArrayFilter("orderid", app.AppOrderId) ? "custom-active" : "")">@app.AppName</a>
|
||||
<a asp-action="ListInvoices" asp-route-storeId="@Model.StoreId" asp-route-count="@Model.Count" asp-route-searchTerm="@Model.Search.Toggle("appid", app.Id)" class="dropdown-item @(HasArrayFilter("appid", app.Id) ? "custom-active" : "")">@app.AppName</a>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@ -379,16 +379,7 @@
|
||||
</td>
|
||||
<td>@invoice.Date.ToBrowserDate()</td>
|
||||
<td>
|
||||
<div class="text-truncate" style="max-width:120px;" data-bs-toggle="tooltip" title="@invoice.OrderId">
|
||||
@if (invoice.RedirectUrl != string.Empty)
|
||||
{
|
||||
<a href="@invoice.RedirectUrl" rel="noreferrer noopener">@invoice.OrderId</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
@invoice.OrderId
|
||||
}
|
||||
</div>
|
||||
<vc:truncate-center text="@invoice.OrderId" link="@invoice.RedirectUrl" classes="truncate-center-id" />
|
||||
</td>
|
||||
<td class="text-break">@invoice.InvoiceId</td>
|
||||
<td>
|
||||
|
Loading…
Reference in New Issue
Block a user