Created
March 30, 2012 17:25
-
-
Save juliomistral/2253128 to your computer and use it in GitHub Desktop.
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
import requests | |
import simplejson | |
from datetime import datetime | |
from isodate import parse_duration | |
from django.core.cache import cache | |
from django.conf import settings | |
from yola.services import ProductService | |
SUBSCRIPTION_TYPES_FOR = { | |
'40000101' : 'silver', | |
'40000035' : 'silver', | |
} | |
GRACE_PERIOD_FOR = { | |
'silver' : 'P7D', | |
} | |
BILLING_PERIOD_FOR = { | |
'silver' : 'P0D', | |
} | |
import logging | |
log = logging.getLogger(__name__) | |
def _get_product_definition(sku): | |
""" | |
Retrieve the product definition for the provided SKU. Some magic will occur to determine what project | |
it's running in to choose the correct method of product retrieval (remote API vs. model retrieval). | |
""" | |
cache_key = 'michango.subscription.product.%s' % sku | |
product_def = cache.get(cache_key) | |
if product_def is not None: | |
return product_def | |
response = ProductService().get_last_available_product(sku=sku) | |
log.debug(response) | |
if response['http_code'] == 200: | |
product_def = response['response'] | |
else: | |
raise ValueError('No product was found for the provided sku: %s' % sku) | |
cache.set(cache_key, product_def) | |
return product_def | |
class SubscriptionManager(object): | |
def __init__(self, user, endpoint_url=None): | |
self.user = user | |
if endpoint_url is None: | |
self.endpoint_url = settings.MICHANGO_URL | |
else: | |
self.endpoint_url = endpoint_url | |
def get_all_subscriptions(self): | |
subscriptions_url = '%s/user/%s/subscriptions' % (self.endpoint_url, self.user.id) | |
response = requests.get(subscriptions_url) | |
log.debug(response) | |
if response.status_code != 200: | |
raise Exception('Error occurred contacting subscription end-point: %s' % response.status_code) | |
raw_subs = simplejson.loads(response.content) | |
return Subscription.from_list(raw_subs) | |
def add_subscription(self, sku, expiry_date=None): | |
""" | |
Takes the provided subscription product and adds it to the user's subscription set. The client | |
can override the expiry date (i.e., a pro rata purchase), otherwise the expiry date will be | |
today + the product's term. | |
""" | |
product_def = _get_product_definition(sku) | |
product_meta = product_def['product_meta'] | |
if 'term' not in product_meta: | |
raise Exception('Provided sku was not for a subscription product. No term in product meta.') | |
term = product_meta['term'] | |
today = datetime.today().replace(tzinfo=None) | |
if expiry_date is None: | |
term_duration = parse_duration(term) | |
expiry_date = today + term_duration | |
data = { | |
'user_id' : self.user.id, | |
'status' : 'active', | |
'term' : term, | |
'sku' : sku, | |
'type' : SUBSCRIPTION_TYPES_FOR[sku], | |
'start_date' : today, | |
'expiry_date' : expiry_date, | |
'deprovision_date' : self._calculate_deprovision_date(expiry_date, SUBSCRIPTION_TYPES_FOR[sku]), | |
'billing_date' : self._calculate_billing_date(expiry_date, SUBSCRIPTION_TYPES_FOR[sku]), | |
} | |
log.debug('Posting to subscription end-point with data: %s' % data) | |
subscriptions_url = '%s/user/%s/subscriptions/' % (self.endpoint_url, self.user.id) | |
headers = {'Accepts': 'application/json'} | |
response = requests.post(subscriptions_url, data=data, headers=headers) | |
log.debug('Response from posting new subscription: %s' % response) | |
if response.status_code != 200: | |
raise Exception('Error occurred contacting subscription end-point: %s' % response.status_code) | |
def _calculate_deprovision_date(self, expiry_date, type): | |
grace_period_duration = parse_duration(GRACE_PERIOD_FOR[type]) | |
return expiry_date + grace_period_duration | |
def _calculate_billing_date(self, expiry_date, type): | |
billing_date_duration = parse_duration(BILLING_PERIOD_FOR[type]) | |
return expiry_date - billing_date_duration | |
class Subscription(object): | |
def __init__(self, **kwargs): | |
for key, value in kwargs.iteritems(): | |
setattr(self, key, value) | |
@classmethod | |
def from_list(cls, raw_data_list): | |
subs = [] | |
for item in raw_data_list: | |
subs.append(Subscription(**item)) | |
return subs | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment