222 lines
7.2 KiB
Python
222 lines
7.2 KiB
Python
from django.utils.dateparse import parse_datetime
|
|
from datetime import timedelta
|
|
|
|
from django.conf import settings
|
|
import logging
|
|
import requests
|
|
|
|
from oauth.oauth_client import oauth
|
|
from users.licenses import MYSKILLBOX_LICENSES, is_myskillbox_product, TEACHER_KEY
|
|
from users.models import License
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
class HepClientException(Exception):
|
|
pass
|
|
|
|
|
|
class HepClientUnauthorizedException(Exception):
|
|
pass
|
|
|
|
|
|
class HepClientNoTokenException(Exception):
|
|
pass
|
|
|
|
|
|
class HepClient:
|
|
URL = settings.HEP_URL
|
|
HEADERS = {
|
|
'accept': 'application/json',
|
|
'content-type': 'application/json'
|
|
}
|
|
|
|
def _call(self, url, request, token, method='get', data=None):
|
|
|
|
request_url = f'{self.URL}{url}'
|
|
|
|
token_parameters = {
|
|
'token': token,
|
|
'request': request
|
|
}
|
|
|
|
if method == 'post':
|
|
response = requests.post(request_url, json=data)
|
|
elif method == 'get':
|
|
response = oauth.hep.get(url, params=data, **token_parameters)
|
|
elif method == 'put':
|
|
response = requests.put(request_url, data=data)
|
|
|
|
# Todo handle 401 and most important network errors
|
|
if response.status_code == 401:
|
|
raise HepClientUnauthorizedException(response.status_code, response.json())
|
|
elif response.status_code != 200:
|
|
raise HepClientException(response.status_code, response.json())
|
|
|
|
return response
|
|
|
|
def is_email_verified(self, user_data):
|
|
return user_data['email_verified_at'] is not None
|
|
|
|
def user_details(self, request=None, token=None):
|
|
self._has_credentials(request, token)
|
|
response = self._call('api/auth/user', request, token)
|
|
return response.json()['data']
|
|
|
|
def fetch_eorders(self, request=None, token=None):
|
|
|
|
# self._has_credentials(request, token)
|
|
# data = {
|
|
# 'filters[product_type]': 'eLehrmittel',
|
|
# }
|
|
# response = self._call('api/partners/users/orders/search', request, token, data=data)
|
|
# return response.json()['data']
|
|
|
|
return [
|
|
{
|
|
"id": 5,
|
|
"status": "paid",
|
|
"order_total": 10000,
|
|
"created_at": "2021-05-10T20:52:16.000000Z",
|
|
"billing_address": {
|
|
"id": 20,
|
|
"salutation": "male",
|
|
"first_name": "Hans",
|
|
"last_name": "Meier",
|
|
"company": "Lustig GmbH",
|
|
"street": "Sulgenrain 12890",
|
|
"city": "Bern",
|
|
"post_code": "3007",
|
|
"country": "Schweiz"
|
|
},
|
|
"delivery_address": {
|
|
"id": 19,
|
|
"salutation": "male",
|
|
"first_name": "Hans",
|
|
"last_name": "Muster",
|
|
"company": "Muster AG",
|
|
"street": "Ruderweg 24",
|
|
"city": "Bern",
|
|
"post_code": "3000",
|
|
"country": "Schweiz"
|
|
},
|
|
"entries": [
|
|
{
|
|
"id": 3433,
|
|
"uri": "\/products\/myskillbox-lernende",
|
|
"url": None,
|
|
"title": "mySkillbox für Lernende ",
|
|
"subtitle": "Lizenz gültig für 4 Jahre",
|
|
"isbn": "978-3-0355-1397-4",
|
|
"slug": "myskillbox-lernende",
|
|
"product_type": "eLehrmittel",
|
|
"product_form": "",
|
|
"cover": "https:\/\/hep-verlag.fra1.digitaloceanspaces.com\/staging\/products\/2921\/978-3-0355-1397-4.jpg",
|
|
"price": 100,
|
|
"price_total": 100,
|
|
"amount": 1,
|
|
"authors": []
|
|
}
|
|
]
|
|
}
|
|
]
|
|
|
|
def active_myskillbox_product_for_customer(self, request=None, token=None):
|
|
eorders = self.fetch_eorders(request=request, token=token)
|
|
myskillbox_products = self._extract_myskillbox_products(eorders)
|
|
|
|
if len(myskillbox_products) == 0:
|
|
return None
|
|
else:
|
|
return self._get_active_product(myskillbox_products)
|
|
|
|
def _has_credentials(self, request, token):
|
|
if request is None and token is None:
|
|
raise HepClientNoTokenException
|
|
|
|
def coupon_redeem(self, coupon, customer_id):
|
|
try:
|
|
response = self._call(f'/rest/deutsch/V1/coupon/{coupon}/customer/{customer_id}', method='put')
|
|
except HepClientException:
|
|
return None
|
|
|
|
response_data = response.json()
|
|
if response_data[0] == '201':
|
|
return None
|
|
|
|
return response_data[0]
|
|
|
|
def myskillbox_product_for_customer(self, admin_token, customer_id):
|
|
orders = self._customer_orders(admin_token, customer_id)
|
|
products = self._extract_myskillbox_products(orders)
|
|
|
|
if len(products) == 0:
|
|
return None
|
|
else:
|
|
return self._get_relevant_product(products)
|
|
|
|
def _extract_myskillbox_products(self, eorders):
|
|
products = []
|
|
|
|
for eorder in eorders:
|
|
|
|
status = ''
|
|
if 'status' in eorder:
|
|
status = eorder['status']
|
|
|
|
for entry in eorder['entries']:
|
|
if is_myskillbox_product(entry['isbn']):
|
|
product = {
|
|
'raw': entry,
|
|
'activated': self._get_item_activation(eorder),
|
|
'status': status,
|
|
'order_id': entry['id'],
|
|
'license': MYSKILLBOX_LICENSES[entry['isbn']],
|
|
'isbn': entry['isbn']
|
|
}
|
|
|
|
products.append(product)
|
|
|
|
return products
|
|
|
|
def _get_item_activation(self, eorder):
|
|
if 'created_at' in eorder:
|
|
return parse_datetime(eorder['created_at'])
|
|
|
|
def _get_active_product(self, products):
|
|
|
|
def filter_valid_products(product):
|
|
|
|
if product['status'] != 'paid':
|
|
return False
|
|
|
|
expiry_delta = product['activated'] + timedelta(product['license']['duration'])
|
|
|
|
if License.is_product_active(expiry_delta, product['isbn']):
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
active_products = list(filter(filter_valid_products, products))
|
|
|
|
if len(active_products) == 0:
|
|
return None
|
|
elif len(active_products) == 1:
|
|
return active_products[0]
|
|
else:
|
|
return self._select_from_teacher_products(active_products)
|
|
|
|
def _select_from_teacher_products(self, active_products):
|
|
teacher_edition = None
|
|
|
|
# select first teacher product, as they are all valid it does not matter which one
|
|
for product in active_products:
|
|
if product['license']['edition'] == TEACHER_KEY:
|
|
teacher_edition = product
|
|
break
|
|
|
|
# select a student product, as they are all valid it does not matter which one
|
|
if not teacher_edition:
|
|
return active_products[0]
|
|
|
|
return teacher_edition
|