Coverage for src / mesh / views / forms / discussion_forms.py: 49%
45 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-08-27 14:14 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-08-27 14:14 +0000
1from gettext import gettext as _
3from django import forms
5from mesh.crud.comments import submission_roles
6from mesh.models.orm.discussion_models import ALLOWED_ROLES, Discussion, DiscussionType
7from mesh.models.orm.user_models import User
10class DiscussionForm(forms.ModelForm):
11 class Meta:
12 model = Discussion
13 fields = ["title", "members"]
14 widgets = {"members": forms.CheckboxSelectMultiple}
16 def __init__(self, *args, submission=None, **kwargs):
17 super().__init__(*args, **kwargs)
18 self.submission = submission
19 self.fields["members"].queryset = self._eligible_users(submission)
21 def _eligible_users(self, submission):
22 # users ayant un rôle sur la submission : auteur, reviewers, éditeurs
23 from django.db.models import Q
25 return User.objects.filter(
26 Q(pk=submission.created_by_id)
27 | Q(
28 pk__in=submission.versions.filter(reviews__isnull=False).values(
29 "reviews__reviewer"
30 )
31 )
32 | Q(pk__in=submission.editors.values("user"))
33 ).distinct()
35 def clean(self):
36 cleaned = super().clean()
37 members = cleaned.get("members")
38 if members is not None:
39 roles = set()
40 for m in members:
41 roles |= submission_roles(m, submission=self.submission)
42 if "author" in roles and "reviewer" in roles:
43 raise forms.ValidationError(
44 _("Un fil ne peut pas contenir à la fois des auteurs et des relecteurs.")
45 )
46 # déduire le type pour le champ non-null
47 cleaned["type"] = self._infer_type(roles)
48 return cleaned
50 def _infer_type(self, roles):
51 if "author" in roles:
52 return DiscussionType.EDITOR_AUTHOR
53 if "reviewer" in roles:
54 return DiscussionType.EDITOR_REVIEWER
55 return DiscussionType.EDITOR_ONLY
57 def members_roles(self) -> dict:
58 return {
59 str(u.pk): sorted(submission_roles(u, submission=self.submission))
60 for u in self.fields["members"].queryset
61 }
63 def allowed_roles(self) -> dict:
64 # sorted() convert set to list -> serialisable (json can't encoe a set)
65 return {str(k): sorted(v) for k, v in ALLOWED_ROLES.items()}
67 def save(self, commit=True):
68 instance = super().save(commit=False)
69 instance.type = self.cleaned_data["type"]
70 if commit:
71 instance.save()
72 self.save_m2m()
73 return instance