def post(self, request, *args, **kwargs):
        year = kwargs.get('year')
        semester = kwargs.get('semester')

        year, semester = parse_year_semester(year=year, semester=semester)
        people = self.get_people(semester=semester, year=year)

        if not request.user.has_perm('profiles.add_duespayment') or not request.user.has_perm('profiles.delete_duespayment') or not request.user.has_perm('profiles.change_duespayment'):
            raise PermissionDenied

        to_be_saved = []

        for person in people:
            paid = request.POST.get('pk_{}-paid'.format(person.pk), False)
            current_dues_payments = person.dues_payments.filter(semester=semester, year=year)

            if current_dues_payments and paid is False:
                current_dues_payments.delete()
            elif not current_dues_payments and paid == 'on':
                to_be_saved.append(DuesPayment(person=person, semester=semester, year=year))

        if to_be_saved:
            DuesPayment.objects.bulk_create(to_be_saved)

        return redirect('profiles:roster', semester=semester, year=year)
    def post(self, request, *args, **kwargs):
        year = kwargs.get('year')
        semester = kwargs.get('semester')

        year, semester = parse_year_semester(year=year, semester=semester)
        people = self.get_people(semester=semester, year=year)

        if not request.user.has_perm('profiles.add_duespayment') or not request.user.has_perm('profiles.delete_duespayment') or not request.user.has_perm('profiles.change_duespayment'):
            raise PermissionDenied

        to_be_saved = []

        for person in people:
            paid = request.POST.get('pk_{}-paid'.format(person.pk), False)
            current_dues_payments = person.dues_payments.filter(semester=semester, year=year)

            if current_dues_payments and paid is False:
                current_dues_payments.delete()
            elif not current_dues_payments and paid == 'on':
                to_be_saved.append(DuesPayment(person=person, semester=semester, year=year))

        if to_be_saved:
            DuesPayment.objects.bulk_create(to_be_saved)

        return redirect('profiles:roster', semester=semester, year=year)
    def tours_status(self, semester=None, year=None):
        """
        Returns dictionary of form:
        {
            'status': 'complete'|'incomplete'|'projected',
            'num_required': int,
            'num_remaining': int,
            'num_to_sign_up': int,
            'num_extra': int,
            'date_projected': date|None,
            'complete': [],
            'late': [],
            'missed': [],
            'upcoming': [],
            'tours': [],
        }
        """
        year, semester = core_utils.parse_year_semester(year, semester)
        now_obj = core_utils.now()
        semester_tours = self.tours.filter(counts_for_requirements=True).semester(semester=semester, year=year).order_by('time')
        complete = semester_tours.filter(missed=False, time__lte=now_obj)
        late = semester_tours.filter(late=True, missed=False, time__lte=now_obj)
        missed = semester_tours.filter(missed=True, time__lte=now_obj)
        past = semester_tours.filter(time__lt=now_obj)
        upcoming = semester_tours.filter(time__gte=now_obj)

        num_required = self.tours_required_num(semester=semester, year=year)
        num_remaining = num_required - complete.count()
        num_extra = abs(min(num_remaining, 0))
        num_remaining = max(num_remaining, 0)
        num_to_sign_up = max(num_remaining - upcoming.count(), 0)

        # calculate status
        if num_remaining <= 0:
            status = 'complete'
        elif num_remaining <= upcoming.count():
            status = 'projected'
        else:
            status = 'incomplete'

        if status == 'projected':
            completion_obj = upcoming[num_remaining - 1]
            date_projected = completion_obj.time
        else:
            date_projected = None

        return {
            'status': status,
            'num_required': num_required,
            'num_remaining': num_remaining,
            'num_to_sign_up': num_to_sign_up,
            'num_extra': num_extra,
            'date_projected': date_projected,
            'complete': complete,
            'late': late,
            'missed': missed,
            'past': past,
            'upcoming': upcoming,
            'tours': semester_tours,
        }
Exemple #4
0
    def semester(self, semester=None, year=None):
        """
        Includes only members who are inactive for the given semester and year
        """
        year, semester = core_utils.parse_year_semester(year=year, semester=semester)
        start, end = core_utils.semester_bounds(semester=semester, year=year)

        return self.filter(time__gte=start, time__lte=end)
    def get(self, request, *args, **kwargs):
        semester = kwargs.get('semester')
        year = kwargs.get('year')
        year, semester = parse_year_semester(year=year, semester=semester)
        people = Person.objects.current_members(semester=semester, year=year)
        output = '\n'.join(person.as_vcard() for person in people)
        response = HttpResponse(output, content_type="text/x-vCard")
        response['Content-Disposition'] = 'attachment; filename=cks_members_{}_{}.vcf'.format(semester, year)

        return response
    def get(self, request, *args, **kwargs):
        semester = kwargs.get('semester')
        year = kwargs.get('year')
        year, semester = parse_year_semester(year=year, semester=semester)
        people = Person.objects.current_members(semester=semester, year=year)
        output = '\n'.join(person.as_vcard() for person in people)
        response = HttpResponse(output, content_type="text/x-vCard")
        response['Content-Disposition'] = 'attachment; filename=cks_members_{}_{}.vcf'.format(semester, year)

        return response
    def requirements(self, semester=None, year=None):
        """
        Get requirements for a given semester.
        """
        year, semester = core_utils.parse_year_semester(year, semester)

        tours_required = self.tours_required_num(semester, year)
        shifts_required = self.shifts_required_num(semester, year)
        dues_required = core_utils.dues_required(semester=semester, year=year)

        return tours_required, shifts_required, dues_required
    def dues_status(self, semester=None, year=None):
        year, semester = core_utils.parse_year_semester(year, semester)
        dues_required = core_utils.dues_required(semester=semester, year=year)

        if dues_required:
            if self.dues_payments.filter(year=year, semester=semester):
                return 'complete'
            else:
                return 'incomplete'
        else:
            return 'not_required'
    def get(self, request, *args, **kwargs):
        year = kwargs.get('year')
        semester = kwargs.get('semester')
        year, semester = parse_year_semester(year, semester)
        prev_semester = delta_semester(semester=semester, year=year, delta=-1, as_dict=True)
        next_semester = delta_semester(semester=semester, year=year, delta=1, as_dict=True)
        collect_dues = dues_required(semester=semester, year=year)
        person = request.user.person

        if not person.is_active(semester=next_semester['semester'], year=next_semester['year']):
            next_semester = None

        if not person.is_active(semester=prev_semester['semester'], year=prev_semester['year']):
            prev_semester = None

        person.cached_status = {
            'tours_status': person.tours_status(year=year, semester=semester),
            'shifts_status': person.shifts_status(year=year, semester=semester),
            'dues_status': person.dues_status(year=year, semester=semester),
        }

        # determine status
        tours_status = person.cached_status['tours_status']['status']
        shifts_status = person.cached_status['shifts_status']['status']
        dues_status = person.cached_status['dues_status']

        statuses = (tours_status, shifts_status, dues_status)

        if tours_status == 'incomplete' or shifts_status == 'incomplete' or dues_status == 'incomplete':
            status = 'incomplete'
        elif all([x in ('complete', 'projected', 'not_required') for x in statuses]) and any([x == 'projected' for x in statuses]):
            status = 'projected'
        else:
            status = 'complete'

        status_names = {
            'incomplete': 'Requirements Incomplete',
            'projected': 'Projected to Complete',
            'complete': 'Requirements Complete',
        }

        context = {
            'person': person,
            'status_class': status,
            'status': status_names[status],
            'tours': person.tours.semester(year=year, semester=semester).order_by('time'),
            'shifts': person.shifts.semester(year=year, semester=semester).order_by('time'),
            'next_semester': next_semester,
            'prev_semester': prev_semester,
            'collect_dues': collect_dues,
        }

        return render(request, 'public/profile.html', context)
    def shifts_required_num(self, semester=None, year=None):
        year, semester = core_utils.parse_year_semester(year, semester)

        # start with default
        shifts_required = core_utils.get_default_num_shifts(semester=semester, year=year)

        # check for override
        try:
            overridden_reqs = self.overridden_requirements.get(semester=semester, year=year)
            shifts_required = overridden_reqs.shifts_required
        except OverrideRequirement.DoesNotExist:
            pass

        # get number of missed shifts
        num_missed = self.shifts.semester(semester=semester, year=year).filter(missed=True).count()
        num_extra = num_missed * core_utils.get_setting('Missed Shift Penalty')

        return shifts_required + num_extra
Exemple #11
0
    def get(self, request, *args, **kwargs):
        year = kwargs.get('year')
        semester = kwargs.get('semester')

        year, semester = parse_year_semester(year=year, semester=semester)

        prev_semester = delta_semester(semester=semester, year=year, delta=-1, as_dict=True)
        next_semester = delta_semester(semester=semester, year=year, delta=1, as_dict=True)
        collect_dues = dues_required(semester=semester, year=year)

        people = self.get_people(semester=semester, year=year)

        is_current_semester = semester == current_semester() and year == now().year

        # cache requirements status results so that we don't have to keep hitting the db
        for person in people:
            dues_status = person.dues_status(semester=semester, year=year)
            person.cached_status = {
                'tours_status': person.tours_status(semester=semester, year=year),
                'shifts_status': person.shifts_status(semester=semester, year=year),
                'dues_status': dues_status,
                'active': person.is_active(semester=semester, year=year)
            }

            # dues payments
            if collect_dues:
                paid = dues_status == 'complete'
                person.dues_payment_form = DuesPaymentForm(initial={'pk': person.pk, 'paid': paid}, prefix='pk_{}'.format(person.pk))

        context = {
            'semester': semester,
            'year': year,
            'people': people,
            'prev_semester': prev_semester,
            'next_semester': next_semester,
            'collect_dues': collect_dues,
            'is_current_semester': is_current_semester,
        }

        return render(request, 'profiles/roster.html', context)
Exemple #12
0
    def get(self, request, *args, **kwargs):
        year = kwargs.get('year')
        semester = kwargs.get('semester')

        year, semester = parse_year_semester(year=year, semester=semester)

        prev_semester = delta_semester(semester=semester, year=year, delta=-1, as_dict=True)
        next_semester = delta_semester(semester=semester, year=year, delta=1, as_dict=True)
        collect_dues = dues_required(semester=semester, year=year)

        people = self.get_people(semester=semester, year=year)

        is_current_semester = semester == current_semester() and year == now().year

        # cache requirements status results so that we don't have to keep hitting the db
        for person in people:
            dues_status = person.dues_status(semester=semester, year=year)
            person.cached_status = {
                'tours_status': person.tours_status(semester=semester, year=year),
                'shifts_status': person.shifts_status(semester=semester, year=year),
                'dues_status': dues_status,
                'active': person.is_active(semester=semester, year=year)
            }

            # dues payments
            if collect_dues:
                paid = dues_status == 'complete'
                person.dues_payment_form = DuesPaymentForm(initial={'pk': person.pk, 'paid': paid}, prefix='pk_{}'.format(person.pk))

        context = {
            'semester': semester,
            'year': year,
            'people': people,
            'prev_semester': prev_semester,
            'next_semester': next_semester,
            'collect_dues': collect_dues,
            'is_current_semester': is_current_semester,
        }

        return render(request, 'profiles/roster.html', context)
Exemple #13
0
    def get(self, request, *args, **kwargs):
        year = kwargs.get('year')
        semester = kwargs.get('semester')
        year, semester = parse_year_semester(year, semester)
        prev_semester = delta_semester(semester=semester,
                                       year=year,
                                       delta=-1,
                                       as_dict=True)
        next_semester = delta_semester(semester=semester,
                                       year=year,
                                       delta=1,
                                       as_dict=True)
        collect_dues = dues_required(semester=semester, year=year)
        person = request.user.person

        if not person.is_active(semester=next_semester['semester'],
                                year=next_semester['year']):
            next_semester = None

        if not person.is_active(semester=prev_semester['semester'],
                                year=prev_semester['year']):
            prev_semester = None

        person.cached_status = {
            'tours_status': person.tours_status(year=year, semester=semester),
            'shifts_status': person.shifts_status(year=year,
                                                  semester=semester),
            'dues_status': person.dues_status(year=year, semester=semester),
        }

        # determine status
        tours_status = person.cached_status['tours_status']['status']
        shifts_status = person.cached_status['shifts_status']['status']
        dues_status = person.cached_status['dues_status']

        statuses = (tours_status, shifts_status, dues_status)

        if tours_status == 'incomplete' or shifts_status == 'incomplete' or dues_status == 'incomplete':
            status = 'incomplete'
        elif all(
            [x in ('complete', 'projected', 'not_required')
             for x in statuses]) and any([x == 'projected' for x in statuses]):
            status = 'projected'
        else:
            status = 'complete'

        status_names = {
            'incomplete': 'Requirements Incomplete',
            'projected': 'Projected to Complete',
            'complete': 'Requirements Complete',
        }

        context = {
            'person':
            person,
            'status_class':
            status,
            'status':
            status_names[status],
            'tours':
            person.tours.semester(year=year,
                                  semester=semester).order_by('time'),
            'shifts':
            person.shifts.semester(year=year,
                                   semester=semester).order_by('time'),
            'next_semester':
            next_semester,
            'prev_semester':
            prev_semester,
            'collect_dues':
            collect_dues,
        }

        return render(request, 'public/profile.html', context)