142 lines
5.2 KiB
Python
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 {}
|