gault-millau/apps/booking/models/services.py
2019-10-01 18:25:57 +03:00

142 lines
5.2 KiB
Python

from abc import ABC, abstractmethod
import json
import requests
from django.conf import settings
from rest_framework import status
import booking.models.models as models
from rest_framework import serializers
class AbstractBookingService(ABC):
""" Abstract class for Guestonline && Lastable booking services"""
def __init__(self, service):
self.service = None
self.response = None
if service not in [models.Booking.LASTABLE, models.Booking.GUESTONLINE]:
raise Exception('Service %s is not implemented yet' % service)
self.service = service
if service == models.Booking.GUESTONLINE:
self.token = settings.GUESTONLINE_TOKEN
self.url = settings.GUESTONLINE_SERVICE
elif service == models.Booking.LASTABLE:
self.token = settings.LASTABLE_TOKEN
self.url = settings.LASTABLE_SERVICE
@staticmethod
def get_certain_keys(d: dict, keys_to_preserve: set) -> dict:
""" Helper """
return {key: d[key] for key in d.keys() & keys_to_preserve}
@abstractmethod
def check_whether_booking_available(self, restaurant_id, date):
""" checks whether booking is available """
pass
@abstractmethod
def cancel_booking(self, payload):
""" cancels booking and returns the result """
pass
@abstractmethod
def create_pending_booking(self, payload):
""" returns pending booking id if created. otherwise False """
pass
@abstractmethod
def update_pending_booking(self, payload):
""" updates pending booking with contacts """
pass
@abstractmethod
def get_common_headers(self):
pass
@abstractmethod
def get_booking_details(self, payload):
""" fetches booking details from external service """
pass
class GuestonlineService(AbstractBookingService):
def __init__(self):
super().__init__(models.Booking.GUESTONLINE)
def get_common_headers(self):
return {'X-Token': self.token, 'Content-type': 'application/json', 'Accept': 'application/json'}
def check_whether_booking_available(self, restaurant_id, date: str):
url = f'{self.url}v1/runtime_services'
params = {'restaurant_id': restaurant_id, 'date': date, 'expands[]': 'table_availabilities'}
r = requests.get(url, headers=self.get_common_headers(), params=params)
if not status.is_success(r.status_code):
return False
response = json.loads(r.content)['runtime_services']
keys_to_preserve = {'left_seats', 'table_availabilities', 'closed', 'start_time', 'end_time', 'last_booking'}
response = map(lambda x: self.get_certain_keys(x, keys_to_preserve), response)
self.response = response
return True
def commit_booking(self, payload):
url = self.url + 'v1/pending_bookings/' + payload + '/commit'
r = requests.put(url, headers=self.get_common_headers())
self.response = json.loads(r.content)
if status.is_success(r.status_code) and self.response is None:
raise serializers.ValidationError(detail='Booking already committed.')
return status.is_success(r.status_code)
def update_pending_booking(self, payload):
booking_id = payload.pop('pending_booking_id')
url = self.url + 'v1/pending_bookings/' + booking_id
payload['lastname'] = payload.pop('last_name')
payload['firstname'] = payload.pop('first_name')
payload['mobile_phone'] = payload.pop('phone')
headers = self.get_common_headers()
r = requests.put(url, headers=headers, data=json.dumps({'contact_info': payload}))
return status.is_success(r.status_code)
def create_pending_booking(self, payload):
url = self.url + 'v1/pending_bookings'
payload['hour'] = payload.pop('booking_time')
payload['persons'] = payload.pop('booked_persons_number')
payload['date'] = payload.pop('booking_date')
r = requests.post(url, headers=self.get_common_headers(), data=json.dumps(payload))
return json.loads(r.content)['id'] if status.is_success(r.status_code) else False
def cancel_booking(self, payload):
url = f'{self.url}v1/pending_bookings/{payload}'
r = requests.delete(url, headers=self.get_common_headers())
return status.is_success(r.status_code)
def get_booking_details(self, payload):
url = f'{self.url}v1/bookings/{payload}'
r = requests.get(url, headers=self.get_common_headers())
return json.loads(r.content)
class LastableService(AbstractBookingService):
def __init__(self):
super().__init__(models.Booking.LASTABLE)
def create_pending_booking(self, payload):
pass
def get_common_headers(self):
return {'Authorization': f'Bearer {self.token}', 'Content-type': 'application/json',
'Accept': 'application/json'}
def check_whether_booking_available(self, restaurant_id, date):
return False
def commit_booking(self, payload):
return False
def update_pending_booking(self, payload):
return False
def cancel_booking(self, payload):
return False
def get_booking_details(self, payload):
return {}