Skip to content

Commit

Permalink
Receipt fixes and improvements (#5505)
Browse files Browse the repository at this point in the history
* Fix additional div

* Don't show payment number if there is only one

* Bump max-width to prevent wrapping in top container

* Fix colspan

* Re-add POS data

Closes #5498.

* Right-align amounts

* Re-order

* Don't show redundant receive date if there is only one payment

* Table improvements

* Unify crypto amount display

* More formatting improvements

* Only show Subtotal if there are calculations applicable to it

* Making margin on the bottom smaller to reduce expansion on Bitcoinize machines

---------

Co-authored-by: rockstardev <5191402+rockstardev@users.noreply.github.com>
  • Loading branch information
dennisreimann and rockstardev committed Nov 23, 2023
1 parent 62865d7 commit c8b9a42
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 114 deletions.
2 changes: 1 addition & 1 deletion BTCPayServer/Controllers/UIInvoiceController.UI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ public async Task<IActionResult> InvoiceReceipt(string invoiceId, [FromQuery] bo
Amount = paymentEntity.PaidAmount.Gross,
Paid = paymentEntity.InvoicePaidAmount.Net,
ReceivedDate = paymentEntity.ReceivedTime.DateTime,
AmountFormatted = _displayFormatter.Currency(paymentEntity.PaidAmount.Gross, paymentEntity.PaidAmount.Currency, DisplayFormatter.CurrencyFormat.None),
AmountFormatted = _displayFormatter.Currency(paymentEntity.PaidAmount.Gross, paymentEntity.PaidAmount.Currency),
PaidFormatted = _displayFormatter.Currency(paymentEntity.InvoicePaidAmount.Net, i.Currency, DisplayFormatter.CurrencyFormat.Symbol),
RateFormatted = _displayFormatter.Currency(paymentEntity.Rate, i.Currency, DisplayFormatter.CurrencyFormat.Symbol),
PaymentMethod = paymentMethodId.ToPrettyString(),
Expand Down
2 changes: 1 addition & 1 deletion BTCPayServer/PaymentRequest/PaymentRequestService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ public async Task<ViewPaymentRequestViewModel> GetPaymentRequest(string id, stri
Amount = paymentEntity.PaidAmount.Gross,
Paid = paymentEntity.InvoicePaidAmount.Net,
ReceivedDate = paymentEntity.ReceivedTime.DateTime,
AmountFormatted = _displayFormatter.Currency(paymentEntity.PaidAmount.Gross, paymentEntity.PaidAmount.Currency, DisplayFormatter.CurrencyFormat.None),
AmountFormatted = _displayFormatter.Currency(paymentEntity.PaidAmount.Gross, paymentEntity.PaidAmount.Currency),
PaidFormatted = _displayFormatter.Currency(paymentEntity.InvoicePaidAmount.Net, blob.Currency, DisplayFormatter.CurrencyFormat.Symbol),
RateFormatted = _displayFormatter.Currency(paymentEntity.Rate, blob.Currency, DisplayFormatter.CurrencyFormat.Symbol),
PaymentMethod = paymentMethodId.ToPrettyString(),
Expand Down
5 changes: 2 additions & 3 deletions BTCPayServer/Views/UIInvoice/InvoiceReceipt.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
</script>
}
<style>
#InvoiceReceipt { --wrap-max-width: 720px; }
#InvoiceReceipt { --wrap-max-width: 768px; }
#InvoiceSummary { gap: var(--btcpay-space-l); }
#PaymentDetails table tbody tr:first-child td { padding-top: 1rem; }
#PaymentDetails table tbody:not(:last-child) tr:last-child > th,td { padding-bottom: 1rem; }
Expand Down Expand Up @@ -86,7 +86,6 @@
</div>
}
</div>
</div>

@if (isProcessing)
{
Expand Down Expand Up @@ -122,7 +121,7 @@
<tr>
<td class="date-col">@payment.ReceivedDate.ToBrowserDate()</td>
<td class="amount-col">@payment.PaidFormatted</td>
<td class="amount-col">@payment.AmountFormatted @payment.PaymentMethod</td>
<td class="amount-col">@payment.AmountFormatted</td>
</tr>
@if (!string.IsNullOrEmpty(payment.Destination))
{
Expand Down
232 changes: 124 additions & 108 deletions BTCPayServer/Views/UIInvoice/InvoiceReceiptPrint.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
var isFreeInvoice = (Model.Status == InvoiceStatus.New && Model.Amount == 0);
var isSettled = Model.Status == InvoiceStatus.Settled;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
Expand Down Expand Up @@ -70,124 +72,138 @@
</style>
</head>

<body style="margin:0; padding:0; background-color:#fff">
<center>
<div>
<partial name="_StatusMessage" model="@(new ViewDataDictionary(ViewData) { { "Margin", "mb-4" } })" />

<div class="justify-content-center">
<partial name="_StoreHeader" model="(Model.StoreName, Model.LogoFileId)" />
<div id="InvoiceSummary" class="bg-tile">
@if (isProcessing)
<body class="m-0 p-0 bg-white">
<center>
<partial name="_StoreHeader" model="(Model.StoreName, Model.LogoFileId)" />
<div id="InvoiceSummary" style="max-width:600px">
@if (isProcessing)
{
<div class="lead text-center fw-semibold" id="invoice-processing">
The invoice has detected a payment but is still waiting to be settled.
</div>
}
else if (!isSettled)
{
<div class="lead text-center fw-semibold" id="invoice-unsettled">
The invoice is not settled.
</div>
}
else
{
<div id="PaymentDetails">
<div class="my-2 text-center small">
@if (!string.IsNullOrEmpty(Model.OrderId))
{
<div class="lead text-center fw-semibold" id="invoice-processing">
The invoice has detected a payment but is still waiting to be settled.
</div>
<div>Order ID: @Model.OrderId</div>
}
else if (!isSettled)
@Model.Timestamp.ToBrowserDate()
</div>
<table class="table table-borderless table-sm small my-0">
<tr>
<td class="text-nowrap text-secondary">Total</td>
<td class="text-end fw-semibold">@DisplayFormatter.Currency(Model.Amount, Model.Currency, DisplayFormatter.CurrencyFormat.Symbol)</td>
</tr>
<tr>
<td colspan="2"><hr class="w-100 my-0"/></td>
</tr>
@if (Model.AdditionalData?.Any() is true &&
(Model.AdditionalData.ContainsKey("Cart") || Model.AdditionalData.ContainsKey("Discount") || Model.AdditionalData.ContainsKey("Tip")))
{
<div class="lead text-center fw-semibold" id="invoice-unsettled">
The invoice is not settled.
</div>
@if (Model.AdditionalData.ContainsKey("Cart"))
{
@foreach (var (key, value) in (Dictionary<string, object>)Model.AdditionalData["Cart"])
{
<tr>
<td class="text-secondary">@key</td>
<td class="text-end">@value</td>
</tr>
}
}
@if (Model.AdditionalData.ContainsKey("Subtotal"))
{
<tr>
<td class="text-secondary">Subtotal</td>
<td class="text-end">@Model.AdditionalData["Subtotal"]</td>
</tr>
}
@if (Model.AdditionalData.ContainsKey("Discount"))
{
<tr>
<td class="text-secondary">Discount</td>
<td class="text-end">@Model.AdditionalData["Discount"]</td>
</tr>
}
@if (Model.AdditionalData.ContainsKey("Tip"))
{
<tr>
<td class="text-secondary">Tip</td>
<td class="text-end">@Model.AdditionalData["Tip"]</td>
</tr>
}
<tr>
<td colspan="2"><hr class="w-100 my-0"/></td>
</tr>
}
else
@if (Model.Payments?.Any() is true)
{
<div id="PaymentDetails" class="bg-tile">
<div class="table-responsive my-0">
<table class="table table-borderless table-sm small my-0" style="max-width: 500px">
<thead>
<tr>
<th class="fw-normal text-secondary"></th>
<th class="fw-normal text-secondary"></th>
</tr>
</thead>
<tbody>
<tr>
<td class="fw-normal text-nowrap text-secondary">Paid</td>
<td>@DisplayFormatter.Currency(Model.Amount, Model.Currency, DisplayFormatter.CurrencyFormat.Symbol)</td>
</tr>
<tr>
<td class="fw-normal text-nowrap text-secondary">Date/Time</td>
<td>@Model.Timestamp.ToBrowserDate()</td>
</tr>
@if (!string.IsNullOrEmpty(Model.OrderId))
{
<tr>
<td class="fw-normal text-nowrap text-secondary">Order ID</td>
<td>@Model.OrderId</td>
</tr>
}

@if (Model.Payments?.Any() is true)
{
@for (int i = 0; i < Model.Payments.Count; i++)
{
var payment = Model.Payments[i];
<tr>
<td colspan="2" class="fw-normal text-nowrap text-secondary">Payment @(i + 1)</td>

</tr>
<tr>
<td class="fw-normal text-nowrap text-secondary">Received</td>
<td>@payment.ReceivedDate.ToBrowserDate()</td>
</tr>
<tr>
<td class="fw-normal text-nowrap text-secondary"></td>
<td colspan="2">@payment.AmountFormatted @payment.PaymentMethod</td>
</tr>
<tr>
<td class="fw-normal text-nowrap text-secondary"></td>
<td colspan="2">@payment.PaidFormatted</td>
</tr>
<tr>
<td class="fw-normal text-nowrap text-secondary">Rate</td>
<td colspan="2">@payment.RateFormatted</td>
</tr>

@if (!string.IsNullOrEmpty(payment.Destination))
{
<tr>
<td class="fw-normal text-nowrap text-secondary">Destination</td>
<td style="word-break:break-all">@payment.Destination</td>
</tr>
}
@if (!string.IsNullOrEmpty(payment.PaymentProof))
{
<tr>
<td class="fw-normal text-nowrap text-secondary">Pay Proof</td>
<td style="word-break:break-all">@payment.PaymentProof</td>
</tr>
}
}
}
</tbody>
<tfoot>
<tr>
<th class="fw-normal text-secondary"></th>
<th class="fw-normal text-secondary"></th>
</tr>
</tfoot>
</table>
</div>
</div>

if (Model.ReceiptOptions.ShowQR is true)
@for (var i = 0; i < Model.Payments.Count; i++)
{
<vc:qr-code style="width:" data="@Context.Request.GetCurrentUrl()" size="128"></vc:qr-code>
var payment = Model.Payments[i];
@if (Model.Payments.Count > 1)
{
<tr>
<td colspan="2" class="text-nowrap text-secondary">Payment @(i + 1)</td>
</tr>
<tr>
<td class="text-nowrap">Received</td>
<td>@payment.ReceivedDate.ToBrowserDate()</td>
</tr>
}
<tr>
<td class="text-nowrap text-secondary">@(Model.Payments.Count == 1 ? "Paid" : "")</td>
<td class="text-end">@payment.AmountFormatted</td>
</tr>
<tr>
<td colspan="2" class="text-end">@payment.PaidFormatted</td>
</tr>
<tr>
<td class="text-nowrap text-secondary">Rate</td>
<td class="text-end">@payment.RateFormatted</td>
</tr>
@if (!string.IsNullOrEmpty(payment.Destination))
{
<tr>
<td class="text-nowrap text-secondary">Destination</td>
<td class="text-break">@payment.Destination</td>
</tr>
}
@if (!string.IsNullOrEmpty(payment.PaymentProof))
{
<tr>
<td class="text-nowrap text-secondary">Pay Proof</td>
<td class="text-break">@payment.PaymentProof</td>
</tr>
}
}
<tr>
<td colspan="2"><hr class="w-100 my-0"/></td>
</tr>
}
</div>
</table>
</div>
</div>

<footer class="store-footer" style="padding: 0.5rem;">
<a class="store-powered-by" style="color: #000;" href="https://btcpayserver.org" target="_blank" rel="noreferrer noopener">
Powered by <partial name="_StoreFooterLogo" />
</a>
</footer>
</center>
if (Model.ReceiptOptions.ShowQR is true)
{
<vc:qr-code data="@Context.Request.GetCurrentUrl()" size="128" />
}
}
</div>
<div class="store-footer p-3">
<a class="store-powered-by" style="color:#000;">Powered by <partial name="_StoreFooterLogo" /></a>
</div>
<hr class="w-100 my-0 bg-none"/>
</center>
</body>

<script>
window.print();
</script>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@
<tr>
<td class="text-break"><vc:truncate-center text="@payment.Id" link="@payment.Link" padding="7" classes="truncate-center-id" /></td>
<td class="amount-col">@payment.PaidFormatted</td>
<td class="text-end text-nowrap">@payment.AmountFormatted @payment.PaymentMethod</td>
<td class="text-end text-nowrap">@payment.AmountFormatted</td>
</tr>
}
}
Expand Down

0 comments on commit c8b9a42

Please sign in to comment.