diff --git a/club/forms.py b/club/forms.py
index 0492577b..e0966fed 100644
--- a/club/forms.py
+++ b/club/forms.py
@@ -53,6 +53,7 @@ class MailingForm(forms.Form):
ACTION_NEW_MAILING = 1
ACTION_NEW_SUBSCRIPTION = 2
+ ACTION_REMOVE_SUBSCRIPTION = 3
subscription_users = AutoCompleteSelectMultipleField(
"users",
@@ -61,13 +62,14 @@ class MailingForm(forms.Form):
required=False,
)
- def __init__(self, club_id, user_id, *args, **kwargs):
+ def __init__(self, club_id, user_id, mailings, *args, **kwargs):
super(MailingForm, self).__init__(*args, **kwargs)
self.fields["action"] = forms.TypedChoiceField(
(
(self.ACTION_NEW_MAILING, _("New Mailing")),
(self.ACTION_NEW_SUBSCRIPTION, _("Subscribe")),
+ (self.ACTION_REMOVE_SUBSCRIPTION, _("Remove")),
),
coerce=int,
label=_("Action"),
@@ -76,6 +78,15 @@ class MailingForm(forms.Form):
widget=forms.HiddenInput(),
)
+ # Generate bulk removal forms, they are never required
+ for mailing in mailings:
+ self.fields["removal_" + str(mailing.id)] = forms.ModelMultipleChoiceField(
+ mailing.subscriptions.all(),
+ label=_("Remove"),
+ required=False,
+ widget=forms.CheckboxSelectMultiple,
+ )
+
# Include fields for handling mailing creation
mailing_fields = ("email", "club", "moderator")
self.fields.update(forms.fields_for_model(Mailing, fields=mailing_fields))
@@ -133,8 +144,6 @@ class MailingForm(forms.Form):
def clean(self):
cleaned_data = super(MailingForm, self).clean()
- print(cleaned_data)
-
if not "action" in cleaned_data:
# If there is no action provided, we can stop here
raise forms.ValidationError(_("An action is required"), code="invalid")
diff --git a/club/models.py b/club/models.py
index d446c080..50cacd0d 100644
--- a/club/models.py
+++ b/club/models.py
@@ -446,18 +446,20 @@ class MailingSubscription(models.Model):
def can_be_edited_by(self, user):
return self.user is not None and user.id == self.user.id
- @property
+ @cached_property
def get_email(self):
if self.user and not self.email:
return self.user.email
return self.email
+ @cached_property
+ def get_username(self):
+ if self.user:
+ return str(self.user)
+ return _("Unregistered user")
+
def fetch_format(self):
return self.get_email + " "
def __str__(self):
- if self.user:
- user = str(self.user)
- else:
- user = _("Unregistered user")
- return "(%s) - %s : %s" % (self.mailing, user, self.email)
+ return "(%s) - %s : %s" % (self.mailing, self.get_username, self.email)
diff --git a/club/templates/club/mailing.jinja b/club/templates/club/mailing.jinja
index 7d485338..1222a332 100644
--- a/club/templates/club/mailing.jinja
+++ b/club/templates/club/mailing.jinja
@@ -1,4 +1,5 @@
{% extends "core/base.jinja" %}
+{% from 'core/macros.jinja' import select_all_checkbox %}
{% block title %}
{% trans %}Mailing lists{% endtrans %}
@@ -10,8 +11,7 @@
{% trans %}Remember : mailing lists need to be moderated, if your new created list is not shown wait until moderation takes action{% endtrans %}
{% for mailing in mailings %}
- {% if mailing.is_moderated %}
-
{% trans %}Mailing{% endtrans %} {{ mailing.email_full }}
+ {% trans %}Mailing{% endtrans %} {{ mailing.email_full }}
{%- if user.is_owner(mailing) -%}
- {% trans %}Delete{% endtrans %}
{%- endif -%}
@@ -19,27 +19,38 @@
-
-
-
-
- {% trans %}User{% endtrans %} |
- {% trans %}Email{%endtrans%} |
-
- {% for subscriber in mailing.subscriptions.all() %}
-
- {% if subscriber.user %}
- {{ subscriber.user }} |
- {% else %}
- {% trans %}Unregistered user{% endtrans %} |
- {% endif %}
- {{ subscriber.get_email }} |
- {% trans %}Delete{% endtrans %} |
-
- {% endfor %}
-
+
+ {% else %}
+ {% trans %}There is no subscriber for this mailing list{% endtrans %}
{% endif %}
{% endfor %}
diff --git a/club/urls.py b/club/urls.py
index d560a560..c5a01e02 100644
--- a/club/urls.py
+++ b/club/urls.py
@@ -70,11 +70,6 @@ urlpatterns = [
MailingAutoGenerationView.as_view(),
name="mailing_generate",
),
- url(
- r"^(?P[0-9]+)/mailing/clean$",
- MailingAutoCleanView.as_view(),
- name="mailing_clean",
- ),
url(
r"^(?P[0-9]+)/mailing/delete$",
MailingDeleteView.as_view(),
diff --git a/club/views.py b/club/views.py
index 06c8c7f3..151dab16 100644
--- a/club/views.py
+++ b/club/views.py
@@ -513,23 +513,29 @@ class ClubMailingView(ClubTabsMixin, CanEditMixin, DetailFormView):
template_name = "club/mailing.jinja"
current_tab = "mailing"
- def get_form_kwargs(self, *args, **kwargs):
- kwargs = super(ClubMailingView, self).get_form_kwargs(*args, **kwargs)
+ def get_form_kwargs(self):
+ kwargs = super(ClubMailingView, self).get_form_kwargs()
kwargs["club_id"] = self.get_object().id
kwargs["user_id"] = self.request.user.id
+ kwargs["mailings"] = self.mailings
return kwargs
+ def dispatch(self, request, *args, **kwargs):
+ self.mailings = Mailing.objects.filter(club_id=self.get_object().id).all()
+ return super(ClubMailingView, self).dispatch(request, *args, **kwargs)
+
def get_context_data(self, **kwargs):
kwargs = super(ClubMailingView, self).get_context_data(**kwargs)
kwargs["club"] = self.get_object()
kwargs["user"] = self.request.user
- kwargs["mailings"] = Mailing.objects.filter(club_id=self.get_object().id).all()
+ kwargs["mailings"] = self.mailings
kwargs["mailings_moderated"] = (
kwargs["mailings"].exclude(is_moderated=False).all()
)
kwargs["form_actions"] = {
"NEW_MALING": self.form_class.ACTION_NEW_MAILING,
"NEW_SUBSCRIPTION": self.form_class.ACTION_NEW_SUBSCRIPTION,
+ "REMOVE_SUBSCRIPTION": self.form_class.ACTION_REMOVE_SUBSCRIPTION,
}
return kwargs
@@ -565,6 +571,19 @@ class ClubMailingView(ClubTabsMixin, CanEditMixin, DetailFormView):
sub.clean()
sub.save()
+ def remove_subscription(self, cleaned_data):
+ """
+ Remove specified users from a mailing list
+ """
+ fields = [
+ cleaned_data[key]
+ for key in cleaned_data.keys()
+ if key.startswith("removal_")
+ ]
+ for field in fields:
+ for sub in field:
+ sub.delete()
+
def form_valid(self, form):
resp = super(ClubMailingView, self).form_valid(form)
@@ -576,6 +595,9 @@ class ClubMailingView(ClubTabsMixin, CanEditMixin, DetailFormView):
if cleaned_data["action"] == self.form_class.ACTION_NEW_SUBSCRIPTION:
self.add_new_subscription(cleaned_data)
+ if cleaned_data["action"] == self.form_class.ACTION_REMOVE_SUBSCRIPTION:
+ self.remove_subscription(cleaned_data)
+
return resp
def get_success_url(self, **kwargs):
@@ -634,18 +656,6 @@ class MailingAutoGenerationView(View):
return redirect("club:mailing", club_id=club.id)
-class MailingAutoCleanView(View):
- def dispatch(self, request, *args, **kwargs):
- self.mailing = get_object_or_404(Mailing, pk=kwargs["mailing_id"])
- if not request.user.can_edit(self.mailing):
- raise PermissionDenied
- return super(MailingAutoCleanView, self).dispatch(request, *args, **kwargs)
-
- def get(self, request, *args, **kwargs):
- self.mailing.subscriptions.all().delete()
- return redirect("club:mailing", club_id=self.mailing.club.id)
-
-
class PosterListView(ClubTabsMixin, PosterListBaseView, CanViewMixin):
"""List communication posters"""
diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po
index d5f73570..ec15c62e 100644
--- a/locale/fr/LC_MESSAGES/django.po
+++ b/locale/fr/LC_MESSAGES/django.po
@@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-04-28 15:00+0200\n"
+"POT-Creation-Date: 2019-05-01 22:45+0200\n"
"PO-Revision-Date: 2016-07-18\n"
"Last-Translator: Skia \n"
"Language-Team: AE info \n"
@@ -177,7 +177,7 @@ msgstr "type de cible"
#: accounting/models.py:313 club/models.py:413
#: club/templates/club/club_members.jinja:16
#: club/templates/club/club_old_members.jinja:8
-#: club/templates/club/mailing.jinja:28 club/views.py:112
+#: club/templates/club/mailing.jinja:32
#: counter/templates/counter/cash_summary_list.jinja:32
#: counter/templates/counter/stats.jinja:15
#: counter/templates/counter/stats.jinja:52
@@ -345,7 +345,7 @@ msgstr "Compte en banque : "
#: accounting/templates/accounting/club_account_details.jinja:60
#: accounting/templates/accounting/label_list.jinja:26
#: club/templates/club/club_sellings.jinja:50
-#: club/templates/club/mailing.jinja:16 club/templates/club/mailing.jinja:39
+#: club/templates/club/mailing.jinja:16 club/templates/club/mailing.jinja:34
#: com/templates/com/mailing_admin.jinja:19
#: com/templates/com/news_admin_list.jinja:41
#: com/templates/com/news_admin_list.jinja:70
@@ -386,7 +386,7 @@ msgid "Delete"
msgstr "Supprimer"
#: accounting/templates/accounting/bank_account_details.jinja:18
-#: club/views.py:129 core/views/user.py:205 sas/templates/sas/picture.jinja:86
+#: club/views.py:78 core/views/user.py:205 sas/templates/sas/picture.jinja:86
msgid "Infos"
msgstr "Infos"
@@ -405,7 +405,7 @@ msgstr "Nouveau compte club"
#: accounting/templates/accounting/bank_account_details.jinja:27
#: accounting/templates/accounting/bank_account_list.jinja:22
#: accounting/templates/accounting/club_account_details.jinja:58
-#: accounting/templates/accounting/journal_details.jinja:89 club/views.py:175
+#: accounting/templates/accounting/journal_details.jinja:89 club/views.py:124
#: com/templates/com/news_admin_list.jinja:39
#: com/templates/com/news_admin_list.jinja:68
#: com/templates/com/news_admin_list.jinja:115
@@ -893,6 +893,101 @@ msgstr "Opérations sans étiquette"
msgid "Refound this account"
msgstr "Rembourser ce compte"
+#: club/forms.py:60 club/forms.py:197
+msgid "Users to add"
+msgstr "Utilisateurs à ajouter"
+
+#: club/forms.py:61 club/forms.py:198 core/views/group.py:63
+msgid "Search users to add (one or more)."
+msgstr "Recherche les utilisateurs à ajouter (un ou plus)."
+
+#: club/forms.py:70
+#, fuzzy
+#| msgid "New mailing"
+msgid "New Mailing"
+msgstr "Nouvelle mailing liste"
+
+#: club/forms.py:71
+#, fuzzy
+#| msgid "Unsubscribe"
+msgid "Subscribe"
+msgstr "Se désabonner"
+
+#: club/forms.py:72 club/forms.py:85 com/templates/com/news_admin_list.jinja:40
+#: com/templates/com/news_admin_list.jinja:116
+#: com/templates/com/news_admin_list.jinja:198
+#: com/templates/com/news_admin_list.jinja:274
+msgid "Remove"
+msgstr "Retirer"
+
+#: club/forms.py:75 launderette/views.py:228
+msgid "Action"
+msgstr "Action"
+
+#: club/forms.py:122
+#, fuzzy
+#| msgid "This field is required."
+msgid "This field is required"
+msgstr "Ce champ est obligatoire."
+
+#: club/forms.py:134 club/forms.py:259
+msgid "One of the selected users doesn't exist"
+msgstr "Un des utilisateurs sélectionné n'existe pas"
+
+#: club/forms.py:138
+#, fuzzy
+#| msgid "One of the selected users doesn't exist"
+msgid "One of the selected users doesn't have an email address"
+msgstr "Un des utilisateurs sélectionné n'existe pas"
+
+#: club/forms.py:149
+#, fuzzy
+#| msgid "This field is required."
+msgid "An action is required"
+msgstr "Ce champ est obligatoire."
+
+#: club/forms.py:162
+msgid "You must specify at least an user or an email address"
+msgstr ""
+
+#: club/forms.py:172 counter/views.py:1481
+msgid "Begin date"
+msgstr "Date de début"
+
+#: club/forms.py:178 com/views.py:85 com/views.py:221 counter/views.py:1487
+#: election/views.py:190 subscription/views.py:52
+msgid "End date"
+msgstr "Date de fin"
+
+#: club/forms.py:183 club/templates/club/club_sellings.jinja:21
+#: core/templates/core/user_account_detail.jinja:18
+#: core/templates/core/user_account_detail.jinja:51
+#: counter/templates/counter/cash_summary_list.jinja:33 counter/views.py:168
+msgid "Counter"
+msgstr "Comptoir"
+
+#: club/forms.py:241 club/templates/club/club_members.jinja:21
+#: club/templates/club/club_members.jinja:46
+#: core/templates/core/user_clubs.jinja:29
+msgid "Mark as old"
+msgstr "Marquer comme ancien"
+
+#: club/forms.py:263
+msgid "User must be subscriber to take part to a club"
+msgstr "L'utilisateur doit être cotisant pour faire partie d'un club"
+
+#: club/forms.py:267 core/views/group.py:82
+msgid "You can not add the same user twice"
+msgstr "Vous ne pouvez pas ajouter deux fois le même utilisateur"
+
+#: club/forms.py:288
+msgid "You should specify a role"
+msgstr "Vous devez choisir un rôle"
+
+#: club/forms.py:299 sas/views.py:129 sas/views.py:195 sas/views.py:286
+msgid "You do not have the permission to do that"
+msgstr "Vous n'avez pas la permission de faire cela"
+
#: club/models.py:51
msgid "unix name"
msgstr "nom unix"
@@ -988,9 +1083,9 @@ msgstr "Au moins un utilisateur ou un email est nécessaire"
msgid "This email is already suscribed in this mailing"
msgstr "Cet email est déjà abonné à cette mailing"
-#: club/models.py:462 club/templates/club/mailing.jinja:36
+#: club/models.py:459
msgid "Unregistered user"
-msgstr "Désabonner un utilisateur"
+msgstr "Utilisateur non enregistré"
#: club/templates/club/club_list.jinja:4 club/templates/club/club_list.jinja:37
msgid "Club list"
@@ -1037,12 +1132,6 @@ msgstr "Description"
msgid "Since"
msgstr "Depuis"
-#: club/templates/club/club_members.jinja:21
-#: club/templates/club/club_members.jinja:46 club/views.py:363
-#: core/templates/core/user_clubs.jinja:29
-msgid "Mark as old"
-msgstr "Marquer comme ancien"
-
#: club/templates/club/club_members.jinja:50
msgid "There are no members in this club."
msgstr "Il n'y a pas de membres dans ce club."
@@ -1067,8 +1156,8 @@ msgstr "Du"
msgid "To"
msgstr "Au"
-#: club/templates/club/club_sellings.jinja:5 club/views.py:195
-#: club/views.py:563 counter/templates/counter/counter_main.jinja:19
+#: club/templates/club/club_sellings.jinja:5 club/views.py:144
+#: club/views.py:378 counter/templates/counter/counter_main.jinja:19
#: counter/templates/counter/last_ops.jinja:35
msgid "Sellings"
msgstr "Ventes"
@@ -1094,13 +1183,6 @@ msgstr "unités"
msgid "Benefit: "
msgstr "Bénéfice : "
-#: club/templates/club/club_sellings.jinja:21 club/views.py:502
-#: core/templates/core/user_account_detail.jinja:18
-#: core/templates/core/user_account_detail.jinja:51
-#: counter/templates/counter/cash_summary_list.jinja:33 counter/views.py:168
-msgid "Counter"
-msgstr "Comptoir"
-
#: club/templates/club/club_sellings.jinja:22
#: core/templates/core/user_account_detail.jinja:19
#: core/templates/core/user_account_detail.jinja:52
@@ -1189,11 +1271,11 @@ msgstr "Comptabilité : "
msgid "Manage launderettes"
msgstr "Gestion des laveries"
-#: club/templates/club/mailing.jinja:4
+#: club/templates/club/mailing.jinja:5
msgid "Mailing lists"
msgstr "Mailing listes"
-#: club/templates/club/mailing.jinja:10
+#: club/templates/club/mailing.jinja:11
msgid ""
"Remember : mailing lists need to be moderated, if your new created list is "
"not shown wait until moderation takes action"
@@ -1206,34 +1288,38 @@ msgstr ""
msgid "Generate mailing list"
msgstr "Générer la liste de diffusion"
-#: club/templates/club/mailing.jinja:23
-msgid "Clean mailing list"
-msgstr "Néttoyer la liste de diffusion"
-
-#: club/templates/club/mailing.jinja:29
+#: club/templates/club/mailing.jinja:33
#: com/templates/com/mailing_admin.jinja:10
msgid "Email"
msgstr "Email"
-#: club/templates/club/mailing.jinja:47
+#: club/templates/club/mailing.jinja:49
+msgid "Remove from mailing list"
+msgstr "Supprimer de la liste de diffusion"
+
+#: club/templates/club/mailing.jinja:53
+msgid "There is no subscriber for this mailing list"
+msgstr "Il n'y a pas d'abonnés dans cette liste de diffusion"
+
+#: club/templates/club/mailing.jinja:58
msgid "No mailing list existing for this club"
msgstr "Aucune mailing liste n'existe pour ce club"
-#: club/templates/club/mailing.jinja:51
+#: club/templates/club/mailing.jinja:63
msgid "New member"
msgstr "Nouveau membre"
-#: club/templates/club/mailing.jinja:55
+#: club/templates/club/mailing.jinja:83
msgid "Add to mailing list"
msgstr "Ajouter à la mailing liste"
-#: club/templates/club/mailing.jinja:59
+#: club/templates/club/mailing.jinja:87
msgid "New mailing"
-msgstr "Nouvelle mailing liste"
+msgstr "Nouvelle liste de diffusion"
-#: club/templates/club/mailing.jinja:63
+#: club/templates/club/mailing.jinja:100
msgid "Create mailing list"
-msgstr "Créer une mailing liste"
+msgstr "Créer une liste de diffusion"
#: club/templates/club/page_history.jinja:8
msgid "No page existing for this club"
@@ -1243,79 +1329,42 @@ msgstr "Aucune page n'existe pour ce club"
msgid "Club stats"
msgstr "Statistiques du club"
-#: club/views.py:139
+#: club/views.py:88
msgid "Members"
msgstr "Membres"
-#: club/views.py:148
+#: club/views.py:97
msgid "Old members"
msgstr "Anciens membres"
-#: club/views.py:158 core/templates/core/page.jinja:33
+#: club/views.py:107 core/templates/core/page.jinja:33
msgid "History"
msgstr "Historique"
-#: club/views.py:166 core/templates/core/base.jinja:121 core/views/user.py:228
+#: club/views.py:115 core/templates/core/base.jinja:121 core/views/user.py:228
#: sas/templates/sas/picture.jinja:95 trombi/views.py:60
msgid "Tools"
msgstr "Outils"
-#: club/views.py:186
+#: club/views.py:135
msgid "Edit club page"
msgstr "Éditer la page de club"
-#: club/views.py:202
+#: club/views.py:151
msgid "Mailing list"
msgstr "Listes de diffusion"
-#: club/views.py:211 com/views.py:141
+#: club/views.py:160 com/views.py:141
msgid "Posters list"
msgstr "Liste d'affiches"
-#: club/views.py:221 counter/templates/counter/counter_list.jinja:21
+#: club/views.py:170 counter/templates/counter/counter_list.jinja:21
#: counter/templates/counter/counter_list.jinja:43
#: counter/templates/counter/counter_list.jinja:59
msgid "Props"
msgstr "Propriétés"
-#: club/views.py:319
-msgid "Users to add"
-msgstr "Utilisateurs à ajouter"
-
-#: club/views.py:320 core/views/group.py:63
-msgid "Search users to add (one or more)."
-msgstr "Recherche les utilisateurs à ajouter (un ou plus)."
-
-#: club/views.py:381
-msgid "One of the selected users doesn't exist"
-msgstr "Un des utilisateurs sélectionné n'existe pas"
-
-#: club/views.py:385
-msgid "User must be subscriber to take part to a club"
-msgstr "L'utilisateur doit être cotisant pour faire partie d'un club"
-
-#: club/views.py:389 core/views/group.py:82
-msgid "You can not add the same user twice"
-msgstr "Vous ne pouvez pas ajouter deux fois le même utilisateur"
-
-#: club/views.py:410
-msgid "You should specify a role"
-msgstr "Vous devez choisir un rôle"
-
-#: club/views.py:421 sas/views.py:129 sas/views.py:195 sas/views.py:286
-msgid "You do not have the permission to do that"
-msgstr "Vous n'avez pas la permission de faire cela"
-
-#: club/views.py:491 counter/views.py:1481
-msgid "Begin date"
-msgstr "Date de début"
-
-#: club/views.py:497 com/views.py:85 com/views.py:221 counter/views.py:1487
-#: election/views.py:190 subscription/views.py:52
-msgid "End date"
-msgstr "Date de fin"
-
-#: club/views.py:520 core/templates/core/user_stats.jinja:27
+#: club/views.py:335 core/templates/core/user_stats.jinja:27
#: counter/views.py:1635
msgid "Product"
msgstr "Produit"
@@ -1547,13 +1596,6 @@ msgstr "Auteur"
msgid "Moderator"
msgstr "Modérateur"
-#: com/templates/com/news_admin_list.jinja:40
-#: com/templates/com/news_admin_list.jinja:116
-#: com/templates/com/news_admin_list.jinja:198
-#: com/templates/com/news_admin_list.jinja:274
-msgid "Remove"
-msgstr "Retirer"
-
#: com/templates/com/news_admin_list.jinja:47
msgid "Notices to moderate"
msgstr "Informations à modérer"
@@ -4612,10 +4654,6 @@ msgstr "Éditer la page de présentation"
msgid "Book launderette slot"
msgstr "Réserver un créneau de laverie"
-#: launderette/views.py:228
-msgid "Action"
-msgstr "Action"
-
#: launderette/views.py:240
msgid "Tokens, separated by spaces"
msgstr "Jetons, séparés par des espaces"