mirror of
https://gitlab.com/animath/si/plateforme.git
synced 2025-04-01 18:51:11 +00:00
138 lines
5.7 KiB
Python
138 lines
5.7 KiB
Python
# Copyright (C) 2025 by Animath
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
from citric import Client
|
|
from django.conf import settings
|
|
from django.db import models
|
|
from django.urls import reverse_lazy
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
from participation.models import Team, Tournament
|
|
from registration.models import ParticipantRegistration, StudentRegistration
|
|
|
|
|
|
class Survey(models.Model):
|
|
"""
|
|
Ce modèle représente un sondage LimeSurvey afin de faciliter l'import des
|
|
participant⋅es au sondage et d'effectuer le suivi.
|
|
"""
|
|
survey_id = models.IntegerField(
|
|
primary_key=True,
|
|
verbose_name=_("survey identifier"),
|
|
help_text=_("The numeric identifier of the Limesurvey."),
|
|
)
|
|
|
|
name = models.CharField(
|
|
max_length=255,
|
|
verbose_name=_("display name"),
|
|
)
|
|
|
|
invite_team = models.BooleanField(
|
|
default=False,
|
|
verbose_name=_("invite whole team"),
|
|
help_text=_("When this field is checked, teams will get only one survey invitation instead of one per person."),
|
|
)
|
|
|
|
invite_coaches = models.BooleanField(
|
|
default=True,
|
|
verbose_name=_("invite coaches"),
|
|
help_text=_("When this field is checked, coaches will also be invited in the survey. No effect when the whole team is invited."),
|
|
)
|
|
|
|
tournament = models.ForeignKey(
|
|
Tournament,
|
|
null=True,
|
|
blank=True,
|
|
default=None,
|
|
on_delete=models.SET_NULL,
|
|
related_name="surveys",
|
|
verbose_name=_("tournament restriction"),
|
|
help_text=_("When this field is filled, the survey participants will be restricted to this tournament members."),
|
|
)
|
|
|
|
completed_registrations = models.ManyToManyField(
|
|
ParticipantRegistration,
|
|
blank=True,
|
|
related_name="completed_surveys",
|
|
verbose_name=_("participants that completed the survey"),
|
|
)
|
|
|
|
completed_teams = models.ManyToManyField(
|
|
Team,
|
|
blank=True,
|
|
related_name="completed_surveys",
|
|
verbose_name=_("teams that completed the survey"),
|
|
)
|
|
|
|
@property
|
|
def participants(self):
|
|
if self.invite_team:
|
|
teams = Team.objects.filter(participation__valid=True)
|
|
if self.tournament:
|
|
teams = teams.filter(participation__tournament=self.tournament)
|
|
return teams.all()
|
|
else:
|
|
if self.invite_coaches:
|
|
registrations = ParticipantRegistration.objects.filter(team__participation__valid=True)
|
|
else:
|
|
registrations = StudentRegistration.objects.filter(team__participation__valid=True)
|
|
if self.tournament:
|
|
registrations = registrations.filter(team__participation__tournament=self.tournament)
|
|
return registrations.all()
|
|
|
|
@property
|
|
def completed(self):
|
|
if self.invite_team:
|
|
return self.completed_teams
|
|
else:
|
|
return self.completed_registrations
|
|
|
|
def get_absolute_url(self):
|
|
return reverse_lazy("survey:survey_detail", args=(self.survey_id,))
|
|
|
|
def generate_participants_data(self):
|
|
participants_data = []
|
|
if self.invite_team:
|
|
for team in self.participants:
|
|
participant_data = {"firstname": team.name, "lastname": f"(équipe {team.trigram})", "email": team.email}
|
|
participants_data.append(participant_data)
|
|
else:
|
|
for reg in self.participants:
|
|
participant_data = {"firstname": reg.user.first_name, "lastname": reg.user.last_name, "email": reg.user.email}
|
|
participants_data.append(participant_data)
|
|
return participants_data
|
|
|
|
def invite_all(self):
|
|
participants_data = self.generate_participants_data()
|
|
with Client(f"{settings.LIMESURVEY_URL}/index.php/admin/remotecontrol", settings.LIMESURVEY_USER, settings.LIMESURVEY_PASSWORD) as client:
|
|
try:
|
|
current_participants = client.list_participants(self.survey_id, limit=10000)
|
|
except:
|
|
current_participants = []
|
|
current_participants_email = set(participant['participant_info']['email'] for participant in current_participants)
|
|
participants_data = [participant_data for participant_data in participants_data if participant_data['email'] not in current_participants_email]
|
|
try:
|
|
client.activate_tokens(self.survey_id)
|
|
except:
|
|
pass
|
|
new_participants = client.add_participants(self.survey_id, participant_data=participants_data)
|
|
if new_participants:
|
|
client.invite_participants(self.survey_id, token_ids=[participant['tid'] for participant in new_participants])
|
|
return new_participants
|
|
|
|
def fetch_completion_data(self):
|
|
with Client(f"{settings.LIMESURVEY_URL}/index.php/admin/remotecontrol", settings.LIMESURVEY_USER, settings.LIMESURVEY_PASSWORD) as client:
|
|
participants = client.list_participants(self.survey_id, limit=10000, attributes=['completed'])
|
|
if self.invite_team:
|
|
team_names = [participant['participant_info']['firstname'] for participant in participants if participant['completed'] != 'N']
|
|
self.completed_teams.set(list(Team.objects.filter(name__in=team_names).values_list('id', flat=True)))
|
|
else:
|
|
mails = [participant['participant_info']['email'] for participant in participants if participant['completed'] != 'N']
|
|
self.completed_registrations.set(list(ParticipantRegistration.objects.filter(user__email__in=mails).values_list('id', flat=True)))
|
|
self.save()
|
|
|
|
|
|
class Meta:
|
|
verbose_name = _("survey")
|
|
verbose_name_plural = _("surveys")
|