diff --git a/BTCPayServer.Tests/SeleniumTests.cs b/BTCPayServer.Tests/SeleniumTests.cs index 78aa8f569..6295133d2 100644 --- a/BTCPayServer.Tests/SeleniumTests.cs +++ b/BTCPayServer.Tests/SeleniumTests.cs @@ -2690,9 +2690,9 @@ namespace BTCPayServer.Tests var sums = cartData.FindElements(By.CssSelector("tfoot tr")); Assert.Equal(2, items.Count); Assert.Equal(4, sums.Count); - Assert.Contains("Manual entry 1", items[0].FindElement(By.CssSelector("th")).Text); + Assert.Contains("Custom Amount 1", items[0].FindElement(By.CssSelector("th")).Text); Assert.Contains("1 234,00 €", items[0].FindElement(By.CssSelector("td")).Text); - Assert.Contains("Manual entry 2", items[1].FindElement(By.CssSelector("th")).Text); + Assert.Contains("Custom Amount 2", items[1].FindElement(By.CssSelector("th")).Text); Assert.Contains("0,56 €", items[1].FindElement(By.CssSelector("td")).Text); Assert.Contains("Subtotal", sums[0].FindElement(By.CssSelector("th")).Text); Assert.Contains("1 234,56 €", sums[0].FindElement(By.CssSelector("td")).Text); @@ -2713,9 +2713,9 @@ namespace BTCPayServer.Tests sums = paymentDetails.FindElements(By.CssSelector("tr.sums-data")); Assert.Equal(2, items.Count); Assert.Equal(4, sums.Count); - Assert.Contains("Manual entry 1", items[0].FindElement(By.CssSelector(".key")).Text); + Assert.Contains("Custom Amount 1", items[0].FindElement(By.CssSelector(".key")).Text); Assert.Contains("1 234,00 €", items[0].FindElement(By.CssSelector(".val")).Text); - Assert.Contains("Manual entry 2", items[1].FindElement(By.CssSelector(".key")).Text); + Assert.Contains("Custom Amount 2", items[1].FindElement(By.CssSelector(".key")).Text); Assert.Contains("0,56 €", items[1].FindElement(By.CssSelector(".val")).Text); Assert.Contains("Subtotal", sums[0].FindElement(By.CssSelector(".key")).Text); Assert.Contains("1 234,56 €", sums[0].FindElement(By.CssSelector(".val")).Text); @@ -2776,7 +2776,7 @@ namespace BTCPayServer.Tests Assert.Contains("1 x 1,00 € = 1,00 €", items[0].FindElement(By.CssSelector("td")).Text); Assert.Contains("Green Tea", items[1].FindElement(By.CssSelector("th")).Text); Assert.Contains("2 x 1,00 € = 2,00 €", items[1].FindElement(By.CssSelector("td")).Text); - Assert.Contains("Manual entry 1", items[2].FindElement(By.CssSelector("th")).Text); + Assert.Contains("Custom Amount 1", items[2].FindElement(By.CssSelector("th")).Text); Assert.Contains("1,23 €", items[2].FindElement(By.CssSelector("td")).Text); Assert.Contains("Total", sums[0].FindElement(By.CssSelector("th")).Text); Assert.Contains("4,23 €", sums[0].FindElement(By.CssSelector("td")).Text); @@ -2795,7 +2795,7 @@ namespace BTCPayServer.Tests Assert.Contains("1 x 1,00 € = 1,00 €", items[0].FindElement(By.CssSelector(".val")).Text); Assert.Contains("Green Tea", items[1].FindElement(By.CssSelector(".key")).Text); Assert.Contains("2 x 1,00 € = 2,00 €", items[1].FindElement(By.CssSelector(".val")).Text); - Assert.Contains("Manual entry 1", items[2].FindElement(By.CssSelector(".key")).Text); + Assert.Contains("Custom Amount 1", items[2].FindElement(By.CssSelector(".key")).Text); Assert.Contains("1,23 €", items[2].FindElement(By.CssSelector(".val")).Text); Assert.Contains("Total", sums[0].FindElement(By.CssSelector(".key")).Text); Assert.Contains("4,23 €", sums[0].FindElement(By.CssSelector(".val")).Text); diff --git a/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs b/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs index 2904c6f41..27202be97 100644 --- a/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs +++ b/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs @@ -377,7 +377,7 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers { for (var i = 0; i < amountsArray.Count; i++) { - cartData.Add($"Manual entry {i+1}", _displayFormatter.Currency(amountsArray[i].ToObject(), settings.Currency, DisplayFormatter.CurrencyFormat.Symbol)); + cartData.Add($"Custom Amount {i+1}", _displayFormatter.Currency(amountsArray[i].ToObject(), settings.Currency, DisplayFormatter.CurrencyFormat.Symbol)); } } receiptData.Add("Cart", cartData); diff --git a/BTCPayServer/Services/Apps/AppService.cs b/BTCPayServer/Services/Apps/AppService.cs index 944f1cbf8..c4fd79f8f 100644 --- a/BTCPayServer/Services/Apps/AppService.cs +++ b/BTCPayServer/Services/Apps/AppService.cs @@ -151,9 +151,13 @@ namespace BTCPayServer.Services.Apps { // flatten single items from POS data var data = e.Metadata.PosData?.ToObject(); - if (data is { Cart.Length: > 0 }) + var hasCart = data is { Cart.Length: > 0 }; + var hasAmounts = data is { Amounts.Length: > 0 }; + var date = e.InvoiceTime.Date; + var itemCode = e.Metadata.ItemCode ?? typeof(Plugins.PointOfSale.PosViewType).DisplayName(Plugins.PointOfSale.PosViewType.Light.ToString()); + if (hasCart) { - foreach (var lineItem in data.Cart) + foreach (var lineItem in data!.Cart) { var item = items.FirstOrDefault(p => p.Id == lineItem.Id); if (item == null) @@ -165,18 +169,23 @@ namespace BTCPayServer.Services.Apps { ItemCode = item.Id, FiatPrice = lineItem.Price, - Date = e.InvoiceTime.Date + Date = date }); } } } - else + if (hasAmounts) + { + res.AddRange(data!.Amounts.Select(amount => new InvoiceStatsItem { ItemCode = itemCode, FiatPrice = amount, Date = date })); + } + // no further info, just add the total amount + if (!hasCart && !hasAmounts) { res.Add(new InvoiceStatsItem { - ItemCode = e.Metadata.ItemCode ?? typeof(Plugins.PointOfSale.PosViewType).DisplayName(Plugins.PointOfSale.PosViewType.Light.ToString()), + ItemCode = itemCode, FiatPrice = e.PaidAmount.Net, - Date = e.InvoiceTime.Date + Date = date }); } return res; diff --git a/BTCPayServer/Services/Invoices/PosAppData.cs b/BTCPayServer/Services/Invoices/PosAppData.cs index 2b3120b8f..685b20ce4 100644 --- a/BTCPayServer/Services/Invoices/PosAppData.cs +++ b/BTCPayServer/Services/Invoices/PosAppData.cs @@ -11,6 +11,9 @@ public class PosAppData [JsonProperty(PropertyName = "cart")] public PosAppCartItem[] Cart { get; set; } + [JsonProperty(PropertyName = "amounts")] + public decimal[] Amounts { get; set; } + [JsonProperty(PropertyName = "customAmount")] public decimal CustomAmount { get; set; } diff --git a/BTCPayServer/wwwroot/pos/keypad.js b/BTCPayServer/wwwroot/pos/keypad.js index bd0474022..8be748f4a 100644 --- a/BTCPayServer/wwwroot/pos/keypad.js +++ b/BTCPayServer/wwwroot/pos/keypad.js @@ -32,9 +32,10 @@ document.addEventListener("DOMContentLoaded",function () { calculation () { if (!this.tipNumeric && !(this.discountNumeric > 0 || this.discountPercentNumeric > 0) && this.amounts.length < 2 && this.cart.length === 0) return null let calc = '' + const hasAmounts = this.amounts.length && this.amounts.reduce((sum, amt) => sum + parseFloat(amt || 0), 0) > 0; if (this.cart.length) calc += this.cart.map(item => `${item.count} x ${item.title} (${this.formatCurrency(item.price, true)}) = ${this.formatCurrency((item.price||0) * item.count, true)}`).join(' + ') - if (this.cart.length && this.amounts.length) calc += ' + ' - if (this.amounts.length) calc += this.amounts.map(amt => this.formatCurrency(amt, true)).join(' + ') + if (this.cart.length && hasAmounts) calc += ' + ' + if (hasAmounts) calc += this.amounts.map(amt => this.formatCurrency(amt || 0, true)).join(' + ') if (this.discountNumeric > 0 || this.discountPercentNumeric > 0) calc += ` - ${this.formatCurrency(this.discountNumeric, true)} (${this.discountPercent}%)` if (this.tipNumeric > 0) calc += ` + ${this.formatCurrency(this.tipNumeric, true)}` if (this.tipPercent) calc += ` (${this.tipPercent}%)`