public async Task AdjustStorageAsync(IStorableSubscriber storableSubscriber, int additionalStorage, string storagePlanId) { var subscriptionItemService = new StripeSubscriptionItemService(); var subscriptionService = new StripeSubscriptionService(); var sub = await subscriptionService.GetAsync(storableSubscriber.GatewaySubscriptionId); if (sub == null) { throw new GatewayException("Subscription not found."); } var storageItem = sub.Items?.Data?.FirstOrDefault(i => i.Plan.Id == storagePlanId); if (additionalStorage > 0 && storageItem == null) { await subscriptionItemService.CreateAsync(new StripeSubscriptionItemCreateOptions { PlanId = storagePlanId, Quantity = additionalStorage, Prorate = true, SubscriptionId = sub.Id }); } else if (additionalStorage > 0 && storageItem != null) { await subscriptionItemService.UpdateAsync(storageItem.Id, new StripeSubscriptionItemUpdateOptions { PlanId = storagePlanId, Quantity = additionalStorage, Prorate = true }); } else if (additionalStorage == 0 && storageItem != null) { await subscriptionItemService.DeleteAsync(storageItem.Id); } if (additionalStorage > 0) { await PreviewUpcomingInvoiceAndPayAsync(storableSubscriber, storagePlanId, 400); } }
public async Task AdjustSeatsAsync(Guid organizationId, int seatAdjustment) { var organization = await _organizationRepository.GetByIdAsync(organizationId); if (organization == null) { throw new NotFoundException(); } if (string.IsNullOrWhiteSpace(organization.StripeCustomerId)) { throw new BadRequestException("No payment method found."); } if (string.IsNullOrWhiteSpace(organization.StripeSubscriptionId)) { throw new BadRequestException("No subscription found."); } var plan = StaticStore.Plans.FirstOrDefault(p => p.Type == organization.PlanType); if (plan == null) { throw new BadRequestException("Existing plan not found."); } if (!plan.CanBuyAdditionalSeats) { throw new BadRequestException("Plan does not allow additional seats."); } var newSeatTotal = organization.Seats + seatAdjustment; if (plan.BaseSeats > newSeatTotal) { throw new BadRequestException($"Plan has a minimum of {plan.BaseSeats} seats."); } var additionalSeats = newSeatTotal - plan.BaseSeats; if (plan.MaxAdditionalSeats.HasValue && additionalSeats > plan.MaxAdditionalSeats.Value) { throw new BadRequestException($"Organization plan allows a maximum of " + $"{plan.MaxAdditionalSeats.Value} additional seats."); } if (!organization.Seats.HasValue || organization.Seats.Value > newSeatTotal) { var userCount = await _organizationUserRepository.GetCountByOrganizationIdAsync(organization.Id); if (userCount > newSeatTotal) { throw new BadRequestException($"Your organization currently has {userCount} seats filled. Your new plan " + $"only has ({newSeatTotal}) seats. Remove some users."); } } var invoiceService = new StripeInvoiceService(); var subscriptionItemService = new StripeSubscriptionItemService(); var subscriptionService = new StripeSubscriptionService(); var sub = await subscriptionService.GetAsync(organization.StripeSubscriptionId); if (sub == null) { throw new BadRequestException("Subscription not found."); } var seatItem = sub.Items?.Data?.FirstOrDefault(i => i.Plan.Id == plan.StripeSeatPlanId); if (seatItem == null) { await subscriptionItemService.CreateAsync(new StripeSubscriptionItemCreateOptions { PlanId = plan.StripeSeatPlanId, Quantity = additionalSeats, Prorate = true, SubscriptionId = sub.Id }); await PreviewUpcomingAndPayAsync(invoiceService, organization, plan); } else if (additionalSeats > 0) { await subscriptionItemService.UpdateAsync(seatItem.Id, new StripeSubscriptionItemUpdateOptions { PlanId = plan.StripeSeatPlanId, Quantity = additionalSeats, Prorate = true }); await PreviewUpcomingAndPayAsync(invoiceService, organization, plan); } else if (additionalSeats == 0) { await subscriptionItemService.DeleteAsync(seatItem.Id); } organization.Seats = (short?)newSeatTotal; await _organizationRepository.ReplaceAsync(organization); }