mirror of
https://github.com/bitwarden/server.git
synced 2025-01-26 22:31:30 +01:00
storage adjustment and billing fixes
This commit is contained in:
parent
a8ff190fb5
commit
b49c16f529
@ -395,7 +395,7 @@ namespace Bit.Api.Controllers
|
||||
throw new UnauthorizedAccessException();
|
||||
}
|
||||
|
||||
await _userService.AdjustStorageAsync(user, model.StroageGbAdjustment.Value);
|
||||
await _userService.AdjustStorageAsync(user, model.StorageGbAdjustment.Value);
|
||||
}
|
||||
|
||||
[HttpPut("cancel-premium")]
|
||||
|
@ -168,6 +168,19 @@ namespace Bit.Api.Controllers
|
||||
await _organizationService.AdjustSeatsAsync(orgIdGuid, model.SeatAdjustment.Value);
|
||||
}
|
||||
|
||||
[HttpPut("{id}/storage")]
|
||||
[HttpPost("{id}/storage")]
|
||||
public async Task PutStorage(string id, [FromBody]StorageRequestModel model)
|
||||
{
|
||||
var orgIdGuid = new Guid(id);
|
||||
if(!_currentContext.OrganizationOwner(orgIdGuid))
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
await _organizationService.AdjustStorageAsync(orgIdGuid, model.StorageGbAdjustment.Value);
|
||||
}
|
||||
|
||||
[HttpPut("{id}/cancel")]
|
||||
[HttpPost("{id}/cancel")]
|
||||
public async Task PutCancel(string id)
|
||||
|
@ -6,14 +6,14 @@ namespace Bit.Core.Models.Api
|
||||
public class StorageRequestModel : IValidatableObject
|
||||
{
|
||||
[Required]
|
||||
public short? StroageGbAdjustment { get; set; }
|
||||
public short? StorageGbAdjustment { get; set; }
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if(StroageGbAdjustment == 0)
|
||||
if(StorageGbAdjustment == 0)
|
||||
{
|
||||
yield return new ValidationResult("Storage adjustment cannot be 0.",
|
||||
new string[] { nameof(StroageGbAdjustment) });
|
||||
new string[] { nameof(StorageGbAdjustment) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ namespace Bit.Core.Services
|
||||
Task CancelSubscriptionAsync(Guid organizationId, bool endOfPeriod = false);
|
||||
Task ReinstateSubscriptionAsync(Guid organizationId);
|
||||
Task UpgradePlanAsync(Guid organizationId, PlanType plan, int additionalSeats);
|
||||
Task AdjustStorageAsync(Guid organizationId, short storageAdjustmentGb);
|
||||
Task AdjustSeatsAsync(Guid organizationId, int seatAdjustment);
|
||||
Task<Tuple<Organization, OrganizationUser>> SignUpAsync(OrganizationSignup organizationSignup);
|
||||
Task DeleteAsync(Organization organization);
|
||||
|
@ -222,6 +222,29 @@ namespace Bit.Core.Services
|
||||
// TODO: Update organization
|
||||
}
|
||||
|
||||
public async Task AdjustStorageAsync(Guid organizationId, short storageAdjustmentGb)
|
||||
{
|
||||
var organization = await _organizationRepository.GetByIdAsync(organizationId);
|
||||
if(organization == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
var plan = StaticStore.Plans.FirstOrDefault(p => p.Type == organization.PlanType);
|
||||
if(plan == null)
|
||||
{
|
||||
throw new BadRequestException("Existing plan not found.");
|
||||
}
|
||||
|
||||
if(!plan.MaxStorageGb.HasValue)
|
||||
{
|
||||
throw new BadRequestException("Plan does not allow additional storage.");
|
||||
}
|
||||
|
||||
await BillingHelpers.AdjustStorageAsync(organization, storageAdjustmentGb, plan.StripStoragePlanId);
|
||||
await _organizationRepository.ReplaceAsync(organization);
|
||||
}
|
||||
|
||||
public async Task AdjustSeatsAsync(Guid organizationId, int seatAdjustment)
|
||||
{
|
||||
var organization = await _organizationRepository.GetByIdAsync(organizationId);
|
||||
@ -288,7 +311,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
var seatItem = sub.Items?.Data?.FirstOrDefault(i => i.Plan.Id == plan.StripeSeatPlanId);
|
||||
if(seatItem == null)
|
||||
if(additionalSeats > 0 && seatItem == null)
|
||||
{
|
||||
await subscriptionItemService.CreateAsync(new StripeSubscriptionItemCreateOptions
|
||||
{
|
||||
@ -298,7 +321,7 @@ namespace Bit.Core.Services
|
||||
SubscriptionId = sub.Id
|
||||
});
|
||||
}
|
||||
else if(additionalSeats > 0)
|
||||
else if(additionalSeats > 0 && seatItem != null)
|
||||
{
|
||||
await subscriptionItemService.UpdateAsync(seatItem.Id, new StripeSubscriptionItemUpdateOptions
|
||||
{
|
||||
@ -307,7 +330,7 @@ namespace Bit.Core.Services
|
||||
Prorate = true
|
||||
});
|
||||
}
|
||||
else if(additionalSeats == 0)
|
||||
else if(seatItem != null && additionalSeats == 0)
|
||||
{
|
||||
await subscriptionItemService.DeleteAsync(seatItem.Id);
|
||||
}
|
||||
|
@ -183,8 +183,8 @@ namespace Bit.Core.Utilities
|
||||
throw new BadRequestException("Subscription not found.");
|
||||
}
|
||||
|
||||
var seatItem = sub.Items?.Data?.FirstOrDefault(i => i.Plan.Id == storagePlanId);
|
||||
if(seatItem == null)
|
||||
var storageItem = sub.Items?.Data?.FirstOrDefault(i => i.Plan.Id == storagePlanId);
|
||||
if(additionalStorage > 0 && storageItem == null)
|
||||
{
|
||||
await subscriptionItemService.CreateAsync(new StripeSubscriptionItemCreateOptions
|
||||
{
|
||||
@ -194,23 +194,23 @@ namespace Bit.Core.Utilities
|
||||
SubscriptionId = sub.Id
|
||||
});
|
||||
}
|
||||
else if(additionalStorage > 0)
|
||||
else if(additionalStorage > 0 && storageItem != null)
|
||||
{
|
||||
await subscriptionItemService.UpdateAsync(seatItem.Id, new StripeSubscriptionItemUpdateOptions
|
||||
await subscriptionItemService.UpdateAsync(storageItem.Id, new StripeSubscriptionItemUpdateOptions
|
||||
{
|
||||
PlanId = storagePlanId,
|
||||
Quantity = additionalStorage,
|
||||
Prorate = true
|
||||
});
|
||||
}
|
||||
else if(additionalStorage == 0)
|
||||
else if(additionalStorage == 0 && storageItem != null)
|
||||
{
|
||||
await subscriptionItemService.DeleteAsync(storagePlanId);
|
||||
await subscriptionItemService.DeleteAsync(storageItem.Id);
|
||||
}
|
||||
|
||||
if(additionalStorage > 0)
|
||||
{
|
||||
await PreviewUpcomingInvoiceAndPayAsync(storableSubscriber, storagePlanId, 300);
|
||||
await PreviewUpcomingInvoiceAndPayAsync(storableSubscriber, storagePlanId, 400);
|
||||
}
|
||||
|
||||
storableSubscriber.MaxStorageGb = newStorageGb;
|
||||
|
Loading…
Reference in New Issue
Block a user