Add support for multiple licenses

This commit is contained in:
Christian Cueni 2020-07-01 15:29:10 +02:00
parent 28a617e5f5
commit 4944745da0
8 changed files with 110 additions and 61 deletions

View File

@ -6,14 +6,36 @@ import requests
logger = logging.getLogger(__name__)
TEACHER_EDITION_DURATION = 365
STUDENT_EDITION_DURATION = 4*365
TEACHER_KEY = 'teacher'
STUDENT_KEY = 'student'
MYSKILLBOX_TEACHER_EDITION_ISBN = "978-3-0355-1823-8"
MYSKILLBOX_STUDENT_EDITION_ISBN = "978-3-0355-1397-4"
MYSKILLBOX_LICENSES = {
"978-3-0355-1397-4": {
'edition': STUDENT_KEY,
'duration': 4 * 365,
'name': 'Student 4 years'
},
"978-3-0355-1860-3": {
'edition': STUDENT_KEY,
'duration': 365,
'name': 'Student 1 year'
},
"978-3-0355-1861-0": {
'edition': TEACHER_KEY,
'duration': 30,
'name': 'Teacher test 1 month'
},
"978-3-0355-1862-7": {
'edition': STUDENT_KEY,
'duration': 30,
'name': 'Student test 1 month'
},
"978-3-0355-1823-8": {
'edition': TEACHER_KEY,
'duration': 365,
'name': 'Teacher 1 year'
}
}
class HepClientException(Exception):
@ -151,22 +173,16 @@ class HepClient:
if 'order_id' in item:
order_id = item['order_id']
if item['sku'] == MYSKILLBOX_TEACHER_EDITION_ISBN or \
item['sku'] == MYSKILLBOX_STUDENT_EDITION_ISBN:
if item['sku'] in list(MYSKILLBOX_LICENSES.keys()):
product = {
'raw': item,
'activated': self._get_item_activation(order_item),
'status': status,
'order_id': order_id
'order_id': order_id,
'license': MYSKILLBOX_LICENSES[item['sku']],
'isbn': item['sku']
}
if item['sku'] == MYSKILLBOX_TEACHER_EDITION_ISBN:
product['edition'] = TEACHER_KEY
else:
product['edition'] = STUDENT_KEY
products.append(product)
return products
@ -182,12 +198,9 @@ class HepClient:
if product['status'] != 'complete':
return False
if product['edition'] == TEACHER_KEY:
expiry_delta = product['activated'] + timedelta(TEACHER_EDITION_DURATION)
else:
expiry_delta = product['activated'] + timedelta(STUDENT_EDITION_DURATION)
expiry_delta = product['activated'] + timedelta(product['license']['duration'])
if HepClient.is_product_active(expiry_delta, product['edition']):
if HepClient.is_product_active(expiry_delta, product['isbn']):
return True
else:
return False
@ -206,7 +219,7 @@ class HepClient:
# select first teacher product, as they are all valid it does not matter which one
for product in active_products:
if product['edition'] == TEACHER_KEY:
if product['license']['edition'] == TEACHER_KEY:
teacher_edition = product
break
@ -217,12 +230,7 @@ class HepClient:
return teacher_edition
@staticmethod
def is_product_active(expiry_date, edition):
if edition == TEACHER_KEY:
duration = TEACHER_EDITION_DURATION
else:
duration = STUDENT_EDITION_DURATION
def is_product_active(expiry_date, isbn):
now = datetime.now()
return expiry_date >= now >= expiry_date - timedelta(days=duration)
return expiry_date >= now >= expiry_date - timedelta(days=MYSKILLBOX_LICENSES[isbn]['duration'])

View File

@ -30,7 +30,7 @@ class ApiAccessTestCase(TestCase):
def test_publicGraphqlEndpoint_shouldBeAccessibleWithoutLogin(self):
query= json.dumps({
query = json.dumps({
'operationName': 'BetaLogin',
'query': '''
mutation BetaLogin($input: BetaLoginInput!){

View File

@ -2,7 +2,15 @@ import json
from datetime import datetime, timedelta
from django.test import TestCase
from core.hep_client import HepClient, TEACHER_EDITION_DURATION
from core.hep_client import HepClient, MYSKILLBOX_LICENSES
ISBNS = list(MYSKILLBOX_LICENSES.keys())
STUDENT_ISBN = ISBNS[0]
STUDENT_LICENSE = MYSKILLBOX_LICENSES[STUDENT_ISBN]
TEACHER_ISBN = ISBNS[-1]
TEACHER_LICENSE = MYSKILLBOX_LICENSES[TEACHER_ISBN]
class HepClientTestCases(TestCase):
@ -13,21 +21,24 @@ class HepClientTestCases(TestCase):
def test_has_no_valid_product(self):
products = [
{
'edition': 'teacher',
'license': TEACHER_LICENSE,
'isbn': TEACHER_ISBN,
'raw': {},
'activated': self.now - timedelta(2*TEACHER_EDITION_DURATION),
'activated': self.now - timedelta(2*TEACHER_LICENSE['duration']),
'status': 'complete'
},
{
'edition': 'teacher',
'license': TEACHER_LICENSE,
'isbn': TEACHER_ISBN,
'raw': {},
'activated': self.now - timedelta(3 * TEACHER_EDITION_DURATION),
'activated': self.now - timedelta(3 * TEACHER_LICENSE['duration']),
'status': 'complete'
},
{
'edition': 'teacher',
'license': TEACHER_LICENSE,
'isbn': TEACHER_ISBN,
'raw': {},
'activated': self.now - timedelta(4 * TEACHER_EDITION_DURATION),
'activated': self.now - timedelta(4 * TEACHER_LICENSE['duration']),
'status': 'complete'
}
]
@ -38,7 +49,8 @@ class HepClientTestCases(TestCase):
def test_has_no_not_completed_product(self):
products = [
{
'edition': 'teacher',
'license': TEACHER_LICENSE,
'isbn': TEACHER_ISBN,
'raw': {},
'activated': self.now - timedelta(7),
'status': 'not'
@ -51,7 +63,8 @@ class HepClientTestCases(TestCase):
def test_has_valid_product(self):
products = [
{
'edition': 'teacher',
'license': TEACHER_LICENSE,
'isbn': TEACHER_ISBN,
'raw': {
'id': 0
},
@ -59,19 +72,21 @@ class HepClientTestCases(TestCase):
'status': 'complete'
},
{
'edition': 'teacher',
'license': TEACHER_LICENSE,
'isbn': TEACHER_ISBN,
'raw': {
'id': 1
},
'activated': self.now - timedelta(3 * TEACHER_EDITION_DURATION),
'activated': self.now - timedelta(3 * TEACHER_LICENSE['duration']),
'status': 'complete'
},
{
'edition': 'teacher',
'license': TEACHER_LICENSE,
'isbn': TEACHER_ISBN,
'raw': {
'id': 2
},
'activated': self.now - timedelta(4 * TEACHER_EDITION_DURATION),
'activated': self.now - timedelta(4 * TEACHER_LICENSE['duration']),
'status': 'complete'
}
]
@ -82,7 +97,8 @@ class HepClientTestCases(TestCase):
def test_has_multiple_valid_teacher_products_but_only_one_active(self):
products = [
{
'edition': 'teacher',
'license': TEACHER_LICENSE,
'isbn': TEACHER_ISBN,
'raw': {
'id': 0
},
@ -90,19 +106,21 @@ class HepClientTestCases(TestCase):
'status': 'complete'
},
{
'edition': 'teacher',
'license': TEACHER_LICENSE,
'isbn': TEACHER_ISBN,
'raw': {
'id': 1
},
'activated': self.now - timedelta(3 * TEACHER_EDITION_DURATION),
'activated': self.now - timedelta(3 * TEACHER_LICENSE['duration']),
'status': 'complete'
},
{
'edition': 'teacher',
'license': TEACHER_LICENSE,
'isbn': TEACHER_ISBN,
'raw': {
'id': 2
},
'activated': self.now - timedelta(4 * TEACHER_EDITION_DURATION),
'activated': self.now - timedelta(4 * TEACHER_LICENSE['duration']),
'status': 'complete'
}
]
@ -113,7 +131,8 @@ class HepClientTestCases(TestCase):
def test_has_valid_student_and_teacher_edition(self):
products = [
{
'edition': 'student',
'license': STUDENT_LICENSE,
'isbn': STUDENT_ISBN,
'raw': {
'id': 0
},
@ -121,7 +140,8 @@ class HepClientTestCases(TestCase):
'status': 'complete'
},
{
'edition': 'teacher',
'license': TEACHER_LICENSE,
'isbn': TEACHER_ISBN,
'raw': {
'id': 1
},
@ -137,12 +157,12 @@ class HepClientTestCases(TestCase):
expiry_date = self.now + timedelta(3)
is_active = HepClient.is_product_active(expiry_date, 'teacher')
is_active = HepClient.is_product_active(expiry_date, TEACHER_ISBN)
self.assertTrue(is_active)
def test_product_is_not_active(self):
expiry_date = self.now - timedelta(3 * TEACHER_EDITION_DURATION)
expiry_date = self.now - timedelta(3 * TEACHER_LICENSE['duration'])
is_active = HepClient.is_product_active(expiry_date, 'teacher')
is_active = HepClient.is_product_active(expiry_date, TEACHER_ISBN)
self.assertFalse(is_active)

View File

@ -24,7 +24,8 @@ class Command(BaseCommand):
if product and License.objects.filter(licensee=hep_user, order_id=product['order_id']).count() == 0:
license = License.objects.create_license_for_role(hep_user, product['activated'], product['raw'],
product['edition'], product['order_id'])
product['license']['edition'], product['order_id'],
product['isbn'])
if license.is_valid():
hep_user.license_expiry_date = license.expire_date

View File

@ -9,7 +9,7 @@ from django.utils.translation import ugettext_lazy as _
from django.db import models
from django.contrib.auth.models import UserManager as DjangoUserManager
from core.hep_client import TEACHER_EDITION_DURATION, STUDENT_EDITION_DURATION
from core.hep_client import MYSKILLBOX_LICENSES
class RoleManager(models.Manager):
@ -129,14 +129,14 @@ class UserManager(DjangoUserManager):
class LicenseManager(models.Manager):
def create_license_for_role(self, licensee, activation_date, raw, role, order_id):
def create_license_for_role(self, licensee, activation_date, raw, role, order_id, isbn):
Role = apps.get_model('users', 'Role')
expiry_date = activation_date + timedelta(MYSKILLBOX_LICENSES[isbn]['duration'])
if role == 'teacher':
user_role = Role.objects.get_default_teacher_role()
expiry_date = activation_date + timedelta(TEACHER_EDITION_DURATION)
else:
user_role = Role.objects.get_default_student_role()
expiry_date = activation_date + timedelta(STUDENT_EDITION_DURATION)
new_license = self._create_license_for_role(licensee, expiry_date, raw, user_role, order_id)
new_license.licensee.license_expiry_date = new_license.expire_date

View File

@ -0,0 +1,18 @@
# Generated by Django 2.1.15 on 2020-07-01 12:37
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0019_userdata'),
]
operations = [
migrations.AddField(
model_name='license',
name='isbn',
field=models.CharField(default='978-3-0355-1397-48', max_length=50),
),
]

View File

@ -9,7 +9,7 @@ from django.core.exceptions import ObjectDoesNotExist
from django.db import models
from django.utils.translation import ugettext_lazy as _
from core.hep_client import HepClient
from core.hep_client import HepClient, MYSKILLBOX_LICENSES
from users.managers import RoleManager, UserRoleManager, UserManager, LicenseManager
DEFAULT_SCHOOL_ID = 1
@ -248,6 +248,8 @@ class License(models.Model):
expire_date = models.DateField(blank=False, null=True, )
order_id = models.IntegerField(blank=False, null=False, default=-1)
raw = models.TextField(default='')
isbn = models.CharField(max_length=50, blank=False, null=False,
default=list(MYSKILLBOX_LICENSES.keys())[0]) # student license
objects = LicenseManager()
@ -256,8 +258,7 @@ class License(models.Model):
def is_valid(self):
return HepClient.is_product_active(
datetime(self.expire_date.year, self.expire_date.month, self.expire_date.day),
self.for_role.key)
datetime(self.expire_date.year, self.expire_date.month, self.expire_date.day), self.isbn)
def __str__(self):
return f'License for role: {self.for_role}'

View File

@ -48,7 +48,8 @@ def check_and_create_licenses(hep_client, user):
if product:
license = License.objects.create_license_for_role(user, product['activated'], product['raw'],
product['edition'], product['order_id'])
product['license']['edition'],
product['order_id'], product['isbn'])
# todo handle no license case
else:
return None, NO_VALID_LICENSE