diff --git a/openslides/assignments/static/js/assignments/base.js b/openslides/assignments/static/js/assignments/base.js
index da843f9a8..35d595d02 100644
--- a/openslides/assignments/static/js/assignments/base.js
+++ b/openslides/assignments/static/js/assignments/base.js
@@ -6,9 +6,55 @@ angular.module('OpenSlidesApp.assignments', [])
.factory('AssignmentPollOption', [
'DS',
- function (DS) {
+ 'jsDataModel',
+ 'gettextCatalog',
+ 'Config',
+ function (DS, jsDataModel, gettextCatalog, Config) {
return DS.defineResource({
name: 'assignments/polloption',
+ useClass: jsDataModel,
+ methods: {
+ getVotes: function () {
+ if (!this.poll.has_votes) {
+ return;
+ }
+ var poll = this.poll;
+ var votes = [];
+ var config = Config.get('assignments_poll_100_percent_base').value;
+ angular.forEach(this.votes, function(vote) {
+ // check for special value
+ var value;
+ switch (vote.weight) {
+ case -1:
+ value = gettextCatalog.getString('majority');
+ break;
+ case -2:
+ value = gettextCatalog.getString('undocumented');
+ break;
+ default:
+ value = vote.weight;
+ break;
+ }
+ // calculate percent value
+ var percentStr, percentNumber;
+ if (config == "WITHOUT_INVALID" && poll.votesvalid > 0 && vote.weight >= 0) {
+ percentNumber = Math.round(vote.weight * 100 / poll.votesvalid * 10) / 10;
+ } else if (config == "WITH_INVALID" && poll.votescast > 0 && vote.weight >= 0) {
+ percentNumber = Math.round(vote.weight * 100 / (poll.votescast) * 10) / 10;
+ }
+ if (percentNumber) {
+ percentStr = "(" + percentNumber + "%)";
+ }
+ votes.push({
+ 'label': gettextCatalog.getString(vote.value),
+ 'value': value,
+ 'percentStr': percentStr,
+ 'percentNumber': percentNumber
+ });
+ });
+ return votes;
+ }
+ },
relations: {
belongsTo: {
'assignments/poll': {
@@ -27,10 +73,43 @@ angular.module('OpenSlidesApp.assignments', [])
.factory('AssignmentPoll', [
'DS',
+ 'gettextCatalog',
'AssignmentPollOption',
- function (DS, AssignmentPollOption) {
+ 'Config',
+ function (DS, gettextCatalog, AssignmentPollOption, Config) {
return DS.defineResource({
name: 'assignments/poll',
+ methods: {
+ // returns object with value and percent (for votes valid/invalid/cast only)
+ getVote: function (vote) {
+ if (!this.has_votes || !vote) {
+ return;
+ }
+ var value = '';
+ switch (vote) {
+ case -1:
+ value = gettextCatalog.getString('majority');
+ break;
+ case -2:
+ value = gettextCatalog.getString('undocumented');
+ break;
+ default:
+ value = vote;
+ break;
+ }
+ // calculate percent value
+ var config = Config.get('assignments_poll_100_percent_base').value;
+ var percent;
+ if ((config == "WITHOUT_INVALID" && vote == this.votesvalid && vote >= 0) ||
+ (config == "WITH_INVALID" && vote == this.votescast && vote >= 0)) {
+ percent = '(100%)';
+ }
+ return {
+ 'value': value,
+ 'percent': percent
+ };
+ },
+ },
relations: {
belongsTo: {
'assignments/assignment': {
diff --git a/openslides/assignments/static/js/assignments/site.js b/openslides/assignments/static/js/assignments/site.js
index 28358bab1..4f2c9bdda 100644
--- a/openslides/assignments/static/js/assignments/site.js
+++ b/openslides/assignments/static/js/assignments/site.js
@@ -254,6 +254,7 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
.controller('AssignmentDetailCtrl', [
'$scope',
'$http',
+ 'filterFilter',
'gettext',
'ngDialog',
'AssignmentForm',
@@ -262,7 +263,7 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
'User',
'assignment',
'phases',
- function($scope, $http, gettext, ngDialog, AssignmentForm, operator, Assignment, User, assignment, phases) {
+ function($scope, $http, filterFilter, gettext, ngDialog, AssignmentForm, operator, Assignment, User, assignment, phases) {
User.bindAll({}, $scope, 'users');
Assignment.bindOne(assignment.id, $scope, 'assignment');
Assignment.loadRelations(assignment, 'agenda_item');
@@ -337,6 +338,9 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
$http.post('/rest/assignments/assignment/' + assignment.id + '/create_poll/')
.success(function(data){
$scope.alert.show = false;
+ if (assignment.phase == 0) {
+ $scope.updatePhase(1);
+ }
})
.error(function(data){
$scope.alert = { type: 'danger', msg: data.detail, show: true };
@@ -390,6 +394,15 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
data: JSON.stringify({user: user})})
} else {
$http.post('/rest/assignments/assignment/' + assignment.id + '/mark_elected/', {'user': user})
+ .then(function(success) {
+ var elected = filterFilter(assignment.assignment_related_users,{elected: true});
+ // Set phase to 'finished' if there are enough (= number of open posts) elected users.
+ // Note: The array 'elected' does NOT contains the candidate who is just marked as elected.
+ // So add 1 to length to get the real number of all elected users.
+ if (elected.length + 1 == assignment.open_posts ) {
+ $scope.updatePhase(2);
+ }
+ });
}
};
@@ -490,8 +503,9 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
'assignmentpoll',
'ballot',
function($scope, gettextCatalog, AssignmentPoll, assignmentpoll, ballot) {
- // set initial values for form model
- $scope.model = assignmentpoll;
+ // set initial values for form model by create deep copy of assignmentpoll object
+ // so detail view is not updated while editing poll
+ $scope.model = angular.copy(assignmentpoll);
$scope.ballot = ballot;
$scope.formFields = [];
$scope.alert = {};
@@ -499,6 +513,16 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
// add dynamic form fields
assignmentpoll.options.forEach(function(option) {
if (assignmentpoll.yesnoabstain) {
+ var defaultValue = {
+ 'yes': '',
+ 'no': '',
+ 'abstain': ''
+ };
+ if (option.votes.length) {
+ defaultValue.yes = option.votes[0].weight;
+ defaultValue.no = option.votes[1].weight;
+ defaultValue.abstain = option.votes[2].weight;
+ }
$scope.formFields.push(
{
noFormControl: true,
@@ -511,7 +535,8 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
label: gettextCatalog.getString('Yes'),
type: 'number',
required: true
- }
+ },
+ defaultValue: defaultValue.yes
},
{
key: 'no_' + option.candidate_id,
@@ -520,7 +545,8 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
label: gettextCatalog.getString('No'),
type: 'number',
required: true
- }
+ },
+ defaultValue: defaultValue.no
},
{
key:'abstain_' + option.candidate_id,
@@ -529,9 +555,14 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
label: gettextCatalog.getString('Abstain'),
type: 'number',
required: true
- }
+ },
+ defaultValue: defaultValue.abstain
});
} else {
+ var defaultValue;
+ if (option.votes.length) {
+ defaultValue = option.votes[0].weight;
+ }
$scope.formFields.push(
{
key: 'vote_' + option.candidate_id,
@@ -540,7 +571,8 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
label: option.candidate.get_full_name(),
type: 'number',
required: true
- }
+ },
+ defaultValue: defaultValue
});
}
});
@@ -599,6 +631,7 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
});
});
}
+ // save change poll object on server
poll.DSUpdate({
assignment_id: poll.assignment_id,
votes: votes,
diff --git a/openslides/assignments/static/templates/assignments/assignment-detail.html b/openslides/assignments/static/templates/assignments/assignment-detail.html
index 2d4e1ef26..ff669c535 100644
--- a/openslides/assignments/static/templates/assignments/assignment-detail.html
+++ b/openslides/assignments/static/templates/assignments/assignment-detail.html
@@ -150,7 +150,9 @@