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

1from gettext import gettext as _ 

2 

3from django import forms 

4 

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 

8 

9 

10class DiscussionForm(forms.ModelForm): 

11 class Meta: 

12 model = Discussion 

13 fields = ["title", "members"] 

14 widgets = {"members": forms.CheckboxSelectMultiple} 

15 

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) 

20 

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 

24 

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() 

34 

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 

49 

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 

56 

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 } 

62 

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()} 

66 

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