-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add script to schedule in price changes.
- Loading branch information
Showing
1 changed file
with
106 additions
and
0 deletions.
There are no files selected for viewing
106 changes: 106 additions & 0 deletions
106
subscriptions/management/commands/schedule_price_change.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import re | ||
|
||
from django.conf import settings | ||
from django.contrib.auth.models import User | ||
from django.core.management.base import BaseCommand, CommandError | ||
import stripe | ||
|
||
from api_keys.models import APIKey | ||
from subscriptions.models import Subscription | ||
|
||
stripe.api_key = settings.STRIPE_SECRET_KEY | ||
stripe.api_version = settings.STRIPE_API_VERSION | ||
|
||
|
||
class Command(BaseCommand): | ||
help = "Create a new user with associated Stripe subscription" | ||
|
||
def add_arguments(self, parser): | ||
prices = stripe.Price.list(limit=100) | ||
price_ids = [price.id for price in prices.data if price.product.name.startswith('MapIt')] | ||
parser.add_argument('--old-price', choices=price_ids, required=True) | ||
parser.add_argument('--new-price', choices=price_ids, required=True) | ||
|
||
def handle(self, *args, **options): | ||
old_price = options['old-price'] | ||
new_price = options['new-price'] | ||
|
||
for sub_obj in Subscription.objects.all(): | ||
subscription = stripe.Subscription.retrieve(sub_obj.stripe_id, expand=[ | ||
'schedule.phases.items.price']) | ||
|
||
# Possibilities: | ||
# * No schedule, just a monthly plan | ||
# * 2 phases: Just asked for downgrade, so at current price, then new price, then no schedule | ||
# * 2 phases: Already on 'new price' schedule, awaiting change | ||
# * 1 phase: Been downgraded, so new price, then no schedule | ||
# * 1 phase: On 'new price' schedule, change already happened (shouldn't get this one, should already have run this!) | ||
if subscription.schedule: | ||
if len(subscription.schedule.phases) > 2: | ||
raise Exception, f'{subscription.id} has more than 2 phases!' | ||
elif len(subscription.schedule.phases) == 2: | ||
if subscription.schedule.phases[1].items.price != old_price: | ||
continue | ||
phases = [ | ||
subscription.schedule.phases[0], | ||
subscription.schedule.phases[1], | ||
{ | ||
'items': [{'price': new_price}], | ||
'iterations': 1, | ||
'proration_behavior': 'none', | ||
'default_tax_rates': [settings.STRIPE_TAX_RATE], | ||
}, | ||
] | ||
# Maintain current discount, if any | ||
if schedule.phases[1].discounts and schedule.phases[1].discounts[0].coupon: | ||
phases[2]['discounts'] = [{'coupon': schedule.phases[1].discounts[0].coupon}] | ||
stripe.SubscriptionSchedule.modify(schedule.id, phases=phases) | ||
else: # Must be 1 | ||
if subscription.schedule.phases[0].items.price != old_price: | ||
continue | ||
stripe.SubscriptionSchedule.release(subscription.schedule) | ||
schedule = stripe.SubscriptionSchedule.create(from_subscription=subscription.id) | ||
phases = [ | ||
{ | ||
'items': [{'price': schedule.phases[0]['items'][0].price}], | ||
'start_date': schedule.phases[0].start_date, | ||
'iterations': 2, | ||
'proration_behavior': 'none', | ||
'default_tax_rates': [settings.STRIPE_TAX_RATE], | ||
}, | ||
{ | ||
'items': [{'price': new_price}], | ||
'iterations': 1, | ||
'proration_behavior': 'none', | ||
'default_tax_rates': [settings.STRIPE_TAX_RATE], | ||
}, | ||
] | ||
# Maintain current discount, if any | ||
if schedule.phases[0].discounts and schedule.phases[0].discounts[0].coupon: | ||
phases[0]['discounts'] = [{'coupon': schedule.phases[0].discounts[0].coupon}] | ||
phases[1]['discounts'] = [{'coupon': schedule.phases[0].discounts[0].coupon}] | ||
stripe.SubscriptionSchedule.modify(schedule.id, phases=phases) | ||
else: | ||
if subscription['items'].data[0].price.id != old_price: | ||
continue | ||
schedule = stripe.SubscriptionSchedule.create(from_subscription=subscription.id) | ||
phases = [ | ||
{ | ||
'items': [{'price': schedule.phases[0]['items'][0].price}], | ||
'start_date': schedule.phases[0].start_date, | ||
'iterations': 2, | ||
'proration_behavior': 'none', | ||
'default_tax_rates': [settings.STRIPE_TAX_RATE], | ||
}, | ||
{ | ||
'items': [{'price': new_price}], | ||
'iterations': 1, | ||
'proration_behavior': 'none', | ||
'default_tax_rates': [settings.STRIPE_TAX_RATE], | ||
}, | ||
] | ||
# Maintain current discount, if any | ||
if schedule.phases[0].discounts and schedule.phases[0].discounts[0].coupon: | ||
phases[0]['discounts'] = [{'coupon': schedule.phases[0].discounts[0].coupon}] | ||
phases[1]['discounts'] = [{'coupon': schedule.phases[0].discounts[0].coupon}] | ||
stripe.SubscriptionSchedule.modify(schedule.id, phases=phases) |