Skip to content
Snippets Groups Projects
Commit b41d9752 authored by Hangzhi Yu's avatar Hangzhi Yu
Browse files

Add status-based handling of notifications

parent 31428640
No related branches found
No related tags found
1 merge request!360Resolve "Reimplement notification system on base of new calendar system"
Pipeline #192637 failed
...@@ -8,7 +8,7 @@ class Migration(migrations.Migration): ...@@ -8,7 +8,7 @@ class Migration(migrations.Migration):
dependencies = [ dependencies = [
('chronos', '0017_optional_slot_number'), ('chronos', '0017_optional_slot_number'),
('core', '0066_alter_freebusy_options_and_more'), ('core', '0066_add_calendar_alarm'),
] ]
operations = [ operations = [
...@@ -16,6 +16,7 @@ class Migration(migrations.Migration): ...@@ -16,6 +16,7 @@ class Migration(migrations.Migration):
name='LessonEventAlarm', name='LessonEventAlarm',
fields=[ fields=[
('calendaralarm_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='core.calendaralarm')), ('calendaralarm_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='core.calendaralarm')),
('status', models.CharField(choices=[('c', 'Created'), ('e', 'Edited'), ('d', 'Deleted')], default='c', max_length=1, verbose_name='Status')),
], ],
options={ options={
'verbose_name': 'Lesson event alarm', 'verbose_name': 'Lesson event alarm',
......
...@@ -1359,10 +1359,10 @@ class LessonEvent(CalendarEvent): ...@@ -1359,10 +1359,10 @@ class LessonEvent(CalendarEvent):
@property @property
def all_teachers(self: LessonEvent) -> list[Person]: def all_teachers(self: LessonEvent) -> list[Person]:
"""Get list of all teachers for this lesson event.""" """Get list of all teachers for this lesson event."""
all_teachers = list(self.teachers.all()) all_teachers = self.teachers.all()
if self.amends: if self.amends:
all_teachers += list(self.amends.teachers.all()) all_teachers = all_teachers.union(self.amends.teachers.all())
return all_teachers return list(all_teachers)
@property @property
def group_names(self: LessonEvent) -> str: def group_names(self: LessonEvent) -> str:
...@@ -1589,11 +1589,26 @@ class LessonEvent(CalendarEvent): ...@@ -1589,11 +1589,26 @@ class LessonEvent(CalendarEvent):
return objs return objs
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
adding_status = self._state.adding
super().save(*args, **kwargs) super().save(*args, **kwargs)
# Save alarm in lesson event alarm model # Save alarm in lesson event alarm model
if self.amends: if self.amends:
alarm, created = LessonEventAlarm.objects.get_or_create(event=self, defaults={"send_notifications": True}) if adding_status:
# TODO: allow for generating multiple alarms for one event
alarm = LessonEventAlarm(event=self, send_notifications=True)
alarm.save()
else:
alarms = LessonEventAlarm.objects.filter(event=self, status="c")
for alarm in alarms:
if alarm.notifications.filter(sent=True).exists():
follow_up_alarm = LessonEventAlarm(
event=self, send_notifications=True, status="e"
)
follow_up_alarm.save()
else:
alarm.update_or_create_notifications()
class Meta: class Meta:
verbose_name = _("Lesson Event") verbose_name = _("Lesson Event")
...@@ -1603,11 +1618,16 @@ class LessonEvent(CalendarEvent): ...@@ -1603,11 +1618,16 @@ class LessonEvent(CalendarEvent):
class LessonEventAlarm(CalendarAlarm): class LessonEventAlarm(CalendarAlarm):
"""Alarm model for lesson events.""" """Alarm model for lesson events."""
STATUS_CHOICES = {"c": _("Created"), "e": _("Edited"), "d": _("Deleted")}
status = models.CharField(
verbose_name=_("Status"), max_length=1, choices=STATUS_CHOICES, default="c"
)
def value_description(self, request: HttpRequest | None = None) -> str: def value_description(self, request: HttpRequest | None = None) -> str:
return LessonEvent.value_title(self.event) return LessonEvent.value_title(self.event)
def value_trigger(self, request: HttpRequest | None = None) -> Union[datetime, timedelta]: def value_trigger(self, request: HttpRequest | None = None) -> datetime | timedelta:
# question: allow for generating multiple alarms for one event?
if "fixed_time_relative" in get_site_preferences()["chronos__alarm_trigger_mode"]: if "fixed_time_relative" in get_site_preferences()["chronos__alarm_trigger_mode"]:
return ( return (
self.event.datetime_start self.event.datetime_start
...@@ -1618,15 +1638,37 @@ class LessonEventAlarm(CalendarAlarm): ...@@ -1618,15 +1638,37 @@ class LessonEventAlarm(CalendarAlarm):
) )
elif "strictly_relative" in get_site_preferences()["chronos__alarm_trigger_mode"]: elif "strictly_relative" in get_site_preferences()["chronos__alarm_trigger_mode"]:
return get_site_preferences()["chronos__time_in_advance_alarms"] return get_site_preferences()["chronos__time_in_advance_alarms"]
def value_notification_sender(self, request: HttpRequest | None = None) -> str: def value_notification_sender(self, request: HttpRequest | None = None) -> str:
return _("Lesson notification") return _("Lesson notification")
def value_notification_recipients(self, request: HttpRequest | None = None) -> [Person]: def value_notification_recipients(self, request: HttpRequest | None = None) -> [Person]:
return self.event.all_teachers return self.event.all_teachers
def value_notification_title(self, request: HttpRequest | None = None) -> str:
return render_to_string(
"chronos/lesson_event_notification_title.txt",
{
"event": self.event,
"event_title": LessonEvent.value_title(self.event, request),
"status": self.STATUS_CHOICES[self.status].lower(),
},
)
def value_notification_description(self, request: HttpRequest | None = None) -> str: def value_notification_description(self, request: HttpRequest | None = None) -> str:
return _("bliblablubb") # FIXME: In some (?) cases, this is incomplete (e.g. room names are missing)
return render_to_string(
"chronos/lesson_event_notification_description.txt",
{"event": self.event, "status": self.STATUS_CHOICES[self.status].lower()},
)
def value_notification_icon(self, request: HttpRequest | None = None) -> str:
return "calendar-remove-outline" if self.event.cancelled else "calendar-alert-outline"
# TODO: how to get fitting link (from vue-router)?
# TODO: timetable overview page needs to be fitted so that CW is specified
# def value_notification_link(self, request: HttpRequest | None = None) -> str:
# raise NotImplementedError()
class Meta: class Meta:
verbose_name = _("Lesson event alarm") verbose_name = _("Lesson event alarm")
......
{% load i18n %}{% with rooms=event.room_names_with_amends comment=event.comment %}{% trans "Groups" %}: {{ event.group_names|default:"–" }}{% if event.subject or event.amends and event.amends.subject %} · {% trans "Subject" %}: {{ event.subject_name_with_amends }}{% endif %} · {% trans "Teachers" %}: {{ event.teacher_names_with_amends|default:"–" }}{% if rooms %} · {% trans "Rooms" %}: {{ rooms }}{% endif %}{% if comment %} · {{ comment }}{% endif %}{% endwith %}
{% load i18n %}{% trans "Lesson" %}{% if event.amends %} {% if event.cancelled %}{% trans "cancellation" %}{% else %}{% trans "substitution" %}{% endif %}{% endif %} {{ status }}: {{ event.datetime_start|date:"SHORT_DATETIME_FORMAT" }} - {{ event.datetime_end|date:"SHORT_DATETIME_FORMAT" }} · {{ event.group_names }}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment