mirror of
https://github.com/bitwarden/server.git
synced 2025-06-30 07:36:14 -05:00
[AC-2795] Add account credit & tax information to provider subscription (#4276)
* Add account credit, suspension and tax information to subscription response * Run dotnet format'
This commit is contained in:
@ -8,11 +8,11 @@ public record ConsolidatedBillingSubscriptionResponse(
|
||||
DateTime CurrentPeriodEndDate,
|
||||
decimal? DiscountPercentage,
|
||||
string CollectionMethod,
|
||||
DateTime? UnpaidPeriodEndDate,
|
||||
int? GracePeriod,
|
||||
DateTime? SuspensionDate,
|
||||
IEnumerable<ProviderPlanResponse> Plans,
|
||||
long AccountCredit,
|
||||
TaxInformationDTO TaxInformation,
|
||||
DateTime? CancelAt,
|
||||
IEnumerable<ProviderPlanResponse> Plans)
|
||||
SubscriptionSuspensionDTO Suspension)
|
||||
{
|
||||
private const string _annualCadence = "Annual";
|
||||
private const string _monthlyCadence = "Monthly";
|
||||
@ -20,9 +20,9 @@ public record ConsolidatedBillingSubscriptionResponse(
|
||||
public static ConsolidatedBillingSubscriptionResponse From(
|
||||
ConsolidatedBillingSubscriptionDTO consolidatedBillingSubscription)
|
||||
{
|
||||
var (providerPlans, subscription, suspensionDate, unpaidPeriodEndDate) = consolidatedBillingSubscription;
|
||||
var (providerPlans, subscription, taxInformation, suspension) = consolidatedBillingSubscription;
|
||||
|
||||
var providerPlansDTO = providerPlans
|
||||
var providerPlanResponses = providerPlans
|
||||
.Select(providerPlan =>
|
||||
{
|
||||
var plan = StaticStore.GetPlan(providerPlan.PlanType);
|
||||
@ -37,18 +37,16 @@ public record ConsolidatedBillingSubscriptionResponse(
|
||||
cadence);
|
||||
});
|
||||
|
||||
var gracePeriod = subscription.CollectionMethod == "charge_automatically" ? 14 : 30;
|
||||
|
||||
return new ConsolidatedBillingSubscriptionResponse(
|
||||
subscription.Status,
|
||||
subscription.CurrentPeriodEnd,
|
||||
subscription.Customer?.Discount?.Coupon?.PercentOff,
|
||||
subscription.CollectionMethod,
|
||||
unpaidPeriodEndDate,
|
||||
gracePeriod,
|
||||
suspensionDate,
|
||||
providerPlanResponses,
|
||||
subscription.Customer?.Balance ?? 0,
|
||||
taxInformation,
|
||||
subscription.CancelAt,
|
||||
providerPlansDTO);
|
||||
suspension);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,5 +5,5 @@ namespace Bit.Core.Billing.Models;
|
||||
public record ConsolidatedBillingSubscriptionDTO(
|
||||
List<ConfiguredProviderPlanDTO> ProviderPlans,
|
||||
Subscription Subscription,
|
||||
DateTime? SuspensionDate,
|
||||
DateTime? UnpaidPeriodEndDate);
|
||||
TaxInformationDTO TaxInformation,
|
||||
SubscriptionSuspensionDTO Suspension);
|
||||
|
6
src/Core/Billing/Models/SubscriptionSuspensionDTO.cs
Normal file
6
src/Core/Billing/Models/SubscriptionSuspensionDTO.cs
Normal file
@ -0,0 +1,6 @@
|
||||
namespace Bit.Core.Billing.Models;
|
||||
|
||||
public record SubscriptionSuspensionDTO(
|
||||
DateTime SuspensionDate,
|
||||
DateTime UnpaidPeriodEndDate,
|
||||
int GracePeriod);
|
@ -1,4 +1,8 @@
|
||||
namespace Bit.Core.Billing;
|
||||
using Bit.Core.Billing.Models;
|
||||
using Bit.Core.Services;
|
||||
using Stripe;
|
||||
|
||||
namespace Bit.Core.Billing;
|
||||
|
||||
public static class Utilities
|
||||
{
|
||||
@ -8,4 +12,67 @@ public static class Utilities
|
||||
string internalMessage = null,
|
||||
Exception innerException = null) => new("Something went wrong with your request. Please contact support.",
|
||||
internalMessage, innerException);
|
||||
|
||||
public static async Task<SubscriptionSuspensionDTO> GetSuspensionAsync(
|
||||
IStripeAdapter stripeAdapter,
|
||||
Subscription subscription)
|
||||
{
|
||||
if (subscription.Status is not "past_due" && subscription.Status is not "unpaid")
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var openInvoices = await stripeAdapter.InvoiceSearchAsync(new InvoiceSearchOptions
|
||||
{
|
||||
Query = $"subscription:'{subscription.Id}' status:'open'"
|
||||
});
|
||||
|
||||
if (openInvoices.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var currentDate = subscription.TestClock?.FrozenTime ?? DateTime.UtcNow;
|
||||
|
||||
switch (subscription.CollectionMethod)
|
||||
{
|
||||
case "charge_automatically":
|
||||
{
|
||||
var firstOverdueInvoice = openInvoices
|
||||
.Where(invoice => invoice.PeriodEnd < currentDate && invoice.Attempted)
|
||||
.MinBy(invoice => invoice.Created);
|
||||
|
||||
if (firstOverdueInvoice == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
const int gracePeriod = 14;
|
||||
|
||||
return new SubscriptionSuspensionDTO(
|
||||
firstOverdueInvoice.Created.AddDays(gracePeriod),
|
||||
firstOverdueInvoice.PeriodEnd,
|
||||
gracePeriod);
|
||||
}
|
||||
case "send_invoice":
|
||||
{
|
||||
var firstOverdueInvoice = openInvoices
|
||||
.Where(invoice => invoice.DueDate < currentDate)
|
||||
.MinBy(invoice => invoice.Created);
|
||||
|
||||
if (firstOverdueInvoice?.DueDate == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
const int gracePeriod = 30;
|
||||
|
||||
return new SubscriptionSuspensionDTO(
|
||||
firstOverdueInvoice.DueDate.Value.AddDays(gracePeriod),
|
||||
firstOverdueInvoice.PeriodEnd,
|
||||
gracePeriod);
|
||||
}
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user