Исправлена отправка уведомлений для объявлений всем участникам

Проблема:
- get_participants для announcement возвращал none()
- notification_signals использовал participants вместо get_participants
- Уведомления не создавались для объявлений с include_all_employees

Решение:
- get_participants для announcement/channel теперь возвращает всех
  активных сотрудников если include_all_employees=True
- notification_signals использует get_participants для
  announcement/channel/department/global типов
- Добавлены тестовые скрипты для проверки

Тестирование:
✅ Уведомления создаются для всех участников (кроме автора)
✅ Тип уведомления: announcement_new_message
✅ Приоритет: high, каналы: web + telegram
This commit is contained in:
admin i 2025-11-30 12:25:19 +03:00
parent 7c2b6b73e3
commit 413c2c25b4
4 changed files with 183 additions and 1 deletions

View File

@ -266,6 +266,19 @@ class Chat(models.Model):
).distinct()
if self.type == "global":
return Employee.objects.filter(is_active=True)
if self.type in ["announcement", "channel"]:
# Если include_all_employees - все активные сотрудники
if self.include_all_employees:
return Employee.objects.filter(is_active=True)
# Иначе только явно добавленные через participants или ChatMembership
from .models import ChatMembership
membership_ids = ChatMembership.objects.filter(
chat=self
).values_list("user_id", flat=True)
return Employee.objects.filter(
Q(id__in=self.participants.values_list('id', flat=True)) |
Q(id__in=membership_ids)
).distinct()
return Employee.objects.none()
def __str__(self):

View File

@ -37,7 +37,11 @@ def create_message_notifications(sender, instance, created, **kwargs):
content = instance.content
# Получаем всех участников чата кроме автора
participants = chat.participants.exclude(id=author.id)
# Для announcement/channel/department используем get_participants
if chat.type in ['announcement', 'channel', 'department', 'global']:
participants = chat.get_participants.exclude(id=author.id)
else:
participants = chat.participants.exclude(id=author.id)
# 1. Обработка упоминаний (@username)
mentioned_users = extract_mentions(content)

View File

@ -0,0 +1,84 @@
#!/usr/bin/env python
"""
Тестирование уведомлений для объявлений
"""
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'eusrr_backend.settings')
django.setup()
from communications.models import Chat, Message
from employees.models import Employee
def test_announcement_notifications():
"""Проверяет, что уведомления для объявлений отправляются всем"""
# Находим чат-объявление
announcement = Chat.objects.filter(type='announcement').first()
if not announcement:
print("❌ Нет объявлений в системе")
return
print(f"✓ Найдено объявление: {announcement.name}")
print(f" Created by: {announcement.created_by}")
print(f" include_all_employees: {announcement.include_all_employees}")
# Получаем участников
participants = announcement.get_participants
print(f" Участников (get_participants): {participants.count()}")
# Список участников
for p in participants[:5]:
print(f" - {p.get_full_name() or p.username} ({p.email})")
if participants.count() > 5:
print(f" ... и ещё {participants.count() - 5}")
# Проверяем последнее сообщение
last_message = announcement.messages.order_by('-created_at').first()
if last_message:
print(f"\n✓ Последнее сообщение:")
print(f" ID: {last_message.id}")
print(f" Автор: {last_message.author}")
print(f" Текст: {last_message.content[:50]}...")
print(f" Создано: {last_message.created_at}")
# Проверяем уведомления
from notifications.models import Notification
notifications = Notification.objects.filter(
content_type__model='message',
object_id=last_message.id
)
print(f"\n✓ Уведомлений создано: {notifications.count()}")
# Проверяем тип уведомлений
announcement_notifs = notifications.filter(
notification_type__code='announcement_new_message'
)
print(f" Типа 'announcement_new_message': {announcement_notifs.count()}")
# Показываем первые 5
for n in notifications[:5]:
print(f" - Для: {n.recipient.get_full_name()}")
print(f" Тип: {n.notification_type.code}")
print(f" Прочитано: {n.is_read}")
else:
print("\n❌ Нет сообщений в объявлении")
# Итоги
print("\n" + "="*60)
all_employees = Employee.objects.filter(is_active=True).count()
print(f"Всего активных сотрудников: {all_employees}")
print(f"Участников объявления: {participants.count()}")
if participants.count() == all_employees:
print("✅ ПРАВИЛЬНО: Все сотрудники получат уведомления")
else:
print(f"⚠️ ВНИМАНИЕ: Уведомления получат только {participants.count()} из {all_employees}")
if __name__ == '__main__':
test_announcement_notifications()

View File

@ -0,0 +1,81 @@
#!/usr/bin/env python
"""
Создаём тестовое сообщение в объявлении и проверяем уведомления
"""
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'eusrr_backend.settings')
django.setup()
from communications.models import Chat, Message
from employees.models import Employee
from notifications.models import Notification
def create_test_message():
"""Создаёт тестовое сообщение в объявлении"""
# Находим чат-объявление
announcement = Chat.objects.filter(type='announcement').first()
if not announcement:
print("❌ Нет объявлений в системе")
return
print(f"✓ Найдено объявление: {announcement.name}")
print(f" Created by: {announcement.created_by}")
# Подсчитываем уведомления ДО
notif_count_before = Notification.objects.count()
print(f"\nУведомлений ДО создания сообщения: {notif_count_before}")
# Создаём сообщение
message = Message.objects.create(
chat=announcement,
author=announcement.created_by,
content="ТЕСТОВОЕ ОБЪЯВЛЕНИЕ для проверки уведомлений"
)
print(f"\n✓ Создано сообщение ID={message.id}")
# Подсчитываем уведомления ПОСЛЕ
notif_count_after = Notification.objects.count()
print(f"Уведомлений ПОСЛЕ создания сообщения: {notif_count_after}")
print(f"Создано новых уведомлений: {notif_count_after - notif_count_before}")
# Проверяем уведомления для этого сообщения
message_notifs = Notification.objects.filter(
content_type__model='message',
object_id=message.id
)
print(f"\nУведомлений для сообщения ID={message.id}: {message_notifs.count()}")
if message_notifs.exists():
print("\n📧 Список уведомлений:")
for n in message_notifs:
print(f" - Получатель: {n.recipient.get_full_name()}")
print(f" Тип: {n.notification_type.code}")
print(f" Заголовок: {n.title}")
print()
else:
print("\n❌ Уведомления НЕ созданы!")
print("\nПроверяем настройки:")
print(f" - message.is_system: {message.is_system}")
print(f" - message.is_deleted: {message.is_deleted}")
print(f" - chat.type: {announcement.type}")
# Проверяем участников
participants = announcement.get_participants
print(f" - Участников: {participants.count()}")
for p in participants:
print(f" * {p.get_full_name()} (ID={p.id})")
print(f" - Автор: {message.author.get_full_name()} (ID={message.author.id})")
# Участники без автора
participants_no_author = participants.exclude(id=message.author.id)
print(f" - Участников без автора: {participants_no_author.count()}")
if __name__ == '__main__':
create_test_message()