pms_integrations branch init commit
This commit is contained in:
0
pms_integration/__init__.py
Normal file
0
pms_integration/__init__.py
Normal file
3
pms_integration/admin.py
Normal file
3
pms_integration/admin.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
||||||
6
pms_integration/apps.py
Normal file
6
pms_integration/apps.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class PmsIntegrationConfig(AppConfig):
|
||||||
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
|
name = 'pms_integration'
|
||||||
53
pms_integration/manager.py
Normal file
53
pms_integration/manager.py
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# pms_integration/manager.py
|
||||||
|
|
||||||
|
import importlib
|
||||||
|
from hotels.models import Hotel, PMSIntegrationLog, Reservation
|
||||||
|
from asgiref.sync import sync_to_async
|
||||||
|
|
||||||
|
class PMSIntegrationManager:
|
||||||
|
"""Универсальный менеджер интеграции с PMS."""
|
||||||
|
|
||||||
|
def __init__(self, hotel_id):
|
||||||
|
self.hotel_id = hotel_id
|
||||||
|
self.hotel = None
|
||||||
|
self.plugin = None
|
||||||
|
|
||||||
|
async def load_hotel_data(self):
|
||||||
|
"""Загружает данные отеля и инициализирует соответствующий плагин."""
|
||||||
|
self.hotel = await sync_to_async(Hotel.objects.get)(id=self.hotel_id)
|
||||||
|
pms_system = self.hotel.pms
|
||||||
|
|
||||||
|
if not pms_system:
|
||||||
|
raise ValueError("PMS система не настроена для отеля.")
|
||||||
|
|
||||||
|
plugin_module = f"pms_integration.plugins.{pms_system.name.lower()}_pms"
|
||||||
|
try:
|
||||||
|
plugin_class = getattr(importlib.import_module(plugin_module), f"{pms_system.name.capitalize()}PMSPlugin")
|
||||||
|
self.plugin = plugin_class(self.hotel.api)
|
||||||
|
except (ImportError, AttributeError) as e:
|
||||||
|
raise ValueError(f"Плагин для PMS '{pms_system.name}' не найден: {e}")
|
||||||
|
|
||||||
|
async def fetch_and_save_data(self):
|
||||||
|
"""Получение данных от PMS и их сохранение."""
|
||||||
|
raw_data = self.plugin.fetch_data()
|
||||||
|
parsed_data = self.plugin.parse_data(raw_data)
|
||||||
|
|
||||||
|
# Сохраняем данные в БД
|
||||||
|
for res in parsed_data:
|
||||||
|
await sync_to_async(Reservation.objects.update_or_create)(
|
||||||
|
reservation_id=res["id"],
|
||||||
|
defaults={
|
||||||
|
"hotel": self.hotel,
|
||||||
|
"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"),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
# Логируем успех
|
||||||
|
await sync_to_async(PMSIntegrationLog.objects.create)(
|
||||||
|
hotel=self.hotel, status="success", message="Данные успешно обновлены."
|
||||||
|
)
|
||||||
0
pms_integration/migrations/__init__.py
Normal file
0
pms_integration/migrations/__init__.py
Normal file
3
pms_integration/models.py
Normal file
3
pms_integration/models.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
# Create your models here.
|
||||||
0
pms_integration/plugins/__init__.py
Normal file
0
pms_integration/plugins/__init__.py
Normal file
27
pms_integration/plugins/base_plugin.py
Normal file
27
pms_integration/plugins/base_plugin.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# pms_integration/plugins/base_plugin.py
|
||||||
|
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
class BasePMSPlugin(ABC):
|
||||||
|
"""Базовый класс для всех плагинов PMS интеграции."""
|
||||||
|
|
||||||
|
def __init__(self, api_config):
|
||||||
|
"""
|
||||||
|
Конструктор плагина.
|
||||||
|
:param api_config: Конфигурация API (объект модели APIConfiguration).
|
||||||
|
"""
|
||||||
|
self.api_config = api_config
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def fetch_data(self):
|
||||||
|
"""
|
||||||
|
Метод для получения данных от PMS.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def parse_data(self, raw_data):
|
||||||
|
"""
|
||||||
|
Метод для обработки сырых данных от PMS.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
31
pms_integration/plugins/bnovo_pms.py
Normal file
31
pms_integration/plugins/bnovo_pms.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# pms_integration/plugins/example_pms.py
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from .base_plugin import BasePMSPlugin
|
||||||
|
|
||||||
|
class ExamplePMSPlugin(BasePMSPlugin):
|
||||||
|
"""Плагин для интеграции с Example PMS."""
|
||||||
|
|
||||||
|
def fetch_data(self):
|
||||||
|
"""Получение данных от Example 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()
|
||||||
|
|
||||||
|
def parse_data(self, raw_data):
|
||||||
|
"""Обработка данных от Example 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"),
|
||||||
|
}
|
||||||
|
for res in reservations
|
||||||
|
]
|
||||||
0
pms_integration/plugins/ecvi_pms.py
Normal file
0
pms_integration/plugins/ecvi_pms.py
Normal file
31
pms_integration/plugins/shelter_pms.py
Normal file
31
pms_integration/plugins/shelter_pms.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# pms_integration/plugins/shelter_pms.py
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from .base_plugin import BasePMSPlugin
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
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"),
|
||||||
|
}
|
||||||
|
for res in reservations
|
||||||
|
]
|
||||||
3
pms_integration/tests.py
Normal file
3
pms_integration/tests.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
||||||
3
pms_integration/views.py
Normal file
3
pms_integration/views.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
# Create your views here.
|
||||||
@@ -43,6 +43,7 @@ INSTALLED_APPS = [
|
|||||||
'bot',
|
'bot',
|
||||||
'hotels',
|
'hotels',
|
||||||
'users',
|
'users',
|
||||||
|
'pms_integration'
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
|
|||||||
Reference in New Issue
Block a user