Point of Sale support free entry

This commit is contained in:
nicolas.dorier
2018-04-26 22:09:18 +09:00
parent 82d8fda05f
commit 4f9e4116a2
7 changed files with 54 additions and 16 deletions

View File

@@ -997,7 +997,7 @@ namespace BTCPayServer.Tests
Assert.Equal("orange", vmview.Items[1].Title); Assert.Equal("orange", vmview.Items[1].Title);
Assert.Equal(10.0m, vmview.Items[1].Price.Value); Assert.Equal(10.0m, vmview.Items[1].Price.Value);
Assert.Equal("$5.00", vmview.Items[0].Price.Formatted); Assert.Equal("$5.00", vmview.Items[0].Price.Formatted);
Assert.IsType<RedirectResult>(apps.ViewPointOfSale(appId, "orange").Result); Assert.IsType<RedirectResult>(apps.ViewPointOfSale(appId, 0, "orange").Result);
var invoice = user.BitPay.GetInvoices().First(); var invoice = user.BitPay.GetInvoices().First();
Assert.Equal(10.00, invoice.Price); Assert.Equal(10.00, invoice.Price);
Assert.Equal("CAD", invoice.Currency); Assert.Equal("CAD", invoice.Currency);

View File

@@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework> <TargetFramework>netcoreapp2.0</TargetFramework>
<Version>1.0.1.92</Version> <Version>1.0.1.93</Version>
<NoWarn>NU1701,CA1816,CA1308,CA1810,CA2208</NoWarn> <NoWarn>NU1701,CA1816,CA1308,CA1810,CA2208</NoWarn>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@@ -42,10 +42,12 @@ namespace BTCPayServer.Controllers
" price: 15\n\n" + " price: 15\n\n" +
"tshirt:\n" + "tshirt:\n" +
" price: 25"; " price: 25";
ShowCustomAmount = true;
} }
public string Title { get; set; } public string Title { get; set; }
public string Currency { get; set; } public string Currency { get; set; }
public string Template { get; set; } public string Template { get; set; }
public bool ShowCustomAmount { get; set; }
} }
[HttpGet] [HttpGet]
@@ -57,7 +59,7 @@ namespace BTCPayServer.Controllers
return NotFound(); return NotFound();
var settings = app.GetSettings<PointOfSaleSettings>(); var settings = app.GetSettings<PointOfSaleSettings>();
return View(new UpdatePointOfSaleViewModel() { Title = settings.Title, Currency = settings.Currency, Template = settings.Template }); return View(new UpdatePointOfSaleViewModel() { Title = settings.Title, ShowCustomAmount = settings.ShowCustomAmount, Currency = settings.Currency, Template = settings.Template });
} }
[HttpPost] [HttpPost]
[Route("{appId}/settings/pos")] [Route("{appId}/settings/pos")]
@@ -83,6 +85,7 @@ namespace BTCPayServer.Controllers
app.SetSettings(new PointOfSaleSettings() app.SetSettings(new PointOfSaleSettings()
{ {
Title = vm.Title, Title = vm.Title,
ShowCustomAmount = vm.ShowCustomAmount,
Currency = vm.Currency.ToUpperInvariant(), Currency = vm.Currency.ToUpperInvariant(),
Template = vm.Template Template = vm.Template
}); });
@@ -99,9 +102,13 @@ namespace BTCPayServer.Controllers
if (app == null) if (app == null)
return NotFound(); return NotFound();
var settings = app.GetSettings<PointOfSaleSettings>(); var settings = app.GetSettings<PointOfSaleSettings>();
var currency = _Currencies.GetCurrencyData(settings.Currency);
double step = currency == null ? 1 : Math.Pow(10, -(currency.Divisibility));
return View(new ViewPointOfSaleViewModel() return View(new ViewPointOfSaleViewModel()
{ {
Title = settings.Title, Title = settings.Title,
Step = step.ToString(CultureInfo.InvariantCulture),
ShowCustomAmount = settings.ShowCustomAmount,
Items = Parse(settings.Template, settings.Currency) Items = Parse(settings.Template, settings.Currency)
}); });
} }
@@ -155,23 +162,43 @@ namespace BTCPayServer.Controllers
[HttpPost] [HttpPost]
[Route("{appId}/pos")] [Route("{appId}/pos")]
public async Task<IActionResult> ViewPointOfSale(string appId, string choiceKey) public async Task<IActionResult> ViewPointOfSale(string appId, double amount, string choiceKey)
{ {
var app = await GetApp(appId, AppType.PointOfSale); var app = await GetApp(appId, AppType.PointOfSale);
if (string.IsNullOrEmpty(choiceKey) && amount <= 0)
{
return RedirectToAction(nameof(ViewPointOfSale), new { appId = appId });
}
if (app == null) if (app == null)
return NotFound(); return NotFound();
var settings = app.GetSettings<PointOfSaleSettings>(); var settings = app.GetSettings<PointOfSaleSettings>();
if(string.IsNullOrEmpty(choiceKey) && !settings.ShowCustomAmount)
{
return RedirectToAction(nameof(ViewPointOfSale), new { appId = appId });
}
string title = null;
double price = 0.0;
if (!string.IsNullOrEmpty(choiceKey))
{
var choices = Parse(settings.Template, settings.Currency); var choices = Parse(settings.Template, settings.Currency);
var choice = choices.FirstOrDefault(c => c.Id == choiceKey); var choice = choices.FirstOrDefault(c => c.Id == choiceKey);
if (choice == null) if (choice == null)
return NotFound(); return NotFound();
title = choice.Title;
price = (double)choice.Price.Value;
}
else
{
price = amount;
title = settings.Title;
}
var store = await GetStore(app); var store = await GetStore(app);
var invoice = await _InvoiceController.CreateInvoiceCore(new NBitpayClient.Invoice() var invoice = await _InvoiceController.CreateInvoiceCore(new NBitpayClient.Invoice()
{ {
ItemDesc = choice.Title, ItemDesc = title,
Currency = settings.Currency, Currency = settings.Currency,
Price = (double)choice.Price.Value, Price = price,
}, store, HttpContext.Request.GetAbsoluteRoot()); }, store, HttpContext.Request.GetAbsoluteRoot());
return Redirect(invoice.Data.Url); return Redirect(invoice.Data.Url);
} }

View File

@@ -17,5 +17,8 @@ namespace BTCPayServer.Models.AppViewModels
[Required] [Required]
[MaxLength(5000)] [MaxLength(5000)]
public string Template { get; set; } public string Template { get; set; }
[Display(Name = "User can input custom amount")]
public bool ShowCustomAmount { get; set; }
} }
} }

View File

@@ -18,6 +18,8 @@ namespace BTCPayServer.Models.AppViewModels
public ItemPrice Price { get; set; } public ItemPrice Price { get; set; }
public string Title { get; set; } public string Title { get; set; }
} }
public bool ShowCustomAmount { get; set; }
public string Step { get; set; }
public string Title { get; set; } public string Title { get; set; }
public Item[] Items { get; set; } public Item[] Items { get; set; }
} }

View File

@@ -29,6 +29,10 @@
<input asp-for="Currency" class="form-control" /> <input asp-for="Currency" class="form-control" />
<span asp-validation-for="Currency" class="text-danger"></span> <span asp-validation-for="Currency" class="text-danger"></span>
</div> </div>
<div class="form-group">
<label asp-for="ShowCustomAmount"></label>
<input asp-for="ShowCustomAmount" type="checkbox" class="form-check" />
</div>
<div class="form-group"> <div class="form-group">
<label asp-for="Template" class="control-label"></label>* <label asp-for="Template" class="control-label"></label>*
<textarea asp-for="Template" rows="20" cols="40" class="form-control"></textarea> <textarea asp-for="Template" rows="20" cols="40" class="form-control"></textarea>

View File

@@ -19,7 +19,7 @@
<h1 class="mb-4">@Model.Title</h1> <h1 class="mb-4">@Model.Title</h1>
<form method="post"> <form method="post">
<div class="row"> <div class="row">
@foreach (var item in Model.Items) @foreach(var item in Model.Items)
{ {
<div class="col-sm-4 mb-3"> <div class="col-sm-4 mb-3">
<h3>@item.Title</h3> <h3>@item.Title</h3>
@@ -28,18 +28,20 @@
} }
</div> </div>
</form> </form>
@*<div class="row mt-4"> @if(Model.ShowCustomAmount)
{
<div class="row mt-4">
<div class="col-md-4 offset-md-4 col-sm-6 offset-sm-3"> <div class="col-md-4 offset-md-4 col-sm-6 offset-sm-3">
<h3>Something else</h3> <form method="post" data-buy>
<form data-buy>
<div class="input-group"> <div class="input-group">
<input class="form-control" type="number" step="0.00001" name="amount" placeholder="undefined (optional)"><div class="input-group-append"> <input class="form-control" type="number" min="0" step="@Model.Step" name="amount" placeholder="amount"><div class="input-group-append">
<button class="btn btn-primary" type="submit">Pay</button> <button class="btn btn-primary" type="submit">Pay</button>
</div> </div>
</div> </div>
</form> </form>
</div> </div>
</div>*@ </div>
}
</div> </div>
</div> </div>
<script src="~/vendor/jquery/jquery.js"></script> <script src="~/vendor/jquery/jquery.js"></script>