Added get_allowed_actions to new motion app
This commit is contained in:
parent
a27bd7eade
commit
4cc6539f0c
@ -30,7 +30,8 @@ from openslides.projector.api import register_slidemodel
|
|||||||
from openslides.projector.models import SlideMixin
|
from openslides.projector.models import SlideMixin
|
||||||
from openslides.agenda.models import Item
|
from openslides.agenda.models import Item
|
||||||
|
|
||||||
from .workflow import motion_workflow_choices, get_state, State, WorkflowError
|
from .workflow import (motion_workflow_choices, get_state, State, WorkflowError,
|
||||||
|
DUMMY_STATE)
|
||||||
|
|
||||||
|
|
||||||
# TODO: Save submitter and supporter in the same table
|
# TODO: Save submitter and supporter in the same table
|
||||||
@ -237,6 +238,9 @@ class Motion(SlideMixin, models.Model):
|
|||||||
except IndexError:
|
except IndexError:
|
||||||
return self.new_version
|
return self.new_version
|
||||||
|
|
||||||
|
def is_submitter(self, person):
|
||||||
|
self.submitter.filter(person=person).exists()
|
||||||
|
|
||||||
def is_supporter(self, person):
|
def is_supporter(self, person):
|
||||||
return self.supporter.filter(person=person).exists()
|
return self.supporter.filter(person=person).exists()
|
||||||
|
|
||||||
@ -266,7 +270,7 @@ class Motion(SlideMixin, models.Model):
|
|||||||
Create a new poll for this motion
|
Create a new poll for this motion
|
||||||
"""
|
"""
|
||||||
# TODO: auto increment the poll_number in the Database
|
# TODO: auto increment the poll_number in the Database
|
||||||
if self.state.poll:
|
if self.state.create_poll:
|
||||||
poll_number = self.polls.aggregate(Max('poll_number'))['poll_number__max'] or 0
|
poll_number = self.polls.aggregate(Max('poll_number'))['poll_number__max'] or 0
|
||||||
poll = MotionPoll.objects.create(motion=self, poll_number=poll_number + 1)
|
poll = MotionPoll.objects.create(motion=self, poll_number=poll_number + 1)
|
||||||
poll.set_options()
|
poll.set_options()
|
||||||
@ -281,7 +285,7 @@ class Motion(SlideMixin, models.Model):
|
|||||||
try:
|
try:
|
||||||
return get_state(self.state_id)
|
return get_state(self.state_id)
|
||||||
except WorkflowError:
|
except WorkflowError:
|
||||||
return None
|
return DUMMY_STATE
|
||||||
|
|
||||||
def set_state(self, next_state):
|
def set_state(self, next_state):
|
||||||
"""
|
"""
|
||||||
@ -321,6 +325,40 @@ class Motion(SlideMixin, models.Model):
|
|||||||
## number = self.number or '<i>[%s]</i>' % ugettext('no number')
|
## number = self.number or '<i>[%s]</i>' % ugettext('no number')
|
||||||
## return '(%s %s)' % (ugettext('motion'), number)
|
## return '(%s %s)' % (ugettext('motion'), number)
|
||||||
|
|
||||||
|
def get_allowed_actions(self, person):
|
||||||
|
"""
|
||||||
|
Gets a dictonary with all allowed actions for a specific person.
|
||||||
|
|
||||||
|
The dictonary contains the following actions.
|
||||||
|
|
||||||
|
* edit
|
||||||
|
* delete
|
||||||
|
* create_poll
|
||||||
|
* support
|
||||||
|
* unsupport
|
||||||
|
* change_state
|
||||||
|
* reset_state
|
||||||
|
"""
|
||||||
|
actions = {
|
||||||
|
'edit': (self.is_submitter(person) and
|
||||||
|
self.state.edit_as_submitter) or
|
||||||
|
person.has_perm('motion.can_manage_motion'),
|
||||||
|
|
||||||
|
'create_poll': person.has_perm('motion.can_manage_motion') and
|
||||||
|
self.state.create_poll,
|
||||||
|
|
||||||
|
'support': self.state.support and
|
||||||
|
config['motion_min_supporters'] > 0 and
|
||||||
|
not self.is_submitter(person),
|
||||||
|
|
||||||
|
'change_state': person.has_perm('motion.can_manage_motion'),
|
||||||
|
|
||||||
|
}
|
||||||
|
actions['delete'] = actions['edit'] #TODO: Only if the motion has no number
|
||||||
|
actions['unsupport'] = actions['support']
|
||||||
|
actions['reset_state'] = 'change_state'
|
||||||
|
return actions
|
||||||
|
|
||||||
|
|
||||||
class MotionVersion(models.Model):
|
class MotionVersion(models.Model):
|
||||||
title = models.CharField(max_length=255, verbose_name=ugettext_lazy("Title"))
|
title = models.CharField(max_length=255, verbose_name=ugettext_lazy("Title"))
|
||||||
|
@ -15,6 +15,7 @@ from django.utils.translation import ugettext as _
|
|||||||
|
|
||||||
from openslides.config.signals import default_config_value
|
from openslides.config.signals import default_config_value
|
||||||
|
|
||||||
|
|
||||||
@receiver(default_config_value, dispatch_uid="motion_default_config")
|
@receiver(default_config_value, dispatch_uid="motion_default_config")
|
||||||
def default_config(sender, key, **kwargs):
|
def default_config(sender, key, **kwargs):
|
||||||
return {
|
return {
|
||||||
|
@ -36,17 +36,6 @@
|
|||||||
|
|
||||||
<h4>{% trans "Vote results" %}:</h4>
|
<h4>{% trans "Vote results" %}:</h4>
|
||||||
{% with motion.polls.all as polls %}
|
{% with motion.polls.all as polls %}
|
||||||
{% if not polls.exists %}
|
|
||||||
{% if perms.motion.can_manage_motion %}
|
|
||||||
<a href="{% url 'motion_poll_create' motion.id %}">
|
|
||||||
<span class="button">
|
|
||||||
<span class="icon statistics">{% trans 'New vote' %}</span>
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
{% else %}
|
|
||||||
-
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
<ul class="results">
|
<ul class="results">
|
||||||
{% for poll in polls %}
|
{% for poll in polls %}
|
||||||
{% if perms.motion.can_manage_motion or poll.has_votes %}
|
{% if perms.motion.can_manage_motion or poll.has_votes %}
|
||||||
@ -73,13 +62,6 @@
|
|||||||
<img src="{% static 'images/icons/voting-total.png' %}" title="{% trans 'Votes cast' %}"> {{ poll.print_votescast }}
|
<img src="{% static 'images/icons/voting-total.png' %}" title="{% trans 'Votes cast' %}"> {{ poll.print_votescast }}
|
||||||
</div>
|
</div>
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
{% if perms.motion.can_manage_motion %}
|
|
||||||
{% if forloop.last %}
|
|
||||||
<a href="{% url 'motion_poll_create' motion.pk %}">
|
|
||||||
<span class="button"><span class="icon statistics">{% trans 'New vote' %}</span></span>
|
|
||||||
</a>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if perms.motion.can_manage_motion %}
|
{% if perms.motion.can_manage_motion %}
|
||||||
<a href="{% model_url poll %}">
|
<a href="{% model_url poll %}">
|
||||||
@ -91,5 +73,10 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
{% if allowed_actions.create_poll %}
|
||||||
|
<a href="{% url 'motion_poll_create' motion.pk %}">
|
||||||
|
<span class="button"><span class="icon statistics">{% trans 'New vote' %}</span></span>
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -64,6 +64,11 @@ class MotionDetailView(DetailView):
|
|||||||
raise Http404
|
raise Http404
|
||||||
return object
|
return object
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(MotionDetailView, self).get_context_data(**kwargs)
|
||||||
|
context['allowed_actions'] = self.object.get_allowed_actions(self.request.user)
|
||||||
|
return context
|
||||||
|
|
||||||
motion_detail = MotionDetailView.as_view()
|
motion_detail = MotionDetailView.as_view()
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,12 +8,14 @@ ugettext = lambda s: s
|
|||||||
_workflow = None
|
_workflow = None
|
||||||
|
|
||||||
class State(object):
|
class State(object):
|
||||||
def __init__(self, id, name, next_states=[], poll=False, support=False):
|
def __init__(self, id, name, next_states=[], create_poll=False, support=False,
|
||||||
|
edit_as_submitter=False):
|
||||||
self.id = id
|
self.id = id
|
||||||
self.name = name
|
self.name = name
|
||||||
self.next_states = next_states
|
self.next_states = next_states
|
||||||
self.poll = poll
|
self.create_poll = create_poll
|
||||||
self.support = support
|
self.support = support
|
||||||
|
self.edit_as_submitter=edit_as_submitter
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
@ -61,6 +63,7 @@ def get_state(state='default'):
|
|||||||
populate_workflow(default_state, _workflow)
|
populate_workflow(default_state, _workflow)
|
||||||
return get_state(state)
|
return get_state(state)
|
||||||
|
|
||||||
|
|
||||||
def populate_workflow(state, workflow):
|
def populate_workflow(state, workflow):
|
||||||
workflow[state.id] = state
|
workflow[state.id] = state
|
||||||
for s in state.next_states:
|
for s in state.next_states:
|
||||||
@ -68,8 +71,12 @@ def populate_workflow(state, workflow):
|
|||||||
populate_workflow(s, workflow)
|
populate_workflow(s, workflow)
|
||||||
|
|
||||||
|
|
||||||
default_workflow = State('pub', ugettext('Published'), support=True, next_states=[
|
DUMMY_STATE = State('dummy', ugettext('Unknwon state'))
|
||||||
State('per', ugettext('Permitted'), poll=True, next_states=[
|
|
||||||
|
default_workflow = State('pub', ugettext('Published'), support=True,
|
||||||
|
edit_as_submitter=True, next_states=[
|
||||||
|
State('per', ugettext('Permitted'), create_poll=True,
|
||||||
|
edit_as_submitter=True, next_states=[
|
||||||
State('acc', ugettext('Accepted')),
|
State('acc', ugettext('Accepted')),
|
||||||
State('rej', ugettext('Rejected')),
|
State('rej', ugettext('Rejected')),
|
||||||
State('wit', ugettext('Withdrawed')),
|
State('wit', ugettext('Withdrawed')),
|
||||||
|
Loading…
Reference in New Issue
Block a user