Files
Touchh/antifroud/check_fraud.py
2025-02-01 19:49:46 +10:00

143 lines
6.3 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.

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.start_time = timezone.now() - timedelta(days=30)
self.end_time = timezone.now()
self.violations = []
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 fetch_user_logs(self):
try:
self.log_info("Начинается извлечение логов активности пользователей.")
user_logs = UserActivityLog.objects.filter(fraud_checked=False)
self.log_info(f"Найдено {user_logs.count()} логов активности для анализа.")
return user_logs
except Exception as e:
self.log_error(f"Ошибка при извлечении логов активности: {e}")
return UserActivityLog.objects.none()
def fetch_reservations(self):
try:
self.log_info("Начинается извлечение бронирований.")
reservations = Reservation.objects.filter(fraud_checked=False)
self.log_info(f"Найдено {reservations.count()} бронирований для анализа.")
return reservations
except Exception as e:
self.log_error(f"Ошибка при извлечении бронирований: {e}")
return Reservation.objects.none()
def find_violations(self):
self.log_info("Начинается анализ несоответствий.")
user_logs = self.fetch_user_logs()
reservations = self.fetch_reservations()
log_lookup = {}
for log in user_logs:
params = parse_qs(log.url_parameters or "")
hotel_id = params.get("utm_content", [None])[0]
room_number = params.get("utm_term", [None])[0]
if hotel_id and room_number:
key = (hotel_id, room_number)
log_lookup.setdefault(key, []).append(log)
for reservation in reservations:
key = (reservation.hotel.hotel_id, reservation.room_number)
logs = log_lookup.get(key, [])
if reservation.status == "заселен" and not logs:
self.record_violation(
hotel=reservation.hotel,
room_number=reservation.room_number,
violation_type="no_qr_scan",
details=f"Бронирование для номера {reservation.room_number} в отеле '{reservation.hotel.name}' "
f"не имеет записи сканирования QR."
)
for log in logs:
if log.created < reservation.check_in:
self.record_violation(
hotel=reservation.hotel,
room_number=reservation.room_number,
violation_type="early_check_in",
details=f"Раннее заселение: сканирование QR {log.created} раньше времени заезда "
f"{reservation.check_in} для номера {reservation.room_number}."
)
for (hotel_id, room_number), logs in log_lookup.items():
matching_reservations = reservations.filter(
hotel__hotel_id=hotel_id,
room_number=room_number
)
if not matching_reservations.exists():
for log in logs:
self.record_violation(
hotel=Hotel.objects.filter(hotel_id=hotel_id).first(),
room_number=room_number,
violation_type="no_reservation",
details=f"Сканирование QR {log.created} для номера {room_number} в отеле с ID '{hotel_id}' "
f"не соответствует ни одному бронированию."
)
def record_violation(self, hotel, room_number, violation_type, details):
if hotel:
self.violations.append(ViolationLog(
hotel=hotel,
room_number=room_number,
violation_type=violation_type,
violation_details=details
))
self.log_warning(f"Зафиксировано нарушение: {details}")
def save_violations(self):
if self.violations:
ViolationLog.objects.bulk_create(self.violations)
self.log_info(f"Создано {len(self.violations)} записей в ViolationLog.")
else:
self.log_info("Нарушений не обнаружено.")
def run_check(self):
self.log_info(f"Запуск проверки с {self.start_time} по {self.end_time}.")
try:
self.find_violations()
#self.save_violations()
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 завершена.")