Partially paid invoices should be reused in payment requests. Cleanup the code. (#2008)

This commit is contained in:
Nicolas Dorier
2020-10-23 21:00:23 +09:00
committed by GitHub
parent 20322c6ab8
commit 758f627e12
5 changed files with 51 additions and 14 deletions

View File

@@ -233,17 +233,22 @@ namespace BTCPayServer.Controllers
return BadRequest("Payment Request has expired"); return BadRequest("Payment Request has expired");
} }
var statusesAllowedToDisplay = new List<InvoiceStatus>() { InvoiceStatus.New }; var stateAllowedToDisplay = new HashSet<InvoiceState>()
var validInvoice = result.Invoices.FirstOrDefault(invoice => statusesAllowedToDisplay.Contains(invoice.Status)); {
new InvoiceState(InvoiceStatus.New, InvoiceExceptionStatus.None),
if (validInvoice != null) new InvoiceState(InvoiceStatus.New, InvoiceExceptionStatus.PaidPartial),
};
var currentInvoice = result
.Invoices
.FirstOrDefault(invoice => stateAllowedToDisplay.Contains(invoice.State));
if (currentInvoice != null)
{ {
if (redirectToInvoice) if (redirectToInvoice)
{ {
return RedirectToAction("Checkout", "Invoice", new { Id = validInvoice.Id }); return RedirectToAction("Checkout", "Invoice", new { Id = currentInvoice.Id });
} }
return Ok(validInvoice.Id); return Ok(currentInvoice.Id);
} }
if (result.AllowCustomPaymentAmounts && amount != null) if (result.AllowCustomPaymentAmounts && amount != null)
@@ -295,8 +300,7 @@ namespace BTCPayServer.Controllers
} }
var invoices = result.Invoices.Where(requestInvoice => var invoices = result.Invoices.Where(requestInvoice =>
requestInvoice.StatusFormatted.Equals(InvoiceState.ToString(InvoiceStatus.New), requestInvoice.State.Status == InvoiceStatus.New && !requestInvoice.Payments.Any());
StringComparison.InvariantCulture) && !requestInvoice.Payments.Any());
if (!invoices.Any()) if (!invoices.Any())
{ {

View File

@@ -143,7 +143,7 @@ namespace BTCPayServer.Models.PaymentRequestViewModels
public string AmountFormatted { get; set; } public string AmountFormatted { get; set; }
public InvoiceState State { get; set; } public InvoiceState State { get; set; }
public InvoiceStatus Status { get; set; } public InvoiceStatus Status { get; set; }
public string StatusFormatted { get; set; } public string StateFormatted { get; set; }
public List<PaymentRequestInvoicePayment> Payments { get; set; } public List<PaymentRequestInvoicePayment> Payments { get; set; }
public string Currency { get; set; } public string Currency { get; set; }

View File

@@ -109,8 +109,7 @@ namespace BTCPayServer.PaymentRequest
Currency = entity.Currency, Currency = entity.Currency,
ExpiryDate = entity.ExpirationTime.DateTime, ExpiryDate = entity.ExpirationTime.DateTime,
State = state, State = state,
Status = state.Status, StateFormatted = state.ToString(),
StatusFormatted = state.ToString(),
Payments = entity Payments = entity
.GetPayments() .GetPayments()
.Select(paymentEntity => .Select(paymentEntity =>

View File

@@ -826,6 +826,40 @@ namespace BTCPayServer.Services.Invoices
(Status != InvoiceStatus.Invalid && ExceptionStatus == InvoiceExceptionStatus.Marked); (Status != InvoiceStatus.Invalid && ExceptionStatus == InvoiceExceptionStatus.Marked);
#pragma warning restore CA1305 // Specify IFormatProvider; #pragma warning restore CA1305 // Specify IFormatProvider;
} }
public override int GetHashCode()
{
return HashCode.Combine(Status, ExceptionStatus);
}
public static bool operator ==(InvoiceState a, InvoiceState b)
{
if (a is null && b is null)
return true;
if (a is null)
return false;
return a.Equals(b);
}
public static bool operator !=(InvoiceState a, InvoiceState b)
{
return !(a == b);
}
public bool Equals(InvoiceState o)
{
if (o is null)
return false;
return o.Status == Status && o.ExceptionStatus == ExceptionStatus;
}
public override bool Equals(object obj)
{
if (obj is InvoiceState o)
{
return this.Equals(o);
}
return false;
}
public override string ToString() public override string ToString()
{ {
return ToString(Status) + (ExceptionStatus == InvoiceExceptionStatus.None ? string.Empty : $" ({ToString(ExceptionStatus)})"); return ToString(Status) + (ExceptionStatus == InvoiceExceptionStatus.None ? string.Empty : $" ({ToString(ExceptionStatus)})");

View File

@@ -1,4 +1,4 @@
@using BTCPayServer.Services.Invoices @using BTCPayServer.Services.Invoices
@using BTCPayServer.Client.Models @using BTCPayServer.Client.Models
@model BTCPayServer.Models.PaymentRequestViewModels.ViewPaymentRequestViewModel @model BTCPayServer.Models.PaymentRequestViewModels.ViewPaymentRequestViewModel
@@ -264,7 +264,7 @@
<td>@invoice.ExpiryDate.ToString("g")</td> <td>@invoice.ExpiryDate.ToString("g")</td>
<td class="text-right">@invoice.AmountFormatted</td> <td class="text-right">@invoice.AmountFormatted</td>
<td class="text-right"></td> <td class="text-right"></td>
<td class="text-right text-print-default @StatusTextClass(invoice.State)">@invoice.StatusFormatted</td> <td class="text-right text-print-default @StatusTextClass(invoice.State)">@invoice.StateFormatted</td>
</tr> </tr>
if (invoice.Payments != null && invoice.Payments.Any()) if (invoice.Payments != null && invoice.Payments.Any())
{ {
@@ -322,7 +322,7 @@
<td v-text="formatDate(invoice.expiryDate)"></td> <td v-text="formatDate(invoice.expiryDate)"></td>
<td class="text-right">{{invoice.amountFormatted}}</td> <td class="text-right">{{invoice.amountFormatted}}</td>
<td class="text-right"></td> <td class="text-right"></td>
<td class="text-right text-print-default" :class="statusTextClass(invoice.statusFormatted)">{{invoice.statusFormatted}}</td> <td class="text-right text-print-default" :class="statusTextClass(invoice.stateFormatted)">{{invoice.stateFormatted}}</td>
</tr> </tr>
<template v-if="invoice.payments && invoice.payments.length > 0"> <template v-if="invoice.payments && invoice.payments.length > 0">
<tr class="table-borderless table-light"> <tr class="table-borderless table-light">