Commit f77c801a authored by Luko van der Maas's avatar Luko van der Maas
Browse files

Merge branch 'feature/newsletter-planning' into 'master'

Add newsletter planning feature

See merge request !1206
parents 18baa35a eb3a112b
......@@ -215,8 +215,7 @@ class RegistrationViewSet(GenericViewSet, RetrieveModelMixin,
def destroy(self, request, pk=None, **kwargs):
registration = self.get_object()
try:
services.cancel_registration(request,
registration.member,
services.cancel_registration(registration.member,
registration.event)
return Response(status=204)
except RegistrationError as e:
......
"""The emails defined by the events package"""
from django.conf import settings
from django.core.mail import EmailMessage
from django.template.loader import get_template
from django.utils import translation
......@@ -6,15 +7,13 @@ from django.utils.translation import ugettext_lazy as _
from events.models import Registration
from members.models import Profile
from thaliawebsite.templatetags import baseurl
def notify_first_waiting(request, event):
def notify_first_waiting(event):
"""
Send an email to the first person on the waiting list
when someone cancels their registration
:param request: the request object
:param event: the event
"""
if (event.max_participants is not None and
......@@ -42,7 +41,7 @@ def notify_first_waiting(request, event):
'event': event,
'registration': first_waiting,
'member': first_waiting_member,
'base_url': baseurl.baseurl(context={'request': request})
'base_url': settings.BASE_URL
})
EmailMessage(
......
......@@ -118,11 +118,10 @@ def create_registration(member, event):
raise RegistrationError(_("You may not register."))
def cancel_registration(request, member, event):
def cancel_registration(member, event):
"""
Cancel a user registration for an event
:param request: the request object
:param member: the user
:param event: the event
"""
......@@ -138,7 +137,7 @@ def cancel_registration(request, member, event):
if (event_permissions(member, event)["cancel_registration"] and
registration):
if registration.queue_position == 0:
emails.notify_first_waiting(request, event)
emails.notify_first_waiting(event)
if (event.send_cancel_email and
event.after_cancel_deadline):
......
{% load baseurl %}Hi,
Hi,
A member that was registered for the event '{{ event.title }}' that you're organising has cancelled their registration after the deadline.
......
......@@ -234,7 +234,7 @@ class ServicesTest(TestCase):
}
with self.assertRaises(RegistrationError):
services.cancel_registration(None, self.member, self.event)
services.cancel_registration(self.member, self.event)
registration = Registration.objects.create(
event=self.event,
......@@ -242,22 +242,22 @@ class ServicesTest(TestCase):
)
with self.assertRaises(RegistrationError):
services.cancel_registration(None, self.member, self.event)
services.cancel_registration(self.member, self.event)
perms_mock.return_value["cancel_registration"] = True
services.cancel_registration(None, self.member, self.event)
notify_first_mock.assert_called_once_with(None, self.event)
services.cancel_registration(self.member, self.event)
notify_first_mock.assert_called_once_with(self.event)
self.event.send_cancel_email = True
self.event.save()
services.cancel_registration(None, self.member, self.event)
services.cancel_registration(self.member, self.event)
self.event.cancel_deadline = timezone.make_aware(datetime(2017, 1, 1))
self.event.save()
services.cancel_registration(None, self.member, self.event)
services.cancel_registration(self.member, self.event)
notify_organiser_mock.assert_called_once_with(self.event, registration)
registration.refresh_from_db()
......@@ -271,7 +271,7 @@ class ServicesTest(TestCase):
date=timezone.make_aware(datetime(2017, 9, 1))
)
services.cancel_registration(None, self.member, self.event)
services.cancel_registration(self.member, self.event)
@mock.patch('events.services.event_permissions')
def test_update_registration(self, perms_mock):
......
......@@ -122,7 +122,7 @@ class EventCancelView(View):
def post(self, request, *args, **kwargs):
event = get_object_or_404(Event, pk=kwargs['pk'])
try:
services.cancel_registration(request, request.member, event)
services.cancel_registration(request.member, event)
messages.success(request,
_("Registration successfully cancelled."))
except RegistrationError as e:
......
......@@ -11,11 +11,10 @@ from partners.models import Partner
from newsletters import services
def send_newsletter(request, newsletter):
def send_newsletter(newsletter):
"""
Sends the newsletter as HTML and plaintext email
:param request: the request object
:param newsletter: the newsletter to be send
"""
partners = Partner.objects.filter(is_main_partner=True)
......@@ -47,8 +46,7 @@ def send_newsletter(request, newsletter):
'newsletter': newsletter,
'agenda_events': events,
'main_partner': main_partner,
'lang_code': language[0],
'request': request
'lang_code': language[0]
}
html_message = html_template.render(context)
......
from django.core.management.base import BaseCommand
from django.http import HttpRequest
from newsletters import emails, models
from newsletters import models, services
class Command(BaseCommand):
......@@ -32,4 +32,4 @@ class Command(BaseCommand):
request.META['SERVER_PORT'] = options['server-port']
for n in models.Newsletter.objects.all():
if n.sent or options['include-unsent']:
emails.save_to_disk(n, request)
services.save_to_disk(n, request)
from django.core.management.base import BaseCommand
from django.utils import timezone
from newsletters import emails
from newsletters.models import Newsletter
class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument('pk')
def handle(self, *args, **options):
newsletters = Newsletter.objects.filter(
send_date__lte=timezone.now(),
sent=False
)
for n in newsletters:
emails.send_newsletter(n)
# Generated by Django 2.1.7 on 2019-04-08 15:31
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('newsletters', '0006_make_newslettercontent_non_abstract'),
]
operations = [
migrations.AddField(
model_name='newsletter',
name='send_date',
field=models.DateTimeField(blank=True, null=True, verbose_name='Send date'),
),
]
......@@ -2,6 +2,7 @@
from django.core.exceptions import ValidationError
from django.db import models
from django.urls import reverse
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from tinymce.models import HTMLField
......@@ -29,6 +30,12 @@ class Newsletter(models.Model, metaclass=ModelTranslateMeta):
null=True
)
send_date = models.DateTimeField(
verbose_name=_('Send date'),
blank=True,
null=True,
)
description = MultilingualField(
HTMLField,
verbose_name=_('Introduction'),
......@@ -60,6 +67,11 @@ class Newsletter(models.Model, metaclass=ModelTranslateMeta):
'description_en': _('Please make sure all urls are absolute '
'and contain http(s)://.')
})
if self.send_date and self.send_date <= timezone.now():
errors.update({
'send_date': _('Please make sure the send date is '
'not in the past.')
})
if errors:
raise ValidationError(errors)
......
......@@ -106,7 +106,7 @@ def admin_send(request, pk):
return redirect(newsletter)
if request.POST:
emails.send_newsletter(request, newsletter)
emails.send_newsletter(newsletter)
newsletter.sent = True
newsletter.save()
......
"""Obtain the base url"""
from django.conf import settings
from django.template import Library
register = Library() # pylint: disable=invalid-name
@register.simple_tag(takes_context=True)
def baseurl(context):
@register.simple_tag()
def baseurl():
"""
:return: a BASE_URL template context for the current request.
:return: the BASE_URL defined in the settings
"""
request = context['request']
if request.is_secure():
scheme = 'https://'
else:
scheme = 'http://'
return scheme + request.get_host()
return settings.BASE_URL
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment