diff --git a/candidates/models.py b/candidates/models.py index c7501a2..48881e7 100644 --- a/candidates/models.py +++ b/candidates/models.py @@ -142,53 +142,58 @@ def get_progress_by_candidate(candidates, term): elective_req = None elective_event_types = EventType.objects.none() + + # Get Elective requirement or otherwise have it as None try: elective_req = requirements.get( eventcandidaterequirement__event_type__name='Elective') - requirements = requirements.exclude(id=elective_req.id) + except CandidateRequirement.DoesNotExist: + elective_req = None + + if elective_req: required_event_types = requirements.filter( requirement_type=CandidateRequirement.EVENT).values_list( 'eventcandidaterequirement__event_type', flat=True) elective_event_types = EventType.objects.filter( eligible_elective=True).exclude(id__in=required_event_types) - except CandidateRequirement.DoesNotExist: - elective_req = None - elective_event_types = EventType.objects.none() + requirements = requirements.exclude(id=elective_req.id) progress_by_candidate = {candidate: [] for candidate in candidates} # Dictionary of elective progresses elective_progress_by_candidate = {} - # Calculate elective requirements satisfied by elective events (doesn't - # include extra required events that count for electives). - # TODO(ehy): this doesn't work when there isn't an elective requirement - remaining_elective_events = len(upcoming_events.filter( - event_type__in=elective_event_types)) - for candidate in candidates: - elective_progress = { - 'requirement': elective_req, - 'completed': 0, - 'signed_up': 0, - 'warning': False, - 'remaining': remaining_elective_events, - 'required': elective_req.credits_needed if elective_req else 0 - } - elective_progress_by_candidate[candidate] = elective_progress - for attendance in attendances_by_candidate[candidate]: - if attendance.event.event_type in elective_event_types: - elective_progress['completed'] += 1 - for event_type in elective_event_types: - signup_counter = signup_counters_by_candidate[candidate] - elective_progress['signed_up'] += signup_counter[ - event_type.name] - - # Handle per-candidate elective requirements - elective_crp_objects = crp_objects.filter(requirement=elective_req) - for crp in elective_crp_objects: - elective_progress = elective_progress_by_candidate[crp.candidate] - elective_progress['completed'] += crp.manually_recorded_credits - elective_progress['required'] = crp.alternate_credits_needed + # Set up Elective requirement (via elective_req) progress, + # if Elective requirement is set + if elective_req: + # Calculate elective requirements satisfied by elective events (doesn't + # include extra required events that count for electives). + remaining_elective_events = len(upcoming_events.filter( + event_type__in=elective_event_types)) + for candidate in candidates: + elective_progress = { + 'requirement': elective_req, + 'completed': 0, + 'signed_up': 0, + 'warning': False, + 'remaining': remaining_elective_events, + 'required': elective_req.credits_needed if elective_req else 0 + } + elective_progress_by_candidate[candidate] = elective_progress + for attendance in attendances_by_candidate[candidate]: + if attendance.event.event_type in elective_event_types: + elective_progress['completed'] += 1 + for event_type in elective_event_types: + signup_counter = signup_counters_by_candidate[candidate] + elective_progress['signed_up'] += signup_counter[ + event_type.name] + + # Handle per-candidate elective requirements + elective_crp_objects = crp_objects.filter(requirement=elective_req) + for crp in elective_crp_objects: + elective_progress = elective_progress_by_candidate[crp.candidate] + elective_progress['completed'] += crp.manually_recorded_credits + elective_progress['required'] = crp.alternate_credits_needed remaining = collections.Counter() for event in upcoming_events: @@ -219,7 +224,10 @@ def get_progress_by_candidate(candidates, term): req_progress['remaining'] = remaining[req.get_name()] progress_by_candidate[candidate].append(req_progress) event_type = req.eventcandidaterequirement.event_type - if event_type.eligible_elective: + + # Elective progress on eligible event types are only counted + # when an Elective requirement is set + if elective_req and event_type.eligible_elective: elective_progress = elective_progress_by_candidate[ candidate] elective_progress['remaining'] += remaining[ @@ -239,18 +247,20 @@ def get_progress_by_candidate(candidates, term): req_progress['requirement'] = req progress_by_candidate[candidate].append(req_progress) - # Trigger warnings for elective events - for elective_progress in elective_progress_by_candidate.values(): - completed = elective_progress['completed'] - remaining = elective_progress['remaining'] - required = elective_progress['required'] - if completed + remaining < required: - elective_progress['warning'] = True - - # Merge elective progresses with the others - for candidate in candidates: - elective_progress = elective_progress_by_candidate[candidate] - progress_by_candidate[candidate].append(elective_progress) + # Final processing of Elective Events (if Elective requirement is set) + if elective_req: + # Trigger warnings for elective events + for elective_progress in elective_progress_by_candidate.values(): + completed = elective_progress['completed'] + remaining = elective_progress['remaining'] + required = elective_progress['required'] + if completed + remaining < required: + elective_progress['warning'] = True + + # Merge elective progresses with the others (only if an Elective Requirement is set) + for candidate in candidates: + elective_progress = elective_progress_by_candidate[candidate] + progress_by_candidate[candidate].append(elective_progress) return progress_by_candidate diff --git a/candidates/views.py b/candidates/views.py index ead40c1..594f4ec 100644 --- a/candidates/views.py +++ b/candidates/views.py @@ -953,7 +953,7 @@ def get_context_data(self, **kwargs): for req_progress in progress_item['requirements']: requirement = req_progress['requirement'] # Exclude progresses with the wrong requirement - if (not requirement) or (self.display_req and self.display_req != requirement): + if self.display_req and (self.display_req != requirement): continue req_name = requirement.get_name() if req_name not in progresses_by_req: @@ -998,8 +998,6 @@ def get_context_data(self, **kwargs): total_unfinished = 0 for progress_item in progress.values(): for req_progress in progress_item['requirements']: - if not req_progress['requirement']: - continue req_name = req_progress['requirement'].get_name() completed = req_progress['completed'] required = req_progress['required']