2019-01-14 22:43:29 +01:00
|
|
|
using System;
|
|
|
|
using System.Linq;
|
2019-03-05 09:09:17 +01:00
|
|
|
using System.Threading;
|
2019-01-14 22:43:29 +01:00
|
|
|
using System.Threading.Tasks;
|
2020-11-17 13:46:23 +01:00
|
|
|
using BTCPayServer.Abstractions.Constants;
|
2022-03-02 18:28:12 +01:00
|
|
|
using BTCPayServer.Abstractions.Extensions;
|
2022-11-25 08:11:13 +01:00
|
|
|
using BTCPayServer.Abstractions.Form;
|
2021-12-11 04:32:23 +01:00
|
|
|
using BTCPayServer.Client;
|
2020-07-24 09:40:37 +02:00
|
|
|
using BTCPayServer.Client.Models;
|
2019-01-14 22:43:29 +01:00
|
|
|
using BTCPayServer.Data;
|
|
|
|
using BTCPayServer.Filters;
|
2022-11-25 10:14:33 +01:00
|
|
|
using BTCPayServer.Forms;
|
2022-11-25 02:42:55 +01:00
|
|
|
using BTCPayServer.Models;
|
2019-01-14 22:43:29 +01:00
|
|
|
using BTCPayServer.Models.PaymentRequestViewModels;
|
|
|
|
using BTCPayServer.PaymentRequest;
|
|
|
|
using BTCPayServer.Services.Invoices;
|
|
|
|
using BTCPayServer.Services.PaymentRequests;
|
|
|
|
using BTCPayServer.Services.Rates;
|
|
|
|
using BTCPayServer.Services.Stores;
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
|
|
|
using Microsoft.AspNetCore.Identity;
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
2022-11-25 02:42:55 +01:00
|
|
|
using Newtonsoft.Json.Linq;
|
2020-07-24 09:40:37 +02:00
|
|
|
using PaymentRequestData = BTCPayServer.Data.PaymentRequestData;
|
|
|
|
using StoreData = BTCPayServer.Data.StoreData;
|
2019-01-14 22:43:29 +01:00
|
|
|
|
|
|
|
namespace BTCPayServer.Controllers
|
|
|
|
{
|
2021-12-11 04:32:23 +01:00
|
|
|
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
|
2019-01-14 22:43:29 +01:00
|
|
|
[Route("payment-requests")]
|
2022-01-07 04:32:00 +01:00
|
|
|
public class UIPaymentRequestController : Controller
|
2019-01-14 22:43:29 +01:00
|
|
|
{
|
2022-01-07 04:32:00 +01:00
|
|
|
private readonly UIInvoiceController _InvoiceController;
|
2019-01-14 22:43:29 +01:00
|
|
|
private readonly UserManager<ApplicationUser> _UserManager;
|
|
|
|
private readonly PaymentRequestRepository _PaymentRequestRepository;
|
|
|
|
private readonly PaymentRequestService _PaymentRequestService;
|
|
|
|
private readonly EventAggregator _EventAggregator;
|
|
|
|
private readonly CurrencyNameTable _Currencies;
|
2019-05-07 10:26:40 +02:00
|
|
|
private readonly InvoiceRepository _InvoiceRepository;
|
2022-11-10 15:12:15 +01:00
|
|
|
private readonly StoreRepository _storeRepository;
|
2019-01-14 22:43:29 +01:00
|
|
|
|
2022-11-26 05:01:00 +01:00
|
|
|
private FormComponentProviders FormProviders { get; }
|
2022-11-25 10:14:33 +01:00
|
|
|
|
2022-01-07 04:32:00 +01:00
|
|
|
public UIPaymentRequestController(
|
|
|
|
UIInvoiceController invoiceController,
|
2019-01-14 22:43:29 +01:00
|
|
|
UserManager<ApplicationUser> userManager,
|
|
|
|
PaymentRequestRepository paymentRequestRepository,
|
|
|
|
PaymentRequestService paymentRequestService,
|
|
|
|
EventAggregator eventAggregator,
|
|
|
|
CurrencyNameTable currencies,
|
2022-11-10 15:12:15 +01:00
|
|
|
StoreRepository storeRepository,
|
2022-11-25 10:14:33 +01:00
|
|
|
InvoiceRepository invoiceRepository,
|
|
|
|
FormComponentProviders formProviders)
|
2019-01-14 22:43:29 +01:00
|
|
|
{
|
|
|
|
_InvoiceController = invoiceController;
|
|
|
|
_UserManager = userManager;
|
|
|
|
_PaymentRequestRepository = paymentRequestRepository;
|
|
|
|
_PaymentRequestService = paymentRequestService;
|
|
|
|
_EventAggregator = eventAggregator;
|
|
|
|
_Currencies = currencies;
|
2022-11-10 15:12:15 +01:00
|
|
|
_storeRepository = storeRepository;
|
2019-05-07 10:26:40 +02:00
|
|
|
_InvoiceRepository = invoiceRepository;
|
2022-11-25 10:14:33 +01:00
|
|
|
FormProviders = formProviders;
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
[BitpayAPIConstraint(false)]
|
2021-12-11 04:32:23 +01:00
|
|
|
[HttpGet("/stores/{storeId}/payment-requests")]
|
|
|
|
public async Task<IActionResult> GetPaymentRequests(string storeId, ListPaymentRequestsViewModel model = null)
|
2019-01-14 22:43:29 +01:00
|
|
|
{
|
2020-07-30 16:10:10 +02:00
|
|
|
model = this.ParseListQuery(model ?? new ListPaymentRequestsViewModel());
|
2020-07-19 23:40:57 +02:00
|
|
|
|
2021-12-20 15:15:32 +01:00
|
|
|
var store = GetCurrentStore();
|
2020-07-30 16:10:10 +02:00
|
|
|
var includeArchived = new SearchString(model.SearchTerm).GetFilterBool("includearchived") == true;
|
2021-12-11 04:32:23 +01:00
|
|
|
var result = await _PaymentRequestRepository.FindPaymentRequests(new PaymentRequestQuery
|
2019-01-14 22:43:29 +01:00
|
|
|
{
|
2020-06-28 10:55:27 +02:00
|
|
|
UserId = GetUserId(),
|
2021-12-20 15:15:32 +01:00
|
|
|
StoreId = store.Id,
|
2020-07-30 16:10:10 +02:00
|
|
|
Skip = model.Skip,
|
|
|
|
Count = model.Count,
|
2020-06-28 10:55:27 +02:00
|
|
|
IncludeArchived = includeArchived
|
2019-01-14 22:43:29 +01:00
|
|
|
});
|
2020-07-30 16:10:10 +02:00
|
|
|
|
2022-11-18 05:24:57 +01:00
|
|
|
model.Items = result.Select(data =>
|
|
|
|
{
|
|
|
|
var blob = data.GetBlob();
|
|
|
|
return new ViewPaymentRequestViewModel(data)
|
|
|
|
{
|
|
|
|
AmountFormatted = _Currencies.FormatCurrency(blob.Amount, blob.Currency)
|
|
|
|
};
|
|
|
|
}).ToList();
|
|
|
|
|
2020-07-30 16:10:10 +02:00
|
|
|
return View(model);
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
|
|
|
|
2021-12-11 04:32:23 +01:00
|
|
|
[HttpGet("/stores/{storeId}/payment-requests/edit/{payReqId?}")]
|
2022-12-14 06:01:48 +01:00
|
|
|
public async Task<IActionResult> EditPaymentRequest(string storeId, string payReqId)
|
2019-01-14 22:43:29 +01:00
|
|
|
{
|
2021-12-20 15:15:32 +01:00
|
|
|
var store = GetCurrentStore();
|
|
|
|
var paymentRequest = GetCurrentPaymentRequest();
|
|
|
|
if (paymentRequest == null && !string.IsNullOrEmpty(payReqId))
|
2019-01-14 22:43:29 +01:00
|
|
|
{
|
|
|
|
return NotFound();
|
|
|
|
}
|
|
|
|
|
2022-12-14 06:01:48 +01:00
|
|
|
var prInvoices = payReqId is null ? null : (await _PaymentRequestService.GetPaymentRequest(payReqId, GetUserId())).Invoices;
|
2022-04-11 10:50:30 +02:00
|
|
|
var vm = new UpdatePaymentRequestViewModel(paymentRequest)
|
2019-01-14 22:43:29 +01:00
|
|
|
{
|
2022-12-14 06:01:48 +01:00
|
|
|
StoreId = store.Id,
|
|
|
|
AmountAndCurrencyEditable = payReqId is null || !prInvoices.Any()
|
2022-04-11 10:50:30 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
vm.Currency ??= store.GetStoreBlob().DefaultCurrency;
|
|
|
|
|
|
|
|
return View(nameof(EditPaymentRequest), vm);
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
|
|
|
|
2021-12-11 04:32:23 +01:00
|
|
|
[HttpPost("/stores/{storeId}/payment-requests/edit/{payReqId?}")]
|
|
|
|
public async Task<IActionResult> EditPaymentRequest(string payReqId, UpdatePaymentRequestViewModel viewModel)
|
2019-01-14 22:43:29 +01:00
|
|
|
{
|
2022-01-11 10:42:44 +01:00
|
|
|
if (!string.IsNullOrEmpty(viewModel.Currency) &&
|
2019-01-14 22:43:29 +01:00
|
|
|
_Currencies.GetCurrencyData(viewModel.Currency, false) == null)
|
|
|
|
ModelState.AddModelError(nameof(viewModel.Currency), "Invalid currency");
|
2022-01-11 10:42:44 +01:00
|
|
|
if (string.IsNullOrEmpty(viewModel.Currency))
|
|
|
|
viewModel.Currency = null;
|
2021-12-20 15:15:32 +01:00
|
|
|
var store = GetCurrentStore();
|
|
|
|
var paymentRequest = GetCurrentPaymentRequest();
|
|
|
|
if (paymentRequest == null && !string.IsNullOrEmpty(payReqId))
|
2019-01-14 22:43:29 +01:00
|
|
|
{
|
|
|
|
return NotFound();
|
|
|
|
}
|
|
|
|
|
2021-12-20 15:15:32 +01:00
|
|
|
if (paymentRequest?.Archived is true && viewModel.Archived)
|
2020-05-08 12:33:47 +02:00
|
|
|
{
|
|
|
|
ModelState.AddModelError(string.Empty, "You cannot edit an archived payment request.");
|
|
|
|
}
|
2022-12-14 06:01:48 +01:00
|
|
|
var data = paymentRequest ?? new PaymentRequestData();
|
|
|
|
data.StoreDataId = viewModel.StoreId;
|
|
|
|
data.Archived = viewModel.Archived;
|
|
|
|
var blob = data.GetBlob();
|
|
|
|
|
|
|
|
if (blob.Amount != viewModel.Amount && payReqId != null)
|
|
|
|
{
|
|
|
|
var prInvoices = (await _PaymentRequestService.GetPaymentRequest(payReqId, GetUserId())).Invoices;
|
|
|
|
if (prInvoices.Any())
|
|
|
|
ModelState.AddModelError(nameof(viewModel.Amount), "Amount and currency are not editable once payment request has invoices");
|
|
|
|
}
|
2020-05-08 12:33:47 +02:00
|
|
|
|
2019-01-14 22:43:29 +01:00
|
|
|
if (!ModelState.IsValid)
|
|
|
|
{
|
2020-06-28 10:55:27 +02:00
|
|
|
return View(nameof(EditPaymentRequest), viewModel);
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
|
|
|
|
2022-12-14 06:01:48 +01:00
|
|
|
|
2019-01-14 22:43:29 +01:00
|
|
|
blob.Title = viewModel.Title;
|
|
|
|
blob.Email = viewModel.Email;
|
2019-08-10 07:05:11 +02:00
|
|
|
blob.Description = viewModel.Description;
|
2019-01-14 22:43:29 +01:00
|
|
|
blob.Amount = viewModel.Amount;
|
2019-05-15 15:02:39 +02:00
|
|
|
blob.ExpiryDate = viewModel.ExpiryDate?.ToUniversalTime();
|
2022-01-11 10:42:44 +01:00
|
|
|
blob.Currency = viewModel.Currency ?? store.GetStoreBlob().DefaultCurrency;
|
2019-01-14 22:43:29 +01:00
|
|
|
blob.EmbeddedCSS = viewModel.EmbeddedCSS;
|
|
|
|
blob.CustomCSSLink = viewModel.CustomCSSLink;
|
|
|
|
blob.AllowCustomPaymentAmounts = viewModel.AllowCustomPaymentAmounts;
|
2022-11-25 02:42:55 +01:00
|
|
|
blob.FormId = viewModel.FormId;
|
2019-01-14 22:43:29 +01:00
|
|
|
|
|
|
|
data.SetBlob(blob);
|
2022-06-04 23:33:26 +02:00
|
|
|
var isNewPaymentRequest = string.IsNullOrEmpty(payReqId);
|
|
|
|
if (isNewPaymentRequest)
|
2019-07-01 10:22:54 +02:00
|
|
|
{
|
|
|
|
data.Created = DateTimeOffset.UtcNow;
|
|
|
|
}
|
2020-05-08 12:33:47 +02:00
|
|
|
|
2019-01-14 22:43:29 +01:00
|
|
|
data = await _PaymentRequestRepository.CreateOrUpdatePaymentRequest(data);
|
2021-08-31 08:07:54 +02:00
|
|
|
_EventAggregator.Publish(new PaymentRequestUpdated { Data = data, PaymentRequestId = data.Id, });
|
2019-02-22 11:37:45 +01:00
|
|
|
|
2022-06-20 04:52:12 +02:00
|
|
|
TempData[WellKnownTempData.SuccessMessage] = $"Payment request \"{viewModel.Title}\" {(isNewPaymentRequest ? "created" : "updated")} successfully";
|
2022-06-04 23:33:26 +02:00
|
|
|
return RedirectToAction(nameof(GetPaymentRequests), new { storeId = store.Id, payReqId = data.Id });
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
|
|
|
|
2021-12-11 04:32:23 +01:00
|
|
|
[HttpGet("{payReqId}")]
|
2019-01-14 22:43:29 +01:00
|
|
|
[AllowAnonymous]
|
2021-12-11 04:32:23 +01:00
|
|
|
public async Task<IActionResult> ViewPaymentRequest(string payReqId)
|
2019-01-14 22:43:29 +01:00
|
|
|
{
|
2021-12-11 04:32:23 +01:00
|
|
|
var result = await _PaymentRequestService.GetPaymentRequest(payReqId, GetUserId());
|
2019-01-14 22:43:29 +01:00
|
|
|
if (result == null)
|
|
|
|
{
|
|
|
|
return NotFound();
|
|
|
|
}
|
2020-05-08 12:33:47 +02:00
|
|
|
|
2021-08-31 08:07:54 +02:00
|
|
|
result.HubPath = PaymentRequestHub.GetHubPath(Request);
|
2019-01-14 22:43:29 +01:00
|
|
|
return View(result);
|
|
|
|
}
|
|
|
|
|
2022-11-25 02:42:55 +01:00
|
|
|
[HttpGet("{payReqId}/form")]
|
|
|
|
[HttpPost("{payReqId}/form")]
|
|
|
|
[AllowAnonymous]
|
2022-11-25 08:11:13 +01:00
|
|
|
public async Task<IActionResult> ViewPaymentRequestForm(string payReqId)
|
2022-11-25 02:42:55 +01:00
|
|
|
{
|
|
|
|
var result = await _PaymentRequestRepository.FindPaymentRequest(payReqId, GetUserId());
|
|
|
|
if (result == null)
|
|
|
|
{
|
|
|
|
return NotFound();
|
|
|
|
}
|
|
|
|
|
|
|
|
var prBlob = result.GetBlob();
|
|
|
|
var prFormId = prBlob.FormId;
|
2022-11-28 12:50:09 +01:00
|
|
|
var formConfig = prFormId is null ? null : Forms.UIFormsController.GetFormData(prFormId)?.Config;
|
|
|
|
switch (formConfig)
|
2022-11-25 02:42:55 +01:00
|
|
|
{
|
|
|
|
case null:
|
2022-11-28 12:50:09 +01:00
|
|
|
case { } when !this.Request.HasFormContentType && prBlob.FormResponse is not null:
|
2022-11-25 08:11:13 +01:00
|
|
|
return RedirectToAction("ViewPaymentRequest", new { payReqId });
|
2022-11-28 12:50:09 +01:00
|
|
|
case { } when !this.Request.HasFormContentType && prBlob.FormResponse is null:
|
|
|
|
break;
|
2022-11-25 02:42:55 +01:00
|
|
|
default:
|
|
|
|
// POST case: Handle form submit
|
2022-11-28 12:50:09 +01:00
|
|
|
var formData = Form.Parse(formConfig);
|
2022-11-26 05:01:00 +01:00
|
|
|
formData.ApplyValuesFromForm(Request.Form);
|
2022-11-25 10:14:33 +01:00
|
|
|
if (FormProviders.Validate(formData, ModelState))
|
2022-11-25 02:42:55 +01:00
|
|
|
{
|
2022-11-25 08:11:13 +01:00
|
|
|
prBlob.FormResponse = JObject.FromObject(formData.GetValues());
|
2022-11-25 02:42:55 +01:00
|
|
|
result.SetBlob(prBlob);
|
|
|
|
await _PaymentRequestRepository.CreateOrUpdatePaymentRequest(result);
|
|
|
|
return RedirectToAction("PayPaymentRequest", new { payReqId });
|
|
|
|
}
|
2022-11-25 08:11:13 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return View("PostRedirect", new PostRedirectViewModel
|
|
|
|
{
|
|
|
|
AspController = "UIForms",
|
|
|
|
AspAction = "ViewPublicForm",
|
|
|
|
RouteParameters =
|
2022-11-26 05:01:00 +01:00
|
|
|
{
|
|
|
|
{ "formId", prFormId }
|
|
|
|
},
|
2022-11-25 08:11:13 +01:00
|
|
|
FormParameters =
|
2022-11-26 05:01:00 +01:00
|
|
|
{
|
|
|
|
{ "redirectUrl", Request.GetCurrentUrl() }
|
|
|
|
}
|
2022-11-25 08:11:13 +01:00
|
|
|
});
|
2022-11-25 02:42:55 +01:00
|
|
|
}
|
|
|
|
|
2021-12-11 04:32:23 +01:00
|
|
|
[HttpGet("{payReqId}/pay")]
|
2019-01-14 22:43:29 +01:00
|
|
|
[AllowAnonymous]
|
2021-12-11 04:32:23 +01:00
|
|
|
public async Task<IActionResult> PayPaymentRequest(string payReqId, bool redirectToInvoice = true,
|
2019-03-05 09:09:17 +01:00
|
|
|
decimal? amount = null, CancellationToken cancellationToken = default)
|
2019-01-14 22:43:29 +01:00
|
|
|
{
|
2020-03-16 09:06:40 +01:00
|
|
|
if (amount.HasValue && amount.Value <= 0)
|
|
|
|
{
|
|
|
|
return BadRequest("Please provide an amount greater than 0");
|
|
|
|
}
|
2020-05-08 12:33:47 +02:00
|
|
|
|
2021-12-11 04:32:23 +01:00
|
|
|
var result = await _PaymentRequestService.GetPaymentRequest(payReqId, GetUserId());
|
2019-01-14 22:43:29 +01:00
|
|
|
if (result == null)
|
|
|
|
{
|
|
|
|
return NotFound();
|
|
|
|
}
|
2020-05-08 12:33:47 +02:00
|
|
|
|
|
|
|
if (result.Archived)
|
|
|
|
{
|
|
|
|
if (redirectToInvoice)
|
|
|
|
{
|
2022-04-22 15:52:57 +02:00
|
|
|
return RedirectToAction("ViewPaymentRequest", new { payReqId });
|
2020-05-08 12:33:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return BadRequest("Payment Request cannot be paid as it has been archived");
|
|
|
|
}
|
|
|
|
|
2021-08-31 08:07:54 +02:00
|
|
|
result.HubPath = PaymentRequestHub.GetHubPath(Request);
|
2019-01-14 22:43:29 +01:00
|
|
|
if (result.AmountDue <= 0)
|
|
|
|
{
|
|
|
|
if (redirectToInvoice)
|
|
|
|
{
|
2022-04-22 15:52:57 +02:00
|
|
|
return RedirectToAction("ViewPaymentRequest", new { payReqId });
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return BadRequest("Payment Request has already been settled.");
|
|
|
|
}
|
2019-02-24 09:26:37 +01:00
|
|
|
|
2021-12-17 07:31:06 +01:00
|
|
|
if (result.ExpiryDate.HasValue && DateTime.UtcNow >= result.ExpiryDate)
|
2019-01-14 22:43:29 +01:00
|
|
|
{
|
|
|
|
if (redirectToInvoice)
|
|
|
|
{
|
2022-04-22 15:52:57 +02:00
|
|
|
return RedirectToAction("ViewPaymentRequest", new { payReqId });
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return BadRequest("Payment Request has expired");
|
|
|
|
}
|
|
|
|
|
2022-11-02 10:41:19 +01:00
|
|
|
var currentInvoice = result.Invoices.GetReusableInvoice(amount);
|
2020-10-23 14:00:23 +02:00
|
|
|
if (currentInvoice != null)
|
2019-01-14 22:43:29 +01:00
|
|
|
{
|
|
|
|
if (redirectToInvoice)
|
|
|
|
{
|
2022-01-07 04:32:00 +01:00
|
|
|
return RedirectToAction("Checkout", "UIInvoice", new { currentInvoice.Id });
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
|
|
|
|
2020-10-23 14:00:23 +02:00
|
|
|
return Ok(currentInvoice.Id);
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
2019-02-24 09:26:37 +01:00
|
|
|
|
2019-01-14 22:43:29 +01:00
|
|
|
try
|
|
|
|
{
|
2022-11-10 15:12:15 +01:00
|
|
|
var store = await _storeRepository.FindStore(result.StoreId);
|
|
|
|
var newInvoice = await _InvoiceController.CreatePaymentRequestInvoice(result, amount, store, Request, cancellationToken);
|
2019-01-14 22:43:29 +01:00
|
|
|
if (redirectToInvoice)
|
|
|
|
{
|
2022-04-22 15:52:57 +02:00
|
|
|
return RedirectToAction("Checkout", "UIInvoice", new { invoiceId = newInvoice.Id });
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
|
|
|
|
2021-07-14 13:43:13 +02:00
|
|
|
return Ok(newInvoice.Id);
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
|
|
|
catch (BitpayHttpException e)
|
|
|
|
{
|
|
|
|
return BadRequest(e.Message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-11 04:32:23 +01:00
|
|
|
[HttpGet("{payReqId}/cancel")]
|
|
|
|
public async Task<IActionResult> CancelUnpaidPendingInvoice(string payReqId, bool redirect = true)
|
2019-05-07 10:26:40 +02:00
|
|
|
{
|
2021-12-11 04:32:23 +01:00
|
|
|
var result = await _PaymentRequestService.GetPaymentRequest(payReqId, GetUserId());
|
2020-05-08 12:33:47 +02:00
|
|
|
if (result == null)
|
2019-05-07 10:26:40 +02:00
|
|
|
{
|
|
|
|
return NotFound();
|
|
|
|
}
|
2019-03-05 09:13:34 +01:00
|
|
|
|
2021-12-31 08:59:02 +01:00
|
|
|
if (!result.AllowCustomPaymentAmounts)
|
|
|
|
{
|
2021-09-17 03:24:48 +02:00
|
|
|
return BadRequest("Not allowed to cancel this invoice");
|
|
|
|
}
|
|
|
|
|
2020-08-04 07:55:13 +02:00
|
|
|
var invoices = result.Invoices.Where(requestInvoice =>
|
2020-11-23 07:57:05 +01:00
|
|
|
requestInvoice.State.Status == InvoiceStatusLegacy.New && !requestInvoice.Payments.Any());
|
2019-05-07 10:26:40 +02:00
|
|
|
|
2020-08-04 07:55:13 +02:00
|
|
|
if (!invoices.Any())
|
2019-05-07 10:26:40 +02:00
|
|
|
{
|
|
|
|
return BadRequest("No unpaid pending invoice to cancel");
|
|
|
|
}
|
2020-05-08 12:33:47 +02:00
|
|
|
|
2020-08-04 07:55:13 +02:00
|
|
|
foreach (var invoice in invoices)
|
|
|
|
{
|
2020-07-24 09:40:37 +02:00
|
|
|
await _InvoiceRepository.MarkInvoiceStatus(invoice.Id, InvoiceStatus.Invalid);
|
2020-08-04 07:55:13 +02:00
|
|
|
}
|
2019-05-07 10:26:40 +02:00
|
|
|
|
|
|
|
if (redirect)
|
|
|
|
{
|
2019-11-07 09:59:35 +01:00
|
|
|
TempData[WellKnownTempData.SuccessMessage] = "Payment cancelled";
|
2022-04-22 15:52:57 +02:00
|
|
|
return RedirectToAction(nameof(ViewPaymentRequest), new { payReqId });
|
2019-05-07 10:26:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return Ok("Payment cancelled");
|
|
|
|
}
|
2020-05-08 12:33:47 +02:00
|
|
|
|
2021-12-11 04:32:23 +01:00
|
|
|
[HttpGet("{payReqId}/clone")]
|
2022-12-14 06:01:48 +01:00
|
|
|
public async Task<IActionResult> ClonePaymentRequest(string payReqId)
|
2019-03-07 06:27:16 +01:00
|
|
|
{
|
2021-12-20 15:15:32 +01:00
|
|
|
var store = GetCurrentStore();
|
2022-12-14 06:01:48 +01:00
|
|
|
var result = await EditPaymentRequest(store.Id, payReqId);
|
2019-03-07 06:27:16 +01:00
|
|
|
if (result is ViewResult viewResult)
|
|
|
|
{
|
|
|
|
var model = (UpdatePaymentRequestViewModel)viewResult.Model;
|
|
|
|
model.Id = null;
|
2020-05-08 12:33:47 +02:00
|
|
|
model.Archived = false;
|
2021-08-31 08:07:54 +02:00
|
|
|
model.ExpiryDate = null;
|
2019-03-07 06:27:16 +01:00
|
|
|
model.Title = $"Clone of {model.Title}";
|
|
|
|
return View("EditPaymentRequest", model);
|
2020-05-08 12:33:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return NotFound();
|
|
|
|
}
|
|
|
|
|
2021-12-11 04:32:23 +01:00
|
|
|
[HttpGet("{payReqId}/archive")]
|
|
|
|
public async Task<IActionResult> TogglePaymentRequestArchival(string payReqId)
|
2020-05-08 12:33:47 +02:00
|
|
|
{
|
2021-12-20 15:15:32 +01:00
|
|
|
var store = GetCurrentStore();
|
2022-12-14 06:01:48 +01:00
|
|
|
var result = await EditPaymentRequest(store.Id, payReqId);
|
2020-05-08 12:33:47 +02:00
|
|
|
if (result is ViewResult viewResult)
|
|
|
|
{
|
|
|
|
var model = (UpdatePaymentRequestViewModel)viewResult.Model;
|
|
|
|
model.Archived = !model.Archived;
|
2021-12-11 04:32:23 +01:00
|
|
|
await EditPaymentRequest(payReqId, model);
|
2020-05-08 12:33:47 +02:00
|
|
|
TempData[WellKnownTempData.SuccessMessage] = model.Archived
|
2022-02-09 15:37:15 +01:00
|
|
|
? "The payment request has been archived and will no longer appear in the payment request list by default again."
|
|
|
|
: "The payment request has been unarchived and will appear in the payment request list by default.";
|
|
|
|
return RedirectToAction("GetPaymentRequests", new { storeId = store.Id });
|
2019-03-07 06:27:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return NotFound();
|
|
|
|
}
|
2021-12-11 04:32:23 +01:00
|
|
|
|
2021-12-20 15:15:32 +01:00
|
|
|
private string GetUserId() => _UserManager.GetUserId(User);
|
2021-12-31 08:59:02 +01:00
|
|
|
|
2021-12-20 15:15:32 +01:00
|
|
|
private StoreData GetCurrentStore() => HttpContext.GetStoreData();
|
2021-12-31 08:59:02 +01:00
|
|
|
|
2021-12-20 15:15:32 +01:00
|
|
|
private PaymentRequestData GetCurrentPaymentRequest() => HttpContext.GetPaymentRequestData();
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
|
|
|
}
|