100 lines
3.9 KiB
Python
100 lines
3.9 KiB
Python
"""
|
||
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'
|
||
)
|
||
|
||
# Планируем напоминание за 1 час до занятия
|
||
reminder_time = instance.start_time - timedelta(hours=1)
|
||
if reminder_time > timezone.now():
|
||
send_lesson_notification.apply_async(
|
||
args=[instance.id, 'lesson_reminder'],
|
||
eta=reminder_time
|
||
)
|
||
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'):
|
||
# Статус изменился
|
||
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
|
||
})
|