From 2c94a87be434120c07949ec3f5587e6f78d19e7f Mon Sep 17 00:00:00 2001 From: Andrew Camilleri Date: Fri, 1 Dec 2023 09:10:58 +0100 Subject: [PATCH] Support adjusting form invoice amount by multiplier (#5463) Co-authored-by: d11n --- BTCPayServer.Tests/FormTests.cs | 59 ++++++++++++++++++++++++ BTCPayServer/Forms/FormDataService.cs | 34 ++++++++------ BTCPayServer/Views/UIForms/Modify.cshtml | 2 + 3 files changed, 81 insertions(+), 14 deletions(-) diff --git a/BTCPayServer.Tests/FormTests.cs b/BTCPayServer.Tests/FormTests.cs index 1d245f75d..0447dce48 100644 --- a/BTCPayServer.Tests/FormTests.cs +++ b/BTCPayServer.Tests/FormTests.cs @@ -198,6 +198,65 @@ public class FormTests : UnitTestBase service.SetValues(form, new JObject { ["test"] = "hello" }); obj = service.GetValues(form); Assert.Equal("hello", obj["test"].Value()); + + var req = service.GenerateInvoiceParametersFromForm(form); + Assert.Null(req.Amount); + Assert.Null(req.Currency); + + form.Fields.Add(new Field + { + Name = $"{FormDataService.InvoiceParameterPrefix}amount", + Type = "number", + Value = "1" + }); + req = service.GenerateInvoiceParametersFromForm(form); + Assert.Equal(1, req.Amount); + + form.Fields.Add(new Field + { + Name = $"{FormDataService.InvoiceParameterPrefix}amount_adjustment", + Type = "number", + Value = "1" + }); + req = service.GenerateInvoiceParametersFromForm(form); + Assert.Equal(2, req.Amount); + form.Fields.Add(new Field + { + Name = $"{FormDataService.InvoiceParameterPrefix}amount_adjustment2", + Type = "number", + Value = "2" + }); + form.Fields.Add(new Field + { + Name = $"{FormDataService.InvoiceParameterPrefix}currency", + Type = "text", + Value = "eur" + }); + req = service.GenerateInvoiceParametersFromForm(form); + Assert.Equal("eur", req.Currency); + Assert.Equal(4, req.Amount); + + + form.Fields.Add(new Field + { + Name = $"{FormDataService.InvoiceParameterPrefix}amount_multiply_adjustment", + Type = "number", + Value = "2" + }); + + req = service.GenerateInvoiceParametersFromForm(form); + Assert.Equal(8, req.Amount); + + + form.Fields.Add(new Field + { + Name = $"{FormDataService.InvoiceParameterPrefix}amount_multiply_adjustment1", + Type = "number", + Value = "2" + }); + + req = service.GenerateInvoiceParametersFromForm(form); + Assert.Equal(16, req.Amount); } private void Clear(Form form) diff --git a/BTCPayServer/Forms/FormDataService.cs b/BTCPayServer/Forms/FormDataService.cs index 08c561def..02d2f9a98 100644 --- a/BTCPayServer/Forms/FormDataService.cs +++ b/BTCPayServer/Forms/FormDataService.cs @@ -153,25 +153,31 @@ public class FormDataService { var amtRaw = GetValue(form, $"{InvoiceParameterPrefix}amount"); var amt = string.IsNullOrEmpty(amtRaw) ? (decimal?) null : decimal.Parse(amtRaw, CultureInfo.InvariantCulture); - var adjustmentAmount = 0m; - foreach (var adjustmentField in form.GetAllFields().Where(f => f.FullName.StartsWith($"{InvoiceParameterPrefix}amount_adjustment"))) + foreach (var f in form.GetAllFields()) { - if (!decimal.TryParse(GetValue(form, adjustmentField.Field), out var adjustment)) + if (f.FullName.StartsWith($"{InvoiceParameterPrefix}amount_adjustment") && decimal.TryParse(GetValue(form, f.Field), out var adjustment)) { - continue; + if (amt is null) + { + amt = adjustment; + } + else + { + amt += adjustment; + } + } + if (f.FullName.StartsWith($"{InvoiceParameterPrefix}amount_multiply_adjustment") && decimal.TryParse(GetValue(form, f.Field), out var adjustmentM)) + { + if (amt is not null) + { + amt *= adjustmentM; + } } - - adjustmentAmount += adjustment; } - - if (amt is null && adjustmentAmount > 0) + + if(amt is not null) { - amt = adjustmentAmount; - } - else if(amt is not null) - { - amt += adjustmentAmount; - amt = Math.Max(0, amt!.Value); + amt = Math.Max(0, amt.Value); } return new CreateInvoiceRequest { diff --git a/BTCPayServer/Views/UIForms/Modify.cshtml b/BTCPayServer/Views/UIForms/Modify.cshtml index 25be1d00a..df4494993 100644 --- a/BTCPayServer/Views/UIForms/Modify.cshtml +++ b/BTCPayServer/Views/UIForms/Modify.cshtml @@ -21,6 +21,7 @@ +