From e93c0111412950251f2eeb1a55585dc9c0cb2a3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Mei=C3=9Fner?= Date: Thu, 29 Oct 2015 18:57:47 +0100 Subject: [PATCH 1/5] Show weekdays of dates again in helpdesk --- scheduler/views.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/scheduler/views.py b/scheduler/views.py index fa5af9f5..bbf6c74f 100644 --- a/scheduler/views.py +++ b/scheduler/views.py @@ -1,20 +1,20 @@ # coding: utf-8 -from datetime import date, datetime +from datetime import date import logging import json import itertools -from time import mktime -from django.core.serializers.json import DjangoJSONEncoder +from django.core.serializers.json import DjangoJSONEncoder from django.core.urlresolvers import reverse from django.contrib import messages from django.db.models import Count -from django.templatetags.l10n import localize from django.utils.safestring import mark_safe from django.views.generic import TemplateView, FormView, DetailView from django.shortcuts import get_object_or_404 +from django.template.defaultfilters import date as date_filter + from django.utils.translation import ugettext_lazy as _ from accounts.models import UserAccount @@ -55,9 +55,9 @@ def getNewsFacility(facility): for item in news_query: news.append({ - 'title':item.title, - 'date':item.creation_date, - 'text':item.text + 'title': item.title, + 'date': item.creation_date, + 'text': item.text }) return news @@ -92,7 +92,7 @@ def get_context_data(self, **kwargs): 'description': mark_safe(facility.description), 'area_slug': facility.place.area.slug, 'shifts': [{ - 'date_string': localize(shift_date), + 'date_string': date_filter(shift_date), 'link': reverse('planner_by_facility', kwargs={ 'pk': facility.pk, 'year': shift_date.year, @@ -105,7 +105,8 @@ def get_context_data(self, **kwargs): context['areas_json'] = json.dumps( [{'slug': area.slug, 'name': area.name} for area in sorted(used_places, key=lambda p: p.name)]) - context['facility_json'] = json.dumps(facility_list, cls=DjangoJSONEncoder) + context['facility_json'] = json.dumps(facility_list, + cls=DjangoJSONEncoder) context['shifts'] = open_shifts return context From 300f43265b72110d08ef3ffad0f0ed35e57cafb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Mei=C3=9Fner?= Date: Thu, 29 Oct 2015 18:58:34 +0100 Subject: [PATCH 2/5] Fix grouping of tasks by workplace --- scheduler/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scheduler/views.py b/scheduler/views.py index bbf6c74f..1002c0e3 100644 --- a/scheduler/views.py +++ b/scheduler/views.py @@ -161,7 +161,7 @@ def get_context_data(self, **kwargs): shifts = Shift.objects.filter(facility=facility) shifts = shifts.on_shiftdate(schedule_date) shifts = shifts.annotate(volunteer_count=Count('helpers')) - shifts = shifts.order_by('task', 'ending_time') + shifts = shifts.order_by('task', 'workplace', 'ending_time') shifts = shifts.select_related('task', 'workplace', 'facility') shifts = shifts.prefetch_related('helpers', 'helpers__user') From 52faaf6d4ecb6a5bdd4907277c26a4fe51f26e6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Mei=C3=9Fner?= Date: Thu, 29 Oct 2015 19:38:49 +0100 Subject: [PATCH 3/5] Quickfix email notifications Notifications are now only sent, when shift is not over yet and there is actually sombody enrolled. --- scheduler/signals.py | 68 +++++++++++-------- .../shift_cancellation_notification.html | 4 +- .../shift_modification_notification.html | 6 +- 3 files changed, 46 insertions(+), 32 deletions(-) diff --git a/scheduler/signals.py b/scheduler/signals.py index 1bcea4f8..b4c9c78c 100644 --- a/scheduler/signals.py +++ b/scheduler/signals.py @@ -1,15 +1,17 @@ # coding=utf-8 import logging -from django.core.mail import EmailMessage +from datetime import datetime -from django.db.models.signals import pre_delete, post_save, pre_save +from django.template.defaultfilters import time as date_filter +from django.core.mail import EmailMessage +from django.db.models.signals import pre_delete, pre_save from django.dispatch import receiver from django.template.loader import render_to_string from scheduler.models import Shift logger = logging.getLogger(__name__) -grace = 5*60 # 5 minutes in seconds +grace = 5 * 60 # 5 minutes in seconds @receiver(pre_delete, sender=Shift) @@ -21,43 +23,55 @@ def send_email_notifications(sender, instance, **kwargs): add some error handling, some sane max recipient handling, tests, etc. """ shift = instance - subject = u'Schicht am {} wurde abgesagt'.format(shift.starting_time.strftime('%d.%m.%y')) + if shift.ending_time >= datetime.now(): + subject = u'Schicht am {} wurde abgesagt'.format( + shift.starting_time.strftime('%d.%m.%y')) - message = render_to_string('shift_cancellation_notification.html', dict(shift=shift)) + message = render_to_string('shift_cancellation_notification.html', + dict(shift=shift)) - from_email = "Volunteer-Planner.org " + from_email = "Volunteer-Planner.org " - addresses = shift.helpers.values_list('user__email', flat=True) + addresses = shift.helpers.values_list('user__email', flat=True) - mail = EmailMessage(subject=subject, body=message, - to=['support@volunteer-planner.org'], - from_email=from_email, - bcc=addresses) - mail.send() + if addresses: + mail = EmailMessage(subject=subject, body=message, + to=['support@volunteer-planner.org'], + from_email=from_email, + bcc=addresses) + mail.send() @receiver(pre_save, sender=Shift) def notify_users_shift_change(sender, instance, **kwargs): shift = instance - old = Shift.objects.filter(pk=shift.pk) - # Test whether this is modification or creation, to avoid DoesNotExist exception - if shift.pk and old.exists(): - old_shift = old.get() - diff_start = (old_shift.starting_time - shift.starting_time).seconds - diff_end = (old_shift.ending_time - shift.ending_time).seconds - if grace < diff_start or grace < diff_end: - subject = u'Schicht am {} wurde verändert'.format(shift.starting_time.strftime('%d.%m.%y')) - message = render_to_string('shift_modification_notification.html', dict(old=old_shift, shift=shift)) + if shift.pk: + old_shift = Shift.objects.get(pk=shift.pk) + + # Test whether this is modification or creation, to avoid DoesNotExist exception + if old_shift.ending_time >= datetime.now(): + + subject = u'Schicht wurde verändert: {task} am {date}'.format( + task=old_shift.task.name, + date=date_filter(old_shift.starting_time)) + + message = render_to_string('shift_modification_notification.html', + dict(old=old_shift, shift=shift)) from_email = "Volunteer-Planner.org " addresses = shift.helpers.values_list('user__email', flat=True) - if 0 < len(addresses): - mail = EmailMessage(subject=subject, body=message, to=['support@volunteer-planner.org'], from_email=from_email, + if addresses: + mail = EmailMessage(subject=subject, + body=message, + to=['support@volunteer-planner.org'], + from_email=from_email, bcc=addresses) - logger.info(u'Shift %s at %s changed: (%s-%s -> %s->%s). Sending email notification to %d affected user(s).', - shift.task.name, shift.facility.name, - old_shift.starting_time, old_shift.ending_time, shift.starting_time, shift.ending_time, - len(addresses)) + logger.info( + u'Shift %s at %s changed: (%s-%s -> %s->%s). Sending email notification to %d affected user(s).', + shift.task.name, shift.facility.name, + old_shift.starting_time, old_shift.ending_time, + shift.starting_time, shift.ending_time, + len(addresses)) mail.send() diff --git a/scheduler/templates/shift_cancellation_notification.html b/scheduler/templates/shift_cancellation_notification.html index 10b98c27..64042f87 100644 --- a/scheduler/templates/shift_cancellation_notification.html +++ b/scheduler/templates/shift_cancellation_notification.html @@ -1,10 +1,10 @@ -{% load i18n %}{% blocktrans with shift_title=shift.task.name location=shift.location.name from_date=shift.starting_time.date from_time=shift.starting_time.time to_time=shift.ending_time.time %} +{% load i18n %}{% blocktrans with shift_title=shift.task.name.strip location=shift.facility.name.strip from_date=shift.starting_time.date|date from_time=shift.starting_time.time to_time=shift.ending_time.time %} Hallo, leider musste auf Wunsch der Zuständigen die folgende Schicht abgesagt werden: {{ shift_title }}, {{ location }} -{{ from_date }} von {{ from_time }} bis {{ to_time }} +{{ from_date }} von {{ from_time }} bis {{ to_time }} Uhr Dies hier ist eine automatisch generierte Email. Bei Fragen, wenden Sie sich bitte an die Emailadresse, die bei den Unterkünften in der Beschreibung angegeben ist. diff --git a/scheduler/templates/shift_modification_notification.html b/scheduler/templates/shift_modification_notification.html index 35d40250..d8f144c5 100644 --- a/scheduler/templates/shift_modification_notification.html +++ b/scheduler/templates/shift_modification_notification.html @@ -1,14 +1,14 @@ -{% load i18n %}{% blocktrans with shift_title=shift.task.name location=shift.location.name from_date=shift.starting_time.date from_time=shift.starting_time.time to_time=shift.ending_time.time old_from_date=shift.starting_time.date old_from_time=shift.starting_time.time old_to_time=shift.ending_time.time %} +{% load i18n %}{% blocktrans with shift_title=shift.task.name.strip location=shift.facility.name.strip from_date=shift.starting_time.date|date from_time=shift.starting_time.time to_time=shift.ending_time.time old_from_date=old.starting_time.date|date old_from_time=old.starting_time.time old_to_time=old.ending_time.time %} Hallo, wir mussten die folgende Schicht zeitlich anpassen: {{ shift_title }}, {{ location }} -{{ old_from_date }} von {{ old_from_time }} bis {{ old_to_time }} +{{ old_from_date }} von {{ old_from_time }} bis {{ old_to_time }} Uhr Die neuen Schichtzeiten sind: -{{ from_date }} von {{ from_time }} bis {{ to_time }} +{{ from_date }} von {{ from_time }} bis {{ to_time }} Uhr Wenn Sie zur neuen Uhrzeit unglücklicher Weise nicht mehr helfen kännen, bitten wir Sie, sich im Volunteer-Planner aus dieser Schicht auszutragen, damit jemand From 1a002f6075f979ffbc7efeba75a445ed413fbb3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Mei=C3=9Fner?= Date: Thu, 29 Oct 2015 20:09:58 +0100 Subject: [PATCH 4/5] Re-added grace and changed shift change notification trigger Signal checks now, if the shift has already began instead of if it did not end yet --- scheduler/signals.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/scheduler/signals.py b/scheduler/signals.py index b4c9c78c..4849f5ac 100644 --- a/scheduler/signals.py +++ b/scheduler/signals.py @@ -1,6 +1,6 @@ # coding=utf-8 import logging -from datetime import datetime +from datetime import datetime, timedelta from django.template.defaultfilters import time as date_filter from django.core.mail import EmailMessage @@ -42,16 +42,29 @@ def send_email_notifications(sender, instance, **kwargs): mail.send() +def times_changed(shift, old_shift, grace=timedelta(minutes=5)): + starting_time = min(shift.starting_time, shift.ending_time) + ending_time = max(shift.starting_time, shift.ending_time) + + old_starting_time = min(old_shift.starting_time, old_shift.ending_time) + old_ending_time = max(old_shift.starting_time, old_shift.ending_time) + + starting_diff = max(old_starting_time, starting_time) - min( + old_starting_time, starting_time) + ending_diff = max(old_ending_time, ending_time) - min( + old_ending_time, ending_time) + + return ending_diff > grace or starting_diff > grace + + @receiver(pre_save, sender=Shift) def notify_users_shift_change(sender, instance, **kwargs): shift = instance - if shift.pk: old_shift = Shift.objects.get(pk=shift.pk) - # Test whether this is modification or creation, to avoid DoesNotExist exception - if old_shift.ending_time >= datetime.now(): - + if old_shift.starting_time >= datetime.now() and times_changed(shift, + old_shift): subject = u'Schicht wurde verändert: {task} am {date}'.format( task=old_shift.task.name, date=date_filter(old_shift.starting_time)) From 101f6d9edb68b0303be797fea267c6bff508a531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Mei=C3=9Fner?= Date: Thu, 29 Oct 2015 20:12:13 +0100 Subject: [PATCH 5/5] Removed unused constant 'grace' is now an optional argument of times_changed method --- scheduler/signals.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scheduler/signals.py b/scheduler/signals.py index 4849f5ac..f72c9ef0 100644 --- a/scheduler/signals.py +++ b/scheduler/signals.py @@ -11,7 +11,6 @@ from scheduler.models import Shift logger = logging.getLogger(__name__) -grace = 5 * 60 # 5 minutes in seconds @receiver(pre_delete, sender=Shift)