2011-07-31 10:46:29 +02:00
|
|
|
#!/usr/bin/env python
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
|
|
openslides.assignment.models
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Models for the assignment app.
|
|
|
|
|
|
|
|
:copyright: 2011 by the OpenSlides team, see AUTHORS.
|
|
|
|
:license: GNU GPL, see LICENSE for more details.
|
|
|
|
"""
|
|
|
|
|
|
|
|
from django.db import models
|
|
|
|
from django.utils.translation import ugettext as _
|
|
|
|
|
|
|
|
from participant.models import Profile
|
|
|
|
|
2012-03-03 09:11:56 +01:00
|
|
|
from projector.models import SlideMixin
|
2012-02-06 22:22:16 +01:00
|
|
|
from projector.api import register_slidemodel
|
2012-02-19 19:27:00 +01:00
|
|
|
from poll.models import BasePoll, CountInvalid, CountVotesCast, BaseOption
|
2011-07-31 10:46:29 +02:00
|
|
|
|
2012-02-03 23:12:28 +01:00
|
|
|
|
2012-03-03 09:11:56 +01:00
|
|
|
class Assignment(models.Model, SlideMixin):
|
2012-02-03 23:12:28 +01:00
|
|
|
prefix = 'assignment'
|
2011-07-31 10:46:29 +02:00
|
|
|
STATUS = (
|
|
|
|
('sea', _('Searching for candidates')),
|
|
|
|
('vot', _('Voting')),
|
|
|
|
('fin', _('Finished')),
|
|
|
|
)
|
|
|
|
|
|
|
|
name = models.CharField(max_length=100, verbose_name = _("Name"))
|
|
|
|
description = models.TextField(null=True, blank=True, verbose_name = _("Description"))
|
2011-09-03 10:52:29 +02:00
|
|
|
posts = models.PositiveSmallIntegerField(verbose_name = _("Number of available posts"))
|
2011-09-03 23:38:14 +02:00
|
|
|
polldescription = models.CharField(max_length=100, null=True, blank=True, verbose_name = _("Short description (for ballot paper)"))
|
2011-07-31 10:46:29 +02:00
|
|
|
profile = models.ManyToManyField(Profile, null=True, blank=True)
|
2011-09-03 11:42:44 +02:00
|
|
|
elected = models.ManyToManyField(Profile, null=True, blank=True, related_name='elected_set')
|
2011-07-31 10:46:29 +02:00
|
|
|
status = models.CharField(max_length=1, choices=STATUS, default='sea')
|
|
|
|
|
|
|
|
def set_status(self, status):
|
|
|
|
error = True
|
|
|
|
for a, b in Assignment.STATUS:
|
|
|
|
if status == a:
|
|
|
|
error = False
|
|
|
|
break
|
|
|
|
if error:
|
|
|
|
raise NameError(_('%s is not a valid status.') % status)
|
|
|
|
if self.status == status:
|
|
|
|
raise NameError(_('The assignment status is already %s.') % self.status)
|
|
|
|
self.status = status
|
|
|
|
self.save()
|
|
|
|
|
|
|
|
def run(self, profile):
|
|
|
|
"""
|
|
|
|
run for a vote
|
|
|
|
"""
|
|
|
|
if self.is_candidate(profile):
|
|
|
|
raise NameError(_('<b>%s</b> is already a candidate.') % profile)
|
|
|
|
self.profile.add(profile)
|
|
|
|
|
|
|
|
def delrun(self, profile):
|
|
|
|
"""
|
|
|
|
stop running for a vote
|
|
|
|
"""
|
|
|
|
if self.is_candidate(profile):
|
|
|
|
self.profile.remove(profile)
|
|
|
|
else:
|
|
|
|
raise NameError(_('%s is no candidate') % profile)
|
|
|
|
|
|
|
|
def is_candidate(self, profile):
|
|
|
|
if profile in self.profile.get_query_set():
|
|
|
|
return True
|
|
|
|
else:
|
|
|
|
return False
|
|
|
|
|
2011-09-03 11:42:44 +02:00
|
|
|
@property
|
|
|
|
def candidates(self):
|
2012-02-19 19:27:00 +01:00
|
|
|
return self.profile.get_query_set()
|
2011-09-03 11:42:44 +02:00
|
|
|
|
|
|
|
def set_elected(self, profile, value=True):
|
|
|
|
if profile in self.candidates:
|
|
|
|
if value and not self.is_elected(profile):
|
|
|
|
self.elected.add(profile)
|
|
|
|
elif not value:
|
|
|
|
self.elected.remove(profile)
|
|
|
|
|
|
|
|
def is_elected(self, profile):
|
|
|
|
if profile in self.elected.all():
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
2011-07-31 10:46:29 +02:00
|
|
|
def gen_poll(self):
|
2012-02-19 19:27:00 +01:00
|
|
|
poll = AssignmentPoll(assignment=self)
|
2011-07-31 10:46:29 +02:00
|
|
|
poll.save()
|
2012-02-19 19:27:00 +01:00
|
|
|
poll.set_options([{'candidate': profile} for profile in self.profile.all()])
|
2011-07-31 10:46:29 +02:00
|
|
|
return poll
|
|
|
|
|
2012-02-06 22:08:08 +01:00
|
|
|
def slide(self):
|
2012-02-03 23:12:28 +01:00
|
|
|
"""
|
2012-02-06 22:08:08 +01:00
|
|
|
return the slide dict
|
2012-02-03 23:12:28 +01:00
|
|
|
"""
|
2012-02-06 22:08:08 +01:00
|
|
|
data = super(Assignment, self).slide()
|
2012-02-03 23:12:28 +01:00
|
|
|
data['assignment'] = self
|
|
|
|
data['title'] = self.name
|
2012-02-06 22:08:08 +01:00
|
|
|
data['template'] = 'projector/Assignment.html'
|
2012-02-03 23:12:28 +01:00
|
|
|
return data
|
|
|
|
|
2011-07-31 10:46:29 +02:00
|
|
|
@models.permalink
|
|
|
|
def get_absolute_url(self, link='view'):
|
|
|
|
if link == 'view':
|
|
|
|
return ('assignment_view', [str(self.id)])
|
|
|
|
if link == 'delete':
|
|
|
|
return ('assignment_delete', [str(self.id)])
|
|
|
|
|
|
|
|
def __unicode__(self):
|
|
|
|
return self.name
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
permissions = (
|
2011-09-04 12:21:58 +02:00
|
|
|
('can_see_assignment', "Can see assignment"),
|
|
|
|
('can_nominate_other', "Can nominate another person"),
|
|
|
|
('can_nominate_self', "Can nominate themselves"),
|
|
|
|
('can_manage_assignment', "Can manage assignment"),
|
2011-07-31 10:46:29 +02:00
|
|
|
)
|
2012-02-03 23:12:28 +01:00
|
|
|
|
2012-02-06 22:22:16 +01:00
|
|
|
register_slidemodel(Assignment)
|
2012-02-19 19:27:00 +01:00
|
|
|
|
|
|
|
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)
|