Parse POS string data for invoice details display (#5275)

* Parse POS string data for invoice details display

Fixes #5240.

* Improve POS data display
This commit is contained in:
d11n
2023-08-26 13:48:48 +02:00
committed by GitHub
parent 97acec340c
commit 58a1c6d2c8
3 changed files with 56 additions and 35 deletions

View File

@@ -172,6 +172,20 @@ namespace BTCPayServer.Controllers
model.ReceiptData = (Dictionary<string, object>)additionalData["receiptData"]; model.ReceiptData = (Dictionary<string, object>)additionalData["receiptData"];
additionalData.Remove("receiptData"); additionalData.Remove("receiptData");
} }
if (additionalData.ContainsKey("posData") && additionalData["posData"] is string posData)
{
// overwrite with parsed JSON if possible
try
{
additionalData["posData"] = PosDataParser.ParsePosData(JObject.Parse(posData));
}
catch (Exception)
{
additionalData["posData"] = posData;
}
}
model.AdditionalData = additionalData; model.AdditionalData = additionalData;
return View(model); return View(model);

View File

@@ -17,7 +17,7 @@
@foreach (var (key, value) in (Dictionary <string, object>)Model.Items["Cart"]) @foreach (var (key, value) in (Dictionary <string, object>)Model.Items["Cart"])
{ {
<tr> <tr>
<td>@key</td> <th>@key</th>
<td class="text-end">@value</td> <td class="text-end">@value</td>
</tr> </tr>
} }
@@ -26,28 +26,28 @@
@if (Model.Items.ContainsKey("Subtotal")) @if (Model.Items.ContainsKey("Subtotal"))
{ {
<tr> <tr>
<td>Subtotal</td> <th>Subtotal</th>
<td class="text-end">@Model.Items["Subtotal"]</td> <td class="text-end">@Model.Items["Subtotal"]</td>
</tr> </tr>
} }
@if (Model.Items.ContainsKey("Discount")) @if (Model.Items.ContainsKey("Discount"))
{ {
<tr> <tr>
<td>Discount</td> <th>Discount</th>
<td class="text-end">@Model.Items["Discount"]</td> <td class="text-end">@Model.Items["Discount"]</td>
</tr> </tr>
} }
@if (Model.Items.ContainsKey("Tip")) @if (Model.Items.ContainsKey("Tip"))
{ {
<tr> <tr>
<td>Tip</td> <th>Tip</th>
<td class="text-end">@Model.Items["Tip"]</td> <td class="text-end">@Model.Items["Tip"]</td>
</tr> </tr>
} }
@if (Model.Items.ContainsKey("Total")) @if (Model.Items.ContainsKey("Total"))
{ {
<tr style="border-top-width:3px"> <tr style="border-top-width:3px">
<td>Total</td> <th>Total</th>
<td class="text-end">@Model.Items["Total"]</td> <td class="text-end">@Model.Items["Total"]</td>
</tr> </tr>
} }
@@ -62,7 +62,7 @@
{ {
if (!string.IsNullOrEmpty(key)) if (!string.IsNullOrEmpty(key))
{ {
<th class="w-225px">@key</th> <th>@key</th>
} }
<td style="white-space:pre-wrap">@* Explicitely remove whitespace at front here *@@if (IsValidURL(str)){<a href="@str" target="_blank" rel="noreferrer noopener">@str</a>}else {@str.Trim()}</td> <td style="white-space:pre-wrap">@* Explicitely remove whitespace at front here *@@if (IsValidURL(str)){<a href="@str" target="_blank" rel="noreferrer noopener">@str</a>}else {@str.Trim()}</td>
} }
@@ -72,7 +72,7 @@
@{ @{
@if (!string.IsNullOrEmpty(key)) @if (!string.IsNullOrEmpty(key))
{ {
Write(Html.Raw($"<h{Model.Level + 3} class=\"mt-4 mb-3\">")); Write(Html.Raw($"<h{Model.Level + 3} class=\"mb-3 fw-semibold\">"));
Write(key); Write(key);
Write(Html.Raw($"</h{Model.Level + 3}>")); Write(Html.Raw($"</h{Model.Level + 3}>"));
} }
@@ -86,7 +86,7 @@
@{ @{
@if (!string.IsNullOrEmpty(key)) @if (!string.IsNullOrEmpty(key))
{ {
Write(Html.Raw($"<h{Model.Level + 3} class=\"mt-4 mb-3\">")); Write(Html.Raw($"<h{Model.Level + 3} class=\"mb-3 fw-semibold\">"));
Write(key); Write(key);
Write(Html.Raw($"</h{Model.Level + 3}>")); Write(Html.Raw($"</h{Model.Level + 3}>"));
} }

View File

@@ -1,6 +1,4 @@
@using Microsoft.AspNetCore.Mvc.TagHelpers
@using BTCPayServer.Client @using BTCPayServer.Client
@using BTCPayServer.Abstractions.TagHelpers
@model InvoiceDetailsModel @model InvoiceDetailsModel
@{ @{
ViewData["Title"] = $"Invoice {Model.Id}"; ViewData["Title"] = $"Invoice {Model.Id}";
@@ -22,6 +20,15 @@
flex-wrap: wrap; flex-wrap: wrap;
gap: var(--btcpay-space-xl) var(--btcpay-space-xxl); gap: var(--btcpay-space-xl) var(--btcpay-space-xxl);
} }
.invoice-information > div {
max-width: 540px;
}
.invoice-information > div table th {
width: 200px;
font-weight: var(--btcpay-font-weight-semibold);
}
</style> </style>
} }
@@ -229,19 +236,19 @@
<h3 class="mb-3">General Information</h3> <h3 class="mb-3">General Information</h3>
<table class="table mb-0"> <table class="table mb-0">
<tr> <tr>
<th class="fw-semibold">Store</th> <th>Store</th>
<td> <td>
<a href="@Model.StoreLink" rel="noreferrer noopener">@Model.StoreName</a> <a href="@Model.StoreLink" rel="noreferrer noopener">@Model.StoreName</a>
</td> </td>
</tr> </tr>
<tr> <tr>
<th class="fw-semibold">Invoice Id</th> <th>Invoice Id</th>
<td>@Model.Id</td> <td>@Model.Id</td>
</tr> </tr>
@if (!string.IsNullOrEmpty(Model.TypedMetadata.OrderId)) @if (!string.IsNullOrEmpty(Model.TypedMetadata.OrderId))
{ {
<tr> <tr>
<th class="fw-semibold">Order Id</th> <th>Order Id</th>
<td> <td>
@if (!string.IsNullOrEmpty(Model.TypedMetadata.OrderUrl)) @if (!string.IsNullOrEmpty(Model.TypedMetadata.OrderUrl))
{ {
@@ -266,14 +273,14 @@
@if (Model.TypedMetadata.PaymentRequestId is not null) @if (Model.TypedMetadata.PaymentRequestId is not null)
{ {
<tr> <tr>
<th class="fw-semibold">Payment Request Id</th> <th>Payment Request Id</th>
<td> <td>
<a href="@Model.PaymentRequestLink" rel="noreferrer noopener">@Model.TypedMetadata.PaymentRequestId</a> <a href="@Model.PaymentRequestLink" rel="noreferrer noopener">@Model.TypedMetadata.PaymentRequestId</a>
</td> </td>
</tr> </tr>
} }
<tr> <tr>
<th class="fw-semibold">State</th> <th>State</th>
<td> <td>
@if (Model.CanMarkStatus) @if (Model.CanMarkStatus)
{ {
@@ -304,29 +311,29 @@
</td> </td>
</tr> </tr>
<tr> <tr>
<th class="fw-semibold">Created Date</th> <th>Created Date</th>
<td>@Model.CreatedDate.ToBrowserDate()</td> <td>@Model.CreatedDate.ToBrowserDate()</td>
</tr> </tr>
<tr> <tr>
<th class="fw-semibold">Expiration Date</th> <th>Expiration Date</th>
<td>@Model.ExpirationDate.ToBrowserDate()</td> <td>@Model.ExpirationDate.ToBrowserDate()</td>
</tr> </tr>
<tr> <tr>
<th class="fw-semibold">Monitoring Date</th> <th>Monitoring Date</th>
<td>@Model.MonitoringDate.ToBrowserDate()</td> <td>@Model.MonitoringDate.ToBrowserDate()</td>
</tr> </tr>
<tr> <tr>
<th class="fw-semibold">Transaction Speed</th> <th>Transaction Speed</th>
<td>@Model.TransactionSpeed</td> <td>@Model.TransactionSpeed</td>
</tr> </tr>
<tr> <tr>
<th class="fw-semibold">Total Fiat Due</th> <th>Total Fiat Due</th>
<td><span data-sensitive>@Model.Fiat</span></td> <td><span data-sensitive>@Model.Fiat</span></td>
</tr> </tr>
@if (!string.IsNullOrEmpty(Model.RefundEmail)) @if (!string.IsNullOrEmpty(Model.RefundEmail))
{ {
<tr> <tr>
<th class="fw-semibold">Refund Email</th> <th>Refund Email</th>
<td> <td>
<a href="mailto:@Model.RefundEmail">@Model.RefundEmail</a> <a href="mailto:@Model.RefundEmail">@Model.RefundEmail</a>
</td> </td>
@@ -335,14 +342,14 @@
@if (!string.IsNullOrEmpty(Model.NotificationUrl)) @if (!string.IsNullOrEmpty(Model.NotificationUrl))
{ {
<tr> <tr>
<th class="fw-semibold">Notification Url</th> <th>Notification Url</th>
<td>@Model.NotificationUrl</td> <td>@Model.NotificationUrl</td>
</tr> </tr>
} }
@if (!string.IsNullOrEmpty(Model.RedirectUrl)) @if (!string.IsNullOrEmpty(Model.RedirectUrl))
{ {
<tr> <tr>
<th class="fw-semibold">Redirect Url</th> <th>Redirect Url</th>
<td> <td>
<a href="@Model.RedirectUrl" rel="noreferrer noopener">@Model.RedirectUrl</a> <a href="@Model.RedirectUrl" rel="noreferrer noopener">@Model.RedirectUrl</a>
</td> </td>
@@ -366,21 +373,21 @@
@if (!string.IsNullOrEmpty(Model.TypedMetadata.ItemCode)) @if (!string.IsNullOrEmpty(Model.TypedMetadata.ItemCode))
{ {
<tr> <tr>
<th class="fw-semibold">Item code</th> <th>Item code</th>
<td>@Model.TypedMetadata.ItemCode</td> <td>@Model.TypedMetadata.ItemCode</td>
</tr> </tr>
} }
@if (!string.IsNullOrEmpty(Model.TypedMetadata.ItemDesc)) @if (!string.IsNullOrEmpty(Model.TypedMetadata.ItemDesc))
{ {
<tr> <tr>
<th class="fw-semibold">Item Description</th> <th>Item Description</th>
<td>@Model.TypedMetadata.ItemDesc</td> <td>@Model.TypedMetadata.ItemDesc</td>
</tr> </tr>
} }
@if (Model.TaxIncluded is not null) @if (Model.TaxIncluded is not null)
{ {
<tr> <tr>
<th class="fw-semibold">Tax Included</th> <th>Tax Included</th>
<td>@Model.TaxIncluded</td> <td>@Model.TaxIncluded</td>
</tr> </tr>
} }
@@ -408,14 +415,14 @@
@if (Model.TypedMetadata.BuyerName is not null) @if (Model.TypedMetadata.BuyerName is not null)
{ {
<tr> <tr>
<th class="fw-semibold">Name</th> <th>Name</th>
<td>@Model.TypedMetadata.BuyerName</td> <td>@Model.TypedMetadata.BuyerName</td>
</tr> </tr>
} }
@if (Model.TypedMetadata.BuyerEmail is not null) @if (Model.TypedMetadata.BuyerEmail is not null)
{ {
<tr> <tr>
<th class="fw-semibold">Email</th> <th>Email</th>
<td> <td>
<a href="mailto:@Model.TypedMetadata.BuyerEmail">@Model.TypedMetadata.BuyerEmail</a> <a href="mailto:@Model.TypedMetadata.BuyerEmail">@Model.TypedMetadata.BuyerEmail</a>
</td> </td>
@@ -424,49 +431,49 @@
@if (Model.TypedMetadata.BuyerPhone is not null) @if (Model.TypedMetadata.BuyerPhone is not null)
{ {
<tr> <tr>
<th class="fw-semibold">Phone</th> <th>Phone</th>
<td>@Model.TypedMetadata.BuyerPhone</td> <td>@Model.TypedMetadata.BuyerPhone</td>
</tr> </tr>
} }
@if (Model.TypedMetadata.BuyerAddress1 is not null) @if (Model.TypedMetadata.BuyerAddress1 is not null)
{ {
<tr> <tr>
<th class="fw-semibold">Address 1</th> <th>Address 1</th>
<td>@Model.TypedMetadata.BuyerAddress1</td> <td>@Model.TypedMetadata.BuyerAddress1</td>
</tr> </tr>
} }
@if (Model.TypedMetadata.BuyerAddress2 is not null) @if (Model.TypedMetadata.BuyerAddress2 is not null)
{ {
<tr> <tr>
<th class="fw-semibold">Address 2</th> <th>Address 2</th>
<td>@Model.TypedMetadata.BuyerAddress2</td> <td>@Model.TypedMetadata.BuyerAddress2</td>
</tr> </tr>
} }
@if (Model.TypedMetadata.BuyerCity is not null) @if (Model.TypedMetadata.BuyerCity is not null)
{ {
<tr> <tr>
<th class="fw-semibold">City</th> <th>City</th>
<td>@Model.TypedMetadata.BuyerCity</td> <td>@Model.TypedMetadata.BuyerCity</td>
</tr> </tr>
} }
@if (Model.TypedMetadata.BuyerState is not null) @if (Model.TypedMetadata.BuyerState is not null)
{ {
<tr> <tr>
<th class="fw-semibold">State</th> <th>State</th>
<td>@Model.TypedMetadata.BuyerState</td> <td>@Model.TypedMetadata.BuyerState</td>
</tr> </tr>
} }
@if (Model.TypedMetadata.BuyerCountry is not null) @if (Model.TypedMetadata.BuyerCountry is not null)
{ {
<tr> <tr>
<th class="fw-semibold">Country</th> <th>Country</th>
<td>@Model.TypedMetadata.BuyerCountry</td> <td>@Model.TypedMetadata.BuyerCountry</td>
</tr> </tr>
} }
@if (Model.TypedMetadata.BuyerZip is not null) @if (Model.TypedMetadata.BuyerZip is not null)
{ {
<tr> <tr>
<th class="fw-semibold">Zip</th> <th>Zip</th>
<td>@Model.TypedMetadata.BuyerZip</td> <td>@Model.TypedMetadata.BuyerZip</td>
</tr> </tr>
} }