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