Coverage for src / mesh / views / components / review_summary.py: 96%

27 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-07-09 13:14 +0000

1from __future__ import annotations 

2 

3from dataclasses import dataclass, field 

4from typing import TYPE_CHECKING 

5 

6if TYPE_CHECKING: 

7 from mesh.models.orm.submission_models import Submission 

8 

9 

10@dataclass 

11class CountWithTotal: 

12 value: int 

13 total: int 

14 

15 def __post_init__(self): 

16 if self.value > self.total: 

17 raise ValueError("CountWithTotal: a value greater than the total has been set.") 

18 

19 

20@dataclass 

21class ReviewSummary: 

22 current_version: int 

23 reviewers_count: CountWithTotal | None = field(default=None) 

24 reports_count: CountWithTotal | None = field(default=None) 

25 

26 

27def build_review_summary(submission: "Submission"): 

28 """ 

29 Returns the submission review summary: 

30 - Current version / round 

31 - Nb of answered/pending reviewer requests 

32 - Nb of review reports out of accepted requests 

33 """ 

34 

35 current_version = submission.versions_censored[0] if submission.versions_censored else None 

36 summary = ReviewSummary( 

37 current_version=current_version.number if current_version else 0, 

38 reviewers_count=CountWithTotal(value=0, total=0), 

39 reports_count=CountWithTotal(value=0, total=0), 

40 ) 

41 

42 if current_version: 

43 reviews = current_version.reviews_censored 

44 if reviews: 

45 answered_reviews = [r for r in reviews if r.accepted is not None] 

46 summary.reviewers_count = CountWithTotal( 

47 value=len(answered_reviews), total=len(reviews) 

48 ) 

49 

50 accepted_reviews = [r for r in answered_reviews if r.accepted] 

51 completed_reviews = sum(1 for r in accepted_reviews if r.submitted) 

52 summary.reports_count = CountWithTotal( 

53 value=completed_reviews, total=len(accepted_reviews) 

54 ) 

55 

56 return summary