diff --git a/openslides/core/static/js/core/site.js b/openslides/core/static/js/core/site.js index 203c38b26..14a2e1191 100644 --- a/openslides/core/static/js/core/site.js +++ b/openslides/core/static/js/core/site.js @@ -177,12 +177,12 @@ angular.module('OpenSlidesApp.core.site', [ // Split up state name // example: "motions.motion.detail.update" -> ['motions', 'motion', 'detail', 'update'] - var patterns = state.name.split('.') + var patterns = state.name.split('.'); // set app and module name from state // - appName: patterns[0] (e.g. "motions") // - moduleNames: patterns without first element (e.g. ["motion", "detail", "update"]) - var appName = '' + var appName = ''; var moduleName = ''; var moduleNames = []; if (patterns.length > 0) { @@ -194,7 +194,7 @@ angular.module('OpenSlidesApp.core.site', [ // example: ["motionBlock", "detail"] -> ["motion-block", "detail"] for (var i = 0; i < moduleNames.length; i++) { moduleNames[i] = moduleNames[i].replace(/([a-z\d])([A-Z])/g, '$1-$2').toLowerCase(); - }; + } // use special templateUrl for create and update view // example: ["motion", "detail", "update"] -> "motion-form" @@ -1436,7 +1436,11 @@ angular.module('OpenSlidesApp.core.site', [ } ]) -.filter("toArray", function(){ +.filter('toArray', function(){ + /* + * Transforms an object to an array. Items of the array are the values of + * the object elements. + */ return function(obj) { var result = []; angular.forEach(obj, function(val, key) { diff --git a/openslides/motions/models.py b/openslides/motions/models.py index 421786e31..fdde434ef 100644 --- a/openslides/motions/models.py +++ b/openslides/motions/models.py @@ -17,6 +17,7 @@ from openslides.poll.models import ( BaseVote, CollectDefaultVotesMixin, ) +from openslides.utils.autoupdate import inform_changed_data from openslides.utils.models import RESTModelMixin from openslides.utils.search import user_name_helper @@ -192,7 +193,7 @@ class Motion(RESTModelMixin, models.Model): return self.title # TODO: Use transaction - def save(self, use_version=None, *args, **kwargs): + def save(self, use_version=None, skip_autoupdate=False, *args, **kwargs): """ Save the motion. @@ -225,14 +226,19 @@ class Motion(RESTModelMixin, models.Model): if not self.identifier and isinstance(self.identifier, str): self.identifier = None - super(Motion, self).save(*args, **kwargs) + # Always skip autoupdate. Maybe we run it later in this method. + super(Motion, self).save(skip_autoupdate=True, *args, **kwargs) if 'update_fields' in kwargs: # Do not save the version data if only some motion fields are updated. + if not skip_autoupdate: + inform_changed_data(self) return if use_version is False: # We do not need to save the version. + if not skip_autoupdate: + inform_changed_data(self) return elif use_version is None: use_version = self.get_last_version() @@ -249,6 +255,8 @@ class Motion(RESTModelMixin, models.Model): if use_version.id is None: if not self.version_data_changed(use_version): # We do not need to save the version. + if not skip_autoupdate: + inform_changed_data(self) return version_number = self.versions.aggregate(Max('version_number'))['version_number__max'] or 0 use_version.version_number = version_number + 1 @@ -256,16 +264,22 @@ class Motion(RESTModelMixin, models.Model): # Necessary line if the version was set before the motion got an id. use_version.motion = use_version.motion - use_version.save() + # Always skip autoupdate. Maybe we run it later in this method. + use_version.save(skip_autoupdate=True) # Set the active version of this motion. This has to be done after the # version is saved in the database. # TODO: Move parts of these last lines of code outside the save method - # when other versions than the last ones should be edited later on. + # when other versions than the last one should be edited later on. if self.active_version is None or not self.state.leave_old_version_active: # TODO: Don't call this if it was not a new version self.active_version = use_version - self.save(update_fields=['active_version']) + # Always skip autoupdate. Maybe we run it later in this method. + self.save(update_fields=['active_version'], skip_autoupdate=True) + + # Finally run autoupdate if it is not skipped by caller. + if not skip_autoupdate: + inform_changed_data(self) def version_data_changed(self, version): """ @@ -530,6 +544,13 @@ class Motion(RESTModelMixin, models.Model): recommendation = State.objects.get(pk=recommendation) self.recommendation = recommendation + def follow_recommendation(self): + """ + Set the state of this motion to its recommendation. + """ + if self.recommendation is not None: + self.set_state(self.recommendation) + def get_agenda_title(self): """ Return a simple title string for the agenda. @@ -624,7 +645,7 @@ class Motion(RESTModelMixin, models.Model): return actions - def write_log(self, message_list, person=None): + def write_log(self, message_list, person=None, skip_autoupdate=False): """ Write a log message. @@ -633,7 +654,8 @@ class Motion(RESTModelMixin, models.Model): """ if person and not person.is_authenticated(): person = None - MotionLog.objects.create(motion=self, message_list=message_list, person=person) + motion_log = MotionLog(motion=self, message_list=message_list, person=person) + motion_log.save(skip_autoupdate=skip_autoupdate) def is_amendment(self): """ diff --git a/openslides/motions/static/js/motions/motion-block.js b/openslides/motions/static/js/motions/motion-block.js index ea45af12a..adff7931e 100644 --- a/openslides/motions/static/js/motions/motion-block.js +++ b/openslides/motions/static/js/motions/motion-block.js @@ -127,6 +127,7 @@ angular.module('OpenSlidesApp.motions.motionBlock', []) .controller('MotionBlockDetailCtrl', [ '$scope', + '$http', 'ngDialog', 'Motion', 'MotionBlockForm', @@ -134,7 +135,7 @@ angular.module('OpenSlidesApp.motions.motionBlock', []) 'motionBlock', 'Projector', 'ProjectionDefault', - function($scope, ngDialog, Motion, MotionBlockForm, MotionBlock, motionBlock, Projector, ProjectionDefault) { + function($scope, $http, ngDialog, Motion, MotionBlockForm, MotionBlock, motionBlock, Projector, ProjectionDefault) { MotionBlock.bindOne(motionBlock.id, $scope, 'motionBlock'); Motion.bindAll({}, $scope, 'motions'); $scope.$watch(function () { @@ -148,6 +149,15 @@ angular.module('OpenSlidesApp.motions.motionBlock', []) $scope.openDialog = function (topic) { ngDialog.open(MotionBlockForm.getDialog(motionBlock)); }; + $scope.followRecommendations = function () { + $http.post('/rest/motions/motion-block/' + motionBlock.id + '/follow_recommendations/') + .success(function(data) { + $scope.alert = { type: 'success', msg: data.detail, show: true }; + }) + .error(function(data) { + $scope.alert = { type: 'danger', msg: data.detail, show: true }; + }); + }; } ]) diff --git a/openslides/motions/static/templates/motions/motion-block-detail.html b/openslides/motions/static/templates/motions/motion-block-detail.html index 87d649fd0..8028ff409 100644 --- a/openslides/motions/static/templates/motions/motion-block-detail.html +++ b/openslides/motions/static/templates/motions/motion-block-detail.html @@ -26,12 +26,11 @@