Merge pull request #2808 from matakuka/ballot_count

print correct number of ballots (closes #2504)
This commit is contained in:
Emanuel Schütze 2017-01-06 11:56:29 +01:00 committed by GitHub
commit f146e11354
4 changed files with 157 additions and 41 deletions

View File

@ -52,12 +52,14 @@ Motions:
- Added DOCX export with docxtemplater. - Added DOCX export with docxtemplater.
- Changed label of former state "commited a bill" to "refered to committee". - Changed label of former state "commited a bill" to "refered to committee".
- New csv import layout and using Papa Parse for parsing the csv. - New csv import layout and using Papa Parse for parsing the csv.
- Number of ballots printed can now be set in config.
Elections: Elections:
- Added options to calculate percentages on different bases. - Added options to calculate percentages on different bases.
- Added calculation for required majority. - Added calculation for required majority.
- Candidates are now sortable. - Candidates are now sortable.
- Removed unused assignment config to publish winner election results only. - Removed unused assignment config to publish winner election results only.
- Number of ballots printed can now be set in config.
Users: Users:
- Added new matrix-interface for managing groups and their permissions. - Added new matrix-interface for managing groups and their permissions.

View File

@ -268,8 +268,9 @@ angular.module('OpenSlidesApp.assignments.pdf', ['OpenSlidesApp.core.pdf'])
'$filter', '$filter',
'gettextCatalog', 'gettextCatalog',
'PDFLayout', 'PDFLayout',
function($filter, gettextCatalog, PDFLayout) { 'Config',
'User',
function($filter, gettextCatalog, PDFLayout, Config, User) {
var createInstance = function(scope, poll, pollNumber) { var createInstance = function(scope, poll, pollNumber) {
// page title // page title
@ -367,58 +368,104 @@ angular.module('OpenSlidesApp.assignments.pdf', ['OpenSlidesApp.core.pdf'])
}; };
}; };
var createTableBody = function(numberOfRows, sheetend) { var createTableBody = function(numberOfRows, sheetend, maxballots) {
var ballotstoprint = numberOfRows * 2;
if (Number.isInteger(maxballots) && maxballots > 0 && maxballots < ballotstoprint) {
ballotstoprint = maxballots;
}
var tableBody = []; var tableBody = [];
for (var i = 0; i < numberOfRows; i++) { while (ballotstoprint > 1){
tableBody.push([createSection(sheetend), createSection(sheetend)]); tableBody.push([createSection(sheetend), createSection(sheetend)]);
ballotstoprint -= 2;
}
if (ballotstoprint == 1) {
tableBody.push([createSection(sheetend), '']);
} }
return tableBody; return tableBody;
}; };
var createContentTable = function() { var createContentTable = function() {
// first, determine how many ballots we need
var tableBody = []; var amount;
var amount_method = Config.get('assignments_pdf_ballot_papers_selection').value;
switch (amount_method) {
case 'NUMBER_OF_ALL_PARTICIPANTS':
amount = User.getAll().length;
break;
case 'NUMBER_OF_DELEGATES':
//TODO: assumption that DELEGATES is always group id 2. This may not be true
var group_id = 2;
amount = User.filter({where: {'groups_id': {contains:group_id} }}).length;
break;
case 'CUSTOM_NUMBER':
amount = Config.get('assignments_pdf_ballot_papers_number').value;
break;
default:
// should not happen.
amount = 0;
}
var tabledContent = [];
var rowsperpage;
var sheetend; var sheetend;
if (poll.pollmethod == 'votes') { if (poll.pollmethod == 'votes') {
if (poll.options.length <= 4) { if (poll.options.length <= 4) {
sheetend = 105; sheetend = 105;
tableBody = createTableBody(4, sheetend); rowsperpage = 4;
} else if (poll.options.length <= 8) { } else if (poll.options.length <= 8) {
sheetend = 140; sheetend = 140;
tableBody = tableBody = createTableBody(3, sheetend); rowsperpage = 3;
} else if (poll.options.length <= 12) { } else if (poll.options.length <= 12) {
sheetend = 210; sheetend = 210;
tableBody = tableBody = createTableBody(2, sheetend); rowsperpage = 2;
} }
else { //works untill ~30 people else { //works untill ~30 people
sheetend = 418; sheetend = 418;
tableBody = createTableBody(1, sheetend); rowsperpage = 1;
} }
} else { } else {
if (poll.options.length <= 2) { if (poll.options.length <= 2) {
sheetend = 105; sheetend = 105;
tableBody = createTableBody(4, sheetend); rowsperpage = 4;
} else if (poll.options.length <= 4) { } else if (poll.options.length <= 4) {
sheetend = 140; sheetend = 140;
tableBody = createTableBody(3, sheetend); rowsperpage = 3;
} else if (poll.options.length <= 6) { } else if (poll.options.length <= 6) {
sheetend = 210; sheetend = 210;
tableBody = createTableBody(2, sheetend); rowsperpage = 2;
} else { } else {
sheetend = 418; sheetend = 418;
tableBody = createTableBody(1, sheetend); rowsperpage = 1;
} }
} }
var page_entries = rowsperpage * 2;
return [{ var fullpages = Math.floor(amount / page_entries);
table: { for (var i=0; i < fullpages; i++) {
headerRows: 1, tabledContent.push({
widths: ['50%', '50%'], table: {
body: tableBody headerRows: 1,
}, widths: ['50%', '50%'],
layout: PDFLayout.getBallotLayoutLines() body: createTableBody(rowsperpage, sheetend),
}]; pageBreak: 'after'
},
layout: PDFLayout.getBallotLayoutLines(),
rowsperpage: rowsperpage
});
}
// fill the last page only partially
var lastpage_ballots = amount - (fullpages * page_entries);
if (lastpage_ballots < page_entries && lastpage_ballots > 0){
var partialpage = createTableBody(rowsperpage, sheetend, lastpage_ballots);
tabledContent.push({
table: {
headerRows: 1,
widths: ['50%', '50%'],
body: partialpage
},
layout: PDFLayout.getBallotLayoutLines(),
rowsperpage: rowsperpage
});
}
return tabledContent;
}; };
var getContent = function() { var getContent = function() {

View File

@ -102,13 +102,33 @@ angular.module('OpenSlidesApp.core.pdf', [])
PDFLayout.getBallotLayoutLines = function() { PDFLayout.getBallotLayoutLines = function() {
return { return {
hLineWidth: function(i, node) { hLineWidth: function(i, node) {
return (i === 0 || i === node.table.body.length) ? 0 : 0.5; if (i === 0){
return 0;
} else if (i === node.table.body.length) {
if (node.rowsperpage && node.rowsperpage > i) {
return 0.5;
} else {
return 0;
}
} else {
return 0.5;
}
}, },
vLineWidth: function(i, node) { vLineWidth: function(i, node) {
return (i === 0 || i === node.table.widths.length) ? 0 : 0.5; return (i === 0 || i === node.table.widths.length) ? 0 : 0.5;
}, },
hLineColor: function(i, node) { hLineColor: function(i, node) {
return (i === 0 || i === node.table.body.length) ? 'none' : 'gray'; if (i === 0){
return 'none';
} else if (i === node.table.body.length) {
if (node.rowsperpage && node.rowsperpage > i) {
return 'gray';
} else {
return 'none';
}
} else {
return 'gray';
}
}, },
vLineColor: function(i, node) { vLineColor: function(i, node) {
return (i === 0 || i === node.table.widths.length) ? 'none' : 'gray'; return (i === 0 || i === node.table.widths.length) ? 'none' : 'gray';

View File

@ -330,7 +330,9 @@ angular.module('OpenSlidesApp.motions.pdf', ['OpenSlidesApp.core.pdf'])
.factory('PollContentProvider', [ .factory('PollContentProvider', [
'PDFLayout', 'PDFLayout',
function(PDFLayout) { 'Config',
'User',
function(PDFLayout, Config, User) {
/** /**
* Generates a content provider for polls * Generates a content provider for polls
* @constructor * @constructor
@ -367,21 +369,66 @@ angular.module('OpenSlidesApp.motions.pdf', ['OpenSlidesApp.core.pdf'])
* @function * @function
* @param {string} id - if of poll * @param {string} id - if of poll
*/ */
var getContent = function() { var getContent = function() {
return [{ var content = [];
table: { var amount;
headerRows: 1, var amount_method = Config.get('motions_pdf_ballot_papers_selection').value;
widths: ['*', '*'], switch (amount_method) {
body: [ case 'NUMBER_OF_ALL_PARTICIPANTS':
[createSection(), createSection()], amount = User.getAll().length;
[createSection(), createSection()], break;
[createSection(), createSection()], case 'NUMBER_OF_DELEGATES':
[createSection(), createSection()] //TODO: assumption that DELEGATES is always group id 2. This may not be true
], var group_id = 2;
}, amount = User.filter({where: {'groups_id': {contains:group_id} }}).length;
layout: PDFLayout.getBallotLayoutLines() break;
}]; case 'CUSTOM_NUMBER':
amount = Config.get('motions_pdf_ballot_papers_number').value;
break;
default:
// should not happen.
amount = 0;
}
var fullpages = Math.floor(amount / 8);
for (var i=0; i < fullpages; i++) {
content.push({
table: {
headerRows: 1,
widths: ['*', '*'],
body: [
[createSection(), createSection()],
[createSection(), createSection()],
[createSection(), createSection()],
[createSection(), createSection()]
],
pageBreak: 'after'
},
layout: PDFLayout.getBallotLayoutLines(),
rowsperpage: 4
});
}
amount = amount - (fullpages * 8);
if (amount > 0) {
var partialpagebody = [];
while (amount > 1) {
partialpagebody.push([createSection(), createSection()]);
amount -=2;
}
if (amount == 1) {
partialpagebody.push([createSection(), '']);
}
content.push({
table: {
headerRows: 1,
widths: ['50%', '50%'],
body: partialpagebody
},
layout: PDFLayout.getBallotLayoutLines(),
rowsperpage: 4
});
}
return content;
}; };
return { return {