2021-01-29 19:28:52 -07:00

136 lines
5.1 KiB
Python

from django.shortcuts import render, reverse
from django.db.models import Avg, Count, Min, Sum
from django.urls import reverse_lazy
from django.views.generic.base import TemplateView
from django.views.generic.edit import FormView, CreateView, UpdateView, DeleteView
from django.views.generic.detail import DetailView
from django.views.generic.list import ListView
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from django.utils import timezone
from django.contrib import messages
from django.contrib.auth.models import User
from accounts.models import Instructor, Student
from .models import Code, Period
from .forms import AttendanceUpdateForm
# EXAMPLE PERMISSION MIXIN
# class MyView(PermissionRequiredMixin, View):
# permission_required = 'polls.add_choice'
# # Or multiple of permissions:
# permission_required = ('polls.view_choice', 'polls.change_choice')
# OVERVIEW
class AttendanceOverview(LoginRequiredMixin, TemplateView):
template_name = 'attendance/attendance_overview.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['user'] = User.objects.get(pk=self.request.user.id)
if hasattr(self.request.user, 'instructor'):
context['student_list'] = Student.objects.filter(department=self.request.user.instructor.department)
context['period_list'] = Period.objects.order_by('-clocked_in')
elif hasattr(self.request.user, 'student'):
# sum all duration fields for student
total_duration = Period.objects.filter(
student=self.request.user.student
).filter(
clocked_in__year=timezone.now().year
).filter(
clocked_in__month=timezone.now().month
).order_by('-clocked_in'
).aggregate(total_duration=Sum('duration'))
hours = ""
# Convert to hours floating point
if hasattr(total_duration, 'total_duration'):
hours = round((total_duration['total_duration'].total_seconds() / 3600), 2)
context['period_list'] = Period.objects.filter(
student=self.request.user.student
).filter(
clocked_in__year=timezone.now().year
).filter(
clocked_in__month=timezone.now().month
).order_by('-clocked_in')
context['period_total'] = hours
return context
class AttendanceUpdateView(LoginRequiredMixin, FormView):
template_name = 'attendance/attendance_form.html'
form_class = AttendanceUpdateForm
def form_valid(self, form):
# update checked in
student_number = form.cleaned_data['qr_string'].split(':')[0]
station_number = form.cleaned_data['qr_string'].split(':')[1]
student = Student.objects.get(student_number=student_number)
if student.is_clocked_in:
student.is_clocked_in=False
period = student.period_set.last()
period.clocked_out=timezone.now()
period.duration=period.clocked_out-period.clocked_in
student.save()
period.save()
messages.add_message(self.request, messages.INFO, f'{student.user.first_name} {student.user.last_name} clocked out.')
else:
student.period_set.create(student=student, station_number=station_number)
student.is_clocked_in=True
student.save()
messages.add_message(self.request, messages.INFO, f'{student.user.first_name} {student.user.last_name} clocked in.')
return super().form_valid(form)
def get_success_url(self):
return reverse('attendance-update')
# PERIODS
class PeriodCreateView(LoginRequiredMixin, CreateView):
model = Period
fields = ['student']
template_name = 'attendance/period_form.html'
class PeriodDetailView(LoginRequiredMixin, DetailView):
model = Period
template_name = 'attendance/period_detail.html'
class PeriodUpdateView(LoginRequiredMixin, UpdateView):
model = Period
fields = ['clocked_out']
template_name = 'attendance/period_form.html'
def get_success_url(self):
pk = self.kwargs["pk"]
return reverse('period-detail', kwargs={'pk': pk})
class PeriodDeleteView(LoginRequiredMixin, DeleteView):
model = Period
success_url = '/attendance'
# CODES
class CodeCreateView(LoginRequiredMixin, CreateView):
model = Code
fields = ['station_number']
template_name = 'attendance/code_form.html'
def form_valid(self, form):
form.instance.student = self.request.user.student
return super().form_valid(form)
class CodeDetailView(LoginRequiredMixin, DetailView):
model = Code
template_name = 'attendance/code_detail.html'
class CodeUpdateView(LoginRequiredMixin, UpdateView):
model = Code
fields = ['station_number']
template_name = 'attendance/code_update_form.html'
def get_success_url(self):
pk = self.kwargs["pk"]
return reverse('code-detail', kwargs={'pk': pk})