mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-03-03 17:36:59 +01:00
Allowing user to invalidate paid invoice
This commit is contained in:
parent
024ab8ff69
commit
0bb260bec9
3 changed files with 76 additions and 13 deletions
|
@ -281,6 +281,16 @@ namespace BTCPayServer.Controllers
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("invoices/invalidatepaid")]
|
||||||
|
[Authorize(AuthenticationSchemes = "Identity.Application")]
|
||||||
|
[BitpayAPIConstraint(false)]
|
||||||
|
public async Task<IActionResult> InvalidatePaidInvoice(string invoiceId)
|
||||||
|
{
|
||||||
|
await _InvoiceRepository.UpdatePaidInvoiceToInvalid(invoiceId);
|
||||||
|
return RedirectToAction(nameof(ListInvoices));
|
||||||
|
}
|
||||||
|
|
||||||
[TempData]
|
[TempData]
|
||||||
public string StatusMessage
|
public string StatusMessage
|
||||||
{
|
{
|
||||||
|
|
|
@ -251,6 +251,18 @@ namespace BTCPayServer.Services.Invoices
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task UpdatePaidInvoiceToInvalid(string invoiceId)
|
||||||
|
{
|
||||||
|
using (var context = _ContextFactory.CreateContext())
|
||||||
|
{
|
||||||
|
var invoiceData = await context.FindAsync<InvoiceData>(invoiceId).ConfigureAwait(false);
|
||||||
|
if (invoiceData == null || invoiceData.Status != "paid")
|
||||||
|
return;
|
||||||
|
invoiceData.Status = "invalid";
|
||||||
|
await context.SaveChangesAsync().ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<InvoiceEntity> GetInvoice(string storeId, string id, bool includeHistoricalAddresses = false)
|
public async Task<InvoiceEntity> GetInvoice(string storeId, string id, bool includeHistoricalAddresses = false)
|
||||||
{
|
{
|
||||||
using (var context = _ContextFactory.CreateContext())
|
using (var context = _ContextFactory.CreateContext())
|
||||||
|
|
|
@ -43,12 +43,28 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach(var invoice in Model.Invoices)
|
@foreach (var invoice in Model.Invoices)
|
||||||
{
|
{
|
||||||
<tr>
|
<tr>
|
||||||
<td>@invoice.Date</td>
|
<td>@invoice.Date</td>
|
||||||
<td>@invoice.InvoiceId</td>
|
<td>@invoice.InvoiceId</td>
|
||||||
<td>@invoice.Status</td>
|
@if (invoice.Status == "paid")
|
||||||
|
{
|
||||||
|
<td>
|
||||||
|
<div class="btn-group">
|
||||||
|
<a class="dropdown-toggle dropdown-toggle-split" style="cursor: pointer;" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
@invoice.Status <span class="sr-only">Toggle Dropdown</span>
|
||||||
|
</a>
|
||||||
|
<div class="dropdown-menu pull-right">
|
||||||
|
<button class="dropdown-item small" data-toggle="modal" data-target="#myModal" onclick="$('#invoiceId').val('@invoice.InvoiceId')">Make Invalid</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<td>@invoice.Status</td>
|
||||||
|
}
|
||||||
<td>@invoice.AmountCurrency</td>
|
<td>@invoice.AmountCurrency</td>
|
||||||
<td><a asp-action="Checkout" asp-route-invoiceId="@invoice.InvoiceId">Checkout</a> - <a asp-action="Invoice" asp-route-invoiceId="@invoice.InvoiceId">Details</a></td>
|
<td><a asp-action="Checkout" asp-route-invoiceId="@invoice.InvoiceId">Checkout</a> - <a asp-action="Invoice" asp-route-invoiceId="@invoice.InvoiceId">Details</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -56,23 +72,48 @@
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<span>
|
<span>
|
||||||
@if(Model.Skip != 0)
|
@if (Model.Skip != 0)
|
||||||
{
|
{
|
||||||
<a href="@Url.Action("ListInvoices", new
|
<a href="@Url.Action("ListInvoices", new
|
||||||
{
|
{
|
||||||
searchTerm = Model.SearchTerm,
|
searchTerm = Model.SearchTerm,
|
||||||
skip = Math.Max(0, Model.Skip - Model.Count),
|
skip = Math.Max(0, Model.Skip - Model.Count),
|
||||||
count = Model.Count,
|
count = Model.Count,
|
||||||
})"><<</a><span> - </span>
|
})"><<</a><span> - </span>
|
||||||
}
|
}
|
||||||
<a href="@Url.Action("ListInvoices", new
|
<a href="@Url.Action("ListInvoices", new
|
||||||
{
|
{
|
||||||
searchTerm = Model.SearchTerm,
|
searchTerm = Model.SearchTerm,
|
||||||
skip = Model.Skip + Model.Count,
|
skip = Model.Skip + Model.Count,
|
||||||
count = Model.Count,
|
count = Model.Count,
|
||||||
})">>></a>
|
})">>></a>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<!-- Modal -->
|
||||||
|
<div id="myModal" class="modal fade" role="dialog">
|
||||||
|
<form method="post" action="/invoices/invalidatepaid">
|
||||||
|
<input id="invoiceId" name="invoiceId" type="hidden" />
|
||||||
|
<div class="modal-dialog">
|
||||||
|
|
||||||
|
<!-- Modal content-->
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title">Set Invoice status to Invalid</h4>
|
||||||
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p>Are you sure you want to invalidate this transaction? This action is NOT undoable!</p>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="submit" class="btn btn-danger">Yes, make invoice Invalid</button>
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
Loading…
Add table
Reference in a new issue