Add a view to see the list of ballots

This commit is contained in:
Tom Hubrecht 2021-04-17 00:23:33 +02:00
parent 2397fdb715
commit 1cdb125356
6 changed files with 109 additions and 0 deletions

View file

@ -14,6 +14,7 @@ from .staticdefs import (
VALIDATE_FUNCTIONS, VALIDATE_FUNCTIONS,
) )
from .utils import ( from .utils import (
BallotsData,
CastFunctions, CastFunctions,
ResultsData, ResultsData,
TallyFunctions, TallyFunctions,
@ -116,6 +117,10 @@ class Question(models.Model):
results_function = getattr(ResultsData, BALLOT_TYPE[self.type]) results_function = getattr(ResultsData, BALLOT_TYPE[self.type])
return results_function(self) return results_function(self)
def display_ballots(self):
display_function = getattr(BallotsData, BALLOT_TYPE[self.type])
return display_function(self)
@property @property
def vote_type(self): def vote_type(self):
return BALLOT_TYPE[self.type] return BALLOT_TYPE[self.type]

View file

@ -0,0 +1,25 @@
{% load i18n %}
<table class="table">
<thead>
<tr>
{% for o in options %}
<th>{{ o }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for ballot in ballots.values %}
<tr>
{% for v in ballot %}
<td class="has-text-centered">
<span class="icon">
<i class="fas fa-{% if v %}check{% else %}times{% endif %}"></i>
</span>
</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>

View file

@ -0,0 +1,36 @@
{% extends "base.html" %}
{% load i18n %}
{% block content %}
<div class="level">
{# Titre de l'élection #}
<div class="level-left is-flex-shrink-1">
<h1 class="title">{{ election.name }}</h1>
</div>
<div class="level-right">
<div class="level-item">
<a class="button is-primary" href="{% url 'election.view' election.pk %}">
<span class="icon">
<i class="fas fa-undo-alt"></i>
</span>
<span>{% trans "Retour" %}</span>
</a>
</div>
</div>
</div>
<div class="level">
<div class="level-left">
<h3 class="subtitle">{% trans "Liste des bulletins" %}</h3>
</div>
</div>
<hr>
{# Tableau des bulletins par question #}
{% for q in election.questions.all %}
{{ q.display_ballots }}
{% endfor %}
{% endblock %}

View file

@ -76,5 +76,10 @@ urlpatterns = [
views.ElectionVotersView.as_view(), views.ElectionVotersView.as_view(),
name="election.voters", name="election.voters",
), ),
path(
"view/<int:pk>/ballots",
views.ElectionBallotsView.as_view(),
name="election.ballots",
),
path("vote/<int:pk>", views.VoteView.as_view(), name="election.vote"), path("vote/<int:pk>", views.VoteView.as_view(), name="election.vote"),
] ]

View file

@ -271,6 +271,31 @@ class ResultsData:
) )
class BallotsData:
"""Classe pour afficher les bulletins d'une question"""
def select(question):
from .models import Vote
votes = Vote.objects.filter(option__question=question)
options = list(question.options.all())
ballots = {}
for v in votes:
ballot = ballots.get(v.user, [False] * len(options))
ballot[options.index(v.option)] = True
ballots[v.user] = ballot
return render_to_string(
"elections/ballots/select.html", {"options": options, "ballots": ballots}
)
def rank(question):
return ""
# ############################################################################# # #############################################################################
# Fonctions pour importer une liste de votant·e·s # Fonctions pour importer une liste de votant·e·s
# ############################################################################# # #############################################################################

View file

@ -479,6 +479,19 @@ class ElectionVotersView(NotArchivedMixin, DetailView):
return context return context
class ElectionBallotsView(NotArchivedMixin, DetailView):
model = Election
template_name = "elections/election_ballots.html"
def get_queryset(self):
return (
super()
.get_queryset()
.filter(tallied=True)
.prefetch_related("questions__options")
)
class VoteView(OpenElectionOnlyMixin, DetailView): class VoteView(OpenElectionOnlyMixin, DetailView):
model = Question model = Question