Show global votes in the single votes table

This commit is contained in:
FinnStutzenstein 2020-03-12 15:42:41 +01:00
parent 29a9a09bc6
commit a05662a0f8
13 changed files with 53 additions and 48 deletions

View File

@ -22,12 +22,6 @@ const AssignmentOptionRelations: RelationDefinition[] = [
ownKey: 'votes',
foreignViewModel: ViewAssignmentVote
},
{
type: 'M2M',
ownIdKey: 'voted_id',
ownKey: 'voted',
foreignViewModel: ViewUser
},
{
type: 'M2O',
ownIdKey: 'poll_id',

View File

@ -14,6 +14,7 @@ import { ViewAssignmentOption } from 'app/site/assignments/models/view-assignmen
import { AssignmentPollTitleInformation, ViewAssignmentPoll } from 'app/site/assignments/models/view-assignment-poll';
import { BasePollRepositoryService } from 'app/site/polls/services/base-poll-repository.service';
import { ViewGroup } from 'app/site/users/models/view-group';
import { ViewUser } from 'app/site/users/models/view-user';
import { CollectionStringMapperService } from '../../core-services/collection-string-mapper.service';
import { DataStoreService } from '../../core-services/data-store.service';
@ -35,6 +36,12 @@ const AssignmentPollRelations: RelationDefinition[] = [
ownIdKey: 'assignment_id',
ownKey: 'assignment',
foreignViewModel: ViewAssignment
},
{
type: 'M2M',
ownIdKey: 'voted_id',
ownKey: 'voted',
foreignViewModel: ViewUser
}
];

View File

@ -10,7 +10,6 @@ import { MotionOption } from 'app/shared/models/motions/motion-option';
import { ViewMotionOption } from 'app/site/motions/models/view-motion-option';
import { ViewMotionPoll } from 'app/site/motions/models/view-motion-poll';
import { ViewMotionVote } from 'app/site/motions/models/view-motion-vote';
import { ViewUser } from 'app/site/users/models/view-user';
import { BaseRepository } from '../base-repository';
import { CollectionStringMapperService } from '../../core-services/collection-string-mapper.service';
import { DataStoreService } from '../../core-services/data-store.service';
@ -22,12 +21,6 @@ const MotionOptionRelations: RelationDefinition[] = [
ownKey: 'votes',
foreignViewModel: ViewMotionVote
},
{
type: 'M2M',
ownIdKey: 'voted_id',
ownKey: 'voted',
foreignViewModel: ViewUser
},
{
type: 'M2O',
ownIdKey: 'poll_id',

View File

@ -14,6 +14,7 @@ import { ViewMotionOption } from 'app/site/motions/models/view-motion-option';
import { MotionPollTitleInformation, ViewMotionPoll } from 'app/site/motions/models/view-motion-poll';
import { BasePollRepositoryService } from 'app/site/polls/services/base-poll-repository.service';
import { ViewGroup } from 'app/site/users/models/view-group';
import { ViewUser } from 'app/site/users/models/view-user';
import { CollectionStringMapperService } from '../../core-services/collection-string-mapper.service';
import { DataStoreService } from '../../core-services/data-store.service';
@ -35,6 +36,12 @@ const MotionPollRelations: RelationDefinition[] = [
ownIdKey: 'motion_id',
ownKey: 'motion',
foreignViewModel: ViewMotion
},
{
type: 'M2M',
ownIdKey: 'voted_id',
ownKey: 'voted',
foreignViewModel: ViewUser
}
];

View File

@ -94,6 +94,14 @@ export class AssignmentPollDetailComponent extends BasePollDetailComponent<ViewA
}
}
}
for (const user of this.poll.voted) {
if (!votes[user.id]) {
votes[user.id] = {
user: user,
votes: [this.translate.instant('empty vote')]
};
}
}
this.setVotesData(Object.values(votes));
this.candidatesLabels = this.pollService.getChartLabels(this.poll);

View File

@ -259,9 +259,12 @@ export abstract class PollService {
public generateChartData(poll: PollData | ViewBasePoll): ChartData {
let fields: CalculablePollKey[];
// TODO: PollData should either be `ViewBasePoll` or `BasePoll` to get SOLID
const isAssignment = Object.keys(poll.options[0]).includes('user');
let isAssignment: boolean;
if (poll instanceof ViewBasePoll) {
isAssignment = poll.pollClassType === 'assignment';
} else {
isAssignment = Object.keys(poll.options[0]).includes('user');
}
if (isAssignment) {
if (poll.pollmethod === AssignmentPollMethod.YNA) {

View File

@ -44,7 +44,8 @@ export const allSlides: SlideManifest[] = [
{
slide: 'motions/motion-poll',
path: 'motions/motion-poll',
loadChildren: './slides/motions/motion-poll/motion-poll-slide.module#MotionPollSlideModule',
loadChildren: () =>
import('./motions/motion-poll/motion-poll-slide.module').then(m => m.MotionPollSlideModule),
verboseName: 'Motion Poll',
elementIdentifiers: ['name', 'id'],
canBeMappedToModel: true
@ -136,7 +137,7 @@ export const allSlides: SlideManifest[] = [
{
slide: 'assignments/assignment-poll',
path: 'assignments/assignment-poll',
loadChildren: () => import('./assignments/poll/poll-slide.module').then(m => m.PollSlideModule),
loadChildren: () => import('./assignments/assignment-poll/assignment-poll-slide.module').then(m => m.AssignmentPollSlideModule),
verboseName: 'Assignment Poll',
elementIdentifiers: ['name', 'id'],
canBeMappedToModel: true

View File

@ -54,7 +54,7 @@ class AssignmentsAppConfig(AppConfig):
required_users_assignments,
)
required_user.add_collection_string(
self.get_model("AssignmentOption").get_collection_string(),
self.get_model("AssignmentPoll").get_collection_string(),
required_users_options,
)

View File

@ -374,20 +374,16 @@ class AssignmentPoll(RESTModelMixin, BasePoll):
def get_amount_global_abstain(self):
if not self.global_abstain:
return None
elif (
self.type == self.TYPE_ANALOG
or self.pollmethod == AssignmentPoll.POLLMETHOD_VOTES
):
elif self.type == self.TYPE_ANALOG:
return self.db_amount_global_abstain
elif self.pollmethod == AssignmentPoll.POLLMETHOD_VOTES:
return sum(option.abstain for option in self.options.all())
else:
return None
def set_amount_global_abstain(self, value):
if (
self.type != self.TYPE_ANALOG
and self.pollmethod != AssignmentPoll.POLLMETHOD_VOTES
):
raise ValueError("Do not set amount_global_abstain YN/YNA polls")
if self.type != self.TYPE_ANALOG:
raise ValueError("Do not set amount_global_abstain for non analog polls")
self.db_amount_global_abstain = value
amount_global_abstain = property(
@ -397,20 +393,16 @@ class AssignmentPoll(RESTModelMixin, BasePoll):
def get_amount_global_no(self):
if not self.global_no:
return None
elif (
self.type == self.TYPE_ANALOG
or self.pollmethod == AssignmentPoll.POLLMETHOD_VOTES
):
elif self.type == self.TYPE_ANALOG:
return self.db_amount_global_no
elif self.pollmethod == AssignmentPoll.POLLMETHOD_VOTES:
return sum(option.no for option in self.options.all())
else:
return None
def set_amount_global_no(self, value):
if (
self.type != self.TYPE_ANALOG
and self.pollmethod != AssignmentPoll.POLLMETHOD_VOTES
):
raise ValueError("Do not set amount_global_no YN/YNA polls")
if self.type != self.TYPE_ANALOG:
raise ValueError("Do not set amount_global_no for non analog polls")
self.db_amount_global_no = value
amount_global_no = property(get_amount_global_no, set_amount_global_no)

View File

@ -2,7 +2,6 @@ from decimal import Decimal
from django.contrib.auth import get_user_model
from django.db import transaction
from django.db.models import F
from openslides.poll.views import BaseOptionViewSet, BasePollViewSet, BaseVoteViewSet
from openslides.utils.auth import has_perm
@ -495,13 +494,13 @@ class AssignmentPollViewSet(BasePollViewSet):
)
inform_changed_data(vote, no_delete_on_restriction=True)
else: # global_no or global_abstain
if data == "A":
poll.amount_global_abstain = F("db_amount_global_abstain") + 1
elif data == "N":
poll.amount_global_no = F("db_amount_global_no") + 1
else:
raise RuntimeError("This should not happen")
poll.save()
option = options[0]
vote = AssignmentVote.objects.create(
option=option, user=user, weight=Decimal(1), value=data
)
inform_changed_data(vote, no_delete_on_restriction=True)
inform_changed_data(option)
inform_changed_data(poll)
poll.voted.add(user)

View File

@ -82,7 +82,7 @@ class MotionsAppConfig(AppConfig):
)
required_user.add_collection_string(
self.get_model("MotionOption").get_collection_string(),
self.get_model("MotionPoll").get_collection_string(),
required_users_options,
)

View File

@ -934,6 +934,7 @@ class MotionPollManager(BaseManager):
class MotionPoll(RESTModelMixin, BasePoll):
access_permissions = MotionPollAccessPermissions()
can_see_permission = "motions.can_see"
option_class = MotionOption
objects = MotionPollManager()

View File

@ -1218,7 +1218,7 @@ class VoteAssignmentPollNamedVotes(VoteAssignmentPollBaseTestClass):
poll = AssignmentPoll.objects.get()
option = poll.options.get(pk=1)
self.assertEqual(option.yes, Decimal("0"))
self.assertEqual(option.no, Decimal("0"))
self.assertEqual(option.no, Decimal("1"))
self.assertEqual(option.abstain, Decimal("0"))
self.assertEqual(poll.amount_global_no, Decimal("1"))
self.assertEqual(poll.amount_global_abstain, Decimal("0"))
@ -1246,7 +1246,7 @@ class VoteAssignmentPollNamedVotes(VoteAssignmentPollBaseTestClass):
option = poll.options.get(pk=1)
self.assertEqual(option.yes, Decimal("0"))
self.assertEqual(option.no, Decimal("0"))
self.assertEqual(option.abstain, Decimal("0"))
self.assertEqual(option.abstain, Decimal("1"))
self.assertEqual(poll.amount_global_no, Decimal("0"))
self.assertEqual(poll.amount_global_abstain, Decimal("1"))