Relations in the client

This commit is contained in:
FinnStutzenstein 2019-10-29 09:00:11 +01:00
parent ced40cab74
commit ce171980e8
28 changed files with 205 additions and 98 deletions

View File

@ -5,12 +5,61 @@ import { TranslateService } from '@ngx-translate/core';
import { DataSendService } from 'app/core/core-services/data-send.service';
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { RelationDefinition } from 'app/core/definitions/relations';
import { AssignmentOption } from 'app/shared/models/assignments/assignment-option';
import { AssignmentPoll } from 'app/shared/models/assignments/assignment-poll';
import { ViewAssignmentOption } from 'app/site/assignments/models/view-assignment-option';
import { AssignmentPollTitleInformation, ViewAssignmentPoll } from 'app/site/assignments/models/view-assignment-poll';
import { BaseRepository } from '../base-repository';
import { ViewAssignmentVote } from 'app/site/assignments/models/view-assignment-vote';
import { ViewGroup } from 'app/site/users/models/view-group';
import { ViewUser } from 'app/site/users/models/view-user';
import { BaseRepository, NestedModelDescriptors } from '../base-repository';
import { CollectionStringMapperService } from '../../core-services/collection-string-mapper.service';
import { DataStoreService } from '../../core-services/data-store.service';
const AssignmentPollRelations: RelationDefinition[] = [
{
type: 'M2M',
ownIdKey: 'groups_id',
ownKey: 'groups',
foreignViewModel: ViewGroup
},
{
type: 'M2M',
ownIdKey: 'voted_id',
ownKey: 'voted',
foreignViewModel: ViewUser
}
];
const AssignmentPollNestedModelDescriptors: NestedModelDescriptors = {
'assignments/assignment-poll': [
{
ownKey: 'options',
foreignViewModel: ViewAssignmentOption,
foreignModel: AssignmentOption,
order: 'weight',
relationDefinitionsByKey: {
user: {
type: 'M2O',
ownIdKey: 'user_id',
ownKey: 'user',
foreignViewModel: ViewUser
},
votes: {
type: 'O2M',
foreignIdKey: 'option_id',
ownKey: 'votes',
foreignViewModel: ViewAssignmentVote
}
},
titles: {
getTitle: (viewOption: ViewAssignmentOption) => (viewOption.user ? viewOption.user.getTitle() : '')
}
}
]
};
/**
* Repository Service for Assignments.
*
@ -49,8 +98,9 @@ export class AssignmentPollRepositoryService extends BaseRepository<
viewModelStoreService,
translate,
relationManager,
AssignmentPoll
// TODO: relations
AssignmentPoll,
AssignmentPollRelations,
AssignmentPollNestedModelDescriptors
);
}

View File

@ -8,11 +8,8 @@ import { RelationManagerService } from 'app/core/core-services/relation-manager.
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { RelationDefinition } from 'app/core/definitions/relations';
import { Assignment } from 'app/shared/models/assignments/assignment';
import { AssignmentOption } from 'app/shared/models/assignments/assignment-option';
import { AssignmentPoll } from 'app/shared/models/assignments/assignment-poll';
import { AssignmentRelatedUser } from 'app/shared/models/assignments/assignment-related-user';
import { AssignmentTitleInformation, ViewAssignment } from 'app/site/assignments/models/view-assignment';
import { ViewAssignmentOption } from 'app/site/assignments/models/view-assignment-option';
import { ViewAssignmentPoll } from 'app/site/assignments/models/view-assignment-poll';
import { ViewAssignmentRelatedUser } from 'app/site/assignments/models/view-assignment-related-user';
import { ViewMediafile } from 'app/site/mediafiles/models/view-mediafile';
@ -35,6 +32,12 @@ const AssignmentRelations: RelationDefinition[] = [
ownIdKey: 'attachments_id',
ownKey: 'attachments',
foreignViewModel: ViewMediafile
},
{
type: 'O2M',
ownKey: 'polls',
foreignIdKey: 'assignment_id',
foreignViewModel: ViewAssignmentPoll
}
];
@ -57,28 +60,6 @@ const AssignmentNestedModelDescriptors: NestedModelDescriptors = {
getTitle: (viewAssignmentRelatedUser: ViewAssignmentRelatedUser) =>
viewAssignmentRelatedUser.user ? viewAssignmentRelatedUser.user.getFullName() : ''
}
},
{
ownKey: 'polls',
foreignViewModel: ViewAssignmentPoll,
foreignModel: AssignmentPoll,
relationDefinitionsByKey: {}
}
],
'assignments/assignment-poll': [
{
ownKey: 'options',
foreignViewModel: ViewAssignmentOption,
foreignModel: AssignmentOption,
order: 'weight',
relationDefinitionsByKey: {
user: {
type: 'M2O',
ownIdKey: 'candidate_id',
ownKey: 'user',
foreignViewModel: ViewUser
}
}
}
]
};

View File

@ -5,12 +5,23 @@ import { TranslateService } from '@ngx-translate/core';
import { DataSendService } from 'app/core/core-services/data-send.service';
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { RelationDefinition } from 'app/core/definitions/relations';
import { AssignmentVote } from 'app/shared/models/assignments/assignment-vote';
import { ViewAssignmentVote } from 'app/site/assignments/models/view-assignment-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';
const AssignmentVoteRelations: RelationDefinition[] = [
{
type: 'M2O',
ownIdKey: 'user_id',
ownKey: 'user',
foreignViewModel: ViewUser
}
];
/**
* Repository Service for Assignments.
*
@ -43,8 +54,8 @@ export class AssignmentVoteRepositoryService extends BaseRepository<ViewAssignme
viewModelStoreService,
translate,
relationManager,
AssignmentVote
// TODO: relations
AssignmentVote,
AssignmentVoteRelations
);
}

View File

@ -5,12 +5,54 @@ import { TranslateService } from '@ngx-translate/core';
import { DataSendService } from 'app/core/core-services/data-send.service';
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { RelationDefinition } from 'app/core/definitions/relations';
import { MotionOption } from 'app/shared/models/motions/motion-option';
import { MotionPoll } from 'app/shared/models/motions/motion-poll';
import { ViewMotionOption } from 'app/site/motions/models/view-motion-option';
import { MotionPollTitleInformation, ViewMotionPoll } from 'app/site/motions/models/view-motion-poll';
import { BaseRepository } from '../base-repository';
import { ViewMotionVote } from 'app/site/motions/models/view-motion-vote';
import { ViewGroup } from 'app/site/users/models/view-group';
import { ViewUser } from 'app/site/users/models/view-user';
import { BaseRepository, NestedModelDescriptors } from '../base-repository';
import { CollectionStringMapperService } from '../../core-services/collection-string-mapper.service';
import { DataStoreService } from '../../core-services/data-store.service';
const MotionPollRelations: RelationDefinition[] = [
{
type: 'M2M',
ownIdKey: 'groups_id',
ownKey: 'groups',
foreignViewModel: ViewGroup
},
{
type: 'M2M',
ownIdKey: 'voted_id',
ownKey: 'voted',
foreignViewModel: ViewUser
}
];
const MotionPollNestedModelDescriptors: NestedModelDescriptors = {
'motions/motion-poll': [
{
ownKey: 'options',
foreignViewModel: ViewMotionOption,
foreignModel: MotionOption,
relationDefinitionsByKey: {
votes: {
type: 'O2M',
foreignIdKey: 'option_id',
ownKey: 'votes',
foreignViewModel: ViewMotionVote
}
},
titles: {
getTitle: (viewOption: ViewMotionOption) => ''
}
}
]
};
/**
* Repository Service for Assignments.
*
@ -39,8 +81,9 @@ export class MotionPollRepositoryService extends BaseRepository<
viewModelStoreService,
translate,
relationManager,
MotionPoll
// TODO: relations
MotionPoll,
MotionPollRelations,
MotionPollNestedModelDescriptors
);
}

View File

@ -23,6 +23,7 @@ import { MotionTitleInformation, ViewMotion } from 'app/site/motions/models/view
import { ViewMotionAmendedParagraph } from 'app/site/motions/models/view-motion-amended-paragraph';
import { ViewMotionBlock } from 'app/site/motions/models/view-motion-block';
import { ViewMotionChangeRecommendation } from 'app/site/motions/models/view-motion-change-recommendation';
import { ViewMotionPoll } from 'app/site/motions/models/view-motion-poll';
import { ViewState } from 'app/site/motions/models/view-state';
import { ViewStatuteParagraph } from 'app/site/motions/models/view-statute-paragraph';
import { ViewSubmitter } from 'app/site/motions/models/view-submitter';
@ -125,12 +126,17 @@ const MotionRelations: RelationDefinition[] = [
ownKey: 'amendments',
foreignViewModel: ViewMotion
},
// TMP:
{
type: 'M2O',
ownIdKey: 'parent_id',
ownKey: 'parent',
foreignViewModel: ViewMotion
},
{
type: 'O2M',
foreignIdKey: 'motion_id',
ownKey: 'polls',
foreignViewModel: ViewMotionPoll
}
// Personal notes are dynamically added in the repo.
];

View File

@ -5,12 +5,23 @@ import { TranslateService } from '@ngx-translate/core';
import { DataSendService } from 'app/core/core-services/data-send.service';
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { RelationDefinition } from 'app/core/definitions/relations';
import { MotionVote } from 'app/shared/models/motions/motion-vote';
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';
const MotionVoteRelations: RelationDefinition[] = [
{
type: 'M2O',
ownIdKey: 'user_id',
ownKey: 'user',
foreignViewModel: ViewUser
}
];
/**
* Repository Service for Assignments.
*
@ -43,8 +54,8 @@ export class MotionVoteRepositoryService extends BaseRepository<ViewMotionVote,
viewModelStoreService,
translate,
relationManager,
MotionVote
// TODO: relations
MotionVote,
MotionVoteRelations
);
}

View File

@ -4,6 +4,7 @@ export class AssignmentOption extends BaseOption<AssignmentOption> {
public static COLLECTIONSTRING = 'assignments/assignment-option';
public user_id: number;
public weight: number;
public constructor(input?: any) {
super(AssignmentOption.COLLECTIONSTRING, input);

View File

@ -1,4 +1,3 @@
import { AssignmentPoll } from './assignment-poll';
import { AssignmentRelatedUser } from './assignment-related-user';
import { BaseModelWithAgendaItemAndListOfSpeakers } from '../base/base-model-with-agenda-item-and-list-of-speakers';
@ -22,18 +21,9 @@ export class Assignment extends BaseModelWithAgendaItemAndListOfSpeakers<Assignm
public id: number;
public assignment_related_users: AssignmentRelatedUser[];
public polls: AssignmentPoll[];
public constructor(input?: any) {
super(Assignment.COLLECTIONSTRING, input);
}
public get candidates_id(): number[] {
return this.assignment_related_users
.sort((a: AssignmentRelatedUser, b: AssignmentRelatedUser) => {
return a.weight - b.weight;
})
.map((candidate: AssignmentRelatedUser) => candidate.user_id);
}
}
export interface Assignment extends AssignmentWithoutNestedModels {}

View File

@ -1,11 +1,11 @@
import { BaseModel } from './base-model';
export abstract class BaseDecimalModel<T = any> extends BaseModel<T> {
protected abstract decimalFields: (keyof this)[];
protected abstract getDecimalFields(): (keyof this)[];
public deserialize(input: any): void {
if (input && typeof input === 'object') {
this.decimalFields.forEach(field => (input[field] = parseInt(input[field], 10)));
this.getDecimalFields().forEach(field => (input[field] = parseInt(input[field], 10)));
}
super.deserialize(input);
}

View File

@ -1,5 +1,4 @@
import { BaseModelWithAgendaItemAndListOfSpeakers } from '../base/base-model-with-agenda-item-and-list-of-speakers';
import { MotionPoll } from './motion-poll';
import { Submitter } from './submitter';
export interface MotionComment {
@ -33,7 +32,6 @@ export interface MotionWithoutNestedModels extends BaseModelWithAgendaItemAndLis
recommendation_extension: string;
tags_id: number[];
attachments_id: number[];
polls: MotionPoll[];
weight: number;
sort_parent_id: number;
created: string;

View File

@ -5,7 +5,8 @@ export abstract class BaseOption<T> extends BaseDecimalModel<T> {
public yes: number;
public no: number;
public abstain: number;
public votes_id: number[];
protected decimalFields: (keyof BaseOption<T>)[] = ['yes', 'no', 'abstain'];
protected getDecimalFields(): (keyof BaseOption<T>)[] {
return ['yes', 'no', 'abstain'];
}
}

View File

@ -28,6 +28,8 @@ export interface BasePollWithoutNestedModels {
export abstract class BasePoll<T, O extends BaseOption<any>> extends BaseDecimalModel<T> {
public options: O[];
protected decimalFields: (keyof BasePoll<T, O>)[] = ['votesvalid', 'votesinvalid', 'votescast'];
protected getDecimalFields(): (keyof BasePoll<T, O>)[] {
return ['votesvalid', 'votesinvalid', 'votescast'];
}
}
export interface BasePoll<T, O extends BaseOption<any>> extends BasePollWithoutNestedModels {}

View File

@ -3,7 +3,10 @@ import { BaseDecimalModel } from '../base/base-decimal-model';
export abstract class BaseVote<T> extends BaseDecimalModel<T> {
public weight: number;
public value: 'Y' | 'N' | 'A';
public option_id: number;
public user_id?: number;
protected decimalFields: (keyof BaseVote<T>)[] = ['weight'];
protected getDecimalFields(): (keyof BaseVote<T>)[] {
return ['weight'];
}
}

View File

@ -1,5 +1,7 @@
import { AssignmentOption } from 'app/shared/models/assignments/assignment-option';
import { ViewUser } from 'app/site/users/models/view-user';
import { BaseViewModel } from '../../base/base-view-model';
import { ViewAssignmentVote } from './view-assignment-vote';
export class ViewAssignmentOption extends BaseViewModel<AssignmentOption> {
public get option(): AssignmentOption {
@ -9,4 +11,9 @@ export class ViewAssignmentOption extends BaseViewModel<AssignmentOption> {
protected _collectionString = AssignmentOption.COLLECTIONSTRING;
}
export interface ViewAssignmentOption extends AssignmentOption {}
interface TIMotionOptionRelations {
votes: ViewAssignmentVote[];
user: ViewUser;
}
export interface ViewAssignmentOption extends AssignmentOption, TIMotionOptionRelations {}

View File

@ -104,7 +104,7 @@ export class ViewAssignment extends BaseViewModelWithAgendaItemAndListOfSpeakers
}
interface IAssignmentRelations {
assignment_related_users: ViewAssignmentRelatedUser[];
polls?: ViewAssignmentPoll[];
polls: ViewAssignmentPoll[];
tags?: ViewTag[];
attachments?: ViewMediafile[];
}

View File

@ -1,5 +1,6 @@
import { MotionOption } from 'app/shared/models/motions/motion-option';
import { BaseViewModel } from '../../base/base-view-model';
import { ViewMotionVote } from './view-motion-vote';
export class ViewMotionOption extends BaseViewModel<MotionOption> {
public get option(): MotionOption {
@ -9,4 +10,8 @@ export class ViewMotionOption extends BaseViewModel<MotionOption> {
protected _collectionString = MotionOption.COLLECTIONSTRING;
}
export interface ViewMotionPoll extends MotionOption {}
interface TIMotionOptionRelations {
votes: ViewMotionVote[];
}
export interface ViewMotionOption extends MotionOption, TIMotionOptionRelations {}

View File

@ -16,6 +16,7 @@ import { ViewCategory } from './view-category';
import { ViewMotionBlock } from './view-motion-block';
import { ViewMotionChangeRecommendation } from './view-motion-change-recommendation';
import { ViewMotionCommentSection } from './view-motion-comment-section';
import { ViewMotionPoll } from './view-motion-poll';
import { ViewState } from './view-state';
import { ViewSubmitter } from './view-submitter';
import { ViewWorkflow } from './view-workflow';
@ -359,6 +360,7 @@ interface TIMotionRelations {
amendments?: ViewMotion[];
changeRecommendations?: ViewMotionChangeRecommendation[];
diffLines?: DiffLinesInParagraph[];
polls: ViewMotionPoll[];
}
export interface ViewMotion extends MotionWithoutNestedModels, TIMotionRelations {}

View File

@ -3,10 +3,14 @@ import { CategoryRepositoryService } from 'app/core/repositories/motions/categor
import { ChangeRecommendationRepositoryService } from 'app/core/repositories/motions/change-recommendation-repository.service';
import { MotionBlockRepositoryService } from 'app/core/repositories/motions/motion-block-repository.service';
import { MotionCommentSectionRepositoryService } from 'app/core/repositories/motions/motion-comment-section-repository.service';
import { MotionPollRepositoryService } from 'app/core/repositories/motions/motion-poll-repository.service';
import { MotionRepositoryService } from 'app/core/repositories/motions/motion-repository.service';
import { MotionVoteRepositoryService } from 'app/core/repositories/motions/motion-vote-repository.service';
import { StateRepositoryService } from 'app/core/repositories/motions/state-repository.service';
import { StatuteParagraphRepositoryService } from 'app/core/repositories/motions/statute-paragraph-repository.service';
import { WorkflowRepositoryService } from 'app/core/repositories/motions/workflow-repository.service';
import { MotionPoll } from 'app/shared/models/motions/motion-poll';
import { MotionVote } from 'app/shared/models/motions/motion-vote';
import { State } from 'app/shared/models/motions/state';
import { Category } from '../../shared/models/motions/category';
import { Motion } from '../../shared/models/motions/motion';
@ -19,6 +23,8 @@ import { ViewMotion } from './models/view-motion';
import { ViewMotionBlock } from './models/view-motion-block';
import { ViewMotionChangeRecommendation } from './models/view-motion-change-recommendation';
import { ViewMotionCommentSection } from './models/view-motion-comment-section';
import { ViewMotionPoll } from './models/view-motion-poll';
import { ViewMotionVote } from './models/view-motion-vote';
import { ViewState } from './models/view-state';
import { ViewStatuteParagraph } from './models/view-statute-paragraph';
import { ViewWorkflow } from './models/view-workflow';
@ -70,7 +76,9 @@ export const MotionsAppConfig: AppConfig = {
viewModel: ViewStatuteParagraph,
searchOrder: 9,
repository: StatuteParagraphRepositoryService
}
},
{ model: MotionPoll, viewModel: ViewMotionPoll, repository: MotionPollRepositoryService },
{ model: MotionVote, viewModel: ViewMotionVote, repository: MotionVoteRepositoryService }
],
mainMenuEntries: [
{

View File

@ -358,11 +358,11 @@ export class MotionPdfService {
}
// voting results
if (motion.motion.polls.length && (!infoToExport || infoToExport.includes('polls'))) {
if (motion.polls.length && (!infoToExport || infoToExport.includes('polls'))) {
const column1 = [];
const column2 = [];
const column3 = [];
motion.motion.polls.map((poll, index) => {
motion.polls.map((poll, index) => {
/*if (poll.has_votes) {
if (motion.motion.polls.length > 1) {
column1.push(index + 1 + '. ' + this.translate.instant('Vote'));

View File

@ -71,8 +71,8 @@ export class MotionPollPdfService extends PollPdfService {
)}`;
if (!title) {
title = `${this.translate.instant('Motion')} - ${motion.identifier}`;
if (motion.motion.polls.length > 1) {
title += ` (${this.translate.instant('Vote')} ${motion.motion.polls.length})`;
if (motion.polls.length > 1) {
title += ` (${this.translate.instant('Vote')} ${motion.polls.length})`;
}
}
if (!subtitle) {

View File

@ -51,3 +51,12 @@ class AssignmentPollAccessPermissions(BaseAccessPermissions):
self, full_data: List[Dict[str, Any]], user_id: int
) -> List[Dict[str, Any]]:
return full_data
class AssignmentVoteAccessPermissions(BaseAccessPermissions):
base_permission = "assignments.can_see"
async def get_restricted_data(
self, full_data: List[Dict[str, Any]], user_id: int
) -> List[Dict[str, Any]]:
return full_data

View File

@ -19,6 +19,7 @@ from ..utils.models import CASCADE_AND_AUTOUPDATE, SET_NULL_AND_AUTOUPDATE
from .access_permissions import (
AssignmentAccessPermissions,
AssignmentPollAccessPermissions,
AssignmentVoteAccessPermissions,
)
@ -268,6 +269,7 @@ class Assignment(RESTModelMixin, AgendaItemWithListOfSpeakersMixin, models.Model
class AssignmentVote(RESTModelMixin, BaseVote):
access_permissions = AssignmentVoteAccessPermissions()
option = models.ForeignKey(
"AssignmentOption", on_delete=models.CASCADE, related_name="votes"
)

View File

@ -74,12 +74,10 @@ class AssignmentOptionSerializer(ModelSerializer):
max_digits=15, decimal_places=6, min_value=-2, read_only=True
)
votes = IdPrimaryKeyRelatedField(many=True, read_only=True)
class Meta:
model = AssignmentOption
fields = ("user",) + BASE_OPTION_FIELDS
read_only_fields = ("user",) + BASE_OPTION_FIELDS
fields = ("user", "weight") + BASE_OPTION_FIELDS
read_only_fields = ("user", "weight") + BASE_OPTION_FIELDS
class AssignmentPollSerializer(ModelSerializer):
@ -133,7 +131,6 @@ class AssignmentSerializer(ModelSerializer):
assignment_related_users = AssignmentRelatedUserSerializer(
many=True, read_only=True
)
polls = IdPrimaryKeyRelatedField(many=True, read_only=True)
agenda_create = BooleanField(write_only=True, required=False, allow_null=True)
agenda_type = IntegerField(
write_only=True, required=False, min_value=1, max_value=3, allow_null=True
@ -150,7 +147,6 @@ class AssignmentSerializer(ModelSerializer):
"phase",
"assignment_related_users",
"poll_description_default",
"polls",
"agenda_item_id",
"list_of_speakers_id",
"agenda_create",

View File

@ -246,22 +246,6 @@ class AssignmentViewSet(ModelViewSet):
message = "User {0} was successfully unelected."
return Response({"detail": message, "args": [str(user)]})
@detail_route(methods=["post"])
def create_poll(self, request, pk=None):
"""
View to create a poll. It is a POST request without any data.
"""
assignment = self.get_object()
if not assignment.candidates.exists():
raise ValidationError(
{"detail": "Can not create ballot because there are no candidates."}
)
with transaction.atomic():
poll = assignment.create_poll()
return Response(
{"detail": "Ballot created successfully.", "createdPollId": poll.pk}
)
@detail_route(methods=["post"])
def sort_related_users(self, request, pk=None):
"""

View File

@ -243,8 +243,6 @@ class MotionOptionSerializer(ModelSerializer):
max_digits=15, decimal_places=6, min_value=-2, read_only=True
)
votes = IdPrimaryKeyRelatedField(many=True, read_only=True)
class Meta:
model = MotionOption
fields = BASE_OPTION_FIELDS
@ -371,7 +369,6 @@ class MotionSerializer(ModelSerializer):
"""
comments = MotionCommentSerializer(many=True, read_only=True)
polls = IdPrimaryKeyRelatedField(many=True, read_only=True)
modified_final_version = CharField(allow_blank=True, required=False)
reason = CharField(allow_blank=True, required=False)
state_restriction = SerializerMethodField()
@ -419,7 +416,6 @@ class MotionSerializer(ModelSerializer):
"recommendation_extension",
"tags",
"attachments",
"polls",
"agenda_item_id",
"list_of_speakers_id",
"agenda_create",

View File

@ -11,6 +11,6 @@ BASE_POLL_FIELDS = (
"id",
)
BASE_OPTION_FIELDS = ("id", "yes", "no", "abstain", "votes")
BASE_OPTION_FIELDS = ("id", "yes", "no", "abstain")
BASE_VOTE_FIELDS = ("id", "weight", "value", "user")
BASE_VOTE_FIELDS = ("id", "weight", "value", "user", "option")

View File

@ -419,7 +419,7 @@ class RetrieveMotion(TestCase):
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_user_without_can_see_user_permission_to_see_motion_and_submitter_data(
self
self,
):
admin = get_user_model().objects.get(username="admin")
Submitter.objects.add(admin, self.motion)

View File

@ -582,7 +582,6 @@ class VoteMotionPollNamedAutoupdates(TestCase):
"yes": "0.000000",
"no": "0.000000",
"abstain": "1.000000",
"votes_id": [vote.id],
}
],
"voted_id": [self.user1.id],
@ -594,6 +593,7 @@ class VoteMotionPollNamedAutoupdates(TestCase):
"weight": "1.000000",
"value": "A",
"user_id": self.user1.id,
"option_id": 1,
},
},
)
@ -605,6 +605,7 @@ class VoteMotionPollNamedAutoupdates(TestCase):
autoupdate[0]["motions/motion-vote:1"],
{
"pollstate": 2,
"option_id": 1,
"id": 1,
"weight": "1.000000",
"value": "A",
@ -626,7 +627,7 @@ class VoteMotionPollNamedAutoupdates(TestCase):
"type": "named",
"title": "test_title_tho8PhiePh8upaex6phi",
"groups_id": [GROUP_DELEGATE_PK],
"options": [{"id": 1, "votes_id": [vote.id]}],
"options": [{"id": 1}],
"id": 1,
},
)
@ -653,12 +654,12 @@ class VoteMotionPollPseudoanonymousAutoupdates(TestCase):
self.other_user, _ = self.create_user()
inform_changed_data(self.other_user)
self.user, user1_password = self.create_user()
self.user, user_password = self.create_user()
self.user.groups.add(self.delegate_group)
self.user.is_present = True
self.user.save()
self.user_client = APIClient()
self.user_client.login(username=self.user.username, password=user1_password)
self.user_client.login(username=self.user.username, password=user_password)
self.poll = MotionPoll.objects.create(
motion=self.motion,
@ -699,7 +700,6 @@ class VoteMotionPollPseudoanonymousAutoupdates(TestCase):
"yes": "0.000000",
"no": "0.000000",
"abstain": "1.000000",
"votes_id": [vote.id],
}
],
"voted_id": [self.user.id],
@ -707,6 +707,7 @@ class VoteMotionPollPseudoanonymousAutoupdates(TestCase):
},
"motions/motion-vote:1": {
"pollstate": 2,
"option_id": 1,
"id": 1,
"weight": "1.000000",
"value": "A",
@ -730,7 +731,7 @@ class VoteMotionPollPseudoanonymousAutoupdates(TestCase):
"type": "pseudoanonymous",
"title": "test_title_cahP1umooteehah2jeey",
"groups_id": [GROUP_DELEGATE_PK],
"options": [{"id": 1, "votes_id": [vote.id]}],
"options": [{"id": 1}],
"id": 1,
},
)
@ -953,7 +954,6 @@ class PublishMotionPoll(TestCase):
"yes": "0.000000",
"no": "2.000000",
"abstain": "0.000000",
"votes_id": [1],
}
],
"voted_id": [],
@ -961,6 +961,7 @@ class PublishMotionPoll(TestCase):
},
"motions/motion-vote:1": {
"pollstate": 4,
"option_id": 1,
"id": 1,
"weight": "2.000000",
"value": "N",