Newer
Older
class Phase:
def __init__(self, name, display, stage, permissions, step, transitions=dict()):
self.name = name
self.display_name = display
self.stage = stage
self.permissions = permissions
self.step = step
# For building transition methods on the parent
self.all_transitions = {}
# For building form actions
self.transitions = {}
for transition, action in transitions.items():
try:
self.all_transitions[transition] = action['display']
method_name = action.get('action')
if method_name:
self.transition_methods[transition] = method_name
show_in_form = action.get('form', True)
show_in_form = True
self.all_transitions[transition] = action
if show_in_form:
self.transitions[transition] = self.all_transitions[transition]
def __str__(self):
return self.display_name
class Stage:
def __init__(self, name, has_external_review=False):
self.name = name
self.has_external_review = has_external_review
def __str__(self):
return self.name
class Permission:
def can_edit(self, user: 'User') -> bool:
return False
def can_staff_review(self, user: 'User') -> bool:
return False
def can_reviewer_review(self, user: 'User') -> bool:
return False
def can_review(self, user: 'User') -> bool:
return self.can_staff_review(user) or self.can_reviewer_review(user)
class StaffReviewPermission(Permission):
def can_staff_review(self, user: 'User') -> bool:
return user.is_apply_staff
class ReviewerReviewPermission(Permission):
def can_reviewer_review(self, user: 'User') -> bool:
return user.is_reviewer
class CanEditPermission(Permission):
def can_edit(self, user: 'User') -> bool:
return True
Request = Stage('Request', False)
Concept = Stage('Concept', False)
Proposal = Stage('Proposal', False)
'internal_review': 'Open Review',
'rejected': 'Reject',
},
'display': 'Under Discussion',
'stage': Request,
'permissions': Permission(),
'step': 0,
},
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
},
'display': 'Internal Review',
'stage': Request,
'permissions': StaffReviewPermission(),
'step': 1,
},
'post_review_discussion': {
'transitions': {
'accepted': 'Accept',
'rejected': 'Reject',
},
'display': 'Under Discussion',
'stage': Request,
'permissions': Permission(),
'step': 2,
},
'accepted': {
'display': 'Accepted',
'stage': Request,
'permissions': Permission(),
'step': 3,
},
'rejected': {
'display': 'Rejected',
'stage': Request,
'permissions': Permission(),
'step': 3,
},
}
'concept_internal_review': 'Open Review',
'concept_rejected': 'Reject',
'permissions': Permission(),
'step': 0,
},
'concept_review_discussion': 'Close Review',
},
'display': 'Internal Review',
'stage': Concept,
'permissions': StaffReviewPermission(),
'step': 1,
},
'concept_review_discussion': {
'transitions': {
'concept_rejected': 'Reject',
},
'display': 'Under Discussion',
'stage': Concept,
'permissions': Permission(),
'step': 2,
},
'invited_to_proposal': {
'display': 'Invited for Proposal',
'transitions': {
'draft_proposal': {'display': 'Progress', 'action': 'progress_application', 'form': False},
},
'stage': Concept,
'permissions': Permission(),
'step': 3,
},
'concept_rejected': {
'display': 'Rejected',
'stage': Concept,
'permissions': Permission(),
'step': 3,
},
},
'display': 'Invited for Proposal',
'stage': Proposal,
'permissions': Permission(),
'proposal_internal_review': 'Open Review',
},
'display': 'Under Discussion',
'stage': Proposal,
'permissions': Permission(),
'post_proposal_review_discussion': 'Close Review',
},
'display': 'Internal Review',
'stage': Proposal,
'permissions': StaffReviewPermission(),
},
'post_proposal_review_discussion': {
'transitions': {
'external_review': 'Open AC review',
'proposal_rejected': 'Reject',
},
'display': 'Under Discussion',
'stage': Proposal,
'permissions': ReviewerReviewPermission(),
},
'external_review': {
'transitions': {
'post_external_review_discussion': 'Close Review',
},
'display': 'Advisory Council Review',
'stage': Proposal,
'permissions': Permission(),
},
'post_external_review_discussion': {
'transitions': {
'proposal_accepted': 'Accept',
'proposal_rejected': 'Reject',
},
'display': 'Under Discussion',
'stage': Proposal,
'permissions': Permission(),
},
'proposal_accepted': {
'display': 'Accepted',
'stage': Proposal,
'permissions': Permission(),
},
'proposal_rejected': {
'display': 'Rejected',
'stage': Proposal,
'permissions': Permission(),
SingleStage = {
phase_name: Phase(phase_name, **phase_data)
for phase_name, phase_data in SingleStageDefinition.items()
}
DoubleStage = {
phase_name: Phase(phase_name, **phase_data)
for phase_name, phase_data in DoubleStageDefinition.items()
}
def get_stages(workflow):
return list(set(phase.stage for phase in workflow.values()))
PHASES = list(itertools.chain(SingleStage.items(), DoubleStage.items()))
STATUSES[value.display_name].add(key)
active_statuses = [
status for status in PHASES
if 'accepted' not in status or 'rejected' not in status or 'invited' not in status
reviews = set()
for phase_name, phase in PHASES:
if 'review' in phase_name:
if user is None:
reviews.add(phase_name)
elif phase.permissions.can_review(user):
reviews.add(phase_name)
return reviews
review_statuses = get_review_statuses()