def get_context_data(self, **kwargs): """Get a list of all other participants who've requested pairing.""" context = super().get_context_data(**kwargs) self.participant = self.request.participant context['pair_requests'] = self.pair_requests context['currently_winter_school'] = is_currently_iap() return context
def _lecture_info(self, participant, user_viewing: bool) -> Dict[str, bool]: """Describe the participant's lecture attendance, if applicable.""" can_set_attendance = self.can_set_attendance(participant) # There are only *two* times of year where it's important to show "yes, you attended" # 1. The enrollment period where participants can record attendance (2nd lecture) # 2. The first week of WS, after lectures but before weekend trips # (this is when participants may not have recorded attendance correctly) # In later weeks, we'll enforce lecture attendance as part of trip signup. show_attendance = date_utils.is_currently_iap() and ( can_set_attendance or date_utils.ws_lectures_complete() ) if show_attendance: attended_lectures = participant.attended_lectures(date_utils.ws_year()) # We don't need to tell participants "You attended lectures!" later in WS. # This is because signup rules enforce lecture attendance *after* week 1. if user_viewing and models.Trip.objects.filter( program=enums.Program.WINTER_SCHOOL.value, trip_date__gte=date_utils.jan_1(), trip_date__lt=date_utils.local_date(), ): show_attendance = False else: # Skip unnecessary db queries attended_lectures = False # Maybe they actually did, but we're not showing. return { 'can_set_attendance': can_set_attendance, 'show_attendance': show_attendance, 'attended_lectures': attended_lectures, }
def test_is_currently_iap(self): """Test the method that approximates if it's Winter School.""" # December before Winter School with freeze_time("2016-12-28 12:00 EST"): self.assertFalse(date_utils.is_currently_iap()) # Weeks during Winter School with freeze_time("2017-01-01 12:00 EST"): self.assertTrue(date_utils.is_currently_iap()) with freeze_time("2017-01-14 12:00 EST"): self.assertTrue(date_utils.is_currently_iap()) with freeze_time("2017-01-31 12:00 EST"): self.assertTrue(date_utils.is_currently_iap()) # The week after Winter School is over with freeze_time("2017-02-10 12:00 EST"): self.assertFalse(date_utils.is_currently_iap())
def supply(self): if not self.request.participant or not date_utils.is_currently_iap(): return self.warn_if_missing_lottery() self.warn_if_car_missing() self.warn_if_dated_info() if self.lotteryinfo: # (warnings are redundant if no lottery info) self.warn_if_no_ranked_trips()
def get_context_data(self, **kwargs): self.participant = self.request.participant return { 'currently_winter_school': is_currently_iap(), 'ranked_signups': json.dumps(self.ranked_signups_dict), 'car_form': self.get_car_form(use_post=True), 'lottery_form': self.get_lottery_form(), 'reciprocally_paired': self.reciprocally_paired, 'paired_par': self.paired_par, }
def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['is_currently_iap'] = is_currently_iap() # There is separate logic for determining if we allow choosing the WS program. # Rather than duplicate that logic here, just see if it's a selectable choice. form: forms.TripForm = context['form'] context['can_select_ws_program'] = any( enums.Program(value) == enums.Program.WINTER_SCHOOL for category, choices in form.fields['program'].choices for value, label in choices) return context
def __init__(self, *args, **kwargs): allowed_programs = kwargs.pop("allowed_programs", None) super().__init__(*args, **kwargs) trip = self.instance if trip.pk is None: # New trips must have *all* dates/times in the future now = local_now() # (the `datetime-local` inputs don't take timezones at all) # We specify only to the minutes' place so that we don't display seconds naive_iso_now = now.replace(tzinfo=None).isoformat( timespec='minutes') self.fields['trip_date'].widget.attrs['min'] = now.date( ).isoformat() # There is *extra* dynamic logic that (open < close at <= trip date) # However, we can at minimum enforce that times occur in the future self.fields['signups_open_at'].widget.attrs['min'] = naive_iso_now self.fields['signups_close_at'].widget.attrs['min'] = naive_iso_now # Use the participant queryset to cover an edge case: # editing an old trip where one of the leaders is no longer a leader! self.fields[ 'leaders'].queryset = models.Participant.objects.get_queryset() self.fields['leaders'].help_text = None # Disable "Hold command..." # We'll dynamically hide the level widget on GET if it's not a winter trip # On POST, we only want this field required for winter trips program = self.data.get('program') program_enum = enums.Program(program) if program else None self.fields['level'].required = (program_enum and program_enum.winter_rules_apply()) initial_program: Optional[ enums.Program] = trip.pk and trip.program_enum if allowed_programs is not None: self.fields['program'].choices = list( self._allowed_program_choices(allowed_programs)) # If it's currently WS, the WS program is almost certainly what's desired for new trips. if (enums.Program.WINTER_SCHOOL in allowed_programs and is_currently_iap() and not trip.pk): initial_program = enums.Program.WINTER_SCHOOL self._init_wimp() # (No need for `ng-init`, we have a custom directive) self.fields['leaders'].widget.attrs['data-ng-model'] = 'leaders' _bind_input(self, 'program', initial=initial_program and initial_program.value) _bind_input(self, 'algorithm', initial=trip and trip.algorithm)
def can_set_attendance(self, participant): # WS chairs can set any time for any user if perm_utils.is_chair(self.request.user, enums.Activity.WINTER_SCHOOL, True): return True # Non-chairs are only allowed during WS when setting enabled if not is_currently_iap(): return False settings = models.WinterSchoolSettings.load() if not settings.allow_setting_attendance: return False # Non-chairs may only set attendance for themselves return participant == self.request.participant
def get_context_data(self, **kwargs): self.participant = self.request.participant lottery_form = self.get_lottery_form() return { 'currently_winter_school': is_currently_iap(), 'ranked_signups': list(self.ranked_signups.values('id', 'trip__id', 'trip__name')), 'lottery_form': lottery_form, # Avoid a redundant query! (We'll show full pairing info separately) 'has_paired_par': bool(lottery_form.instance and lottery_form.instance.paired_with_id), }
def get_form_kwargs(self): kwargs = super().get_form_kwargs() kwargs['initial'] = kwargs.get('initial', {}) if not self.request.user.is_superuser: allowed_programs = list(self.request.participant.allowed_programs) kwargs['allowed_programs'] = allowed_programs if is_currently_iap( ) and enums.Program.WINTER_SCHOOL in allowed_programs: kwargs['initial'][ 'program'] = enums.Program.WINTER_SCHOOL.value else: # The first program may not be open to the leader. # We restrict choices, so ensure leader can lead this program. allowed_program = next(iter(allowed_programs)) kwargs['initial']['program'] = allowed_program.value return kwargs
def get_context_data(self, **kwargs): participant = self.object = self.get_object() user_viewing = self.request.participant == participant context = super().get_context_data(**kwargs) can_set_attendance = self.can_set_attendance(participant) context['can_set_attendance'] = can_set_attendance context['show_attendance'] = date_utils.is_currently_iap() and ( date_utils.ws_lectures_complete() or can_set_attendance) if can_set_attendance: context[ 'attended_lectures'] = models.LectureAttendance.objects.filter( participant=participant, year=date_utils.ws_year()).exists() context['user_viewing'] = user_viewing if user_viewing: user = self.request.user else: user = participant.user context['par_user'] = user context['trips'] = trips = self.get_trips() context['stats'] = self.get_stats(trips) self.include_pairing(context) e_info = participant.emergency_info e_contact = e_info.emergency_contact context['emergency_info_form'] = forms.EmergencyInfoForm( instance=e_info) context['emergency_contact_form'] = forms.EmergencyContactForm( instance=e_contact) context['participant'] = participant if not user_viewing: feedback = participant.feedback_set.select_related( 'trip', 'leader') feedback = feedback.prefetch_related('leader__leaderrating_set') context['all_feedback'] = feedback context['ratings'] = participant.ratings(must_be_active=True) if participant.car: context['car_form'] = forms.CarForm(instance=participant.car) context['wimp'] = self.wimp return context