Merge pull request #6318 from GabrielInTheWorld/fix-candidate-percentbase
Fixes percentbase of candidates in assignments
This commit is contained in:
commit
31f59e069d
@ -41,7 +41,7 @@
|
||||
<div class="single-result" [ngClass]="getVoteClass(vote)">
|
||||
<span>
|
||||
<span *ngIf="vote.showPercent">
|
||||
{{ getVoteAmount(vote, row) | pollPercentBase: poll:'assignment' }}
|
||||
{{ getVoteAmount(vote, row) | pollPercentBase: poll:row:'assignment' }}
|
||||
</span>
|
||||
<span *ngIf="row.class === 'user'">
|
||||
{{ getVoteAmount(vote, row) | parsePollNumber }}
|
||||
@ -59,7 +59,7 @@
|
||||
<td class="result">
|
||||
<div class="single-result">
|
||||
<span>
|
||||
{{ poll.entitled_users_at_stop.length | pollPercentBase: poll:'assignment' }}
|
||||
{{ poll.entitled_users_at_stop.length | pollPercentBase: poll:row:'assignment' }}
|
||||
</span>
|
||||
<span>
|
||||
{{ poll.entitled_users_at_stop.length }}
|
||||
|
@ -3,6 +3,7 @@ import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { AssignmentPollService } from 'app/site/assignments/modules/assignment-poll/services/assignment-poll.service';
|
||||
import { MotionPollService } from 'app/site/motions/services/motion-poll.service';
|
||||
import { PollData } from 'app/site/polls/services/poll.service';
|
||||
import { PollDataOption, PollTableData } from '../../site/polls/services/poll.service';
|
||||
|
||||
/**
|
||||
* Uses a number and a ViewPoll-object.
|
||||
@ -26,7 +27,12 @@ export class PollPercentBasePipe implements PipeTransform {
|
||||
private motionPollService: MotionPollService
|
||||
) {}
|
||||
|
||||
public transform(value: number, poll: PollData, type: 'motion' | 'assignment'): string | null {
|
||||
public transform(
|
||||
value: number,
|
||||
poll: PollData,
|
||||
row: PollDataOption | PollTableData,
|
||||
type: 'motion' | 'assignment'
|
||||
): string | null {
|
||||
// logic handles over the pollService to avoid circular dependencies
|
||||
let voteValueInPercent: string;
|
||||
|
||||
@ -36,9 +42,9 @@ export class PollPercentBasePipe implements PipeTransform {
|
||||
* we cannot expect the projector to work with real types for now, we need to provice the type
|
||||
*/
|
||||
if (type === 'assignment') {
|
||||
voteValueInPercent = this.assignmentPollService.getVoteValueInPercent(value, poll);
|
||||
voteValueInPercent = this.assignmentPollService.getVoteValueInPercent(value, { poll, row });
|
||||
} else {
|
||||
voteValueInPercent = this.motionPollService.getVoteValueInPercent(value, poll);
|
||||
voteValueInPercent = this.motionPollService.getVoteValueInPercent(value, { poll, row });
|
||||
}
|
||||
|
||||
if (voteValueInPercent) {
|
||||
|
@ -196,33 +196,26 @@ export class AssignmentPollService extends PollService {
|
||||
}));
|
||||
}
|
||||
|
||||
private sumOptionsYN(poll: PollData): number {
|
||||
return poll.options.reduce((o, n) => {
|
||||
o += n.yes > 0 ? n.yes : 0;
|
||||
o += n.no > 0 ? n.no : 0;
|
||||
return o;
|
||||
}, 0);
|
||||
private sumOptionsYN(option: PollDataOption): number {
|
||||
return (option?.yes ?? 0) + (option?.no ?? 0);
|
||||
}
|
||||
|
||||
private sumOptionsYNA(poll: PollData): number {
|
||||
return poll.options.reduce((o, n) => {
|
||||
o += n.abstain > 0 ? n.abstain : 0;
|
||||
return o;
|
||||
}, this.sumOptionsYN(poll));
|
||||
private sumOptionsYNA(option: PollDataOption): number {
|
||||
return this.sumOptionsYN(option) + (option?.abstain ?? 0);
|
||||
}
|
||||
|
||||
public getPercentBase(poll: PollData): number {
|
||||
public getPercentBase(poll: PollData, row: PollDataOption): number {
|
||||
const base: AssignmentPollPercentBase = poll.onehundred_percent_base as AssignmentPollPercentBase;
|
||||
let totalByBase: number;
|
||||
switch (base) {
|
||||
case AssignmentPollPercentBase.YN:
|
||||
totalByBase = this.sumOptionsYN(poll);
|
||||
totalByBase = this.sumOptionsYN(row);
|
||||
break;
|
||||
case AssignmentPollPercentBase.YNA:
|
||||
totalByBase = this.sumOptionsYNA(poll);
|
||||
totalByBase = this.sumOptionsYNA(row);
|
||||
break;
|
||||
case AssignmentPollPercentBase.Y:
|
||||
totalByBase = this.sumOptionsYNA(poll);
|
||||
totalByBase = this.sumOptionsYNA(row);
|
||||
break;
|
||||
case AssignmentPollPercentBase.Valid:
|
||||
totalByBase = poll.votesvalid;
|
||||
@ -246,7 +239,7 @@ export class AssignmentPollService extends PollService {
|
||||
const voteValue = option[field];
|
||||
const votingKey = this.translate.instant(this.pollKeyVerbose.transform(field));
|
||||
const resultValue = this.parsePollNumber.transform(voteValue);
|
||||
const resultInPercent = this.getVoteValueInPercent(voteValue, poll);
|
||||
const resultInPercent = this.getVoteValueInPercent(voteValue, { poll, row: option });
|
||||
let resultLabel = `${votingKey}: ${resultValue}`;
|
||||
|
||||
// 0 is a valid number in this case
|
||||
|
@ -241,7 +241,12 @@ export class AssignmentPdfService {
|
||||
.map((singleResult: VotingResult) => {
|
||||
const votingKey = this.translate.instant(this.pollKeyVerbose.transform(singleResult.vote));
|
||||
const resultValue = this.parsePollNumber.transform(singleResult.amount);
|
||||
const resultInPercent = this.pollPercentBase.transform(singleResult.amount, poll, 'assignment');
|
||||
const resultInPercent = this.pollPercentBase.transform(
|
||||
singleResult.amount,
|
||||
poll,
|
||||
votingResult,
|
||||
'assignment'
|
||||
);
|
||||
return `${votingKey}${!!votingKey ? ': ' : ''}${resultValue} ${
|
||||
singleResult.showPercent && resultInPercent ? resultInPercent : ''
|
||||
}`;
|
||||
|
@ -385,7 +385,10 @@ export class MotionPdfService {
|
||||
const resultValue = this.parsePollNumber.transform(value.amount);
|
||||
column1.push(`${votingOption}:`);
|
||||
if (value.showPercent) {
|
||||
const resultInPercent = this.motionPollService.getVoteValueInPercent(value.amount, poll);
|
||||
const resultInPercent = this.motionPollService.getVoteValueInPercent(value.amount, {
|
||||
poll,
|
||||
row: votingResult
|
||||
});
|
||||
// hard check for "null" since 0 is a valid number in this case
|
||||
if (resultInPercent !== null) {
|
||||
column2.push(`(${resultInPercent})`);
|
||||
|
@ -161,6 +161,13 @@ export interface VotingResult {
|
||||
|
||||
const PollChartBarThickness = 20;
|
||||
|
||||
function isPollTableData(value: any): value is PollTableData {
|
||||
if (!value) {
|
||||
return false;
|
||||
}
|
||||
return !!value.votingOption && !!value.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shared service class for polls. Used by child classes {@link MotionPollService}
|
||||
* and {@link AssignmentPollService}
|
||||
@ -215,10 +222,14 @@ export abstract class PollService {
|
||||
/**
|
||||
* return the total number of votes depending on the selected percent base
|
||||
*/
|
||||
public abstract getPercentBase(poll: PollData): number;
|
||||
public abstract getPercentBase(poll: PollData, row: PollDataOption): number;
|
||||
|
||||
public getVoteValueInPercent(value: number, poll: PollData): string | null {
|
||||
const totalByBase = this.getPercentBase(poll);
|
||||
public getVoteValueInPercent(
|
||||
value: number,
|
||||
{ poll, row }: { poll: PollData; row: PollDataOption | PollTableData }
|
||||
): string | null {
|
||||
const option = isPollTableData(row) ? this.transformToOptionData(row) : row;
|
||||
const totalByBase = this.getPercentBase(poll, option);
|
||||
if (totalByBase && totalByBase > 0) {
|
||||
const percentNumber = (value / totalByBase) * 100;
|
||||
if (percentNumber >= 0) {
|
||||
@ -342,6 +353,17 @@ export abstract class PollService {
|
||||
return isAssignment ? this.getPollDataFieldsByMethod(poll) : this.getPollDataFieldsByPercentBase(poll);
|
||||
}
|
||||
|
||||
protected transformToOptionData(data: PollTableData): PollDataOption {
|
||||
const yes = data.value.find(vote => vote.vote === `yes`);
|
||||
const no = data.value.find(vote => vote.vote === `no`);
|
||||
const abstain = data.value.find(vote => vote.vote === `abstain`);
|
||||
return {
|
||||
yes: yes?.amount,
|
||||
no: no?.amount,
|
||||
abstain: abstain?.amount
|
||||
};
|
||||
}
|
||||
|
||||
private getPollDataFieldsByMethod(poll: PollData | ViewBasePoll): CalculablePollKey[] {
|
||||
switch (poll.pollmethod) {
|
||||
case AssignmentPollMethod.YNA: {
|
||||
|
@ -2,7 +2,7 @@ black
|
||||
coverage
|
||||
flake8
|
||||
isort<5.0.0
|
||||
mypy
|
||||
mypy<0.920
|
||||
pytest<5.4.2
|
||||
pytest-django<3.9.0
|
||||
pytest-asyncio<0.11.0
|
||||
|
Loading…
Reference in New Issue
Block a user