import json from datetime import timedelta from urllib.parse import parse_qs from django.utils import timezone from django.db.models import Q from django.db import connection from hotels.models import Reservation, Hotel from .models import UserActivityLog, ViolationLog, RoomDiscrepancy from touchh.utils.log import CustomLogger # Настройка логирования logger = CustomLogger(__name__).get_logger() class ReservationChecker: """ Класс для проверки несоответствий между бронированиями и логами заселения. """ def __init__(self): """ Инициализация времени проверки и списка нарушений. """ self.checkin_diff_hours = 3 def log_info(self, message): logger.info(message) def log_warning(self, message): logger.warning(message) def log_error(self, message): logger.error(message) def run_check(self): self.log_info(f"Запуск проверки.") try: hotels_map = {} hotels = Hotel.objects.all() for hotel in hotels: hotels_map[hotel.hotel_id] = hotel user_logs = UserActivityLog.objects.filter(fraud_checked=False) reservations = Reservation.objects.filter(fraud_checked=False).select_related('hotel') missing = list(reservations) violations = [] check_in_diff = timedelta(hours=self.checkin_diff_hours) for user_log in user_logs: try: params = json.loads(user_log.url_parameters.replace("'", '"')) hotel_id = params['utm_content'] room = params['utm_term'] reserv = next((x for x in reservations if x.hotel.hotel_id == hotel_id and x.room_number == room and user_log.date_time >= x.check_in - check_in_diff and user_log.date_time < x.check_out ), None) v_type = None if reserv: if reserv in missing: missing.remove(reserv) if user_log.date_time < reserv.check_in: v_type = 'early' if user_log.date_time > reserv.check_in + check_in_diff: v_type = 'late' else: v_type = 'no_booking' if v_type: violations.append(RoomDiscrepancy( hotel=hotels_map[hotel_id], room_number=room, discrepancy_type=v_type, booking_id=reserv.reservation_id if reserv else None, check_in_date_expected=reserv.check_in if reserv else None, check_in_date_actual=user_log.date_time, )) user_log.fraud_checked = True except Exception as e: logger.error(e) for miss_reserv in missing: violations.append(RoomDiscrepancy( hotel=miss_reserv.hotel, room_number=miss_reserv.room_number, discrepancy_type='missed', booking_id=miss_reserv.reservation_id, check_in_date_expected=miss_reserv.check_in, )) for reserv in reservations: reserv.fraud_checked = True RoomDiscrepancy.objects.bulk_create(violations) UserActivityLog.objects.bulk_update(user_logs, ['fraud_checked'], 1000) Reservation.objects.bulk_update(reservations, ['fraud_checked'], 1000) except Exception as e: self.log_error(f"Ошибка при выполнении проверки: {e}") self.log_info("Проверка завершена.") # Функция для запуска из планировщика def run_reservation_check(): logger.info("Планировщик вызывает run_reservation_check.") try: checker = ReservationChecker() checker.run_check() except Exception as e: logger.error(f"Ошибка при запуске проверки: {e}") logger.info("run_reservation_check завершена.")