Shelter PMS fully functional

This commit is contained in:
2024-12-09 16:36:11 +09:00
parent 60eaef5527
commit e76a80fb2f
47 changed files with 665 additions and 909 deletions

View File

@@ -1,31 +1,100 @@
# pms_integration/plugins/shelter_pms.py
import requests
import json
from datetime import datetime, timedelta
from asgiref.sync import sync_to_async
from .base_plugin import BasePMSPlugin
from hotels.models import Reservation
from hotels.models import Hotel
class ShelterPMSPlugin(BasePMSPlugin):
"""Плагин для интеграции с Shelter PMS."""
def fetch_data(self):
"""Получение данных от Shelter PMS."""
url = self.api_config.url
headers = {"Authorization": f"Bearer {self.api_config.token}"}
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
return response.json()
class Shelter(BasePMSPlugin):
def __init__(self, config):
super().__init__(config)
self.token = config.token
def parse_data(self, raw_data):
"""Обработка данных от Shelter PMS."""
reservations = raw_data.get("reservations", [])
return [
{
"id": res["id"],
"room_number": res["room_number"],
"room_type": res["room_type"],
"check_in": res["check_in"],
"check_out": res["check_out"],
"status": res["status"],
"price": res.get("price"),
def get_default_parser_settings(self):
"""
Возвращает настройки по умолчанию для обработки данных.
"""
return {
"date_format": "%Y-%m-%dT%H:%M:%S",
"timezone": "UTC"
}
def _fetch_data(self):
"""
Выполняет запрос к API PMS для получения данных.
"""
url = 'https://pms.frontdesk24.ru/sheltercloudapi/Reservations/ByFilter'
headers = {
'accept': 'text/plain',
'Authorization': f'Bearer {self.token}',
'Content-Type': 'application/json',
}
from_index = 0
count_per_request = 50
total_count = None
all_items = []
now = datetime.now()
start_date = (now - timedelta(days=60)).strftime('%Y-%m-%dT%H:%M:%SZ')
end_date = (now + timedelta(days=60)).strftime('%Y-%m-%dT%H:%M:%SZ')
while total_count is None or from_index < total_count:
data = {
"from": start_date,
"until": end_date,
"pagination": {
"from": from_index,
"count": count_per_request
}
}
for res in reservations
]
response = requests.post(url, headers=headers, data=json.dumps(data))
if response.status_code == 200:
response_data = response.json()
items = response_data.get("items", [])
all_items.extend(items)
if total_count is None:
total_count = response_data.get("count", 0)
from_index += len(items)
else:
raise ValueError(f'Shelter API Error: {response.status_code}')
return all_items
async def _save_to_db(self, data, hotel_id):
"""
Сохраняет данные о бронированиях в таблицу Reservation.
:param data: Список данных о бронированиях.
:param hotel_id: ID отеля, к которому относятся бронирования.
"""
hotel = await sync_to_async(Hotel.objects.get)(id=hotel_id)
for item in data:
print(f"Данные для сохранения: {item}")
try:
reservation, created = await sync_to_async(Reservation.objects.update_or_create)(
reservation_id=item["id"],
hotel=hotel,
defaults={
"room_number": item.get("roomNumber", ""), # Номер комнаты
"room_type": item.get("roomTypeName", ""), # Тип комнаты
"check_in": datetime.strptime(item["from"], '%Y-%m-%dT%H:%M:%S'), # Дата заезда
"check_out": datetime.strptime(item["until"], '%Y-%m-%dT%H:%M:%S'), # Дата выезда
"status": item.get("checkInStatus", ""), # Статус бронирования
"price": item.get("reservationPrice", 0), # Цена
"discount": item.get("discount", 0), # Скидка
}
)
if created:
print(f"Создана запись: {reservation}")
else:
print(f"Обновлена запись: {reservation}")
except Exception as e:
print(f"Ошибка при сохранении бронирования ID {item['id']}: {e}")