diff --git a/election/migrations/0003_auto_20171202_1819.py b/election/migrations/0003_auto_20171202_1819.py new file mode 100644 index 00000000..ef7868d6 --- /dev/null +++ b/election/migrations/0003_auto_20171202_1819.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('election', '0002_election_archived'), + ] + + operations = [ + migrations.AlterModelOptions( + name='role', + options={'ordering': ('order',)}, + ), + migrations.AddField( + model_name='role', + name='order', + field=models.PositiveIntegerField(editable=False, default=0, db_index=True), + preserve_default=False, + ), + ] diff --git a/election/models.py b/election/models.py index 2d4599e7..937bca74 100644 --- a/election/models.py +++ b/election/models.py @@ -1,4 +1,5 @@ from django.db import models +from ordered_model.models import OrderedModel from django.utils.translation import ugettext_lazy as _ from django.utils import timezone @@ -81,10 +82,15 @@ class Election(models.Model): results[role.title] = role.results(total_vote) return results + def delete(self): + for election_list in self.election_lists.all(): + election_list.delete() + super(Election, self).delete() + # Permissions -class Role(models.Model): +class Role(OrderedModel): """ This class allows to create a new role avaliable for a candidature """ @@ -149,6 +155,10 @@ class Candidature(models.Model): program = models.TextField(_('description'), null=True, blank=True) election_list = models.ForeignKey(ElectionList, related_name='candidatures', verbose_name=_('election list')) + def delete(self): + for vote in self.votes.all(): + vote.delete() + def can_be_edited_by(self, user): return (user == self.user) or user.can_edit(self.role.election) diff --git a/election/templates/election/election_detail.jinja b/election/templates/election/election_detail.jinja index 0dbafeab..26be2e3d 100644 --- a/election/templates/election/election_detail.jinja +++ b/election/templates/election/election_detail.jinja @@ -273,7 +273,8 @@ th { {%- endfor %} - {%- for role in election.roles.all() %} + {%- set role_list = election.roles.order_by('order').all() %} + {%- for role in role_list %} {%- set count = [0] %} {%- set role_data = election_form.data.getlist(role.title) if role.title in election_form.data else [] %} @@ -283,6 +284,22 @@ th { {% if user.can_edit(role) and election.is_vote_editable -%} {% trans %}Edit{% endtrans %} {% trans %}Delete{% endtrans %} + + {%- if role == role_list.last() %} + + + {%- else %} + + + {%- endif %} + {% if role == role_list.first() %} + + + {% else %} + + + {% endif %} + {%- endif -%}

{{ role.description }}

{%- if role.max_choice > 1 and not election.has_voted(user) and election.can_vote(user) %} diff --git a/election/views.py b/election/views.py index 445b9a5a..8b77994a 100644 --- a/election/views.py +++ b/election/views.py @@ -177,6 +177,23 @@ class ElectionDetailView(CanViewMixin, DetailView): template_name = 'election/election_detail.jinja' pk_url_kwarg = "election_id" + def get(self, request, *arg, **kwargs): + r = super(ElectionDetailView, self).get(request, *arg, **kwargs) + election = self.get_object() + if request.user.can_edit(election) and election.is_vote_editable: + action = request.GET.get('action', None) + role = request.GET.get('role', None) + if action and role and Role.objects.filter(id=role).exists(): + if action == "up": + Role.objects.get(id=role).up() + elif action == "down": + Role.objects.get(id=role).down() + elif action == "bottom": + Role.objects.get(id=role).bottom() + elif action == "top": + Role.objects.get(id=role).top() + return r + def get_context_data(self, **kwargs): """ Add additionnal data to the template """ kwargs = super(ElectionDetailView, self).get_context_data(**kwargs) diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index 51d5023e..96bc80aa 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: 2017-11-06 00:40+0100\n" +"POT-Creation-Date: 2017-12-02 19:02+0100\n" "PO-Revision-Date: 2016-07-18\n" "Last-Translator: Skia \n" "Language-Team: AE info \n" @@ -19,7 +19,7 @@ msgstr "" #: accounting/models.py:61 accounting/models.py:110 accounting/models.py:138 #: accounting/models.py:197 club/models.py:47 #: core/templates/core/base.jinja:297 counter/models.py:113 -#: counter/models.py:139 counter/models.py:183 forum/models.py:49 +#: counter/models.py:140 counter/models.py:184 forum/models.py:49 #: launderette/models.py:38 launderette/models.py:84 launderette/models.py:110 #: stock/models.py:38 stock/models.py:54 stock/models.py:77 stock/models.py:97 msgid "name" @@ -66,8 +66,8 @@ msgid "account number" msgstr "numero de compte" #: accounting/models.py:113 accounting/models.py:139 club/models.py:227 -#: com/models.py:67 com/models.py:178 counter/models.py:148 -#: counter/models.py:184 trombi/models.py:149 +#: com/models.py:67 com/models.py:178 counter/models.py:149 +#: counter/models.py:185 trombi/models.py:149 msgid "club" msgstr "club" @@ -88,13 +88,13 @@ msgstr "Compte club" msgid "%(club_account)s on %(bank_account)s" msgstr "%(club_account)s sur %(bank_account)s" -#: accounting/models.py:195 club/models.py:228 counter/models.py:465 -#: election/models.py:16 launderette/models.py:148 +#: accounting/models.py:195 club/models.py:228 counter/models.py:466 +#: election/models.py:17 launderette/models.py:148 msgid "start date" msgstr "date de début" -#: accounting/models.py:196 club/models.py:229 counter/models.py:466 -#: election/models.py:17 +#: accounting/models.py:196 club/models.py:229 counter/models.py:467 +#: election/models.py:18 msgid "end date" msgstr "date de fin" @@ -107,7 +107,7 @@ msgid "club account" msgstr "compte club" #: accounting/models.py:200 accounting/models.py:257 counter/models.py:53 -#: counter/models.py:297 +#: counter/models.py:298 msgid "amount" msgstr "montant" @@ -128,18 +128,19 @@ msgid "journal" msgstr "classeur" #: accounting/models.py:258 core/models.py:645 core/models.py:1046 -#: core/models.py:1090 core/models.py:1117 counter/models.py:300 -#: counter/models.py:350 counter/models.py:483 eboutic/models.py:39 +#: core/models.py:1090 core/models.py:1117 counter/models.py:301 +#: counter/models.py:351 counter/models.py:484 eboutic/models.py:39 #: eboutic/models.py:73 forum/models.py:239 forum/models.py:314 #: stock/models.py:76 msgid "date" msgstr "date" -#: accounting/models.py:259 counter/models.py:484 stock/models.py:79 +#: accounting/models.py:259 counter/models.py:115 counter/models.py:485 +#: stock/models.py:79 msgid "comment" msgstr "commentaire" -#: accounting/models.py:260 counter/models.py:301 counter/models.py:351 +#: accounting/models.py:260 counter/models.py:302 counter/models.py:352 #: subscription/models.py:55 msgid "payment method" msgstr "méthode de paiement" @@ -165,7 +166,7 @@ msgid "accounting type" msgstr "type comptable" #: accounting/models.py:269 accounting/models.py:371 accounting/models.py:398 -#: accounting/models.py:422 core/models.py:1116 counter/models.py:342 +#: accounting/models.py:422 core/models.py:1116 counter/models.py:343 msgid "label" msgstr "étiquette" @@ -264,7 +265,7 @@ msgstr "" "Vous devez fournir soit un type comptable simplifié ou un type comptable " "standard" -#: accounting/models.py:366 counter/models.py:143 +#: accounting/models.py:366 counter/models.py:144 msgid "code" msgstr "code" @@ -365,9 +366,10 @@ msgstr "Compte en banque : " #: core/templates/core/user_edit.jinja:19 #: counter/templates/counter/last_ops.jinja:29 #: counter/templates/counter/last_ops.jinja:59 -#: election/templates/election/election_detail.jinja:280 -#: election/templates/election/election_detail.jinja:330 -#: election/templates/election/election_detail.jinja:378 +#: election/templates/election/election_detail.jinja:271 +#: election/templates/election/election_detail.jinja:286 +#: election/templates/election/election_detail.jinja:350 +#: election/templates/election/election_detail.jinja:401 #: forum/templates/forum/macros.jinja:21 forum/templates/forum/macros.jinja:123 #: launderette/templates/launderette/launderette_admin.jinja:16 #: launderette/views.py:182 sas/templates/sas/album.jinja:26 @@ -416,9 +418,9 @@ msgstr "Nouveau compte club" #: counter/templates/counter/counter_list.jinja:17 #: counter/templates/counter/counter_list.jinja:33 #: counter/templates/counter/counter_list.jinja:55 -#: election/templates/election/election_detail.jinja:279 -#: election/templates/election/election_detail.jinja:327 -#: election/templates/election/election_detail.jinja:375 +#: election/templates/election/election_detail.jinja:285 +#: election/templates/election/election_detail.jinja:347 +#: election/templates/election/election_detail.jinja:398 #: forum/templates/forum/macros.jinja:20 forum/templates/forum/macros.jinja:62 #: forum/templates/forum/macros.jinja:117 #: launderette/templates/launderette/launderette_list.jinja:16 @@ -926,21 +928,21 @@ msgstr "Vous ne pouvez pas faire de boucles dans les clubs" msgid "A club with that unix_name already exists" msgstr "Un club avec ce nom UNIX existe déjà." -#: club/models.py:226 counter/models.py:463 counter/models.py:481 -#: eboutic/models.py:38 eboutic/models.py:72 election/models.py:140 +#: club/models.py:226 counter/models.py:464 counter/models.py:482 +#: eboutic/models.py:38 eboutic/models.py:72 election/models.py:154 #: launderette/models.py:114 launderette/models.py:152 sas/models.py:180 #: trombi/models.py:148 msgid "user" msgstr "nom d'utilisateur" -#: club/models.py:230 core/models.py:180 election/models.py:139 -#: election/models.py:155 trombi/models.py:150 +#: club/models.py:230 core/models.py:180 election/models.py:153 +#: election/models.py:173 trombi/models.py:150 msgid "role" msgstr "rôle" #: club/models.py:232 core/models.py:66 counter/models.py:114 -#: counter/models.py:140 election/models.py:13 election/models.py:93 -#: election/models.py:141 forum/models.py:50 forum/models.py:186 +#: counter/models.py:141 election/models.py:14 election/models.py:99 +#: election/models.py:155 forum/models.py:50 forum/models.py:186 msgid "description" msgstr "description" @@ -1312,8 +1314,8 @@ msgstr "Hebdomadaire" msgid "Call" msgstr "Appel" -#: com/models.py:63 com/models.py:127 com/models.py:175 election/models.py:12 -#: election/models.py:92 election/models.py:128 forum/models.py:189 +#: com/models.py:63 com/models.py:127 com/models.py:175 election/models.py:13 +#: election/models.py:98 election/models.py:134 forum/models.py:189 #: forum/models.py:237 msgid "title" msgstr "titre" @@ -2001,7 +2003,7 @@ msgstr "Un utilisateur de ce nom d'utilisateur existe déjà" #: core/templates/core/user_detail.jinja:14 #: core/templates/core/user_detail.jinja:16 #: core/templates/core/user_edit.jinja:17 -#: election/templates/election/election_detail.jinja:317 +#: election/templates/election/election_detail.jinja:340 #: forum/templates/forum/macros.jinja:93 forum/templates/forum/macros.jinja:95 #: forum/templates/forum/reply.jinja:38 forum/templates/forum/reply.jinja:40 #: trombi/templates/trombi/user_tools.jinja:41 @@ -3273,67 +3275,67 @@ msgstr "clients" msgid "Not enough money" msgstr "Solde insuffisant" -#: counter/models.py:118 counter/models.py:141 +#: counter/models.py:119 counter/models.py:142 msgid "product type" msgstr "type du produit" -#: counter/models.py:144 +#: counter/models.py:145 msgid "purchase price" msgstr "prix d'achat" -#: counter/models.py:145 +#: counter/models.py:146 msgid "selling price" msgstr "prix de vente" -#: counter/models.py:146 +#: counter/models.py:147 msgid "special selling price" msgstr "prix de vente spécial" -#: counter/models.py:147 +#: counter/models.py:148 msgid "icon" msgstr "icône" -#: counter/models.py:149 +#: counter/models.py:150 msgid "limit age" msgstr "âge limite" -#: counter/models.py:150 +#: counter/models.py:151 msgid "tray price" msgstr "prix plateau" -#: counter/models.py:151 +#: counter/models.py:152 msgid "parent product" msgstr "produit parent" -#: counter/models.py:153 +#: counter/models.py:154 msgid "buying groups" msgstr "groupe d'achat" -#: counter/models.py:154 election/models.py:36 +#: counter/models.py:155 election/models.py:37 msgid "archived" msgstr "archivé" -#: counter/models.py:157 counter/models.py:566 +#: counter/models.py:158 counter/models.py:567 msgid "product" msgstr "produit" -#: counter/models.py:185 +#: counter/models.py:186 msgid "products" msgstr "produits" -#: counter/models.py:186 +#: counter/models.py:187 msgid "counter type" msgstr "type de comptoir" -#: counter/models.py:188 +#: counter/models.py:189 msgid "Bar" msgstr "Bar" -#: counter/models.py:188 +#: counter/models.py:189 msgid "Office" msgstr "Bureau" -#: counter/models.py:188 counter/templates/counter/counter_list.jinja:11 +#: counter/models.py:189 counter/templates/counter/counter_list.jinja:11 #: eboutic/templates/eboutic/eboutic_main.jinja:4 #: eboutic/templates/eboutic/eboutic_main.jinja:24 #: eboutic/templates/eboutic/eboutic_makecommand.jinja:8 @@ -3342,62 +3344,62 @@ msgstr "Bureau" msgid "Eboutic" msgstr "Eboutic" -#: counter/models.py:189 +#: counter/models.py:190 msgid "sellers" msgstr "vendeurs" -#: counter/models.py:192 launderette/models.py:151 +#: counter/models.py:193 launderette/models.py:151 msgid "token" msgstr "jeton" -#: counter/models.py:195 counter/models.py:464 counter/models.py:482 +#: counter/models.py:196 counter/models.py:465 counter/models.py:483 #: launderette/models.py:39 stock/models.py:39 msgid "counter" msgstr "comptoir" -#: counter/models.py:303 +#: counter/models.py:304 msgid "bank" msgstr "banque" -#: counter/models.py:305 counter/models.py:353 +#: counter/models.py:306 counter/models.py:354 msgid "is validated" msgstr "est validé" -#: counter/models.py:308 +#: counter/models.py:309 msgid "refilling" msgstr "rechargement" -#: counter/models.py:346 eboutic/models.py:129 +#: counter/models.py:347 eboutic/models.py:129 msgid "unit price" msgstr "prix unitaire" -#: counter/models.py:347 counter/models.py:555 eboutic/models.py:130 +#: counter/models.py:348 counter/models.py:556 eboutic/models.py:130 msgid "quantity" msgstr "quantité" -#: counter/models.py:352 +#: counter/models.py:353 msgid "Sith account" msgstr "Compte utilisateur" -#: counter/models.py:352 sith/settings.py:368 sith/settings.py:373 +#: counter/models.py:353 sith/settings.py:368 sith/settings.py:373 #: sith/settings.py:395 msgid "Credit card" msgstr "Carte bancaire" -#: counter/models.py:356 +#: counter/models.py:357 msgid "selling" msgstr "vente" -#: counter/models.py:375 +#: counter/models.py:376 msgid "Unknown event" msgstr "Événement inconnu" -#: counter/models.py:376 +#: counter/models.py:377 #, python-format msgid "Eticket bought for the event %(event)s" msgstr "Eticket acheté pour l'événement %(event)s" -#: counter/models.py:378 counter/models.py:390 +#: counter/models.py:379 counter/models.py:391 #, python-format msgid "" "You bought an eticket for the event %(event)s.\n" @@ -3406,51 +3408,51 @@ msgstr "" "Vous avez acheté un Eticket pour l'événement %(event)s.\n" "Vous pouvez le télécharger sur cette page: %(url)s" -#: counter/models.py:467 +#: counter/models.py:468 msgid "last activity date" msgstr "dernière activité" -#: counter/models.py:470 +#: counter/models.py:471 msgid "permanency" msgstr "permanence" -#: counter/models.py:485 +#: counter/models.py:486 msgid "emptied" msgstr "coffre vidée" -#: counter/models.py:488 +#: counter/models.py:489 msgid "cash register summary" msgstr "relevé de caisse" -#: counter/models.py:553 +#: counter/models.py:554 msgid "cash summary" msgstr "relevé" -#: counter/models.py:554 +#: counter/models.py:555 msgid "value" msgstr "valeur" -#: counter/models.py:556 +#: counter/models.py:557 msgid "check" msgstr "chèque" -#: counter/models.py:559 +#: counter/models.py:560 msgid "cash register summary item" msgstr "élément de relevé de caisse" -#: counter/models.py:567 +#: counter/models.py:568 msgid "banner" msgstr "bannière" -#: counter/models.py:568 +#: counter/models.py:569 msgid "event date" msgstr "date de l'événement" -#: counter/models.py:569 +#: counter/models.py:570 msgid "event title" msgstr "titre de l'événement" -#: counter/models.py:570 +#: counter/models.py:571 msgid "secret" msgstr "secret" @@ -3906,49 +3908,49 @@ msgstr "Retourner à l'eboutic" msgid "You do not have enough money to buy the basket" msgstr "Vous n'avez pas assez d'argent pour acheter le panier" -#: election/models.py:14 +#: election/models.py:15 msgid "start candidature" msgstr "début des candidatures" -#: election/models.py:15 +#: election/models.py:16 msgid "end candidature" msgstr "fin des candidatures" -#: election/models.py:21 +#: election/models.py:22 msgid "edit groups" msgstr "groupe d'édition" -#: election/models.py:25 +#: election/models.py:26 msgid "view groups" msgstr "groupe de vue" -#: election/models.py:29 +#: election/models.py:30 msgid "vote groups" msgstr "groupe de vote" -#: election/models.py:33 +#: election/models.py:34 msgid "candidature groups" msgstr "groupe de candidature" -#: election/models.py:91 election/models.py:129 +#: election/models.py:97 election/models.py:135 msgid "election" msgstr "élection" -#: election/models.py:94 +#: election/models.py:100 msgid "max choice" msgstr "nombre de choix maxi" -#: election/models.py:142 +#: election/models.py:156 msgid "election list" msgstr "liste électorale" -#: election/models.py:156 +#: election/models.py:174 msgid "candidature" msgstr "candidature" #: election/templates/election/candidate_form.jinja:4 #: election/templates/election/candidate_form.jinja:13 -#: election/templates/election/election_detail.jinja:366 +#: election/templates/election/election_detail.jinja:389 msgid "Candidate" msgstr "Candidater" @@ -3994,40 +3996,50 @@ msgstr "Vous avez déjà voté pour cette élection." msgid "Blank vote" msgstr "Vote blanc" -#: election/templates/election/election_detail.jinja:284 +#: election/templates/election/election_detail.jinja:307 msgid "You may choose up to" msgstr "Vous pouvez choisir jusqu'à" -#: election/templates/election/election_detail.jinja:284 +#: election/templates/election/election_detail.jinja:307 msgid "people." msgstr "personne(s)" -#: election/templates/election/election_detail.jinja:298 +#: election/templates/election/election_detail.jinja:321 msgid "Choose blank vote" msgstr "Choisir de voter blanc" -#: election/templates/election/election_detail.jinja:305 -#: election/templates/election/election_detail.jinja:345 +#: election/templates/election/election_detail.jinja:328 +#: election/templates/election/election_detail.jinja:368 msgid "votes" msgstr "votes" -#: election/templates/election/election_detail.jinja:338 +#: election/templates/election/election_detail.jinja:361 #: launderette/templates/launderette/launderette_book.jinja:12 msgid "Choose" msgstr "Choisir" -#: election/templates/election/election_detail.jinja:361 +#: election/templates/election/election_detail.jinja:384 msgid "Submit the vote !" msgstr "Envoyer le vote !" -#: election/templates/election/election_detail.jinja:369 +#: election/templates/election/election_detail.jinja:392 msgid "Add a new list" msgstr "Ajouter une nouvelle liste" -#: election/templates/election/election_detail.jinja:373 +#: election/templates/election/election_detail.jinja:396 msgid "Add a new role" msgstr "Ajouter un nouveau rôle" +#: election/templates/election/election_detail.jinja:411 +#: election/templates/election/election_detail.jinja:415 +msgid "Show more" +msgstr "Montrer plus" + +#: election/templates/election/election_detail.jinja:412 +#: election/templates/election/election_detail.jinja:416 +msgid "Show less" +msgstr "Montrer moins" + #: election/templates/election/election_list.jinja:5 msgid "Election list" msgstr "Liste des élections" diff --git a/requirements.txt b/requirements.txt index c17b56b8..b94274f4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,5 +13,6 @@ django-haystack whoosh django-debug-toolbar libsass +django-ordered-model pygraphviz # mysqlclient