Merge pull request #2331 from emanuelschuetze/issue2182b
Motion config: 'calculate % without abstains' (Fixes #2182)
This commit is contained in:
commit
70dfe8f525
@ -764,6 +764,9 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
|
||||
gettext('Elections');
|
||||
gettext('Ballot and ballot papers');
|
||||
gettext('The 100 % base of an election result consists of');
|
||||
gettext('All valid votes (Yes/No/Abstain)');
|
||||
gettext('All votes cast (including invalid votes)');
|
||||
gettext('Disabled (no percents)');
|
||||
gettext('Number of ballot papers (selection)');
|
||||
gettext('Number of all delegates');
|
||||
gettext('Number of all participants');
|
||||
|
@ -23,6 +23,10 @@ def get_config_variables():
|
||||
papers' and 'PDF'. The generator has to be evaluated during app loading
|
||||
(see apps.py).
|
||||
"""
|
||||
PERCENT_BASE_CHOICES_MOTION = ({
|
||||
'value': "WITHOUT_ABSTAIN",
|
||||
'display_name': 'Yes and No votes'},)
|
||||
PERCENT_BASE_CHOICES_MOTION += PERCENT_BASE_CHOICES
|
||||
# General
|
||||
yield ConfigVariable(
|
||||
name='motions_workflow',
|
||||
@ -148,7 +152,7 @@ def get_config_variables():
|
||||
default_value='WITHOUT_INVALID',
|
||||
input_type='choice',
|
||||
label='The 100 % base of a voting result consists of',
|
||||
choices=PERCENT_BASE_CHOICES,
|
||||
choices=PERCENT_BASE_CHOICES_MOTION,
|
||||
weight=355,
|
||||
group='Motions',
|
||||
subgroup='Voting and ballot papers')
|
||||
|
@ -71,7 +71,7 @@ angular.module('OpenSlidesApp.motions', [
|
||||
},
|
||||
methods: {
|
||||
// returns object with value and percent
|
||||
getVote: function (vote) {
|
||||
getVote: function (vote, type) {
|
||||
if (!this.has_votes) {
|
||||
return;
|
||||
}
|
||||
@ -89,13 +89,18 @@ angular.module('OpenSlidesApp.motions', [
|
||||
}
|
||||
// calculate percent value
|
||||
var config = Config.get('motions_poll_100_percent_base').value;
|
||||
var percentStr, percentNumber;
|
||||
var percentStr;
|
||||
var percentNumber = null;
|
||||
if (config == "WITHOUT_INVALID" && this.votesvalid > 0 && vote >= 0) {
|
||||
percentNumber = Math.round(vote * 100 / this.votesvalid * 10) / 10;
|
||||
} else if (config == "WITH_INVALID" && this.votescast > 0 && vote >= 0) {
|
||||
percentNumber = Math.round(vote * 100 / (this.votescast) * 10) / 10;
|
||||
} else if (config == "WITHOUT_ABSTAIN" && vote >= 0) {
|
||||
if (type == 'yes' || type == 'no') {
|
||||
percentNumber = Math.round(vote * 100 / (this.yes + this.no) * 10) / 10;
|
||||
}
|
||||
if (percentNumber) {
|
||||
}
|
||||
if (percentNumber !== null) {
|
||||
percentStr = "(" + percentNumber + "%)";
|
||||
}
|
||||
return {
|
||||
@ -103,7 +108,7 @@ angular.module('OpenSlidesApp.motions', [
|
||||
'percentStr': percentStr,
|
||||
'percentNumber': percentNumber
|
||||
};
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -70,14 +70,15 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid
|
||||
results = function() {
|
||||
return motion.polls.map(function(poll, index) {
|
||||
var id = index + 1,
|
||||
yes = poll.yes,
|
||||
yesRelative = (poll.yes) * 100 / (poll.votescast),
|
||||
no = poll.no,
|
||||
noRelative = (poll.no) * 100 / (poll.votescast),
|
||||
abstain = poll.abstain,
|
||||
abstainRelative = (poll.abstain) * 100 / (poll.votescast),
|
||||
valid = poll.votesvalid,
|
||||
validRelative = (poll.votesvalid) * 100 / (poll.votescast),
|
||||
yes = poll.yes ? poll.yes : '-', // if no poll.yes is given set it to '-'
|
||||
yesRelative = poll.getVote(poll.yes, 'yes').percentStr,
|
||||
no = poll.no ? poll.no : '-',
|
||||
noRelative = poll.getVote(poll.no, 'no').percentStr,
|
||||
abstain = poll.abstain ? poll.abstain : '-',
|
||||
abstainrelativeGet = poll.getVote(poll.abstain, 'abstain').percentStr,
|
||||
abstainRelative = abstainrelativeGet ? abstainrelativeGet : '',
|
||||
valid = poll.votesvalid ? poll.votesvalid : '-',
|
||||
validRelative = poll.getVote(poll.votesvalid, 'votesvalid').percentStr,
|
||||
number = {
|
||||
text: id + ".",
|
||||
width: "5%"
|
||||
@ -100,7 +101,7 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid
|
||||
var indexColumn = converter.createElement("text");
|
||||
var nameColumn = converter.createElement("text", "" + name);
|
||||
var valueColumn = converter.createElement("text", "" + value);
|
||||
var relColumn = converter.createElement("text", "(" + "" + relValue + "%)");
|
||||
var relColumn = converter.createElement("text", relValue);
|
||||
valueColumn.width = "40%";
|
||||
indexColumn.width = "5%";
|
||||
valueColumn.width = "5%";
|
||||
@ -1602,29 +1603,17 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid
|
||||
.config([
|
||||
'gettext',
|
||||
function (gettext) {
|
||||
gettext('The assembly may decide,');
|
||||
gettext('Workflow of new motions');
|
||||
gettext('Motions');
|
||||
|
||||
// subgroup General
|
||||
gettext('General');
|
||||
gettext('Workflow of new motions');
|
||||
gettext('Identifier');
|
||||
gettext('Numbered per category');
|
||||
gettext('Serially numbered');
|
||||
gettext('Set it manually');
|
||||
gettext('Motion preamble');
|
||||
gettext('Stop submitting new motions by non-staff users');
|
||||
gettext('Allow to disable versioning');
|
||||
gettext('Activate amendments');
|
||||
gettext('Amendments');
|
||||
gettext('Prefix for the identifier for amendments');
|
||||
gettext('Number of (minimum) required supporters for a motion');
|
||||
gettext('Choose 0 to disable the supporting system.');
|
||||
gettext('Supporters');
|
||||
gettext('Remove all supporters of a motion if a submitter edits his ' +
|
||||
'motion in early state');
|
||||
gettext('Title for PDF document (all motions)');
|
||||
gettext('Preamble text for PDF document (all motioqns)');
|
||||
gettext('Show paragraph numbering (only in PDF)');
|
||||
/// Prefix for the identifier for amendments
|
||||
gettext('A');
|
||||
gettext('The assembly may decide,');
|
||||
gettext('Default line numbering');
|
||||
/// Line numbering: Outside
|
||||
gettext('Outside');
|
||||
@ -1634,6 +1623,40 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid
|
||||
gettext('None');
|
||||
gettext('Line length');
|
||||
gettext('The maximum number of characters per line. Relevant when line numbering is enabled. Min: 40');
|
||||
gettext('Stop submitting new motions by non-staff users');
|
||||
gettext('Allow to disable versioning');
|
||||
|
||||
// subgroup Amendments
|
||||
gettext('Amendments');
|
||||
gettext('Activate amendments');
|
||||
gettext('Prefix for the identifier for amendments');
|
||||
/// Prefix for the identifier for amendments
|
||||
gettext('A');
|
||||
|
||||
// subgroup Suppoerters
|
||||
gettext('Supporters');
|
||||
gettext('Number of (minimum) required supporters for a motion');
|
||||
gettext('Choose 0 to disable the supporting system.');
|
||||
gettext('Remove all supporters of a motion if a submitter edits his ' +
|
||||
'motion in early state');
|
||||
|
||||
// subgroup Voting and ballot papers
|
||||
gettext('Voting and ballot papers');
|
||||
gettext('The 100 % base of a voting result consists of');
|
||||
gettext('All valid votes (Yes/No/Abstain)');
|
||||
gettext('All votes cast (including invalid votes)');
|
||||
gettext('Disabled (no percents)');
|
||||
gettext('Yes and No votes');
|
||||
gettext('Number of ballot papers (selection)');
|
||||
gettext('Number of all delegates');
|
||||
gettext('Number of all participants');
|
||||
gettext('Use the following custom number');
|
||||
gettext('Custom number of ballot papers');
|
||||
|
||||
// subgroup PDF
|
||||
gettext('Title for PDF document (all motions)');
|
||||
gettext('Preamble text for PDF document (all motioqns)');
|
||||
gettext('Show paragraph numbering (only in PDF)');
|
||||
}
|
||||
]);
|
||||
|
||||
|
@ -151,7 +151,7 @@
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa fa-thumbs-up fa-2x"></i>
|
||||
<td ng-init="voteYes = poll.getVote(poll.yes)">
|
||||
<td ng-init="voteYes = poll.getVote(poll.yes, 'yes')">
|
||||
<span class="result_label"><translate>Yes</translate>:</span>
|
||||
<span class="result_value">
|
||||
{{ voteYes.value }} {{ voteYes.percentStr }}
|
||||
@ -163,7 +163,7 @@
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa fa-thumbs-down fa-2x"></i>
|
||||
<td ng-init="voteNo = poll.getVote(poll.no)">
|
||||
<td ng-init="voteNo = poll.getVote(poll.no, 'no')">
|
||||
<span class="result_label"><translate>No</translate>:</span>
|
||||
<span class="result_value" >
|
||||
{{ voteNo.value }} {{ voteNo.percentStr }}
|
||||
@ -175,7 +175,7 @@
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<strong style="font-size: 26px">∅</strong>
|
||||
<td ng-init="voteAbstain = poll.getVote(poll.abstain)">
|
||||
<td ng-init="voteAbstain = poll.getVote(poll.abstain, 'abstain')">
|
||||
<span class="result_label"><translate>Abstain</translate>:</span>
|
||||
<span class="result_value">
|
||||
{{ voteAbstain.value }} {{ voteAbstain.percentStr }}
|
||||
@ -184,19 +184,19 @@
|
||||
<uib-progressbar value="voteAbstain.percentNumber" type="warning"></uib-progressbar>
|
||||
</div>
|
||||
<!-- valid votes -->
|
||||
<tr>
|
||||
<tr ng-if="poll.votesvalid !== null">
|
||||
<td class="icon">
|
||||
<i class="fa fa-check fa-lg"></i>
|
||||
<td ng-init="votesValid = poll.getVote(poll.votesvalid)">
|
||||
<td ng-init="votesValid = poll.getVote(poll.votesvalid, 'votesvalid')">
|
||||
<span class="result_label"><translate>Valid votes</translate>:</span>
|
||||
<span class="result_value">
|
||||
{{ votesValid.value }} {{ votesValid.percentStr }}
|
||||
</span>
|
||||
<!-- invalid votes -->
|
||||
<tr>
|
||||
<tr ng-if="poll.votesinvalid !== null">
|
||||
<td class="icon">
|
||||
<i class="fa fa-ban fa-lg"></i>
|
||||
<td ng-init="votesInvalid = poll.getVote(poll.votesinvalid)">
|
||||
<td ng-init="votesInvalid = poll.getVote(poll.votesinvalid, 'votesinvalid')">
|
||||
<span class="result_label"><translate>Invalid votes</translate>:</span>
|
||||
<span class="result_value">
|
||||
{{ votesInvalid.value }}
|
||||
@ -205,10 +205,10 @@
|
||||
</span>
|
||||
</span>
|
||||
<!-- votes cast -->
|
||||
<tr class="total">
|
||||
<tr class="total" ng-if="poll.votescast !== null">
|
||||
<td class="icon">
|
||||
<strong style="font-size: 16px">∑</strong>
|
||||
<td ng-init="votesCast = poll.getVote(poll.votescast)">
|
||||
<td ng-init="votesCast = poll.getVote(poll.votescast, 'votescast')">
|
||||
<span class="result_label"><translate>Votes cast</translate>:</span>
|
||||
<span class="result_value">
|
||||
{{ votesCast.value }}
|
||||
|
@ -23,31 +23,31 @@
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa fa-thumbs-up fa-2x"></i>
|
||||
<td ng-init="voteYes = poll.getVote(poll.yes)">
|
||||
<td ng-init="voteYes = poll.getVote(poll.yes, 'yes')">
|
||||
<span class="result_label"><translate>Yes</translate>:</span>
|
||||
<span class="result_value">
|
||||
{{ voteYes.value }} {{ voteYes.percentStr }}
|
||||
</span>
|
||||
<div ng-if="voteYes.percentNumber">
|
||||
<div ng-if="voteYes.percentNumber >= 0">
|
||||
<uib-progressbar value="voteYes.percentNumber" type="success"></uib-progressbar>
|
||||
</div>
|
||||
<!-- no -->
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa fa-thumbs-down fa-2x"></i>
|
||||
<td ng-init="voteNo = poll.getVote(poll.no)">
|
||||
<td ng-init="voteNo = poll.getVote(poll.no, 'no')">
|
||||
<span class="result_label"><translate>No</translate>:</span>
|
||||
<span class="result_value" >
|
||||
{{ voteNo.value }} {{ voteNo.percentStr }}
|
||||
</span>
|
||||
<div ng-if="voteNo.percentNumber">
|
||||
<div ng-if="voteNo.percentNumber >= 0">
|
||||
<uib-progressbar value="voteNo.percentNumber" type="danger"></uib-progressbar>
|
||||
</div>
|
||||
<!-- abstain -->
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<strong style="font-size: 26px">∅</strong>
|
||||
<td ng-init="voteAbstain = poll.getVote(poll.abstain)">
|
||||
<td ng-init="voteAbstain = poll.getVote(poll.abstain, 'abstain')">
|
||||
<span class="result_label"><translate>Abstain</translate>:</span>
|
||||
<span class="result_value">
|
||||
{{ voteAbstain.value }} {{ voteAbstain.percentStr }}
|
||||
|
@ -3,7 +3,6 @@ import locale
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.utils.translation import ugettext_lazy
|
||||
|
||||
from openslides.utils.models import MinMaxIntegerField
|
||||
|
||||
@ -66,11 +65,10 @@ class BaseVote(models.Model):
|
||||
percent_base = 0
|
||||
return print_value(self.weight, percent_base)
|
||||
|
||||
|
||||
PERCENT_BASE_CHOICES = (
|
||||
{'value': 'WITHOUT_INVALID', 'display_name': ugettext_lazy('Only all valid votes')},
|
||||
{'value': 'WITH_INVALID', 'display_name': ugettext_lazy('All votes cast (including invalid votes)')},
|
||||
{'value': 'DISABLED', 'display_name': ugettext_lazy('Disabled (no percents)')})
|
||||
{'value': 'WITHOUT_INVALID', 'display_name': 'All valid votes (Yes/No/Abstain)'},
|
||||
{'value': 'WITH_INVALID', 'display_name': 'All votes cast (including invalid votes)'},
|
||||
{'value': 'DISABLED', 'display_name': 'Disabled (no percents)'})
|
||||
|
||||
|
||||
class CollectDefaultVotesMixin(models.Model):
|
||||
|
Loading…
Reference in New Issue
Block a user