diff --git a/opentech/apply/funds/templatetags/statusbar_tags.py b/opentech/apply/funds/templatetags/statusbar_tags.py index 01d0fc7443b17bd7e85bb591e742d5e999bc9b6d..66ccf0c491e93c5586d3a1d723a6f8c5b224fe28 100644 --- a/opentech/apply/funds/templatetags/statusbar_tags.py +++ b/opentech/apply/funds/templatetags/statusbar_tags.py @@ -1,35 +1,24 @@ -from collections import defaultdict from django import template register = template.Library() -def find_last_visible_phase(phases, user, current_phase): - last_phase = current_phase - while not last_phase.permissions.can_view(user): - last_phase = phases[last_phase.step - 1][0] - return last_phase - - @register.inclusion_tag('funds/includes/status_bar.html') def status_bar(workflow, current_phase, user, css_class='', same_stage=False): - all_phases = defaultdict(list) - for phase in list(workflow.values()): - all_phases[phase.step].append(phase) + phases = workflow.phases_for(user) - # Grab the first phase for each step - visible only, the display phase - phases = [ - phase for phase, *_ in all_phases.values() - if phase.permissions.can_view(user) - and (not same_stage or phase.stage == current_phase.stage) - ] + if same_stage: + phases = [ + phase for phase in phases + if phase.stage == current_phase.stage + ] if not current_phase.permissions.can_view(user): - current_phase = find_last_visible_phase(all_phases, user, current_phase) + current_phase = workflow.latest_visible(current_phase, user) # Current step not shown for user, move current phase to last good location - elif not all_phases[current_phase.step][0].permissions.can_view(user): + elif not workflow.stepped_phases[current_phase.step][0].permissions.can_view(user): new_phase_list = [] for phase in reversed(phases): if phase.step <= current_phase.step and current_phase not in new_phase_list: diff --git a/opentech/apply/funds/workflow.py b/opentech/apply/funds/workflow.py index e2a1d62617e0d79aa7949bd42c627ab5f2499398..c8faf7eee27abc8a44c4045bd996bc8cf1d03b0b 100644 --- a/opentech/apply/funds/workflow.py +++ b/opentech/apply/funds/workflow.py @@ -38,6 +38,29 @@ class Workflow(dict): stages.append(phase.stage) return stages + @property + def stepped_phases(self): + phases = defaultdict(list) + for phase in list(workflow.values()): + all_phases[phase.step].append(phase) + return phases + + def phases_for(self, user): + # Grab the first phase for each step - visible only, the display phase + phases = [ + phase for phase, *_ in self.stepped_phases.values() + if phase.permissions.can_view(user) + ] + + def previous_visible(self, current, user): + """Find the latest phase that the user has view permissions for""" + display_phase = self.stepped_phases[current.step][0] + phases = self.phases_for(user) + index = phases.index(current) + for phase in phases[index - 1::-1]: + if phase.permission.can_view(user): + return phase + class Phase: def __init__(self, name, display, stage, permissions, step, public=None, transitions=dict()):