From 1398f444bd26733be38064916f609e415299993d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=A6=D0=BE=D0=B9?= Date: Sun, 8 Dec 2024 10:24:15 +0900 Subject: [PATCH] pms_integrations branch init commit --- pms_integration/__init__.py | 0 pms_integration/admin.py | 3 ++ pms_integration/apps.py | 6 +++ pms_integration/manager.py | 53 ++++++++++++++++++++++++++ pms_integration/migrations/__init__.py | 0 pms_integration/models.py | 3 ++ pms_integration/plugins/__init__.py | 0 pms_integration/plugins/base_plugin.py | 27 +++++++++++++ pms_integration/plugins/bnovo_pms.py | 31 +++++++++++++++ pms_integration/plugins/ecvi_pms.py | 0 pms_integration/plugins/shelter_pms.py | 31 +++++++++++++++ pms_integration/tests.py | 3 ++ pms_integration/views.py | 3 ++ touchh/settings.py | 1 + 14 files changed, 161 insertions(+) create mode 100644 pms_integration/__init__.py create mode 100644 pms_integration/admin.py create mode 100644 pms_integration/apps.py create mode 100644 pms_integration/manager.py create mode 100644 pms_integration/migrations/__init__.py create mode 100644 pms_integration/models.py create mode 100644 pms_integration/plugins/__init__.py create mode 100644 pms_integration/plugins/base_plugin.py create mode 100644 pms_integration/plugins/bnovo_pms.py create mode 100644 pms_integration/plugins/ecvi_pms.py create mode 100644 pms_integration/plugins/shelter_pms.py create mode 100644 pms_integration/tests.py create mode 100644 pms_integration/views.py diff --git a/pms_integration/__init__.py b/pms_integration/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pms_integration/admin.py b/pms_integration/admin.py new file mode 100644 index 00000000..8c38f3f3 --- /dev/null +++ b/pms_integration/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/pms_integration/apps.py b/pms_integration/apps.py new file mode 100644 index 00000000..329cfc61 --- /dev/null +++ b/pms_integration/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class PmsIntegrationConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'pms_integration' diff --git a/pms_integration/manager.py b/pms_integration/manager.py new file mode 100644 index 00000000..c527e8d0 --- /dev/null +++ b/pms_integration/manager.py @@ -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="Данные успешно обновлены." + ) diff --git a/pms_integration/migrations/__init__.py b/pms_integration/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pms_integration/models.py b/pms_integration/models.py new file mode 100644 index 00000000..71a83623 --- /dev/null +++ b/pms_integration/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/pms_integration/plugins/__init__.py b/pms_integration/plugins/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pms_integration/plugins/base_plugin.py b/pms_integration/plugins/base_plugin.py new file mode 100644 index 00000000..dce554bd --- /dev/null +++ b/pms_integration/plugins/base_plugin.py @@ -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 diff --git a/pms_integration/plugins/bnovo_pms.py b/pms_integration/plugins/bnovo_pms.py new file mode 100644 index 00000000..7b2d6dc6 --- /dev/null +++ b/pms_integration/plugins/bnovo_pms.py @@ -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 + ] diff --git a/pms_integration/plugins/ecvi_pms.py b/pms_integration/plugins/ecvi_pms.py new file mode 100644 index 00000000..e69de29b diff --git a/pms_integration/plugins/shelter_pms.py b/pms_integration/plugins/shelter_pms.py new file mode 100644 index 00000000..728de7ac --- /dev/null +++ b/pms_integration/plugins/shelter_pms.py @@ -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 + ] diff --git a/pms_integration/tests.py b/pms_integration/tests.py new file mode 100644 index 00000000..7ce503c2 --- /dev/null +++ b/pms_integration/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/pms_integration/views.py b/pms_integration/views.py new file mode 100644 index 00000000..91ea44a2 --- /dev/null +++ b/pms_integration/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/touchh/settings.py b/touchh/settings.py index 69ed46dc..75518734 100644 --- a/touchh/settings.py +++ b/touchh/settings.py @@ -43,6 +43,7 @@ INSTALLED_APPS = [ 'bot', 'hotels', 'users', + 'pms_integration' ] MIDDLEWARE = [