use the new poll-api in assignments
This commit is contained in:
parent
5aaa1a53fa
commit
70f1cb8b3e
@ -496,12 +496,7 @@ class ApplicationOption(BaseOption):
|
||||
def __getattr__(self, name):
|
||||
if name in ['yes', 'no', 'contained']:
|
||||
try:
|
||||
value = self.get_votes().get(value=name).weight
|
||||
if value == -1:
|
||||
return _('majority')
|
||||
if value == -2:
|
||||
return _('undocumented')
|
||||
return value
|
||||
return self.get_votes().get(value=name)
|
||||
except Vote.DoesNotExist:
|
||||
pass
|
||||
raise AttributeError(name)
|
||||
@ -517,6 +512,7 @@ class ApplicationPoll(BasePoll, CountInvalid, CountVotesCast):
|
||||
return self.application
|
||||
|
||||
def set_options(self):
|
||||
#TODO: maybe it is possible with .create() to call this without poll=self
|
||||
self.get_option_class()(poll=self).save()
|
||||
|
||||
def append_pollform_fields(self, fields):
|
||||
|
@ -79,9 +79,9 @@
|
||||
<img src="/static/images/icons/voting-yes.png" title="{% trans 'Yes' %}"> {{ option.yes }}<br>
|
||||
<img src="/static/images/icons/voting-no.png" title="{% trans 'No' %}"> {{ option.no }}<br>
|
||||
<img src="/static/images/icons/voting-abstention.png" title="{% trans 'Abstention' %}"> {{ option.contained }}<br>
|
||||
<img src="/static/images/icons/voting-invalid.png" title="{% trans 'Invalid' %}"> {{ poll.votesinvalid }}<br>
|
||||
<img src="/static/images/icons/voting-invalid.png" title="{% trans 'Invalid' %}"> {{ poll.print_votesinvalid }}<br>
|
||||
<div style="border-top: 1px solid; padding-top: 5px; margin: 5px 0; width: 10em;">
|
||||
<img src="/static/images/icons/voting-total.png" title="{% trans 'Votes cast' %}"> {{ poll.votescast }}
|
||||
<img src="/static/images/icons/voting-total.png" title="{% trans 'Votes cast' %}"> {{ poll.poll_votescast }}
|
||||
</div>
|
||||
{% endwith %}
|
||||
{% if perms.application.can_manage_application %}
|
||||
|
@ -17,6 +17,7 @@ from participant.models import Profile
|
||||
|
||||
from projector.models import Slide
|
||||
from projector.api import register_slidemodel
|
||||
from poll.models import BasePoll, CountInvalid, CountVotesCast, BaseOption
|
||||
|
||||
|
||||
class Assignment(models.Model, Slide):
|
||||
@ -73,7 +74,7 @@ class Assignment(models.Model, Slide):
|
||||
|
||||
@property
|
||||
def candidates(self):
|
||||
return Profile.objects.filter(option__poll__assignment=self).order_by('user__first_name').distinct()
|
||||
return self.profile.get_query_set()
|
||||
|
||||
def set_elected(self, profile, value=True):
|
||||
if profile in self.candidates:
|
||||
@ -88,33 +89,9 @@ class Assignment(models.Model, Slide):
|
||||
return False
|
||||
|
||||
def gen_poll(self):
|
||||
from poll.models import Poll
|
||||
poll = Poll()
|
||||
|
||||
candidates = list(self.profile.all())
|
||||
for elected in self.elected.all():
|
||||
try:
|
||||
candidates.remove(elected)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
# Option A: candidates <= available posts -> yes/no/abstention
|
||||
if len(candidates) <= self.posts - self.elected.count():
|
||||
poll.optiondecision = True
|
||||
else:
|
||||
poll.optiondecision = False
|
||||
|
||||
# Option B: candidates == 1 -> yes/no/abstention
|
||||
#if self.profile.count() == 1:
|
||||
# poll.optiondecision = True
|
||||
#else:
|
||||
# poll.optiondecision = False
|
||||
|
||||
poll.assignment = self
|
||||
poll.description = self.polldescription
|
||||
poll = AssignmentPoll(assignment=self)
|
||||
poll.save()
|
||||
for candidate in candidates:
|
||||
poll.add_option(candidate)
|
||||
poll.set_options([{'candidate': profile} for profile in self.profile.all()])
|
||||
return poll
|
||||
|
||||
def slide(self):
|
||||
@ -146,3 +123,23 @@ class Assignment(models.Model, Slide):
|
||||
)
|
||||
|
||||
register_slidemodel(Assignment)
|
||||
|
||||
class AssignmentOption(BaseOption):
|
||||
candidate = models.ForeignKey(Profile)
|
||||
|
||||
def __unicode__(self):
|
||||
return unicode(self.candidate)
|
||||
|
||||
|
||||
class AssignmentPoll(BasePoll, CountInvalid, CountVotesCast):
|
||||
option_class = AssignmentOption
|
||||
|
||||
assignment = models.ForeignKey(Assignment, related_name='poll_set')
|
||||
|
||||
def get_assignment(self):
|
||||
return self.assignment
|
||||
|
||||
|
||||
def append_pollform_fields(self, fields):
|
||||
CountInvalid.append_pollform_fields(self, fields)
|
||||
CountVotesCast.append_pollform_fields(self, fields)
|
||||
|
@ -12,36 +12,31 @@
|
||||
<p><b>{% trans "Short description" %}:</b> {{ poll.description }}</p>
|
||||
<i>-1 := {% trans 'majority' %}, -2 := {% trans 'undocumented' %}</i>
|
||||
<form action="" method="post">{% csrf_token %}
|
||||
<table class="table" style="width:auto;">
|
||||
<table>
|
||||
<tr>
|
||||
<th>{%trans "Option" %}</th>
|
||||
{% if poll.optiondecision %}
|
||||
<th>{%trans "Yes" %}</th>
|
||||
<th>{%trans "No" %}</th>
|
||||
<th>{%trans "Abstention" %}</th>
|
||||
{% else %}
|
||||
<th>{%trans "Votes" %}</th>
|
||||
{% endif %}
|
||||
<th>Option</th>
|
||||
{% for value in poll.get_vote_values %}
|
||||
<th>{{ value }}</th>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% for option in options %}
|
||||
<tr class="{% cycle 'odd' '' %}">
|
||||
<td>{{ option }}</td>
|
||||
{% if poll.optiondecision %}
|
||||
<td>{{ option.form.yes.errors }}{{ option.form.yes }}</td>
|
||||
<td>{{ option.form.no.errors }}{{ option.form.no }}</td>
|
||||
<td>{{ option.form.undesided.errors }}{{ option.form.undesided }}</td>
|
||||
{% else %}
|
||||
<td>{{ option.form.yes.errors }}{{ option.form.yes }}</td>
|
||||
{% endif %}
|
||||
{% for form in forms %}
|
||||
<tr>
|
||||
<td>{{ form.option }}</td>
|
||||
{% for value in form %}
|
||||
<td>
|
||||
{{ value.errors }}
|
||||
{{ value }}
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
<tr class="total">
|
||||
<td>{% trans "Invalid votes" %}</td>
|
||||
<td {% if poll.optiondecision %}colspan="3"{% endif %}>{{ form.invalid.errors }}{{ form.invalid }}</td>
|
||||
<td>{{ pollform.votesinvalid.errors }}{{ pollform.votesinvalid }}</td>
|
||||
</tr>
|
||||
<tr class="total">
|
||||
<td style="white-space: nowrap;"><b>{% trans "Votes cast" %}</b></td>
|
||||
<td {% if poll.optiondecision %}colspan="3"{% endif %}>{{ form.votescast.errors }}{{ form.votescast }}</td>
|
||||
<td>{% trans "Votes cast" %}</td>
|
||||
<td>{{ pollform.votescast.errors }}{{ pollform.votescast }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
@ -119,19 +119,19 @@
|
||||
<p><br></p>
|
||||
<h3>{% trans "Election results" %}</h3>
|
||||
|
||||
{% if assignment.poll_set.all.count > 0 %}
|
||||
{% if polls %}
|
||||
<table id="election_table" style="width: auto;">
|
||||
<tr>
|
||||
<th></th>
|
||||
{% with ballotnumber=assignment.poll_set.all.count %}
|
||||
{% with ballotnumber=polls.count %}
|
||||
<th colspan="{{ ballotnumber|add:'1' }}" style="text-align: center;">
|
||||
{% trans "ballot" %}</th>
|
||||
{% endwith %}
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{% trans "Candidates" %}</th>
|
||||
{% for poll in assignment.poll_set.all %}
|
||||
{% if poll.published and not perms.assignment.can_manage_assignment or perms.assignment.can_manage_assignment %}
|
||||
{% for poll in polls %}
|
||||
{# if poll.published and not perms.assignment.can_manage_assignment or perms.assignment.can_manage_assignment #}
|
||||
<th style="vertical-align: top; white-space:nowrap;">{% if perms.assignment.can_manage_assignment %}<a href="{% url assignment_poll_view poll.id %}">{% endif %}
|
||||
{{ forloop.counter }}. {% trans 'ballot' %}
|
||||
{% if perms.assignment.can_manage_assignment %}
|
||||
@ -148,7 +148,7 @@
|
||||
<a href="{% url assignment_poll_delete poll.id %}"><img src="/static/images/icons/edit-delete.png" title="{% trans 'Delete Poll' %}"></a>
|
||||
{% endif %}
|
||||
</th>
|
||||
{% endif %}
|
||||
{# endif #}
|
||||
{% endfor %}
|
||||
{% if assignment.profile.count > 0 and perms.assignment.can_manage_assignment and assignment.status == "vot" %}
|
||||
<th>
|
||||
@ -180,7 +180,8 @@
|
||||
{% endwith %}
|
||||
</td>
|
||||
{% for v in vote|last %}
|
||||
<td style="white-space:nowrap;">{% if v %}
|
||||
<td style="white-space:nowrap;">
|
||||
{% if v %}
|
||||
{% if v|length == 3 %}
|
||||
<img src="/static/images/icons/voting-yes.png" title="{% trans 'Yes' %}"> {% if v.0 %}{{ v.0 }}{% else %}∅{% endif %}<br>
|
||||
<img src="/static/images/icons/voting-no.png" title="{% trans 'No' %}"> {% if v.1 %}{{ v.1 }}{% else %}∅{% endif %}<br>
|
||||
@ -189,7 +190,9 @@
|
||||
{% if v != "-" %}<img src="/static/images/icons/voting-yes.png" title="{% trans 'Yes' %}">{% endif %}
|
||||
{{ v }}
|
||||
{% endif %}
|
||||
{% else %}∅{% endif %}
|
||||
{% else %}
|
||||
∅
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endfor %}
|
||||
{% if assignment.profile.exists and perms.assignment.can_manage_assignment and assignment.status == "vot" %}
|
||||
@ -199,9 +202,9 @@
|
||||
{% endfor %}
|
||||
<tr>
|
||||
<td>{%trans 'Invalid votes' %}</td>
|
||||
{% for p in polls %}
|
||||
{% if p.published and not perms.assignment.can_manage_assignment or perms.assignment.can_manage_assignment %}
|
||||
<td style="white-space:nowrap;"><img src="/static/images/icons/voting-invalid.png" title="{% trans 'Invalid' %}"> {{ p.votesinvalidf }}</td>
|
||||
{% for poll in polls %}
|
||||
{% if poll.published and not perms.assignment.can_manage_assignment or perms.assignment.can_manage_assignment %}
|
||||
<td style="white-space:nowrap;"><img src="/static/images/icons/voting-invalid.png" title="{% trans 'Invalid' %}"> {{ poll.print_votesinvalid }}</td>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if assignment.profile.exists and perms.assignment.can_manage_assignment and assignment.status == "vot" %}
|
||||
@ -210,9 +213,9 @@
|
||||
</tr>
|
||||
<tr class="total">
|
||||
<td><b>{%trans 'Votes cast' %}</b></td>
|
||||
{% for p in polls %}
|
||||
{% if p.published and not perms.assignment.can_manage_assignment or perms.assignment.can_manage_assignment %}
|
||||
<td style="white-space:nowrap;"><img src="/static/images/icons/voting-total.png" title="{% trans 'Votes cast' %}"> <b>{{ p.votescastf }}</b></td>
|
||||
{% for poll in polls %}
|
||||
{% if poll.published and not perms.assignment.can_manage_assignment or perms.assignment.can_manage_assignment %}
|
||||
<td style="white-space:nowrap;"><img src="/static/images/icons/voting-total.png" title="{% trans 'Votes cast' %}"> <b>{{ poll.print_votescast }}</b></td>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if assignment.profile.exists and perms.assignment.can_manage_assignment and assignment.status == "vot" %}
|
||||
|
@ -12,6 +12,8 @@
|
||||
|
||||
from django.conf.urls.defaults import *
|
||||
|
||||
from assignment.views import ViewPoll #, ActivatePoll
|
||||
|
||||
urlpatterns = patterns('assignment.views',
|
||||
url(r'^assignment/$', 'get_overview', \
|
||||
name='assignment_overview'),
|
||||
@ -55,8 +57,10 @@ urlpatterns = patterns('assignment.views',
|
||||
url(r'^assignment/(?P<assignment_id>\d+)/gen_poll$', 'gen_poll', \
|
||||
name='assignment_gen_poll'),
|
||||
|
||||
url(r'^assignment/poll/(?P<poll_id>\d+)$', 'poll_view', \
|
||||
name='assignment_poll_view'),
|
||||
url(r'^assignment/poll/(?P<poll_id>\d+)$',
|
||||
ViewPoll.as_view(),
|
||||
name='assignment_poll_view'
|
||||
),
|
||||
|
||||
url(r'^assignment/poll/(?P<poll_id>\d+)/del$', 'delete_poll', \
|
||||
name='assignment_poll_delete'),
|
||||
|
@ -16,13 +16,14 @@ from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from openslides.agenda.models import Item
|
||||
#from poll.models import Poll, Option
|
||||
#from poll.forms import OptionResultForm, PollForm
|
||||
from assignment.models import Assignment
|
||||
from assignment.forms import AssignmentForm, AssignmentRunForm
|
||||
from utils.utils import template, permission_required, gen_confirm_form, del_confirm_form, ajax_request
|
||||
from utils.pdf import print_assignment, print_assignment_poll
|
||||
|
||||
from poll.views import PollFormView
|
||||
|
||||
from assignment.models import Assignment, AssignmentPoll, AssignmentOption
|
||||
from assignment.forms import AssignmentForm, AssignmentRunForm
|
||||
|
||||
from participant.models import Profile
|
||||
|
||||
|
||||
@ -69,26 +70,26 @@ def view(request, assignment_id=None):
|
||||
votes = []
|
||||
for candidate in assignment.candidates:
|
||||
tmplist = [[candidate, assignment.is_elected(candidate)], []]
|
||||
#TODO: only show published polls
|
||||
for poll in assignment.poll_set.all():
|
||||
if (poll.published and not request.user.has_perm('assignment.can_manage_assignment')) or request.user.has_perm('assignment.can_manage_assignment'):
|
||||
if candidate in poll.options_values:
|
||||
option = Option.objects.filter(poll=poll).filter(user=candidate)[0]
|
||||
if poll.optiondecision:
|
||||
tmplist[1].append([option.yes, option.no, option.undesided])
|
||||
else:
|
||||
tmplist[1].append(option.yes)
|
||||
#if (poll.published and not request.user.has_perm('assignment.can_manage_assignment')) or request.user.has_perm('assignment.can_manage_assignment'):
|
||||
|
||||
# exisitiert der Spieler in der poll
|
||||
if poll.get_options().filter(candidate=candidate).exists():
|
||||
option = AssignmentOption.objects.filter(poll=poll).get(candidate=candidate)
|
||||
tmplist[1].append(option.get_votes()[0])
|
||||
else:
|
||||
tmplist[1].append("-")
|
||||
votes.append(tmplist)
|
||||
|
||||
polls = []
|
||||
for poll in assignment.poll_set.filter(assignment=assignment):
|
||||
polls.append(poll)
|
||||
polls = assignment.poll_set.all()
|
||||
|
||||
return {'assignment': assignment,
|
||||
return {
|
||||
'assignment': assignment,
|
||||
'form': form,
|
||||
'votes': votes,
|
||||
'polls': polls }
|
||||
'polls': polls,
|
||||
}
|
||||
|
||||
|
||||
@permission_required('assignment.can_manage_assignment')
|
||||
@ -193,56 +194,26 @@ def set_active(request, assignment_id):
|
||||
|
||||
@permission_required('assignment.can_manage_assignment')
|
||||
def gen_poll(request, assignment_id):
|
||||
try:
|
||||
poll = Assignment.objects.get(pk=assignment_id).gen_poll()
|
||||
messages.success(request, _("New ballot was successfully created.") )
|
||||
except Assignment.DoesNotExist:
|
||||
pass
|
||||
return redirect(reverse('assignment_poll_view', args=[poll.id]))
|
||||
|
||||
|
||||
@permission_required('assignment.can_manage_assignment')
|
||||
@template('assignment/poll_view.html')
|
||||
def poll_view(request, poll_id):
|
||||
poll = Poll.objects.get(pk=poll_id)
|
||||
ballotnumber = poll.ballot
|
||||
options = poll.options.order_by('user__user__first_name')
|
||||
assignment = poll.assignment
|
||||
if request.user.has_perm('assignment.can_manage_assignment'):
|
||||
if request.method == 'POST':
|
||||
form = PollForm(request.POST, prefix="poll")
|
||||
if form.is_valid():
|
||||
poll.votesinvalid = form.cleaned_data['invalid'] or 0
|
||||
poll.votescast = form.cleaned_data['votescast'] or 0
|
||||
poll.save()
|
||||
class ViewPoll(PollFormView):
|
||||
poll_class = AssignmentPoll
|
||||
template_name = 'assignment/poll_view.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(ViewPoll, self).get_context_data(**kwargs)
|
||||
self.assignment = self.poll.get_assignment()
|
||||
context['application'] = self.assignment
|
||||
return context
|
||||
|
||||
def get_success_url(self):
|
||||
if not 'apply' in self.request.POST:
|
||||
return reverse('assignment_view', args=[self.poll.assignment.id])
|
||||
return ''
|
||||
|
||||
success = 0
|
||||
for option in options:
|
||||
option.form = OptionResultForm(request.POST, prefix="o%d" % option.id)
|
||||
if option.form.is_valid():
|
||||
option.voteyes = option.form.cleaned_data['yes']
|
||||
option.voteno = option.form.cleaned_data['no'] or 0
|
||||
option.voteundesided = option.form.cleaned_data['undesided'] or 0
|
||||
option.save()
|
||||
success = success + 1
|
||||
if success == options.count():
|
||||
messages.success(request, _("Votes are successfully saved.") )
|
||||
if not 'apply' in request.POST:
|
||||
return redirect(reverse('assignment_view', args=[assignment.id]))
|
||||
else:
|
||||
form = PollForm(initial={'invalid': poll.votesinvalid, 'votescast': poll.votescast}, prefix="poll")
|
||||
for option in options:
|
||||
option.form = OptionResultForm(initial={
|
||||
'yes': option.voteyes,
|
||||
'no': option.voteno,
|
||||
'undesided': option.voteundesided,
|
||||
}, prefix="o%d" % option.id)
|
||||
return {
|
||||
'poll': poll,
|
||||
'form': form,
|
||||
'options': options,
|
||||
'ballotnumber': ballotnumber,
|
||||
}
|
||||
|
||||
@permission_required('assignment.can_manage_assignment')
|
||||
def set_published(request, poll_id, published=True):
|
||||
|
@ -17,8 +17,6 @@ from projector.api import register_slidemodel
|
||||
from projector.models import Slide
|
||||
|
||||
|
||||
|
||||
|
||||
class BaseOption(models.Model):
|
||||
poll = models.ForeignKey('BasePoll')
|
||||
|
||||
@ -39,6 +37,9 @@ class Vote(models.Model):
|
||||
weight = models.IntegerField(default=1)
|
||||
value = models.CharField(max_length=255, null=True)
|
||||
|
||||
def __unicode__(self):
|
||||
return print_value(self.weight)
|
||||
|
||||
|
||||
class CountVotesCast(models.Model):
|
||||
votescast = models.IntegerField(null=True, blank=True, verbose_name=_("Votes cast"))
|
||||
@ -46,6 +47,9 @@ class CountVotesCast(models.Model):
|
||||
def append_pollform_fields(self, fields):
|
||||
fields.append('votescast')
|
||||
|
||||
def print_votescast(self):
|
||||
return print_value(self.votescast)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
@ -56,6 +60,9 @@ class CountInvalid(models.Model):
|
||||
def append_pollform_fields(self, fields):
|
||||
fields.append('votesinvalid')
|
||||
|
||||
def print_votesinvalid(self):
|
||||
return print_value(self.votesinvalid)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
@ -130,3 +137,10 @@ class BasePoll(models.Model, Slide):
|
||||
|
||||
register_slidemodel(BasePoll)
|
||||
|
||||
def print_value(value):
|
||||
if value == -1:
|
||||
return _('majority')
|
||||
elif value == -2:
|
||||
return _('undocumented')
|
||||
return unicode(value)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user