diff --git a/club/migrations/0009_mailing_mailingsubscription.py b/club/migrations/0009_mailing_mailingsubscription.py new file mode 100644 index 00000000..a87fceeb --- /dev/null +++ b/club/migrations/0009_mailing_mailingsubscription.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models +from django.conf import settings + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('club', '0008_auto_20170515_2214'), + ] + + operations = [ + migrations.CreateModel( + name='Mailing', + fields=[ + ('id', models.AutoField(serialize=False, primary_key=True, auto_created=True, verbose_name='ID')), + ('email', models.EmailField(verbose_name='Email address', unique=True, max_length=254)), + ('club', models.ForeignKey(verbose_name='Club', related_name='mailings', to='club.Club')), + ], + ), + migrations.CreateModel( + name='MailingSubscription', + fields=[ + ('id', models.AutoField(serialize=False, primary_key=True, auto_created=True, verbose_name='ID')), + ('email', models.EmailField(verbose_name='Email address', max_length=254, unique=True)), + ('mailing', models.ForeignKey(verbose_name='Mailing', related_name='subscriptions', to='club.Mailing')), + ('user', models.ForeignKey(null=True, verbose_name='User', related_name='mailing_subscriptions', to=settings.AUTH_USER_MODEL, blank=True)), + ], + ), + ] diff --git a/club/models.py b/club/models.py index cbec4872..5a652e20 100644 --- a/club/models.py +++ b/club/models.py @@ -2,6 +2,7 @@ # # Copyright 2016,2017 # - Skia +# - Sli # # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # http://ae.utbm.fr. @@ -220,3 +221,36 @@ class Membership(models.Model): def get_absolute_url(self): return reverse('club:club_members', kwargs={'club_id': self.club.id}) + + +class Mailing(models.Model): + """ + This class correspond to a mailing list + + """ + club = models.ForeignKey(Club, verbose_name=_('Club'), related_name="mailings", null=False, blank=False) + email = models.EmailField(_('Email address'), unique=True) + + def is_owned_by(self, user): + return self.club.has_rights_in_club(user) or user.is_root + + def can_be_edited_by(self, user): + return self.is_owned_by(user) + + def __str__(self): + return "%s - %s" % (self.club, self.email) + + +class MailingSubscription(models.Model): + """ + This class make the link between user and mailing list + """ + mailing = models.ForeignKey(Mailing, verbose_name=_('Mailing'), related_name="subscriptions", null=False, blank=False) + user = models.ForeignKey(User, verbose_name=_('User'), related_name="mailing_subscriptions", null=True, blank=True) + email = models.EmailField(_('Email address'), unique=True) + + def is_owned_by(self, user): + return self.mailing.club.has_rights_in_club(user) or user.is_root + + def can_be_edited_by(self, user): + return self.is_owned_by(user) or (user is not None and user.id == self.user.id) diff --git a/club/templates/club/mailing.jinja b/club/templates/club/mailing.jinja new file mode 100644 index 00000000..26721097 --- /dev/null +++ b/club/templates/club/mailing.jinja @@ -0,0 +1,56 @@ +{% extends "core/base.jinja" %} + +{% block title %} +{% trans %}Mailing lists{% endtrans %} +{% endblock %} + +{% block content %} + {% if has_objects %} + + {% for mailing in object_list %} +

{% trans %}Mailing{% endtrans %} {{ mailing.email }}

+ + + + + + {% for subscriber in mailing.subscriptions.all() %} + + {% if subscriber.user %} + + {% else %} + + {% endif %} + + + {% endfor %} +
{% trans %}User{% endtrans %}{% trans %}Mail{%endtrans%}
{{ subscriber.user }}{% trans %}Unregistered user{% endtrans %}{{ subscriber.email }}
+ {% endfor %} + + {% else %} +

{% trans %}No mailing list existing for this club{% endtrans %}

+ {% endif %} + + {% if club.has_rights_in_club(user) %} + + {% if has_objects %} +

{% trans %}New member{% endtrans %}

+
+ {% csrf_token %} + {{ new_member.as_p() }} +

+
+ {% endif %} + +

{% trans %}New mailing{% endtrans %}

+
+ {% csrf_token %} + {{ new_mailing.as_p() }} +

+
+ {% endif %} + +{% endblock %} + + + diff --git a/club/urls.py b/club/urls.py index 95f7768e..6b233a6e 100644 --- a/club/urls.py +++ b/club/urls.py @@ -2,6 +2,7 @@ # # Copyright 2016,2017 # - Skia +# - Sli # # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # http://ae.utbm.fr. @@ -38,5 +39,8 @@ urlpatterns = [ url(r'^(?P[0-9]+)/sellings/csv$', ClubSellingCSVView.as_view(), name='sellings_csv'), url(r'^(?P[0-9]+)/prop$', ClubEditPropView.as_view(), name='club_prop'), url(r'^(?P[0-9]+)/tools$', ClubToolsView.as_view(), name='tools'), + url(r'^(?P[0-9]+)/mailing$', ClubMailingView.as_view(action=MailingFormType.DISPLAY), name='mailing'), + url(r'^(?P[0-9]+)/mailing/new/mailing$', ClubMailingView.as_view(action=MailingFormType.MAILING), name='mailing_create'), + url(r'^(?P[0-9]+)/mailing/new/subscription$', ClubMailingView.as_view(action=MailingFormType.MEMBER), name='mailing_subscription_create'), url(r'^membership/(?P[0-9]+)/set_old$', MembershipSetOldView.as_view(), name='membership_set_old'), ] diff --git a/club/views.py b/club/views.py index e608d6ac..9eeb9abd 100644 --- a/club/views.py +++ b/club/views.py @@ -2,6 +2,7 @@ # # Copyright 2016,2017 # - Skia +# - Sli # # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # http://ae.utbm.fr. @@ -23,21 +24,53 @@ # from django import forms +from enum import Enum from django.views.generic import ListView, DetailView, TemplateView +from django.views.generic.edit import DeleteView, FormView +from django.views.generic.detail import SingleObjectMixin from django.views.generic.edit import UpdateView, CreateView from django.http import HttpResponseRedirect, HttpResponse -from django.core.urlresolvers import reverse +from django.core.urlresolvers import reverse, reverse_lazy from django.utils import timezone from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext as _t from ajax_select.fields import AutoCompleteSelectField +from django.shortcuts import get_object_or_404 -from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, TabedViewMixin +from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, TabedViewMixin, CanCreateMixin from core.views.forms import SelectDate, SelectDateTime -from club.models import Club, Membership +from club.models import Club, Membership, Mailing, MailingSubscription from sith.settings import SITH_MAXIMUM_FREE_ROLE from counter.models import Selling, Counter +# Custom forms + + +class MailingForm(forms.ModelForm): + class Meta: + model = Mailing + fields = ('email', 'club') + + def __init__(self, *args, **kwargs): + club_id = kwargs.pop('club_id', None) + super(MailingForm, self).__init__(*args, **kwargs) + if club_id: + self.fields['club'].queryset = Club.objects.filter(id=club_id) + + +class MailingSubscriptionForm(forms.ModelForm): + class Meta: + model = MailingSubscription + fields = ('mailing', 'user', 'email') + + def __init__(self, *args, **kwargs): + club_id = kwargs.pop('club_id', None) + super(MailingSubscriptionForm, self).__init__(*args, **kwargs) + if club_id: + self.fields['mailing'].queryset = Mailing.objects.filter(club__id=club_id) + + user = AutoCompleteSelectField('users', label=_('User'), help_text=None, required=False) + class ClubTabsMixin(TabedViewMixin): def get_tabs_title(self): @@ -61,6 +94,11 @@ class ClubTabsMixin(TabedViewMixin): 'slug': 'elderlies', 'name': _("Old members"), }) + tab_list.append({ + 'url': reverse('club:mailing', kwargs={'club_id': self.object.id}), + 'slug': 'mailing', + 'name': _("Mailing list"), + }) if self.request.user.can_edit(self.object): tab_list.append({ 'url': reverse('club:tools', kwargs={'club_id': self.object.id}), @@ -338,3 +376,78 @@ class ClubStatView(TemplateView): kwargs = super(ClubStatView, self).get_context_data(**kwargs) kwargs['club_list'] = Club.objects.all() return kwargs + + +class MailingFormType(Enum): + DISPLAY = 0 + MEMBER = 1 + MAILING = 2 + + +class ClubMailingView(CanViewMixin, ListView): + """ + A list of mailing for a given club + """ + action = None + model = Mailing + template_name = "club/mailing.jinja" + + def dispatch(self, request, *args, **kwargs): + self.club = get_object_or_404(Club, pk=kwargs['club_id']) + self.user = request.user + self.member_form = MailingSubscriptionForm(club_id=self.club.id) + self.mailing_form = MailingForm(club_id=self.club.id) + return super(ClubMailingView, self).dispatch(request, *args, **kwargs) + + def post(self, request, *args, **kwargs): + res = super(ClubMailingView, self).get(request, *args, **kwargs) + if self.action != MailingFormType.DISPLAY: + if self.action == MailingFormType.MAILING: + form = MailingForm + string = 'new_mailing' + elif self.action == MailingFormType.MEMBER: + form = MailingSubscriptionForm + string = 'new_member' + return MailingGenericCreateView.as_view(list_view=self, form_class=form, form_kwarg_string=string)(request, *args, **kwargs) + return res + + def get_queryset(self): + return Mailing.objects.filter(club_id=self.club.id).all() + + def get_context_data(self, **kwargs): + kwargs = super(ClubMailingView, self).get_context_data(**kwargs) + kwargs['new_member'] = self.member_form + kwargs['new_mailing'] = self.mailing_form + kwargs['club'] = self.club + kwargs['user'] = self.user + kwargs['has_objects'] = len(kwargs['object_list']) > 0 + return kwargs + + +class MailingGenericCreateView(CanCreateMixin, CreateView, SingleObjectMixin): + """ + Create a new mailing list + """ + model = Mailing + list_view = None + form_class = None + form_kwarg_string = None + + def get_context_data(self, **kwargs): + view_kwargs = self.list_view.get_context_data(**kwargs) + for key, data in super(MailingGenericCreateView, self).get_context_data(**kwargs).items(): + view_kwargs[key] = data + view_kwargs[self.form_kwarg_string] = view_kwargs['form'] + return view_kwargs + + def get_form_kwargs(self): + kwargs = super(MailingGenericCreateView, self).get_form_kwargs() + kwargs['club_id'] = self.list_view.club.id + return kwargs + + def dispatch(self, request, *args, **kwargs): + self.template_name = self.list_view.template_name + return super(MailingGenericCreateView, self).dispatch(request, *args, **kwargs) + + def get_success_url(self, **kwargs): + return reverse_lazy('club:mailing', kwargs={'club_id': self.list_view.club.id})