Corp/backend/scripts/utils/test_request_notifications.py
lizerk ed636081dc refactor: complete notifications v2 system with frontend translation
- Remove hard-coded Russian translations from backend API
- Backend now returns raw verb values (language-agnostic)
- Implement frontend translation functions for notification titles and categories
- Add category badge system with filters on notifications page
- Create translation utilities in frontend (verbTranslations.ts)
- Add notification settings page structure
- Update API endpoints to return simplified notification data
- Refactor notification signals across all apps
- Remove deprecated code and tests
- Add comprehensive documentation for v2 migration

Backend changes:
- notifications/api/views.py: Remove translation logic, simplify responses
- All notification_signals.py: Update to use consistent patterns
- Remove deprecated Telegram bot command
- Update Celery tasks for new notification structure

Frontend changes:
- app/notifications/page.tsx: Add translation functions and category badges
- hooks/useNotificationWebSocket.ts: New WebSocket hook for real-time updates
- lib/verbTranslations.ts: Centralized translation mappings
- components/NotificationCenter.tsx: Update to use new API format

This makes the notifications module fully reusable and project-independent.
2026-03-09 21:35:36 +03:00

251 lines
8.8 KiB
Python
Executable File
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.

#!/usr/bin/env python
"""
Скрипт для тестирования уведомлений модуля Requests.
Создает тестовые заявления и проверяет отправку уведомлений.
Использование:
python scripts/utils/test_request_notifications.py
"""
import os
import django
import sys
# Добавляем backend в путь
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../..'))
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'eusrr_backend.settings')
django.setup()
from django.contrib.auth import get_user_model
from requests_app.models import Request
from employees.models import Department
from notifications.models import Notification
Employee = get_user_model()
print("\n" + "="*70)
print(" ТЕСТИРОВАНИЕ УВЕДОМЛЕНИЙ МОДУЛЯ REQUESTS")
print("="*70 + "\n")
# Получаем тестовых пользователей
users = Employee.objects.filter(is_active=True)[:3]
if len(users) < 2:
print("[ERROR] Нужно минимум 2 активных пользователя!")
sys.exit(1)
author = users[0]
recipient = users[1]
cc_user = users[2] if len(users) > 2 else None
print(f"👤 Автор заявления: {author.get_full_name()} ({author.email})")
print(f"👤 Получатель: {recipient.get_full_name()} ({recipient.email})")
if cc_user:
print(f"👤 В копии: {cc_user.get_full_name()} ({cc_user.email})")
# Получаем первый отдел (если есть)
department = Department.objects.first()
if not department:
print("\n[WARNING] Нет отделов в системе. Создаем тестовый...")
department = Department.objects.create(
name="Тестовый отдел",
head=recipient
)
print(f"\n🏢 Отдел: {department.name}")
print("\n" + "="*70)
# Меню
print("\nВыберите тест:\n")
print("1. Новое заявление (уведомление получателям)")
print("2. Изменение статуса заявления (одобрение)")
print("3. Изменение статуса заявления (отклонение)")
print("4. Комментарий к заявлению")
print("5. Проверить все уведомления пользователя")
print("0. Выход")
print()
choice = input("Ваш выбор: ").strip()
if choice == '0':
print("Выход.")
sys.exit(0)
if choice == '1':
print("\n📝 Создаем новое заявление...")
# Создаем заявление
request = Request.objects.create(
employee=author,
type='vacation',
comment='Тестовое заявление на отпуск',
status='pending',
department=department
)
# Устанавливаем получателей (это триггерит m2m_changed сигнал)
request.recipients.set([recipient])
if cc_user:
request.cc_users.set([cc_user])
print(f"✅ Создано заявление #{request.id}")
# Проверяем уведомления
notifications = Notification.objects.filter(
recipient__in=[recipient, cc_user] if cc_user else [recipient]
).order_by('-timestamp')[:5]
print(f"\n📬 Отправлено уведомлений: {notifications.count()}")
for notif in notifications:
print(f" - [{notif.recipient.username}] {notif.data.get('title', 'N/A')}")
print(f" Verb: {notif.verb} | Read: {notif.unread}")
elif choice == '2':
# Находим или создаем заявление
request = Request.objects.filter(status='pending').first()
if not request:
print("⚠️ Нет заявлений со статусом 'pending', создаем новое...")
request = Request.objects.create(
employee=author,
type='vacation',
comment='Тестовое заявление для одобрения',
status='pending',
department=department,
approver=recipient
)
request.recipients.set([recipient])
print(f"\n✅ Одобряем заявление #{request.id}...")
request.approver = recipient
request.status = 'approved'
request.save()
print(f"✅ Заявление одобрено!")
# Проверяем уведомления
notifications = Notification.objects.filter(
verb='request_approved',
recipient=author
).order_by('-timestamp')[:3]
print(f"\n📬 Уведомлений об одобрении: {notifications.count()}")
for notif in notifications:
print(f" - [{notif.recipient.username}] {notif.data.get('title', 'N/A')}")
elif choice == '3':
# Находим или создаем заявление
request = Request.objects.filter(status='pending').first()
if not request:
print("⚠️ Нет заявлений со статусом 'pending', создаем новое...")
request = Request.objects.create(
employee=author,
type='vacation',
comment='Тестовое заявление для отклонения',
status='pending',
department=department,
approver=recipient
)
request.recipients.set([recipient])
print(f"\n❌ Отклоняем заявление #{request.id}...")
request.approver = recipient
request.status = 'rejected'
request.save()
print(f"❌ Заявление отклонено!")
# Проверяем уведомления
notifications = Notification.objects.filter(
verb='request_rejected',
recipient=author
).order_by('-timestamp')[:3]
print(f"\n📬 Уведомлений об отклонении: {notifications.count()}")
for notif in notifications:
print(f" - [{notif.recipient.username}] {notif.data.get('title', 'N/A')}")
elif choice == '4':
# Находим или создаем заявление
request = Request.objects.first()
if not request:
print("⚠️ Нет заявлений, создаем новое...")
request = Request.objects.create(
employee=author,
type='vacation',
comment='Тестовое заявление',
status='pending',
department=department
)
request.recipients.set([recipient])
print(f"\n💬 Добавляем комментарий к заявлению #{request.id}...")
from requests_app.models import RequestComment
comment = RequestComment.objects.create(
request=request,
author=recipient,
text='Это тестовый комментарий к заявлению'
)
print(f"✅ Комментарий добавлен!")
# Проверяем уведомления
notifications = Notification.objects.filter(
verb='request_comment',
recipient=author
).order_by('-timestamp')[:3]
print(f"\n📬 Уведомлений о комментарии: {notifications.count()}")
for notif in notifications:
print(f" - [{notif.recipient.username}] {notif.data.get('title', 'N/A')}")
print(f" {notif.description[:80]}...")
elif choice == '5':
print("\n📊 Все уведомления по заявлениям:\n")
request_verbs = ['request_new', 'request_approved', 'request_rejected',
'request_comment', 'request_status_changed']
for user in users:
count = Notification.objects.filter(
recipient=user,
verb__in=request_verbs
).count()
unread = Notification.objects.filter(
recipient=user,
verb__in=request_verbs,
unread=True
).count()
print(f"👤 {user.username}: {count} всего, {unread} непрочитанных")
recent = Notification.objects.filter(
recipient=user,
verb__in=request_verbs
).order_by('-timestamp')[:3]
for notif in recent:
read_icon = "✉️" if notif.unread else "✅"
print(f" {read_icon} {notif.verb}: {notif.data.get('title', 'N/A')[:50]}")
else:
print("[ERROR] Неверный выбор")
sys.exit(1)
print("\n" + "="*70)
print(" ГОТОВО!")
print("="*70)
print("\nДля проверки уведомлений:")
print("- Откройте http://localhost:9000/ и войдите под тестовым пользователем")
print("- Проверьте колокольчик в navbar")
print("- Проверьте вкладку в Chrome DevTools 'Network' → WS (WebSocket)")
print()