2019-01-14 22:43:29 +01:00
|
|
|
using System;
|
|
|
|
using System.Linq;
|
|
|
|
using System.Threading;
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
using BTCPayServer.Data;
|
|
|
|
using BTCPayServer.Services.Invoices;
|
2019-05-30 07:02:52 +00:00
|
|
|
using BTCPayServer.Services.Stores;
|
2019-01-14 22:43:29 +01:00
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
|
|
|
|
namespace BTCPayServer.Services.PaymentRequests
|
|
|
|
{
|
|
|
|
public class PaymentRequestRepository
|
|
|
|
{
|
|
|
|
private readonly ApplicationDbContextFactory _ContextFactory;
|
|
|
|
private readonly InvoiceRepository _InvoiceRepository;
|
|
|
|
|
2021-12-16 17:37:19 +01:00
|
|
|
public PaymentRequestRepository(ApplicationDbContextFactory contextFactory, InvoiceRepository invoiceRepository)
|
2019-01-14 22:43:29 +01:00
|
|
|
{
|
|
|
|
_ContextFactory = contextFactory;
|
|
|
|
_InvoiceRepository = invoiceRepository;
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<PaymentRequestData> CreateOrUpdatePaymentRequest(PaymentRequestData entity)
|
|
|
|
{
|
2022-11-25 02:42:55 +01:00
|
|
|
await using var context = _ContextFactory.CreateContext();
|
2022-01-14 17:50:29 +09:00
|
|
|
if (string.IsNullOrEmpty(entity.Id))
|
2019-01-14 22:43:29 +01:00
|
|
|
{
|
2022-01-14 17:50:29 +09:00
|
|
|
entity.Id = Guid.NewGuid().ToString();
|
|
|
|
await context.PaymentRequests.AddAsync(entity);
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
2022-01-14 17:50:29 +09:00
|
|
|
else
|
|
|
|
{
|
|
|
|
context.PaymentRequests.Update(entity);
|
|
|
|
}
|
|
|
|
|
|
|
|
await context.SaveChangesAsync();
|
|
|
|
return entity;
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<PaymentRequestData> FindPaymentRequest(string id, string userId, CancellationToken cancellationToken = default)
|
|
|
|
{
|
|
|
|
if (string.IsNullOrEmpty(id))
|
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2022-01-14 17:50:29 +09:00
|
|
|
using var context = _ContextFactory.CreateContext();
|
|
|
|
var result = await context.PaymentRequests.Include(x => x.StoreData)
|
|
|
|
.Where(data =>
|
|
|
|
string.IsNullOrEmpty(userId) ||
|
|
|
|
(data.StoreData != null && data.StoreData.UserStores.Any(u => u.ApplicationUserId == userId)))
|
|
|
|
.SingleOrDefaultAsync(x => x.Id == id, cancellationToken);
|
|
|
|
return result;
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<bool> IsPaymentRequestAdmin(string paymentRequestId, string userId)
|
|
|
|
{
|
|
|
|
if (string.IsNullOrEmpty(userId) || string.IsNullOrEmpty(paymentRequestId))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2022-01-14 17:50:29 +09:00
|
|
|
using var context = _ContextFactory.CreateContext();
|
|
|
|
return await context.PaymentRequests.Include(x => x.StoreData)
|
|
|
|
.AnyAsync(data =>
|
|
|
|
data.Id == paymentRequestId &&
|
|
|
|
(data.StoreData != null && data.StoreData.UserStores.Any(u => u.ApplicationUserId == userId)));
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
2020-06-28 17:55:27 +09:00
|
|
|
|
2020-05-19 19:59:23 +02:00
|
|
|
public async Task UpdatePaymentRequestStatus(string paymentRequestId, Client.Models.PaymentRequestData.PaymentRequestStatus status, CancellationToken cancellationToken = default)
|
2019-01-14 22:43:29 +01:00
|
|
|
{
|
2022-01-14 17:50:29 +09:00
|
|
|
using var context = _ContextFactory.CreateContext();
|
|
|
|
var invoiceData = await context.FindAsync<PaymentRequestData>(paymentRequestId);
|
|
|
|
if (invoiceData == null)
|
|
|
|
return;
|
|
|
|
invoiceData.Status = status;
|
|
|
|
await context.SaveChangesAsync(cancellationToken);
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
|
|
|
|
2022-05-02 16:35:28 +09:00
|
|
|
public async Task<PaymentRequestData[]> FindPaymentRequests(PaymentRequestQuery query, CancellationToken cancellationToken = default)
|
2019-01-14 22:43:29 +01:00
|
|
|
{
|
2022-01-14 17:50:29 +09:00
|
|
|
using var context = _ContextFactory.CreateContext();
|
|
|
|
var queryable = context.PaymentRequests.Include(data => data.StoreData).AsQueryable();
|
|
|
|
|
|
|
|
if (!query.IncludeArchived)
|
|
|
|
{
|
|
|
|
queryable = queryable.Where(data => !data.Archived);
|
|
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(query.StoreId))
|
|
|
|
{
|
|
|
|
queryable = queryable.Where(data =>
|
|
|
|
data.StoreDataId == query.StoreId);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (query.Status != null && query.Status.Any())
|
|
|
|
{
|
|
|
|
queryable = queryable.Where(data =>
|
|
|
|
query.Status.Contains(data.Status));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (query.Ids != null && query.Ids.Any())
|
|
|
|
{
|
|
|
|
queryable = queryable.Where(data =>
|
|
|
|
query.Ids.Contains(data.Id));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!string.IsNullOrEmpty(query.UserId))
|
|
|
|
{
|
|
|
|
queryable = queryable.Where(i =>
|
|
|
|
i.StoreData != null && i.StoreData.UserStores.Any(u => u.ApplicationUserId == query.UserId));
|
|
|
|
}
|
|
|
|
|
|
|
|
queryable = queryable.OrderByDescending(u => u.Created);
|
|
|
|
|
|
|
|
if (query.Skip.HasValue)
|
|
|
|
{
|
|
|
|
queryable = queryable.Skip(query.Skip.Value);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (query.Count.HasValue)
|
2019-01-14 22:43:29 +01:00
|
|
|
{
|
2022-01-14 17:50:29 +09:00
|
|
|
queryable = queryable.Take(query.Count.Value);
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
2022-05-02 16:35:28 +09:00
|
|
|
var items = await queryable.ToArrayAsync(cancellationToken);
|
|
|
|
return items;
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<InvoiceEntity[]> GetInvoicesForPaymentRequest(string paymentRequestId,
|
|
|
|
InvoiceQuery invoiceQuery = null)
|
|
|
|
{
|
|
|
|
if (invoiceQuery == null)
|
|
|
|
{
|
|
|
|
invoiceQuery = new InvoiceQuery();
|
|
|
|
}
|
|
|
|
|
2020-06-28 17:55:27 +09:00
|
|
|
invoiceQuery.OrderId = new[] { GetOrderIdForPaymentRequest(paymentRequestId) };
|
2022-10-27 13:17:18 +09:00
|
|
|
return (await _InvoiceRepository.GetInvoices(invoiceQuery))
|
|
|
|
.Where(i => i.InternalTags.Contains(GetInternalTag(paymentRequestId)))
|
|
|
|
.ToArray();
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public static string GetOrderIdForPaymentRequest(string paymentRequestId)
|
|
|
|
{
|
|
|
|
return $"PAY_REQUEST_{paymentRequestId}";
|
|
|
|
}
|
|
|
|
|
|
|
|
public static string GetPaymentRequestIdFromOrderId(string invoiceOrderId)
|
|
|
|
{
|
|
|
|
if (string.IsNullOrEmpty(invoiceOrderId) ||
|
|
|
|
!invoiceOrderId.StartsWith("PAY_REQUEST_", StringComparison.InvariantCulture))
|
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return invoiceOrderId.Replace("PAY_REQUEST_", "", StringComparison.InvariantCulture);
|
2019-02-25 16:15:45 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
public static string GetInternalTag(string id)
|
|
|
|
{
|
|
|
|
return $"PAYREQ#{id}";
|
|
|
|
}
|
|
|
|
public static string[] GetPaymentIdsFromInternalTags(InvoiceEntity invoiceEntity)
|
|
|
|
{
|
|
|
|
return invoiceEntity.GetInternalTags("PAYREQ#");
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public class PaymentRequestUpdated
|
|
|
|
{
|
|
|
|
public string PaymentRequestId { get; set; }
|
|
|
|
public PaymentRequestData Data { get; set; }
|
|
|
|
}
|
|
|
|
|
|
|
|
public class PaymentRequestQuery
|
|
|
|
{
|
|
|
|
public string StoreId { get; set; }
|
2020-06-28 17:55:27 +09:00
|
|
|
public bool IncludeArchived { get; set; } = true;
|
|
|
|
public Client.Models.PaymentRequestData.PaymentRequestStatus[] Status { get; set; }
|
2019-01-14 22:43:29 +01:00
|
|
|
public string UserId { get; set; }
|
|
|
|
public int? Skip { get; set; }
|
|
|
|
public int? Count { get; set; }
|
2020-05-19 19:59:23 +02:00
|
|
|
public string[] Ids { get; set; }
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
|
|
|
}
|