diff --git a/openslides/motions/config_variables.py b/openslides/motions/config_variables.py index ac16c1e08..1d0f4ceb0 100644 --- a/openslides/motions/config_variables.py +++ b/openslides/motions/config_variables.py @@ -103,13 +103,11 @@ def get_config_variables(): subgroup='General') # Amendments - # Amendments currently not implemented. (TODO: Implement it like in OpenSlides 1.7.) yield ConfigVariable( name='motions_amendments_enabled', default_value=False, input_type='boolean', label='Activate amendments', - hidden=True, weight=335, group='Motions', subgroup='Amendments') @@ -118,11 +116,19 @@ def get_config_variables(): name='motions_amendments_prefix', default_value='A', label='Prefix for the identifier for amendments', - hidden=True, weight=340, group='Motions', subgroup='Amendments') + yield ConfigVariable( + name='motions_amendments_apply_title_text', + default_value=False, + input_type='boolean', + label='Apply title and text for new amendments', + weight=342, + group='Motions', + subgroup='Amendments') + # Supporters yield ConfigVariable( diff --git a/openslides/motions/serializers.py b/openslides/motions/serializers.py index c1f4a291c..714d56f89 100644 --- a/openslides/motions/serializers.py +++ b/openslides/motions/serializers.py @@ -243,7 +243,7 @@ class MotionSerializer(ModelSerializer): 'polls', 'agenda_item_id', 'log_messages',) - read_only_fields = ('parent', 'state') # Some other fields are also read_only. See definitions above. + read_only_fields = ('state',) # Some other fields are also read_only. See definitions above. @transaction.atomic def create(self, validated_data): @@ -257,6 +257,7 @@ class MotionSerializer(ModelSerializer): motion.identifier = validated_data.get('identifier') motion.category = validated_data.get('category') motion.origin = validated_data.get('origin', '') + motion.parent = validated_data.get('parent') motion.reset_state(validated_data.get('workflow_id')) motion.save() if validated_data.get('submitters'): diff --git a/openslides/motions/static/js/motions/base.js b/openslides/motions/static/js/motions/base.js index 43b7fe983..2073879b2 100644 --- a/openslides/motions/static/js/motions/base.js +++ b/openslides/motions/static/js/motions/base.js @@ -271,7 +271,7 @@ angular.module('OpenSlidesApp.motions', [ 'motions/motionpoll': { localField: 'polls', foreignKey: 'motion_id', - } + }, }, hasOne: { 'motions/workflowstate': { diff --git a/openslides/motions/static/js/motions/site.js b/openslides/motions/static/js/motions/site.js index 2d81b467a..9da5fe61f 100644 --- a/openslides/motions/static/js/motions/site.js +++ b/openslides/motions/static/js/motions/site.js @@ -272,6 +272,9 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid motion: function(Motion, $stateParams) { return Motion.find($stateParams.id); }, + motions: function(Motion) { + return Motion.findAll(); + }, categories: function(Category) { return Category.findAll(); }, @@ -819,7 +822,7 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid 'gettextCatalog', 'diffService', function($scope, $http, $timeout, ngDialog, MotionForm, Motion, Category, Mediafile, Tag, User, Workflow, Editor, - Config,motion, SingleMotionContentProvider, MotionContentProvider, PdfMakeConverter, + Config, motion, SingleMotionContentProvider, MotionContentProvider, PdfMakeConverter, PdfMakeDocumentProvider, gettextCatalog, diffService) { Motion.bindOne(motion.id, $scope, 'motion'); Category.bindAll({}, $scope, 'categories'); @@ -832,6 +835,10 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid $scope.isCollapsed = true; $scope.lineNumberMode = Config.get('motions_default_line_numbering').value; $scope.lineBrokenText = motion.getTextWithLineBreaks($scope.version); + if (motion.parent_id) { + Motion.bindOne(motion.parent_id, $scope, 'parent'); + } + $scope.amendments = Motion.filter({parent_id: motion.id}); $scope.makePDF = function(){ var content = motion.getText($scope.version) + motion.getReason($scope.version), @@ -875,6 +882,15 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid $scope.unsupport = function () { $http.delete('/rest/motions/motion/' + motion.id + '/support/'); }; + // open dialog for new amendment + $scope.newAmendment = function () { + var dialog = MotionForm.getDialog(); + if (dialog.scope === undefined) { + dialog.scope = {}; + } + dialog.scope = $scope; + ngDialog.open(dialog); + }; // update state $scope.updateState = function (state_id) { $http.put('/rest/motions/motion/' + motion.id + '/set_state/', {'state': state_id}); @@ -1038,6 +1054,7 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid .controller('MotionCreateCtrl', [ '$scope', + '$state', 'gettext', 'Motion', 'MotionForm', @@ -1049,7 +1066,7 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid 'Workflow', 'Agenda', 'AgendaUpdate', - function($scope, gettext, Motion, MotionForm, Category, Config, Mediafile, Tag, User, Workflow, Agenda, AgendaUpdate) { + function($scope, $state, gettext, Motion, MotionForm, Category, Config, Mediafile, Tag, User, Workflow, Agenda, AgendaUpdate) { Category.bindAll({}, $scope, 'categories'); Mediafile.bindAll({}, $scope, 'mediafiles'); Tag.bindAll({}, $scope, 'tags'); @@ -1057,13 +1074,26 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid Workflow.bindAll({}, $scope, 'workflows'); $scope.model = {}; - // set default values for create form + + // Check whether this is a new amendment. + var isAmendment = $scope.$parent.motion && $scope.$parent.motion.id; + + // Set default values for create form // ... set preamble config value as text $scope.model.text = Config.get('motions_preamble').value; + // ... for amendments add parent_id + if (isAmendment) { + if (Config.get('motions_amendments_apply_title_text').value) { + $scope.model.text = $scope.$parent.motion.getText(); + } + $scope.model.parent_id = $scope.$parent.motion.id; + Motion.bindOne($scope.model.parent_id, $scope, 'parent'); + } // ... preselect default workflow $scope.model.workflow_id = Config.get('motions_workflow').value; // get all form fields $scope.formFields = MotionForm.getFormFields(); + // save motion $scope.save = function (motion) { Motion.create(motion).then( @@ -1073,6 +1103,9 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid var changes = [{key: 'type', value: (motion.showAsAgendaItem ? 1 : 2)}, {key: 'parent_id', value: motion.agenda_parent_item_id}]; AgendaUpdate.saveChanges(success.agenda_item_id, changes); + if (isAmendment) { + $state.go('motions.motion.detail', {id: success.id}); + } $scope.closeThisDialog(); } ); @@ -1346,7 +1379,7 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid var importedUsers = []; var importedCategories = []; // collect users and categories - angular.forEach($scope.motions, function (motion){ + angular.forEach($scope.motions, function (motion) { if (!motion.importerror) { // collect user if not exists if (!motion.submitters_id && motion.submitter) { diff --git a/openslides/motions/static/templates/motions/motion-detail.html b/openslides/motions/static/templates/motions/motion-detail.html index f76fbb933..78f33e69f 100644 --- a/openslides/motions/static/templates/motions/motion-detail.html +++ b/openslides/motions/static/templates/motions/motion-detail.html @@ -31,6 +31,10 @@

{{ motion.agenda_item.getTitle() || motion.getTitle() }}

Motion {{ motion.identifier }} + + (Amendment of motion + {{ parent.identifier || parent.getTitle() }}) + | Version {{ motion.getVersion(version).version_number }} @@ -56,7 +60,7 @@

Submitters

- {{ submitter.get_full_name() }}
+ {{ submitter.get_full_name() }}
@@ -77,6 +81,19 @@ Unsupport motion + +
+

Amendments

+
+ + Motion {{ amendment.identifier || amendment.getTitle() }} + +
+ +
diff --git a/openslides/motions/static/templates/motions/motion-form.html b/openslides/motions/static/templates/motions/motion-form.html index 5908b9dc7..82ecda623 100644 --- a/openslides/motions/static/templates/motions/motion-form.html +++ b/openslides/motions/static/templates/motions/motion-form.html @@ -1,5 +1,6 @@

Edit motion

-

New motion

+

New motion

+

New amendment of motion {{ parent.identifier || parent.getTitle() }}

{{ alert.msg }}