Files
Touchh/pms_integration/plugins/ecvi_pms.py
2025-02-02 09:26:44 +09:00

138 lines
5.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ecvi_pms.py
import logging
import requests
import json
import os
from datetime import datetime, timedelta
from asgiref.sync import sync_to_async
from hotels.models import Hotel, Reservation
from .base_plugin import BasePMSPlugin
class EcviPMSPlugin(BasePMSPlugin):
"""
Плагин для интеграции с PMS Ecvi.
"""
def __init__(self, hotel):
super().__init__(hotel.pms)
self.hotel = hotel
if not self.hotel.pms:
raise ValueError(f"Отель {self.hotel.name} не имеет связанной PMS конфигурации.")
self.api_url = self.hotel.pms.url.rstrip("/")
self.token = self.hotel.pms.token
self.username = self.hotel.pms.username
self.password = self.hotel.pms.password
self.logger = logging.getLogger(self.__class__.__name__)
handler_console = logging.StreamHandler()
handler_file = logging.FileHandler('var/log/ecvi_pms_plugin.log')
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
handler_console.setFormatter(formatter)
handler_file.setFormatter(formatter)
self.logger.addHandler(handler_console)
self.logger.addHandler(handler_file)
self.logger.setLevel(logging.WARNING)
def get_default_parser_settings(self):
return {
"field_mapping": {
"check_in": "checkin",
"check_out": "checkout",
"room_number": "room_name",
"room_type_name": "room_type",
"status": "occupancy",
},
"date_format": "%Y-%m-%d %H:%M:%S"
}
async def _fetch_data(self):
headers = {"Content-Type": "application/json"}
data = {"token": self.token}
try:
response = await sync_to_async(requests.post)(
self.api_url, headers=headers, json=data, auth=(self.username, self.password)
)
response.raise_for_status()
response_data = response.json()
self.logger.debug(f"Полученные данные с API: {response_data}")
# Группировка данных по номеру комнаты
structured_data = {}
for item in response_data:
room_number = item.get("room_name", "unknown")
if room_number not in structured_data:
structured_data[room_number] = []
structured_data[room_number].append(item)
# Сохранение данных во временный JSON-файл
temp_dir = os.path.join("temp", "ecvi")
os.makedirs(temp_dir, exist_ok=True)
temp_file = os.path.join(temp_dir, f"ecvi_data_{datetime.now().strftime('%Y%m%d%H%M%S')}.json")
with open(temp_file, 'w') as file:
json.dump(structured_data, file, indent=4, ensure_ascii=False)
return await self._process_data(response_data)
except requests.exceptions.RequestException as e:
self.logger.error(f"Ошибка API: {e}")
return {
"processed_intervals": 0,
"processed_items": 0,
"errors": [str(e)]
}
async def _process_data(self, data):
processed_items = 0
errors = []
date_formats = ["%Y-%m-%d %H:%M:%S", "%Y-%m-%dT%H:%M:%S"]
for item in data:
try:
checkin = item['checkin']
checkout = item['checkout']
if checkin in [None, "0000-00-00 00:00:00"] or checkout in [None, "0000-00-00 00:00:00"]:
continue
checkin = self._parse_date(checkin, date_formats)
checkout = self._parse_date(checkout, date_formats)
reservation, created = await sync_to_async(Reservation.objects.update_or_create)(
reservation_id=item['task_id'],
defaults={
'room_number': item['room_name'],
'room_type': item['room_type'],
'check_in': checkin,
'check_out': checkout,
'status': item['occupancy'],
'hotel': self.hotel,
}
)
processed_items += 1
except Exception as e:
self.logger.error(f"Ошибка обработки записи: {e}")
errors.append(str(e))
return {
"processed_intervals": 1,
"processed_items": processed_items,
"errors": errors
}
@staticmethod
def _parse_date(date_str, formats):
for fmt in formats:
try:
return datetime.strptime(date_str, fmt)
except ValueError:
continue
raise ValueError(f"Дата '{date_str}' не соответствует ожидаемым форматам: {formats}")
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.debug(f"Плагин {self.__class__.__name__} прошел валидацию.")
return True