Merge pull request #2291 from normanjaeckel/MotionAmendment

Reimplemented amendments for motions.
This commit is contained in:
Norman Jäckel 2016-08-31 12:39:48 +02:00 committed by GitHub
commit 08c6fa11b4
6 changed files with 73 additions and 15 deletions

View File

@ -103,26 +103,32 @@ 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')
yield ConfigVariable(
name='motions_amendments_prefix',
default_value='A',
default_value='-',
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(

View File

@ -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'):

View File

@ -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,27 @@ 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.title = $scope.$parent.motion.getTitle();
$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 +1104,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 +1380,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) {
@ -1630,8 +1664,7 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid
gettext('Amendments');
gettext('Activate amendments');
gettext('Prefix for the identifier for amendments');
/// Prefix for the identifier for amendments
gettext('A');
gettext('Apply title and text for new amendments');
// subgroup Suppoerters
gettext('Supporters');

View File

@ -31,6 +31,10 @@
<h1>{{ motion.agenda_item.getTitle() || motion.getTitle() }}</h1>
<h2>
<translate>Motion</translate> {{ motion.identifier }}
<span ng-if="parent">
(<translate>Amendment of motion</translate>
<a ui-sref="motions.motion.detail({id: parent.id})">{{ parent.identifier || parent.getTitle() }}</a>)
</span>
<span ng-if="motion.versions.length > 1" >| Version {{ motion.getVersion(version).version_number }}</span>
<span ng-if="motion.active_version != version" class="label label-warning">
<i class="fa fa-exclamation-triangle"></i>
@ -56,7 +60,7 @@
<!-- submitters -->
<h3 translate>Submitters</h3>
<div ng-repeat="submitter in motion.submitters">
{{ submitter.get_full_name() }}<br>
{{ submitter.get_full_name() }}
</div>
<!-- supporters -->
@ -77,6 +81,19 @@
<translate>Unsupport motion</translate>
</button>
</div>
<!-- Amendments -->
<div ng-if="config('motions_amendments_enabled')">
<h3 translate>Amendments</h3>
<div ng-repeat="amendment in amendments">
<a ui-sref="motions.motion.detail({id: amendment.id})">
<translate>Motion</translate> {{ amendment.identifier || amendment.getTitle() }}
</a>
</div>
<button os-perms="motions.can_create" ng-click="newAmendment()" class="btn btn-default btn-sm">
<i class="fa fa-plus"></i>
<translate>New amendment</translate>
</button>
</div>
</div>
<div class="col-md-4">
<!-- Category -->

View File

@ -1,5 +1,6 @@
<h1 ng-if="model.id" translate>Edit motion</h1>
<h1 ng-if="!model.id" translate>New motion</h1>
<h1 ng-if="!model.id && !parent" translate>New motion</h1>
<h1 ng-if="parent"><translate>New amendment of motion</translate> {{ parent.identifier || parent.getTitle() }}</h1>
<uib-alert ng-show="alert.show" type="{{ alert.type }}" ng-click="alert={}" close="alert={}">
{{ alert.msg }}

View File

@ -171,7 +171,7 @@ class ModelTest(TestCase):
motion.set_identifier()
self.assertEqual(motion.identifier, 'Parent identifier A 1')
self.assertEqual(motion.identifier, 'Parent identifier - 1')
def test_set_identifier_second_amendment(self):
"""
@ -186,7 +186,7 @@ class ModelTest(TestCase):
motion.set_identifier()
self.assertEqual(motion.identifier, 'Parent identifier A 2')
self.assertEqual(motion.identifier, 'Parent identifier - 2')
class ConfigTest(TestCase):