Coverage for middle_layer/review/application_layer/services/launch_srp_consensus_phase_service.py: 100.00%

25 statements  

« prev     ^ index     » next       coverage.py v7.10.5, created at 2026-03-09 06:13 +0000

1# Copyright 2024 Associated Universities, Inc. 

2# 

3# This file is part of Telescope Time Allocation Tools (TTAT). 

4# 

5# TTAT is free software: you can redistribute it and/or modify 

6# it under the terms of the GNU General Public License as published by 

7# the Free Software Foundation, either version 3 of the License, or 

8# any later version. 

9# 

10# TTAT is distributed in the hope that it will be useful, 

11# but WITHOUT ANY WARRANTY; without even the implied warranty of 

12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

13# GNU General Public License for more details. 

14# 

15# You should have received a copy of the GNU General Public License 

16# along with TTAT. If not, see <https://www.gnu.org/licenses/>. 

17# 

18 

19from common.application_layer.orm_repositories.orm_repository import ORMRepository 

20from review.domain_layer.entities.ppr_proposal_review import PPRProposalReview 

21from review.domain_layer.entities.science_review_panel import ScienceReviewPanel 

22 

23 

24def launch_srp_consensus_phase(srp: ScienceReviewPanel, repo: ORMRepository) -> list[PPRProposalReview]: 

25 """Launch the Consensus phase for the given SRP, generating PPRProposalReviews for all of its Proposals 

26 

27 NB: This service doesn't persist anything 

28 

29 :param srp: the ScienceReviewPanel to initiate Consensus phase for 

30 :param repo: Repository for database querying 

31 :return: a list of newly-generated PPRProposalReviews for `srp`, one for each of its Proposals 

32 :raises ValueError: When some non-None ISRs are not Finalized, 

33 or a Proposal on `srp` has multiple Primary or Secondary Reviewers 

34 or PPR Proposal Reviews already exist 

35 """ 

36 

37 # check preconditions: 

38 # - all ISRS are Finalized or None 

39 has_primary = [] 

40 has_secondary = [] 

41 isrs = repo.individual_science_review_repo.list_by_srp_id(srp.science_review_panel_id) 

42 for isr in isrs: 

43 if isr.review_state != "Finalized" and isr.review_type != "None": 

44 raise ValueError( 

45 f"All ISRs for the panel must be Finalized or None before initiating Consensus phase. " 

46 f"ISR {isr.individual_science_review_id} has state {isr.review_state} and type {isr.review_type}" 

47 ) 

48 if isr.review_type == "Primary": 

49 if isr.proposal_id in has_primary: 

50 # this proposal already has a primary... 

51 raise ValueError( 

52 f"Cannot initiate Consensus phase: Proposal {isr.proposal_id} has multiple primary ISRs." 

53 ) 

54 else: 

55 has_primary.append(isr.proposal_id) 

56 if isr.review_type == "Secondary": 

57 if isr.proposal_id in has_secondary: 

58 # this proposal already has a primary... 

59 raise ValueError( 

60 f"Cannot initiate Consensus phase: Proposal {isr.proposal_id} has multiple secondary ISRs." 

61 ) 

62 else: 

63 has_secondary.append(isr.proposal_id) 

64 

65 # Ensure that no PPRs already exist for this panel 

66 pprs = repo.ppr_proposal_review_repo.list_by_srp_id(srp.science_review_panel_id) 

67 if len(pprs): 

68 raise ValueError(f"PPR proposal reviews already exist for this panel.") 

69 

70 # generate PPRProposalReview for each proposal: 

71 proposal_review_list = [] 

72 for proposal in srp.proposals: 

73 proposal_review_list.append(PPRProposalReview(proposal)) 

74 

75 return proposal_review_list