Merge pull request #350 from coreos-inc/superseceded

Allow a stripe plan to be superseded
This commit is contained in:
josephschorr 2015-08-12 15:18:18 -04:00
commit 74bffa3e25
4 changed files with 44 additions and 3 deletions

View file

@ -16,6 +16,7 @@ PLANS = [
'bus_features': False,
'deprecated': True,
'free_trial_days': 14,
'superseded_by': None,
},
{
'title': 'Basic',
@ -26,6 +27,7 @@ PLANS = [
'bus_features': False,
'deprecated': True,
'free_trial_days': 14,
'superseded_by': None,
},
{
'title': 'Yacht',
@ -36,6 +38,7 @@ PLANS = [
'bus_features': True,
'deprecated': True,
'free_trial_days': 180,
'superseded_by': 'bus-small-30',
},
{
'title': 'Personal',
@ -46,6 +49,7 @@ PLANS = [
'bus_features': False,
'deprecated': True,
'free_trial_days': 14,
'superseded_by': 'personal-30',
},
{
'title': 'Skiff',
@ -56,6 +60,7 @@ PLANS = [
'bus_features': True,
'deprecated': True,
'free_trial_days': 14,
'superseded_by': 'bus-micro-30',
},
{
'title': 'Yacht',
@ -66,6 +71,7 @@ PLANS = [
'bus_features': True,
'deprecated': True,
'free_trial_days': 14,
'superseded_by': 'bus-small-30',
},
{
'title': 'Freighter',
@ -76,6 +82,7 @@ PLANS = [
'bus_features': True,
'deprecated': True,
'free_trial_days': 14,
'superseded_by': 'bus-medium-30',
},
{
'title': 'Tanker',
@ -86,6 +93,7 @@ PLANS = [
'bus_features': True,
'deprecated': True,
'free_trial_days': 14,
'superseded_by': 'bus-large-30',
},
# Active plans
@ -98,6 +106,7 @@ PLANS = [
'bus_features': False,
'deprecated': False,
'free_trial_days': 30,
'superseded_by': None,
},
{
'title': 'Personal',
@ -108,6 +117,7 @@ PLANS = [
'bus_features': False,
'deprecated': False,
'free_trial_days': 30,
'superseded_by': None,
},
{
'title': 'Skiff',
@ -118,6 +128,7 @@ PLANS = [
'bus_features': True,
'deprecated': False,
'free_trial_days': 30,
'superseded_by': None,
},
{
'title': 'Yacht',
@ -128,6 +139,7 @@ PLANS = [
'bus_features': True,
'deprecated': False,
'free_trial_days': 30,
'superseded_by': None,
},
{
'title': 'Freighter',
@ -138,6 +150,7 @@ PLANS = [
'bus_features': True,
'deprecated': False,
'free_trial_days': 30,
'superseded_by': None,
},
{
'title': 'Tanker',
@ -148,6 +161,7 @@ PLANS = [
'bus_features': True,
'deprecated': False,
'free_trial_days': 30,
'superseded_by': None,
},
]

View file

@ -45,7 +45,7 @@
</thead>
<tr ng-repeat="plan in plans" ng-show="isPlanVisible(plan, subscribedPlan)"
ng-class="{'active':(subscribedPlan.stripeId === plan.stripeId), 'deprecated-plan':plan.deprecated}">
ng-class="{'active':isPlanActive(plan, subscribedPlan), 'deprecated-plan':plan.deprecated}">
<td>
{{ plan.title }}
<div class="deprecated-plan-label" ng-show="plan.deprecated">
@ -63,7 +63,7 @@
</button>
</div>
<div ng-switch-default>
<button class="btn" ng-show="subscribedPlan.stripeId !== plan.stripeId"
<button class="btn" ng-show="!isPlanActive(plan, subscribedPlan)"
ng-class="subscribedPlan.price == 0 ? 'btn-primary' : 'btn-default'"
ng-click="changeSubscription(plan.stripeId)">
<span class="cor-loader-inline" ng-show="planChanging"></span>
@ -71,7 +71,7 @@
<span ng-show="!planChanging && subscribedPlan.price == 0 && !isExistingCustomer">Start Free Trial</span>
<span ng-show="!planChanging && subscribedPlan.price == 0 && isExistingCustomer">Subscribe</span>
</button>
<button class="btn btn-danger" ng-show="subscription.plan === plan.stripeId && plan.price > 0"
<button class="btn btn-danger" ng-show="isPlanActive(plan, subscribedPlan) && plan.price > 0"
ng-click="cancelSubscription()">
<span class="cor-loader-inline" ng-show="planChanging"></span>
<span ng-show="!planChanging">Cancel</span>

View file

@ -25,7 +25,13 @@ angular.module('quay').directive('planManager', function () {
};
$scope.isPlanVisible = function(plan, subscribedPlan) {
// A plan is visible if it is not deprecated, or if it is both not superseded
// by another plan, and also the active plan for the user.
if (plan['deprecated']) {
superseded = plan['superseded_by']
if (superseded) {
return !$scope.isPlanVisible(superseded, subscribedPlan);
}
return plan == subscribedPlan;
}
@ -36,6 +42,20 @@ angular.module('quay').directive('planManager', function () {
return true;
};
$scope.isPlanActive = function(plan, subscribedPlan) {
// A plan is active if it is either the plan directly subscribed to by the user
// or the plan which supersedes the plan to which the user is subscribed.
if (!subscribedPlan) {
return false;
}
if (subscribedPlan['deprecated'] && subscribedPlan['superseded_by']) {
return $scope.isPlanActive(plan, PlanService.getPlanImmediately(subscribedPlan['superseded_by']));
}
return (plan.stripeId === subscribedPlan.stripeId);
};
$scope.changeSubscription = function(planId, opt_async) {
if ($scope.planChanging) { return; }

View file

@ -148,6 +148,13 @@ function(KeyService, UserService, CookieService, ApiService, Features, Config) {
});
};
planService.getPlanImmediately = function(planId) {
// Get the plan by name, without bothering to check if the plans are loaded.
// This method will return undefined if planId is undefined or null, or if
// the planDict has not yet been loaded.
return planDict[planId];
};
planService.getMinimumPlan = function(privateCount, isBusiness, callback) {
planService.getPlans(function(plans) {
for (var i = 0; i < plans.length; i++) {