assignment and application can be beamt without a item-element

This commit is contained in:
Oskar Hahn 2012-02-03 23:12:28 +01:00
parent fe2efb03fa
commit 5f6c96b3e8
21 changed files with 223 additions and 246 deletions

View File

@ -12,7 +12,6 @@
from django.contrib import admin
from openslides.agenda.models import Item, ItemText
from openslides.agenda.models import Item
admin.site.register(Item)
admin.site.register(ItemText)

View File

@ -15,23 +15,7 @@ from django.contrib import messages
from django.core.context_processors import csrf
from openslides.system.api import config_get
def get_active_item(only_id=False):
"""
Returns the active Item. If no item is active, or it can not find an Item,
it raise Item.DoesNotExist
if only_id is True, returns only the id of this item. Returns None if not Item
is active. Does not Raise Item.DoesNotExist
"""
from agenda.models import Item
id = config_get("presentation", None)
if only_id:
if id is None:
return None
return int(id)
return Item.objects.get(pk=id)
from beamer.api import get_active_element
def is_summary():
@ -40,7 +24,7 @@ def is_summary():
"""
from agenda.models import Item
try:
get_active_item()
get_active_element()
except Item.DoesNotExist:
return True
if config_get('summary', False):

View File

@ -13,8 +13,7 @@
from django.forms import Form, ModelForm, IntegerField, ChoiceField, \
ModelChoiceField, HiddenInput, Select
from django.utils.translation import ugettext as _
from openslides.agenda.models import Item, ItemText, ItemApplication, \
ItemAssignment
from openslides.agenda.models import Item, ItemText
class ItemFormText(ModelForm):
error_css_class = 'error'
@ -26,28 +25,6 @@ class ItemFormText(ModelForm):
exclude = ('closed', 'weight')
class ItemFormApplication(ModelForm):
error_css_class = 'error'
required_css_class = 'required'
items = Item.objects.all().filter(parent=None).order_by('weight')
parent = ModelChoiceField(queryset=items, label=_("Parent item"), required=False)
class Meta:
model = ItemApplication
exclude = ('closed', 'weight')
class ItemFormAssignment(ModelForm):
error_css_class = 'error'
required_css_class = 'required'
items = Item.objects.all().filter(parent=None).order_by('weight')
parent = ModelChoiceField(queryset=items, label=_("Parent item"), required=False)
class Meta:
model = ItemAssignment
exclude = ('closed', 'weight')
def genweightchoices():
l = []
for i in range(-50, 51):
@ -61,10 +38,3 @@ class ElementOrderForm(Form):
label="")
self = IntegerField(widget=HiddenInput(attrs={'class': 'menu-mlid'}))
parent = IntegerField(widget=HiddenInput(attrs={'class': 'menu-plid'}))
MODELFORM = {
'ItemText': ItemFormText,
'ItemApplication': ItemFormApplication,
'ItemAssignment': ItemFormAssignment,
}

View File

@ -18,40 +18,45 @@ except ImportError:
from django.db import models
from django.utils.translation import ugettext as _
from model_utils.models import InheritanceCastModel
from openslides.agenda.api import get_active_item
from openslides.system.api import config_set
from openslides.application.models import Application
from openslides.poll.models import Poll
from openslides.assignment.models import Assignment
from beamer.models import Element
from beamer.api import element_register
from system.api import config_set
from application.models import Application
from poll.models import Poll
from assignment.models import Assignment
class Item(InheritanceCastModel):
class Item(models.Model, Element):
"""
The BasisItem.
Has all the attributes all Items need.
An Agenda Item
"""
title = models.CharField(max_length=100, verbose_name=_("Title"))
text = models.TextField(null=True, blank=True, verbose_name=_("Text"))
transcript = models.TextField(null=True, blank=True, verbose_name=_("Transcript"))
closed = models.BooleanField(default=False, verbose_name=_("Closed"))
weight = models.IntegerField(default=0, verbose_name=_("Weight"))
parent = models.ForeignKey('self', blank=True, null=True)
hidden = models.BooleanField(default=False,
verbose_name=_("Hidden (visible for agenda manager only)"))
prefix = 'item'
@property
def active(self):
def beamer(self):
"""
Return True, if the the item is the active one.
Return a map with all Data for the Beamer
"""
return True if get_active_item(only_id=True) == self.id else False
return {
'item': self,
'title': self.title,
'template': 'beamer/AgendaText.html',
}
@property
def active_parent(self):
"""
Return True if the item has a activ parent
"""
if get_active_item(only_id=True) in \
if get_active_element(only_id=True) in \
[parent.id for parent in self.parents]:
return True
return False
@ -60,7 +65,7 @@ class Item(InheritanceCastModel):
"""
Appoint this item as the active one.
"""
config_set("presentation", self.id)
Element.set_active(self)
if summary:
config_set("summary", True)
else:
@ -182,32 +187,8 @@ class Item(InheritanceCastModel):
)
class ItemText(Item):
"""
An Item with a TextField.
"""
text = models.TextField(null=True, blank=True, verbose_name=_("Text"))
class Meta:
pass
ItemText = Item # ItemText is Depricated
class ItemApplication(Item):
"""
An Item which is connected to an application.
"""
application = models.ForeignKey(Application, verbose_name=_("Application"))
class ItemAssignment(Item):
"""
An Item which is connected to an assignment.
"""
assignment = models.ForeignKey(Assignment, verbose_name=_("Election"))
class ItemPoll(Item):
"""
An Item which is connected to a poll
"""
poll = models.ForeignKey(Poll, verbose_name=_("Poll"))
element_register(Item.prefix, Item)

View File

@ -8,7 +8,7 @@
<ul>
<li class="{% if request.path == url_itemoverview %}selected{% endif %}"><a href="{% url item_overview %}">{%trans "All items" %}</a></li>
{% if perms.agenda.can_manage_agenda %}
<li class="{% active request '/agenda/new/' %}"><a href="{% url item_new 'ItemText' %}">{%trans "New item" %}</a></li>
<li class="{% active request '/agenda/new/' %}"><a href="{% url item_new %}">{%trans "New item" %}</a></li>
{% endif %}
{% if perms.agenda.can_see_projector %}
<li><a href="{% url beamer_show %}"><img src="/static/images/icons/video-projector.png"> {%trans 'Projector view' %}</a></li>

View File

@ -40,14 +40,9 @@ urlpatterns = patterns('agenda.views',
url(r'^agenda/new/$', 'edit',
name='item_new_default'),
url(r'^agenda/new/(?P<form>ItemText|ItemApplication|ItemPoll|'
r'ItemAssignment)/$', 'edit',
url(r'^agenda/new$', 'edit',
name='item_new'),
url(r'^agenda/new/(?P<form>ItemText|ItemApplication|ItemPoll|'
r'ItemAssignment)/(?P<default>\d+)/$', 'edit',
name='item_new_default'),
url(r'^agenda/(?P<item_id>\d+)/del/$', 'delete',
name='item_delete'),

View File

@ -17,18 +17,19 @@ from django.core.urlresolvers import reverse
from django.contrib import messages
from django.utils.translation import ugettext as _
from openslides.agenda.models import Item
from openslides.agenda.api import get_active_item, is_summary, children_list, \
from beamer.api import get_active_element
from agenda.models import Item
from agenda.api import is_summary, children_list, \
del_confirm_form_for_items
from openslides.agenda.forms import ElementOrderForm, MODELFORM
from openslides.application.models import Application
from openslides.assignment.models import Assignment
from openslides.poll.models import Poll
from openslides.system.api import config_set, config_get
from openslides.utils.template import render_block_to_string
from openslides.utils.utils import template, permission_required, \
from agenda.forms import ElementOrderForm, ItemFormText
from application.models import Application
from assignment.models import Assignment
from poll.models import Poll
from system.api import config_set, config_get
from utils.template import render_block_to_string
from utils.utils import template, permission_required, \
del_confirm_form, ajax_request
from openslides.utils.pdf import print_agenda
from utils.pdf import print_agenda
from poll.models import Poll, Option
def view(request, item_id):
@ -69,7 +70,7 @@ def overview(request):
items = children_list(Item.objects.filter(parent=None).exclude(hidden=True).order_by('weight'))
items_hidden = children_list(Item.objects.filter(parent=None).exclude(hidden=False).order_by('weight'))
try:
overview = is_summary() and not get_active_item()
overview = is_summary() and not get_active_element()
except Item.DoesNotExist:
overview = True
return {
@ -163,25 +164,7 @@ def edit(request, item_id=None, form='ItemText', default=None):
else:
messages.error(request, _('Please check the form for errors.'))
else:
initial = {}
if default:
if form == "ItemAssignment":
assignment = Assignment.objects.get(pk=default)
initial = {
'assignment': assignment,
'title': assignment.name,
}
elif form == "ItemApplication":
application = Application.objects.get(pk=default)
initial = {
'application': application,
'title': application.title,
}
if item_id is None:
form = MODELFORM[form](initial=initial)
else:
form = item.edit_form()
form = ItemFormText()
return { 'form': form,
'item': item }

View File

@ -17,12 +17,16 @@ from django.db.models import Max
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
from openslides.participant.models import Profile
from openslides.system.api import config_get
from openslides.utils.utils import _propper_unicode
from beamer.api import element_register
from beamer.models import Element
from participant.models import Profile
from system.api import config_get
from utils.utils import _propper_unicode
class Application(models.Model):
class Application(models.Model, Element):
prefix = "application"
STATUS = (
('pub', _('Published')),
('per', _('Permitted')),
@ -365,12 +369,6 @@ class Application(models.Model):
actions.append("permitversion")
actions.append("rejectversion")
if self.number:
if self.itemapplication_set.all():
actions.append("activateitem")
else:
actions.append("createitem")
return actions
def delete(self, force=False):
@ -432,6 +430,16 @@ class Application(models.Model):
results.append([option.yes, option.no, option.undesided, poll.votesinvalidf, poll.votescastf])
return results
def beamer(self):
"""
return the beamer dict
"""
data = super(Application, self).beamer()
data['application'] = self
data['title'] = self.title
data['template'] = 'beamer/Application.html'
return data
@models.permalink
def get_absolute_url(self, link='view'):
if link == 'view':
@ -474,3 +482,5 @@ class AVersion(models.Model):
.filter(application=self.application) \
.filter(id__lte=self.id).count()
return self._aid
element_register(Application.prefix, Application)

View File

@ -154,19 +154,10 @@
</p>
{% endif %}
{% if "createitem" in actions %}
<h4></h4>
<a href='{% url item_new_default 'ItemApplication' application.id %}'>
<span class="button"><span class="icon item">{%trans 'New agenda item' %}</span></span>
</a>
{% endif %}
{% if "activateitem" in actions %}
<h4></h4>
<a href='{% url application_activate_item application.id %}'>
<span class="button"><span class="icon projector">{%trans 'Show agenda item' %}</span></span>
</a>
{% endif %}
<h4></h4>
<a href='{% url application_activate_item application.id %}'>
<span class="button"><span class="icon projector">{%trans 'Beam Application' %}</span></span>
</a>
{% if "acc" in actions or "rej" in actions %}
<h4>{% trans "Result after vote" %}:</h4>

View File

@ -6,19 +6,19 @@
<div id="sidebar">
<div class="box">
<p><b>{%trans "Status" %}:</b><br>
{% if item.application.status != "pub" %}
{%trans item.application.get_status_display %}
{% if application.status != "pub" %}
{%trans application.get_status_display %}
<br>
{% else %}
{% for note in item.application.notes %}
{% for note in application.notes %}
{{ note }}
{% endfor %}
{% endif %}
</p>
<p><b>{% trans "Submitter" %}:</b><br>
{{ item.application.submitter.profile }}</p>
{% with item.application.poll_set.all as polls %}
{{ application.submitter.profile }}</p>
{% with application.poll_set.all as polls %}
{% if polls|length > 0 and polls.0.has_vote %}
<p><b>{% trans "Poll result" %}:</b></p>
{% for p in polls %}
@ -47,14 +47,14 @@
</div>
</div>
<h1>{% trans "Application No." %} {{ item.application.number }}</h1>
<h1>{% trans "Application No." %} {{ application.number }}</h1>
<b>{{ item.title }}</b>
<p>
<div class="text">{{ item.application.public_version.text|linebreaks }}</div>
{% if item.application.public_version.reason %}
<div class="text">{{ application.public_version.text|linebreaks }}</div>
{% if application.public_version.reason %}
<br>
<div class="reason"><p><b>{% trans "Reason" %}:</b></p>
{{ item.application.public_version.reason|linebreaks }}</div>
{{ application.public_version.reason|linebreaks }}</div>
{% endif %}
</p>
{% endblock %}

View File

@ -332,8 +332,8 @@ def unsupport(request, application_id):
@permission_required('application.can_manage_application')
def set_active(request, application_id):
item = Item.objects.get(itemapplication__application__id=application_id)
item.set_active(False)
application = Application.objects.get(pk=application_id)
application.set_active()
return redirect(reverse('application_view', args=[application_id]))

View File

@ -15,8 +15,12 @@ from django.utils.translation import ugettext as _
from participant.models import Profile
from beamer.models import Element
from beamer.api import element_register
class Assignment(models.Model):
class Assignment(models.Model, Element):
prefix = 'assignment'
STATUS = (
('sea', _('Searching for candidates')),
('vot', _('Voting')),
@ -113,6 +117,16 @@ class Assignment(models.Model):
poll.add_option(candidate)
return poll
def beamer(self):
"""
return the beamer dict
"""
data = super(Assignment, self).beamer()
data['assignment'] = self
data['title'] = self.name
data['template'] = 'beamer/Assignment.html'
return data
@models.permalink
def get_absolute_url(self, link='view'):
if link == 'view':
@ -130,3 +144,5 @@ class Assignment(models.Model):
('can_nominate_self', "Can nominate themselves"),
('can_manage_assignment', "Can manage assignment"),
)
element_register(Assignment.prefix, Assignment)

View File

@ -36,21 +36,14 @@
</span>
</a>
{% if not assignment.itemassignment_set.all %}
<h4></h4>
<a href='{% url item_new_default 'ItemAssignment' assignment.id %}'>
<span class="button">
<span class="icon item">{%trans 'New agenda item' %}</span>
</span>
</a>
{% else %}
<h4></h4>
<a href='{% url assignment_activate_item assignment.id %}'>
<span class="button">
<span class="icon projector">{%trans 'Show agenda item' %}</span>
<span class="icon projector">{%trans 'Beam assignment' %}</span>
</span>
</a>
{% endif %}
</div>
{% endif %}

View File

@ -5,31 +5,31 @@
<script type="text/javascript" src="/static/javascript/assignment.js"></script>
{% endblock %}
{% block content %}
<h1>{% trans "Election" %}: {{ item.assignment }}</h1>
<h1>{% trans "Election" %}: {{ assignment }}</h1>
{% if item.assignment.status != "fin" %}
{% if assignment.status != "fin" %}
<div id="sidebar">
<div class="box">
<p><b>{% trans "Status" %}:</b><br>
{% trans item.assignment.get_status_display %}</p>
{% if item.assignment.status == "sea" or item.assignment.status == "vot" %}
{% trans assignment.get_status_display %}</p>
{% if assignment.status == "sea" or assignment.status == "vot" %}
<p><b>{% trans "Number of available posts" %}:</b><br>
{{ item.assignment.posts }}</p>
{{ assignment.posts }}</p>
{% endif %}
</div>
</div>
{% endif %}
{% if not item.assignment.profile.exists %}
{% if not assignment.profile.exists %}
<p>
<div class="text">{{ item.assignment.description|linebreaks }}</div>
<div class="text">{{ assignment.description|linebreaks }}</div>
</p>
{% endif %}
{% if item.assignment.profile.exists and item.assignment.status != "fin" %}
{% if assignment.profile.exists and assignment.status != "fin" %}
<h3>{% trans "Candidates" %}</h3>
<ol>
{% for profile in item.assignment.profile.all|dictsort:"user.first_name" %}
{% for profile in assignment.profile.all|dictsort:"user.first_name" %}
<li>{{ profile }} </li>
{% empty %}
<li style="list-style: none outside none;">
@ -46,7 +46,7 @@
<table>
<tr>
<th>{% trans "Candidates" %}</th>
{% for poll in item.assignment.poll_set.all %}
{% for poll in assignment.poll_set.all %}
{% if poll.published %}
<th><nobr>{{forloop.counter}}. {% trans "ballot" %}</nobr></th>
{% endif %}
@ -78,7 +78,7 @@
</tr>
{% empty %}
<tr>
<td {% if item.assignment.profile.exist %}colspan="2"{% endif %}><i>{% trans "No ballots available." %}</i></td>
<td {% if assignment.profile.exist %}colspan="2"{% endif %}><i>{% trans "No ballots available." %}</i></td>
</tr>
{% endfor %}
<tr>

View File

@ -187,8 +187,8 @@ def delother(request, assignment_id, profile_id):
@permission_required('assignment.can_manage_application')
def set_active(request, assignment_id):
item = Item.objects.get(itemassignment__assignment__id=assignment_id)
item.set_active(False)
assignment = Assignment.objects.get(pk=assignment_id)
assignment.set_active()
return redirect(reverse('assignment_view', args=[assignment_id]))
@permission_required('assignment.can_manage_assignment')

View File

@ -1,3 +1,35 @@
from system.api import config_set, config_get
from beamer.models import ELEMENT
def get_element_from_eid(eid):
try:
model, id = eid.split()
except ValueError:
return None # We need a elementError hier
return ELEMENT[model].objects.get(pk=id)
def get_active_element(only_eid=False):
"""
Returns the active element. If no element is active, or it can not find an Item,
it raise Element.DoesNotExist
if only_id is True, returns only the id of this item. Returns None if not Item
is active. Does not Raise Item.DoesNotExist
"""
from beamer.models import Element
eid = config_get("presentation", None)
if only_eid:
return eid
return get_element_from_eid(eid)
def element_register(prefix, model):
ELEMENT[prefix] = model
def assignment_votes(item):
votes = []
if item.type == "ItemAssignment":

View File

@ -1,3 +1,40 @@
from django.db import models
# Create your models here.
from system.api import config_set, config_get
ELEMENT = {}
class Element(object):
def beamer(self):
"""
Return a map with all Data for the Beamer
"""
return {
'element': self,
'title': 'dummy-title',
}
@property
def eid(self):
"""
Return the eid from this element
"""
for key, value in ELEMENT.iteritems():
if type(self) == value:
return "%s %d" % (key, self.id)
return None
@property
def active(self):
"""
Return True, if the the element is the active one.
"""
from beamer.api import get_active_element
return True if get_active_element(only_eid=True) == self.eid else False
def set_active(self):
"""
Appoint this item as the active one.
"""
config_set("presentation", "%s %d" % (self.prefix, self.id))

View File

@ -1,19 +0,0 @@
{% extends "beamer.html" %}
{% block title %}{{ block.super }} - {{ item.title }}{% endblock %}
{% block content %}
{%trans "Poll about" %}:
<h1>{{ item.title }}</h1>
<table>
{% for option in item.poll.get_options %}
<tr>
<td>{{ option }}</td>
<td>{{ option.voteyes }}</td>
{% if item.poll.optiondecision %}
<td>{{ option.voteno }}</td>
<td>{{ option.voteundesided }}</td>
{% endif %}
</tr>
{% endfor %}
</table>
{% endblock %}

View File

@ -24,11 +24,11 @@ from utils.template import render_block_to_string
from system.api import config_set, config_get
from agenda.api import get_active_item, is_summary, children_list, \
from agenda.api import is_summary, children_list, \
del_confirm_form_for_items
from agenda.models import Item
from beamer.api import assignment_votes, assignment_polls
from beamer.api import get_active_element, assignment_votes, assignment_polls
@permission_required('agenda.can_see_projector')
@ -36,46 +36,51 @@ def beamer(request):
"""
Shows the active Slide.
"""
data = {'ajax': 'on'}
template = ''
try:
item = get_active_item()
votes = assignment_votes(item)
polls = assignment_polls(item)
if is_summary():
items = item.children.filter(hidden=False)
data['items'] = items
data['title'] = item.title
template = 'beamer/overview.html'
element = get_active_element()
except Item.DoesNotExist: #TODO: It has to be an Element.DoesNotExist
element = None
if element is None:
data = {}
else:
data = element.beamer()
data['ajax'] = 'on'
if element is None or (type(element) == Item and is_summary()):
if element is None:
items = Item.objects.filter(parent=None) \
.filter(hidden=False).order_by('weight')
data['title'] = _("Agenda")
else:
data['item'] = item.cast()
data['title'] = item.title
data['votes'] = votes
data['polls'] = polls
template = 'beamer/%s.html' % (item.type)
except Item.DoesNotExist:
items = Item.objects.filter(parent=None).filter(hidden=False) \
.order_by('weight')
items = element.children.filter(hidden=False)
data['title'] = element.title
data['items'] = items
data['title'] = _("Agenda")
template = 'beamer/overview.html'
data['template'] = 'beamer/AgendaSummary.html'
if request.is_ajax():
content = render_block_to_string(template, 'content', data)
jsondata = {'content': content,
'title': data['title'],
'time': datetime.now().strftime('%H:%M'),
'bigger': config_get('bigger'),
'up': config_get('up'),
'countdown_visible': config_get('countdown_visible'),
'countdown_time': config_get('agenda_countdown_time'),
'countdown_control': config_get('countdown_control'),
}
content = render_block_to_string(data['template'], 'content', data)
jsondata = {
'content': content,
'title': data['title'],
'time': datetime.now().strftime('%H:%M'),
'bigger': config_get('bigger'),
'up': config_get('up'),
'countdown_visible': config_get('countdown_visible'),
'countdown_time': config_get('agenda_countdown_time'),
'countdown_control': config_get('countdown_control'),
}
return ajax_request(jsondata)
else:
return render_to_response(template,
data,
context_instance=RequestContext(request))
return render_to_response(
data['template'],
data,
context_instance=RequestContext(request)
)
@permission_required('agenda.can_manage_agenda')