uchill/backend/apps/schedule/signals.py

98 lines
4.1 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.

"""
Signals для приложения schedule.
Автоматические действия при изменении расписания.
"""
from django.db.models.signals import post_save, pre_delete, pre_save
from django.dispatch import receiver
from django.utils import timezone
from datetime import timedelta
from .models import Lesson
from apps.notifications.tasks import send_lesson_notification
@receiver(post_save, sender=Lesson)
def lesson_saved(sender, instance, created, **kwargs):
"""
Обработка создания или изменения занятия.
При создании:
- Отправка уведомления ментору и клиенту
- Планирование напоминания перед занятием
При изменении:
- Отправка уведомления об изменении времени/статуса
"""
if created:
# Новое занятие создано
send_lesson_notification.delay(
lesson_id=instance.id,
notification_type='lesson_created'
)
# Напоминания отправляются периодической задачей send_lesson_reminders
# (проверяет флаги reminder_24h_sent, reminder_1h_sent, reminder_15m_sent)
else:
# Занятие изменено
# Проверяем, что именно изменилось
if instance.tracker.has_changed('start_time') or instance.tracker.has_changed('end_time'):
# Время изменилось
send_lesson_notification.delay(
lesson_id=instance.id,
notification_type='lesson_rescheduled'
)
if instance.tracker.has_changed('status'):
# Статус изменился — не уведомляем, если занятие уже в прошлом
# (коррекция статуса/стоимости после факта, например отмена задним числом)
ref_time = instance.end_time or instance.start_time
if ref_time and ref_time < timezone.now():
return # Занятие уже прошло — уведомления не отправляем
if instance.status == 'cancelled':
send_lesson_notification.delay(
lesson_id=instance.id,
notification_type='lesson_cancelled'
)
elif instance.status == 'completed':
send_lesson_notification.delay(
lesson_id=instance.id,
notification_type='lesson_completed'
)
@receiver(pre_delete, sender=Lesson)
def lesson_deleted(sender, instance, **kwargs):
"""
Обработка удаления занятия.
Отправка уведомления об отмене.
"""
if instance.status != 'cancelled':
send_lesson_notification.delay(
lesson_id=instance.id,
notification_type='lesson_cancelled'
)
@receiver(pre_save, sender=Lesson)
def lesson_before_save(sender, instance, **kwargs):
"""
Действия перед сохранением занятия.
Инициализация tracker для отслеживания изменений.
"""
if not hasattr(instance, 'tracker'):
# Создаем простой tracker для отслеживания изменений
if instance.pk:
try:
old_instance = Lesson.objects.get(pk=instance.pk)
instance.tracker = type('obj', (object,), {
'has_changed': lambda field: getattr(old_instance, field) != getattr(instance, field)
})
except Lesson.DoesNotExist:
instance.tracker = type('obj', (object,), {
'has_changed': lambda field: False
})
else:
instance.tracker = type('obj', (object,), {
'has_changed': lambda field: False
})