117 lines
4.7 KiB
Python
117 lines
4.7 KiB
Python
import logging
|
||
import requests
|
||
from datetime import datetime
|
||
from .base_plugin import BasePMSPlugin
|
||
|
||
class TravelLinePMSPlugin(BasePMSPlugin):
|
||
"""
|
||
Плагин для интеграции с PMS TravelLine.
|
||
"""
|
||
BASE_URL = "https://partner.tlintegration.com/api/webpms/v1"
|
||
|
||
def __init__(self, pms_config):
|
||
"""
|
||
Инициализация плагина с конфигурацией PMS.
|
||
|
||
:param pms_config: Конфигурация PMS (объект PMSConfiguration).
|
||
"""
|
||
super().__init__(pms_config)
|
||
self.api_key = pms_config.token
|
||
self.logger = logging.getLogger(self.__class__.__name__)
|
||
|
||
def _get_headers(self):
|
||
"""
|
||
Возвращает заголовки для запросов.
|
||
"""
|
||
return {
|
||
"Authorization": f"Bearer {self.api_key}",
|
||
"Content-Type": "application/json"
|
||
}
|
||
|
||
def _fetch_data(self):
|
||
"""
|
||
Получение данных из API TravelLine (поиск бронирований).
|
||
|
||
:return: Список номеров бронирований.
|
||
"""
|
||
url = f"{self.BASE_URL}/bookings"
|
||
params = {
|
||
"roomId": self.pms_config.room_id,
|
||
"modifiedFrom": self.pms_config.modified_from,
|
||
"modifiedTo": self.pms_config.modified_to,
|
||
"state": self.pms_config.state,
|
||
"affectsPeriodFrom": self.pms_config.affects_period_from,
|
||
"affectsPeriodTo": self.pms_config.affects_period_to,
|
||
}
|
||
params = {k: v for k, v in params.items() if v is not None}
|
||
|
||
try:
|
||
response = requests.get(url, headers=self._get_headers(), params=params)
|
||
response.raise_for_status()
|
||
self.logger.info("Данные успешно получены из API TravelLine.")
|
||
return response.json().get("bookingNumbers", [])
|
||
except requests.RequestException as e:
|
||
self.logger.error(f"Ошибка при запросе к API TravelLine: {e}")
|
||
return []
|
||
|
||
def fetch_data(self):
|
||
"""
|
||
Обертка для получения данных из API TravelLine с дополнительной обработкой.
|
||
|
||
:return: Список номеров бронирований.
|
||
"""
|
||
return self._fetch_data()
|
||
|
||
def get_default_parser_settings(self):
|
||
"""
|
||
Возвращает настройки парсера по умолчанию.
|
||
"""
|
||
return {
|
||
"field_mapping": {
|
||
"reservation_id": "bookingNumber",
|
||
"check_in": "actualCheckInDateTime",
|
||
"check_out": "actualCheckOutDateTime",
|
||
"room_number": "roomId",
|
||
"status": "state",
|
||
},
|
||
"date_format": "%Y-%m-%dT%H:%M"
|
||
}
|
||
|
||
def process_data(self, booking_number, room_stay_id, action, actual_date_time):
|
||
"""
|
||
Обработка данных для заселения или выселения проживания.
|
||
|
||
:param booking_number: Номер бронирования.
|
||
:param room_stay_id: Идентификатор проживания.
|
||
:param action: Действие ("check-in" или "check-out").
|
||
:param actual_date_time: Фактические дата и время.
|
||
:return: Ответ API.
|
||
"""
|
||
if action not in ["check-in", "check-out"]:
|
||
raise ValueError("Invalid action. Must be 'check-in' or 'check-out'.")
|
||
|
||
url = f"{self.BASE_URL}/bookings/{booking_number}/room-stays/{room_stay_id}/{action}"
|
||
payload = {
|
||
f"actual{action.capitalize()}DateTime": actual_date_time
|
||
}
|
||
|
||
try:
|
||
response = requests.post(url, headers=self._get_headers(), json=payload)
|
||
response.raise_for_status()
|
||
self.logger.info(f"Успешно выполнено действие '{action}' для бронирования {booking_number}.")
|
||
return response.json()
|
||
except requests.RequestException as e:
|
||
self.logger.error(f"Ошибка при выполнении действия '{action}': {e}")
|
||
return {}
|
||
|
||
def validate_plugin(self):
|
||
"""
|
||
Проверка плагина на соответствие требованиям.
|
||
"""
|
||
required_methods = ["fetch_data", "get_default_parser_settings", "_fetch_data"]
|
||
for method in required_methods:
|
||
if not hasattr(self, method):
|
||
raise ValueError(f"Плагин {type(self).__name__} не реализует метод {method}.")
|
||
self.logger.info(f"Плагин {self.__class__.__name__} успешно прошел валидацию.")
|
||
return True
|