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: def _call(self, url, request, token, method='get', data=None): token_parameters = { 'token': token, 'request': request } if method == 'post': response = oauth.hep.post(url, json=data, **token_parameters) elif method == 'get': response = oauth.hep.get(url, params=data, **token_parameters) elif method == 'put': response = oauth.hep.put(url, data=data, **token_parameters) 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 logout(self, request=None, token=None): self._has_credentials(request, token) self._call('api/auth/logout', request, token, method='post') return True 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 redeem_coupon(self, coupon_code, customer_id, request=None, token=None): self._has_credentials(request, token) try: response = self._call(f'api/partners/users/{customer_id}/coupons/redeem', request, token, method='post', data={'code': coupon_code}) except HepClientException: return None response_data = response.json() # todo handle 404, 402 return response_data def _extract_myskillbox_products(self, eorders): products = [] for eorder in eorders: status = eorder.get('status', '') for entry in eorder['entries']: product = self.entry_to_product(entry, self._get_item_activation(eorder), status) if product: products.append(product) return products def entry_to_product(self, entry, activation_date, status): if is_myskillbox_product(entry['isbn']) and activation_date: return { 'raw': entry, 'activated': activation_date, 'status': status, 'order_id': entry['id'], 'license': MYSKILLBOX_LICENSES[entry['isbn']], 'isbn': entry['isbn'] } return None def _get_item_activation(self, eorder): if 'created_at' in eorder: return parse_datetime(eorder['created_at']) else: return None def _get_active_product(self, products): def filter_valid_products(product): if product['status'] not in ['paid', 'new']: return False expiry_delta = product['activated'] + timedelta(product['license']['duration']) return License.is_product_active(expiry_delta, product['isbn']) 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): # 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: return product # select a student product, as they are all valid it does not matter which one return active_products[0]