From 1a2f0a1b5a2bd527090102db5da1c9738d3ef8a2 Mon Sep 17 00:00:00 2001 From: Oskar Hahn Date: Fri, 1 Feb 2013 17:20:11 +0100 Subject: [PATCH] Added links to set and reset the state of a motion --- openslides/motion/models.py | 23 ++++++++++----- .../templates/motion/motion_detail.html | 9 ++++++ openslides/motion/urls.py | 10 +++++++ openslides/motion/views.py | 29 +++++++++++++++++++ openslides/motion/workflow.py | 5 +++- openslides/utils/views.py | 5 +++- 6 files changed, 72 insertions(+), 9 deletions(-) diff --git a/openslides/motion/models.py b/openslides/motion/models.py index 95d3f1770..e40aa91e4 100644 --- a/openslides/motion/models.py +++ b/openslides/motion/models.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- """ openslides.motion.models - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~~~~~~~~~~~~~~~~~~~~~~~~ Models for the motion app. @@ -88,7 +88,7 @@ class Motion(SlideMixin, models.Model): Saves the motion. Create or update a motion_version object """ if not self.state_id: - self.state = 'default' + self.reset_state() super(Motion, self).save(*args, **kwargs) for attr in ['title', 'text', 'reason']: @@ -296,18 +296,27 @@ class Motion(SlideMixin, models.Model): """ return get_state(self.state_id) - def set_state(self, state): + def set_state(self, next_state): """ Set the state of this motion. - state has to be a valid state id or State object. + next_state has to be a valid state id or State object. """ - if type(state) is not State: - state = get_state(state) - self.state_id = state.id + if type(next_state) is not State: + next_state = get_state(next_state) + if next_state in self.state.next_states: + self.state_id = next_state.id + else: + raise WorkflowError('%s is not a valid next_state' % next_state) state = property(get_state, set_state) + def reset_state(self): + """ + Set the state to the default state. + """ + self.state_id = get_state('default').id + class MotionVersion(models.Model): title = models.CharField(max_length=255, verbose_name=ugettext_lazy("Title")) diff --git a/openslides/motion/templates/motion/motion_detail.html b/openslides/motion/templates/motion/motion_detail.html index 8a498a6c5..ceae96d0d 100644 --- a/openslides/motion/templates/motion/motion_detail.html +++ b/openslides/motion/templates/motion/motion_detail.html @@ -13,7 +13,16 @@

Submitter: {% for submitter in motion.submitter.all %}{{ submitter.person }} {% endfor %}

Supporter: {% for supporter in motion.supporter.all %}{{ supporter.person }} {% endfor %}

State: {{ motion.state }}

+

possible stats:

+ + +

Versions

    {% for motion_version in motion.versions.all %} {% if motion_version.id == motion.version.id %} diff --git a/openslides/motion/urls.py b/openslides/motion/urls.py index 449de24d8..132a9b332 100644 --- a/openslides/motion/urls.py +++ b/openslides/motion/urls.py @@ -62,4 +62,14 @@ urlpatterns = patterns('openslides.motion.views', 'poll_delete', name='motion_poll_delete', ), + + url(r'^(?P\d+)/set_state/(?P[a-z]{3})/$', + 'set_state', + name='motion_set_state', + ), + + url(r'^(?P\d+)/reset_state/$', + 'reset_state', + name='motion_reset_state', + ), ) diff --git a/openslides/motion/views.py b/openslides/motion/views.py index ff627880b..e867409c1 100644 --- a/openslides/motion/views.py +++ b/openslides/motion/views.py @@ -32,6 +32,7 @@ from openslides.config.models import config from .models import Motion, MotionSubmitter, MotionSupporter, MotionPoll from .forms import (BaseMotionForm, MotionSubmitterMixin, MotionSupporterMixin, MotionCreateNewVersionMixin, ConfigForm) +from .workflow import WorkflowError class MotionListView(ListView): """ @@ -233,6 +234,34 @@ class PollDeleteView(PollMixin, DeleteView): poll_delete = PollDeleteView.as_view() +class MotionSetStateView(SingleObjectMixin, RedirectView): + permission_required = 'motion.can_manage_motion' + url_name = 'motion_detail' + model = Motion + reset = False + + def pre_redirect(self, request, *args, **kwargs): + self.object = self.get_object() + try: + if self.reset: + self.object.reset_state() + else: + self.object.state = kwargs['state'] + except WorkflowError: + messages.error(request, _('Can not set the state to: %s.') + % html_strong(kwargs['state'])) + else: + self.object.save() + messages.success(request, _('Motion status was set to: %s.' + % html_strong(self.object.state))) + + def get_url_name_args(self): + return [self.object.pk] + +set_state = MotionSetStateView.as_view() +reset_state = MotionSetStateView.as_view(reset=True) + + class Config(FormView): permission_required = 'config.can_manage_config' form_class = ConfigForm diff --git a/openslides/motion/workflow.py b/openslides/motion/workflow.py index 04178f0d0..18348c756 100644 --- a/openslides/motion/workflow.py +++ b/openslides/motion/workflow.py @@ -30,7 +30,10 @@ def motion_workflow_choices(): def get_state(state='default'): global _workflow if _workflow is not None: - return _workflow[state] + try: + return _workflow[state] + except KeyError: + raise WorkflowError('Unknown state: %s' % state) _workflow = {} for workflow in settings.MOTION_WORKFLOW: if workflow[0] == config['motion_workflow']: diff --git a/openslides/utils/views.py b/openslides/utils/views.py index a8b8657dd..1b0c49496 100644 --- a/openslides/utils/views.py +++ b/openslides/utils/views.py @@ -240,10 +240,13 @@ class RedirectView(PermissionMixin, AjaxMixin, _RedirectView): def get_redirect_url(self, **kwargs): if self.url_name is not None: - return reverse(self.url_name) + return reverse(self.url_name, args=self.get_url_name_args()) else: return super(RedirectView, self).get_redirect_url(**kwargs) + def get_url_name_args(self): + return [] + class FormView(PermissionMixin, ExtraContextMixin, UrlMixin, _FormView): def form_invalid(self, form):