# Проект управления отелями ## Описание Проект для управления отелями, пользователями, интеграциями с PMS, а также для контроля статистики и уведомлений. Включает веб-админку, REST API для управления данными и Telegram-бота для взаимодействия с пользователями. ## Стек технологий - Django (для бэкенда) - Jazzmin (для кастомизации админки) - MySQL (для хранения данных) - python-telegram-bot (для Telegram-бота) - Docker (для контейнеризации базы данных и проекта) ## Установка ### 1. Клонирование репозитория ```bash git clone cd yourrepository ```` ### 2. Установка зависимостей ```bash python -m venv .venv source .venv/bin/activate # Для Linux/MacOS .venv\Scripts\activate # Для Windows pip install -r requirements.txt ``` ### 3. Настройка базы данных MySQL #### 3.1. Запуск контейнера с MySQL Используем Docker для поднятия MySQL контейнера: ``` bash docker-compose up -d mysql ``` #### 3.2. Создание базы данных и пользователя После поднятия контейнера с MySQL, создайте базу данных и пользователя: ### 3.2. Настройка базы данных После поднятия контейнера с MySQL, создайте таблицы и загрузите дамп: ``` docker exec -it mysql_container bash mysql -u root -p ``` Введите пароль от MySQL, а затем загрузите ваш дамп: ```bash mysql -u root -p your_database_name < /path/to/your_dump.sql ``` ### 3.3. Применение миграций После настройки базы данных выполните миграции для вашего Django-проекта: ```bash python manage.py migrate ``` ### 4. Настройка админки Для настройки админки с использованием Dazzling и Jazzmin, добавьте соответствующие настройки в settings.py: ```python INSTALLED_APPS = [ 'dazzle', 'jazzmin', ... ] JAZZMIN_SETTINGS = { "site_title": "My Admin", "site_header": "My Administration", "site_brand": "My Brand", "footer": { "copyright": False, "version": False, }, } ``` ### 5. Запуск проекта Запустите сервер Django: ```bash python manage.py runserver ``` Теперь проект будет доступен по адресу http://127.0.0.1:8000. ##### Структура проекта hotel_manager/ — основная директория проекта. hotel_manager/settings.py — настройки Django. hotel_manager/models.py — модели данных для отелей, пользователей и статистики. hotel_manager/views.py — представления для работы с данными. hotel_manager/urls.py — маршруты проекта. bot/ — директория для бота, использующего python-telegram-bot. ##### Модели Отель (Hotel) Название отеля ID отеля PMS (Bnovo, Travel Line, Realty) Статус интеграции с PMS Пользователь (User) Имя пользователя Роль (Admin или Hotel User) Связь с отелем Настройки уведомлений (Notification Settings) Включено/выключено уведомление Часовой пояс Время отправки уведомлений Статистика (Statistics) Количество несанкционированных заселений за период Статус ошибок Даты и номера нарушений ##### API Администратор: Добавить/удалить отель Добавить/удалить пользователя Проверка статуса интеграции с PMS Управление уведомлениями Пользователь отеля: Получение статистики по заселениям Управление уведомлениями ##### Интеграция с Telegram-ботом Бот для администраторов позволяет управлять отелями, пользователями, уведомлениями и проверять статус интеграций. Бот для пользователей отелей позволяет получать статистику по заселениям и управлять уведомлениями. ##### Пример команды для администратора Добавить отель Список отелей Удалить отель Проверить статус PMS ##### Пример команды для пользователя отеля Показать статистику за вчера Управление уведомлениями #### Проверка интеграции с PMS Для каждого отеля можно проверять статус интеграции с PMS (Bnovo, Travel Line, Realty) и получать ответ о доступности PMS. #### Разработка плагинов для интеграции с PMS Для разработки плагина используются следующие инструменты: - Django - Python - Pydantic *код примера для плагина* ```python from datetime import datetime, timedelta import requests from asgiref.sync import sync_to_async from hotels.models import Reservation from .base_plugin import BasePMSPlugin import logging class ExamplePMSPlugin(BasePMSPlugin): """ Плагин для интеграции с PMS Example. """ def __init__(self, hotel): super().__init__(hotel.pms) self.hotel = hotel self.api_url = self.hotel.pms.url self.token = self.hotel.pms.token self.logger = self._configure_logger() def _configure_logger(self): logger = logging.getLogger(self.__class__.__name__) handler_console = logging.StreamHandler() handler_file = logging.FileHandler(f'{self.__class__.__name__.lower()}.log') formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') handler_console.setFormatter(formatter) handler_file.setFormatter(formatter) logger.addHandler(handler_console) logger.addHandler(handler_file) logger.setLevel(logging.DEBUG) return logger def get_default_parser_settings(self): """ Возвращает настройки для обработки данных. """ return { "field_mapping": { "check_in": "arrival_date", "check_out": "departure_date", "room_number": "room", "status": "status", }, "date_format": "%Y-%m-%d %H:%M:%S" } async def _fetch_data(self): """ Получает данные из API Example PMS. """ headers = { "Authorization": f"Bearer {self.token}", "Content-Type": "application/json", } now = datetime.now() payload = { "from_date": (now - timedelta(days=7)).strftime("%Y-%m-%d"), "to_date": now.strftime("%Y-%m-%d"), } try: response = await sync_to_async(requests.post)( self.api_url, json=payload, headers=headers ) response.raise_for_status() data = response.json() return await self._process_data(data) except requests.exceptions.RequestException as e: self.logger.error(f"Ошибка API: {e}") return {"processed_items": 0, "errors": [str(e)]} async def _process_data(self, data): """ Обрабатывает и сохраняет данные в базу. """ processed_items = 0 errors = [] for item in data.get("bookings", []): try: reservation, created = await sync_to_async(Reservation.objects.update_or_create)( reservation_id=item['id'], defaults={ 'room_number': item['room'], 'check_in': datetime.strptime(item['arrival_date'], "%Y-%m-%d"), 'check_out': datetime.strptime(item['departure_date'], "%Y-%m-%d"), 'status': item['status'], 'hotel': self.hotel, } ) processed_items += 1 except Exception as e: self.logger.error(f"Ошибка обработки записи {item['id']}: {e}") errors.append(str(e)) return {"processed_items": processed_items, "errors": errors} ```