159 lines
5.8 KiB
Python

from django.shortcuts import render, reverse
from django.db.models import Avg, Count, Min, Sum
from django.db.models.functions import Round
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.core.paginator import Paginator
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 django.shortcuts import get_object_or_404
from accounts.models import Instructor, Student
from .models import Code, Period
from .forms import AttendanceUpdateForm, PeriodForm
# 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'] = self.request.user
if hasattr(self.request.user, 'instructor'):
instructor = self.request.user.instructor
context['student_list'] = Student.objects.filter(
department=instructor.department
).annotate(total_hours=Sum('period__duration'))
context['period_list'] = Period.objects.filter(
student__department=instructor.department
).filter(
clocked_in__year=timezone.now().year
).filter(
clocked_in__month=timezone.now().month
)
elif hasattr(self.request.user, 'student'):
student = self.request.user.student
# sum all duration fields for student
context['monthly_total'] = Period.objects.filter(
student = student
).filter(
clocked_in__year=timezone.now().year
).filter(
clocked_in__month=timezone.now().month
).aggregate(duration=Sum('duration'))
context['period_list'] = Period.objects.filter(
student=student
).filter(
clocked_in__year=timezone.now().year
).filter(
clocked_in__month=timezone.now().month
)
if student.current_period_id != None:
context['current_period'] = Period.objects.get(pk=student.current_period_id)
return context
class AttendanceUpdateView(LoginRequiredMixin, FormView):
template_name = 'attendance/attendance_form.html'
form_class = AttendanceUpdateForm
def form_valid(self, form):
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.get(pk=student.current_period_id)
period.clocked_out=timezone.now()
student.save()
period.save()
messages.add_message(self.request, messages.INFO, f'{student.user.first_name} {student.user.last_name} clocked out.')
else:
period = student.period_set.create(student=student, clocked_in=timezone.now(), station_number=station_number)
student.current_period_id = period.pk
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 PeriodListView(LoginRequiredMixin, ListView):
model = Period
paginate_by = 25
template_name = 'attendance/period_list.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if hasattr(self.request.user, 'student'):
period_list = Period.objects.filter(
student = self.request.user.student
)
paginator = Paginator(period_list, 25)
page_number = self.request.GET.get('page')
page_obj = paginator.get_page(page_number)
context['page_obj'] = page_obj
return context
class PeriodCreateView(LoginRequiredMixin, CreateView):
model = Period
form_class = PeriodForm
template_name = 'attendance/period_form.html'
class PeriodDetailView(LoginRequiredMixin, DetailView):
model = Period
template_name = 'attendance/period_detail.html'
class PeriodUpdateView(LoginRequiredMixin, UpdateView):
model = Period
form_class = PeriodForm
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_form.html'
def get_success_url(self):
pk = self.kwargs["pk"]
return reverse('code-detail', kwargs={'pk': pk})