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
« prev ^ index » next coverage.py v7.13.1, created at 2026-07-09 13:14 +0000
1from __future__ import annotations
3from dataclasses import dataclass, field
4from typing import TYPE_CHECKING
6if TYPE_CHECKING:
7 from mesh.models.orm.submission_models import Submission
10@dataclass
11class CountWithTotal:
12 value: int
13 total: int
15 def __post_init__(self):
16 if self.value > self.total:
17 raise ValueError("CountWithTotal: a value greater than the total has been set.")
20@dataclass
21class ReviewSummary:
22 current_version: int
23 reviewers_count: CountWithTotal | None = field(default=None)
24 reports_count: CountWithTotal | None = field(default=None)
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 """
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 )
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 )
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 )
56 return summary