Add support for multiple licenses
This commit is contained in:
parent
28a617e5f5
commit
4944745da0
|
|
@ -6,14 +6,36 @@ import requests
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
TEACHER_EDITION_DURATION = 365
|
|
||||||
STUDENT_EDITION_DURATION = 4*365
|
|
||||||
|
|
||||||
TEACHER_KEY = 'teacher'
|
TEACHER_KEY = 'teacher'
|
||||||
STUDENT_KEY = 'student'
|
STUDENT_KEY = 'student'
|
||||||
|
|
||||||
MYSKILLBOX_TEACHER_EDITION_ISBN = "978-3-0355-1823-8"
|
MYSKILLBOX_LICENSES = {
|
||||||
MYSKILLBOX_STUDENT_EDITION_ISBN = "978-3-0355-1397-4"
|
"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):
|
class HepClientException(Exception):
|
||||||
|
|
@ -151,22 +173,16 @@ class HepClient:
|
||||||
if 'order_id' in item:
|
if 'order_id' in item:
|
||||||
order_id = item['order_id']
|
order_id = item['order_id']
|
||||||
|
|
||||||
if item['sku'] == MYSKILLBOX_TEACHER_EDITION_ISBN or \
|
if item['sku'] in list(MYSKILLBOX_LICENSES.keys()):
|
||||||
item['sku'] == MYSKILLBOX_STUDENT_EDITION_ISBN:
|
|
||||||
|
|
||||||
product = {
|
product = {
|
||||||
'raw': item,
|
'raw': item,
|
||||||
'activated': self._get_item_activation(order_item),
|
'activated': self._get_item_activation(order_item),
|
||||||
'status': status,
|
'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)
|
products.append(product)
|
||||||
|
|
||||||
return products
|
return products
|
||||||
|
|
@ -182,12 +198,9 @@ class HepClient:
|
||||||
if product['status'] != 'complete':
|
if product['status'] != 'complete':
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if product['edition'] == TEACHER_KEY:
|
expiry_delta = product['activated'] + timedelta(product['license']['duration'])
|
||||||
expiry_delta = product['activated'] + timedelta(TEACHER_EDITION_DURATION)
|
|
||||||
else:
|
|
||||||
expiry_delta = product['activated'] + timedelta(STUDENT_EDITION_DURATION)
|
|
||||||
|
|
||||||
if HepClient.is_product_active(expiry_delta, product['edition']):
|
if HepClient.is_product_active(expiry_delta, product['isbn']):
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
@ -206,7 +219,7 @@ class HepClient:
|
||||||
|
|
||||||
# select first teacher product, as they are all valid it does not matter which one
|
# select first teacher product, as they are all valid it does not matter which one
|
||||||
for product in active_products:
|
for product in active_products:
|
||||||
if product['edition'] == TEACHER_KEY:
|
if product['license']['edition'] == TEACHER_KEY:
|
||||||
teacher_edition = product
|
teacher_edition = product
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
@ -217,12 +230,7 @@ class HepClient:
|
||||||
return teacher_edition
|
return teacher_edition
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def is_product_active(expiry_date, edition):
|
def is_product_active(expiry_date, isbn):
|
||||||
if edition == TEACHER_KEY:
|
|
||||||
duration = TEACHER_EDITION_DURATION
|
|
||||||
else:
|
|
||||||
duration = STUDENT_EDITION_DURATION
|
|
||||||
|
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
|
|
||||||
return expiry_date >= now >= expiry_date - timedelta(days=duration)
|
return expiry_date >= now >= expiry_date - timedelta(days=MYSKILLBOX_LICENSES[isbn]['duration'])
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ class ApiAccessTestCase(TestCase):
|
||||||
|
|
||||||
def test_publicGraphqlEndpoint_shouldBeAccessibleWithoutLogin(self):
|
def test_publicGraphqlEndpoint_shouldBeAccessibleWithoutLogin(self):
|
||||||
|
|
||||||
query= json.dumps({
|
query = json.dumps({
|
||||||
'operationName': 'BetaLogin',
|
'operationName': 'BetaLogin',
|
||||||
'query': '''
|
'query': '''
|
||||||
mutation BetaLogin($input: BetaLoginInput!){
|
mutation BetaLogin($input: BetaLoginInput!){
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,15 @@ import json
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
from django.test import TestCase
|
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):
|
class HepClientTestCases(TestCase):
|
||||||
|
|
@ -13,21 +21,24 @@ class HepClientTestCases(TestCase):
|
||||||
def test_has_no_valid_product(self):
|
def test_has_no_valid_product(self):
|
||||||
products = [
|
products = [
|
||||||
{
|
{
|
||||||
'edition': 'teacher',
|
'license': TEACHER_LICENSE,
|
||||||
|
'isbn': TEACHER_ISBN,
|
||||||
'raw': {},
|
'raw': {},
|
||||||
'activated': self.now - timedelta(2*TEACHER_EDITION_DURATION),
|
'activated': self.now - timedelta(2*TEACHER_LICENSE['duration']),
|
||||||
'status': 'complete'
|
'status': 'complete'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'edition': 'teacher',
|
'license': TEACHER_LICENSE,
|
||||||
|
'isbn': TEACHER_ISBN,
|
||||||
'raw': {},
|
'raw': {},
|
||||||
'activated': self.now - timedelta(3 * TEACHER_EDITION_DURATION),
|
'activated': self.now - timedelta(3 * TEACHER_LICENSE['duration']),
|
||||||
'status': 'complete'
|
'status': 'complete'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'edition': 'teacher',
|
'license': TEACHER_LICENSE,
|
||||||
|
'isbn': TEACHER_ISBN,
|
||||||
'raw': {},
|
'raw': {},
|
||||||
'activated': self.now - timedelta(4 * TEACHER_EDITION_DURATION),
|
'activated': self.now - timedelta(4 * TEACHER_LICENSE['duration']),
|
||||||
'status': 'complete'
|
'status': 'complete'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
@ -38,7 +49,8 @@ class HepClientTestCases(TestCase):
|
||||||
def test_has_no_not_completed_product(self):
|
def test_has_no_not_completed_product(self):
|
||||||
products = [
|
products = [
|
||||||
{
|
{
|
||||||
'edition': 'teacher',
|
'license': TEACHER_LICENSE,
|
||||||
|
'isbn': TEACHER_ISBN,
|
||||||
'raw': {},
|
'raw': {},
|
||||||
'activated': self.now - timedelta(7),
|
'activated': self.now - timedelta(7),
|
||||||
'status': 'not'
|
'status': 'not'
|
||||||
|
|
@ -51,7 +63,8 @@ class HepClientTestCases(TestCase):
|
||||||
def test_has_valid_product(self):
|
def test_has_valid_product(self):
|
||||||
products = [
|
products = [
|
||||||
{
|
{
|
||||||
'edition': 'teacher',
|
'license': TEACHER_LICENSE,
|
||||||
|
'isbn': TEACHER_ISBN,
|
||||||
'raw': {
|
'raw': {
|
||||||
'id': 0
|
'id': 0
|
||||||
},
|
},
|
||||||
|
|
@ -59,19 +72,21 @@ class HepClientTestCases(TestCase):
|
||||||
'status': 'complete'
|
'status': 'complete'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'edition': 'teacher',
|
'license': TEACHER_LICENSE,
|
||||||
|
'isbn': TEACHER_ISBN,
|
||||||
'raw': {
|
'raw': {
|
||||||
'id': 1
|
'id': 1
|
||||||
},
|
},
|
||||||
'activated': self.now - timedelta(3 * TEACHER_EDITION_DURATION),
|
'activated': self.now - timedelta(3 * TEACHER_LICENSE['duration']),
|
||||||
'status': 'complete'
|
'status': 'complete'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'edition': 'teacher',
|
'license': TEACHER_LICENSE,
|
||||||
|
'isbn': TEACHER_ISBN,
|
||||||
'raw': {
|
'raw': {
|
||||||
'id': 2
|
'id': 2
|
||||||
},
|
},
|
||||||
'activated': self.now - timedelta(4 * TEACHER_EDITION_DURATION),
|
'activated': self.now - timedelta(4 * TEACHER_LICENSE['duration']),
|
||||||
'status': 'complete'
|
'status': 'complete'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
@ -82,7 +97,8 @@ class HepClientTestCases(TestCase):
|
||||||
def test_has_multiple_valid_teacher_products_but_only_one_active(self):
|
def test_has_multiple_valid_teacher_products_but_only_one_active(self):
|
||||||
products = [
|
products = [
|
||||||
{
|
{
|
||||||
'edition': 'teacher',
|
'license': TEACHER_LICENSE,
|
||||||
|
'isbn': TEACHER_ISBN,
|
||||||
'raw': {
|
'raw': {
|
||||||
'id': 0
|
'id': 0
|
||||||
},
|
},
|
||||||
|
|
@ -90,19 +106,21 @@ class HepClientTestCases(TestCase):
|
||||||
'status': 'complete'
|
'status': 'complete'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'edition': 'teacher',
|
'license': TEACHER_LICENSE,
|
||||||
|
'isbn': TEACHER_ISBN,
|
||||||
'raw': {
|
'raw': {
|
||||||
'id': 1
|
'id': 1
|
||||||
},
|
},
|
||||||
'activated': self.now - timedelta(3 * TEACHER_EDITION_DURATION),
|
'activated': self.now - timedelta(3 * TEACHER_LICENSE['duration']),
|
||||||
'status': 'complete'
|
'status': 'complete'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'edition': 'teacher',
|
'license': TEACHER_LICENSE,
|
||||||
|
'isbn': TEACHER_ISBN,
|
||||||
'raw': {
|
'raw': {
|
||||||
'id': 2
|
'id': 2
|
||||||
},
|
},
|
||||||
'activated': self.now - timedelta(4 * TEACHER_EDITION_DURATION),
|
'activated': self.now - timedelta(4 * TEACHER_LICENSE['duration']),
|
||||||
'status': 'complete'
|
'status': 'complete'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
@ -113,7 +131,8 @@ class HepClientTestCases(TestCase):
|
||||||
def test_has_valid_student_and_teacher_edition(self):
|
def test_has_valid_student_and_teacher_edition(self):
|
||||||
products = [
|
products = [
|
||||||
{
|
{
|
||||||
'edition': 'student',
|
'license': STUDENT_LICENSE,
|
||||||
|
'isbn': STUDENT_ISBN,
|
||||||
'raw': {
|
'raw': {
|
||||||
'id': 0
|
'id': 0
|
||||||
},
|
},
|
||||||
|
|
@ -121,7 +140,8 @@ class HepClientTestCases(TestCase):
|
||||||
'status': 'complete'
|
'status': 'complete'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'edition': 'teacher',
|
'license': TEACHER_LICENSE,
|
||||||
|
'isbn': TEACHER_ISBN,
|
||||||
'raw': {
|
'raw': {
|
||||||
'id': 1
|
'id': 1
|
||||||
},
|
},
|
||||||
|
|
@ -137,12 +157,12 @@ class HepClientTestCases(TestCase):
|
||||||
|
|
||||||
expiry_date = self.now + timedelta(3)
|
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)
|
self.assertTrue(is_active)
|
||||||
|
|
||||||
def test_product_is_not_active(self):
|
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)
|
self.assertFalse(is_active)
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,8 @@ class Command(BaseCommand):
|
||||||
|
|
||||||
if product and License.objects.filter(licensee=hep_user, order_id=product['order_id']).count() == 0:
|
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'],
|
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():
|
if license.is_valid():
|
||||||
hep_user.license_expiry_date = license.expire_date
|
hep_user.license_expiry_date = license.expire_date
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.contrib.auth.models import UserManager as DjangoUserManager
|
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):
|
class RoleManager(models.Manager):
|
||||||
|
|
@ -129,14 +129,14 @@ class UserManager(DjangoUserManager):
|
||||||
|
|
||||||
class LicenseManager(models.Manager):
|
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')
|
Role = apps.get_model('users', 'Role')
|
||||||
|
expiry_date = activation_date + timedelta(MYSKILLBOX_LICENSES[isbn]['duration'])
|
||||||
|
|
||||||
if role == 'teacher':
|
if role == 'teacher':
|
||||||
user_role = Role.objects.get_default_teacher_role()
|
user_role = Role.objects.get_default_teacher_role()
|
||||||
expiry_date = activation_date + timedelta(TEACHER_EDITION_DURATION)
|
|
||||||
else:
|
else:
|
||||||
user_role = Role.objects.get_default_student_role()
|
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 = self._create_license_for_role(licensee, expiry_date, raw, user_role, order_id)
|
||||||
new_license.licensee.license_expiry_date = new_license.expire_date
|
new_license.licensee.license_expiry_date = new_license.expire_date
|
||||||
|
|
|
||||||
|
|
@ -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),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -9,7 +9,7 @@ from django.core.exceptions import ObjectDoesNotExist
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import ugettext_lazy as _
|
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
|
from users.managers import RoleManager, UserRoleManager, UserManager, LicenseManager
|
||||||
|
|
||||||
DEFAULT_SCHOOL_ID = 1
|
DEFAULT_SCHOOL_ID = 1
|
||||||
|
|
@ -248,6 +248,8 @@ class License(models.Model):
|
||||||
expire_date = models.DateField(blank=False, null=True, )
|
expire_date = models.DateField(blank=False, null=True, )
|
||||||
order_id = models.IntegerField(blank=False, null=False, default=-1)
|
order_id = models.IntegerField(blank=False, null=False, default=-1)
|
||||||
raw = models.TextField(default='')
|
raw = models.TextField(default='')
|
||||||
|
isbn = models.CharField(max_length=50, blank=False, null=False,
|
||||||
|
default=list(MYSKILLBOX_LICENSES.keys())[0]) # student license
|
||||||
|
|
||||||
objects = LicenseManager()
|
objects = LicenseManager()
|
||||||
|
|
||||||
|
|
@ -256,8 +258,7 @@ class License(models.Model):
|
||||||
|
|
||||||
def is_valid(self):
|
def is_valid(self):
|
||||||
return HepClient.is_product_active(
|
return HepClient.is_product_active(
|
||||||
datetime(self.expire_date.year, self.expire_date.month, self.expire_date.day),
|
datetime(self.expire_date.year, self.expire_date.month, self.expire_date.day), self.isbn)
|
||||||
self.for_role.key)
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f'License for role: {self.for_role}'
|
return f'License for role: {self.for_role}'
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,8 @@ def check_and_create_licenses(hep_client, user):
|
||||||
|
|
||||||
if product:
|
if product:
|
||||||
license = License.objects.create_license_for_role(user, product['activated'], product['raw'],
|
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
|
# todo handle no license case
|
||||||
else:
|
else:
|
||||||
return None, NO_VALID_LICENSE
|
return None, NO_VALID_LICENSE
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue