1
0
mirror of https://github.com/bitwarden/server.git synced 2024-11-21 12:05:42 +01:00

Added filter for status when getting invoices (#4866)

This commit is contained in:
Conner Turnbull 2024-10-09 09:00:36 -04:00 committed by GitHub
parent 669f1ea5dc
commit 9d06c7b1e0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 24 additions and 14 deletions

View File

@ -1,4 +1,5 @@
using Bit.Api.Billing.Models.Responses; #nullable enable
using Bit.Api.Billing.Models.Responses;
using Bit.Core.Billing.Services; using Bit.Core.Billing.Services;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
@ -43,7 +44,7 @@ public class AccountsBillingController(
} }
[HttpGet("invoices")] [HttpGet("invoices")]
public async Task<IResult> GetInvoicesAsync([FromQuery] string startAfter = null) public async Task<IResult> GetInvoicesAsync([FromQuery] string? status = null, [FromQuery] string? startAfter = null)
{ {
var user = await userService.GetUserByPrincipalAsync(User); var user = await userService.GetUserByPrincipalAsync(User);
if (user == null) if (user == null)
@ -54,6 +55,7 @@ public class AccountsBillingController(
var invoices = await paymentHistoryService.GetInvoiceHistoryAsync( var invoices = await paymentHistoryService.GetInvoiceHistoryAsync(
user, user,
5, 5,
status,
startAfter); startAfter);
return TypedResults.Ok(invoices); return TypedResults.Ok(invoices);

View File

@ -1,4 +1,5 @@
using Bit.Api.Billing.Models.Requests; #nullable enable
using Bit.Api.Billing.Models.Requests;
using Bit.Api.Billing.Models.Responses; using Bit.Api.Billing.Models.Responses;
using Bit.Core; using Bit.Core;
using Bit.Core.Billing.Services; using Bit.Core.Billing.Services;
@ -63,7 +64,7 @@ public class OrganizationBillingController(
} }
[HttpGet("invoices")] [HttpGet("invoices")]
public async Task<IResult> GetInvoicesAsync([FromRoute] Guid organizationId, [FromQuery] string startAfter = null) public async Task<IResult> GetInvoicesAsync([FromRoute] Guid organizationId, [FromQuery] string? status = null, [FromQuery] string? startAfter = null)
{ {
if (!await currentContext.ViewBillingHistory(organizationId)) if (!await currentContext.ViewBillingHistory(organizationId))
{ {
@ -80,6 +81,7 @@ public class OrganizationBillingController(
var invoices = await paymentHistoryService.GetInvoiceHistoryAsync( var invoices = await paymentHistoryService.GetInvoiceHistoryAsync(
organization, organization,
5, 5,
status,
startAfter); startAfter);
return TypedResults.Ok(invoices); return TypedResults.Ok(invoices);

View File

@ -1,4 +1,5 @@
using Bit.Core.Billing.Models; #nullable enable
using Bit.Core.Billing.Models;
using Bit.Core.Entities; using Bit.Core.Entities;
namespace Bit.Core.Billing.Services; namespace Bit.Core.Billing.Services;
@ -8,7 +9,8 @@ public interface IPaymentHistoryService
Task<IEnumerable<BillingHistoryInfo.BillingInvoice>> GetInvoiceHistoryAsync( Task<IEnumerable<BillingHistoryInfo.BillingInvoice>> GetInvoiceHistoryAsync(
ISubscriber subscriber, ISubscriber subscriber,
int pageSize = 5, int pageSize = 5,
string startAfter = null); string? status = null,
string? startAfter = null);
Task<IEnumerable<BillingHistoryInfo.BillingTransaction>> GetTransactionHistoryAsync( Task<IEnumerable<BillingHistoryInfo.BillingTransaction>> GetTransactionHistoryAsync(
ISubscriber subscriber, ISubscriber subscriber,

View File

@ -1,4 +1,5 @@
using Bit.Core.AdminConsole.Entities; #nullable enable
using Bit.Core.AdminConsole.Entities;
using Bit.Core.Billing.Models; using Bit.Core.Billing.Models;
using Bit.Core.Entities; using Bit.Core.Entities;
using Bit.Core.Models.BitStripe; using Bit.Core.Models.BitStripe;
@ -16,11 +17,12 @@ public class PaymentHistoryService(
public async Task<IEnumerable<BillingHistoryInfo.BillingInvoice>> GetInvoiceHistoryAsync( public async Task<IEnumerable<BillingHistoryInfo.BillingInvoice>> GetInvoiceHistoryAsync(
ISubscriber subscriber, ISubscriber subscriber,
int pageSize = 5, int pageSize = 5,
string startAfter = null) string? status = null,
string? startAfter = null)
{ {
if (subscriber is not { GatewayCustomerId: not null, GatewaySubscriptionId: not null }) if (subscriber is not { GatewayCustomerId: not null, GatewaySubscriptionId: not null })
{ {
return null; return Array.Empty<BillingHistoryInfo.BillingInvoice>();
} }
var invoices = await stripeAdapter.InvoiceListAsync(new StripeInvoiceListOptions var invoices = await stripeAdapter.InvoiceListAsync(new StripeInvoiceListOptions
@ -28,6 +30,7 @@ public class PaymentHistoryService(
Customer = subscriber.GatewayCustomerId, Customer = subscriber.GatewayCustomerId,
Subscription = subscriber.GatewaySubscriptionId, Subscription = subscriber.GatewaySubscriptionId,
Limit = pageSize, Limit = pageSize,
Status = status,
StartingAfter = startAfter StartingAfter = startAfter
}); });
@ -48,6 +51,7 @@ public class PaymentHistoryService(
}; };
return transactions?.OrderByDescending(i => i.CreationDate) return transactions?.OrderByDescending(i => i.CreationDate)
.Select(t => new BillingHistoryInfo.BillingTransaction(t)); .Select(t => new BillingHistoryInfo.BillingTransaction(t))
?? Array.Empty<BillingHistoryInfo.BillingTransaction>();
} }
} }

View File

@ -29,7 +29,7 @@ public class PaymentHistoryServiceTests
var result = await paymentHistoryService.GetInvoiceHistoryAsync(subscriber); var result = await paymentHistoryService.GetInvoiceHistoryAsync(subscriber);
// Assert // Assert
Assert.NotNull(result); Assert.NotEmpty(result);
Assert.Single(result); Assert.Single(result);
await stripeAdapter.Received(1).InvoiceListAsync(Arg.Any<StripeInvoiceListOptions>()); await stripeAdapter.Received(1).InvoiceListAsync(Arg.Any<StripeInvoiceListOptions>());
} }
@ -47,7 +47,7 @@ public class PaymentHistoryServiceTests
var result = await paymentHistoryService.GetInvoiceHistoryAsync(null); var result = await paymentHistoryService.GetInvoiceHistoryAsync(null);
// Assert // Assert
Assert.Null(result); Assert.Empty(result);
} }
[Fact] [Fact]
@ -66,7 +66,7 @@ public class PaymentHistoryServiceTests
var result = await paymentHistoryService.GetTransactionHistoryAsync(subscriber); var result = await paymentHistoryService.GetTransactionHistoryAsync(subscriber);
// Assert // Assert
Assert.NotNull(result); Assert.NotEmpty(result);
Assert.Single(result); Assert.Single(result);
await transactionRepository.Received(1).GetManyByOrganizationIdAsync(subscriber.Id, Arg.Any<int>(), Arg.Any<DateTime?>()); await transactionRepository.Received(1).GetManyByOrganizationIdAsync(subscriber.Id, Arg.Any<int>(), Arg.Any<DateTime?>());
} }
@ -84,6 +84,6 @@ public class PaymentHistoryServiceTests
var result = await paymentHistoryService.GetTransactionHistoryAsync(null); var result = await paymentHistoryService.GetTransactionHistoryAsync(null);
// Assert // Assert
Assert.Null(result); Assert.Empty(result);
} }
} }