From 76339dc65a90c2928ded33dcad5dd4d705639e0c Mon Sep 17 00:00:00 2001 From: Nathan Chapman Date: Mon, 8 Feb 2021 20:28:18 -0700 Subject: [PATCH] Add signal for period created to auto-clockin Student --- accounts/models.py | 1 + .../templates/accounts/account_detail.html | 2 +- attendance/models.py | 9 +++++++++ .../templates/attendance/attendance_form.html | 2 +- .../attendance_overview_instructor.html | 2 ++ .../attendance_overview_student.html | 6 +++++- .../attendance/period_confirm_delete.html | 14 +++++++++----- .../templates/attendance/period_detail.html | 18 ++++++++++++------ .../templates/attendance/period_form.html | 2 +- attendance/views.py | 17 ++++------------- home/templates/home/home.html | 8 ++++---- static/scss/_home.scss | 4 ++++ static/scss/_periods.scss | 6 ++++++ tracker/middleware.py | 5 +++++ tracker/settings.py | 2 +- 15 files changed, 65 insertions(+), 33 deletions(-) diff --git a/accounts/models.py b/accounts/models.py index 73df69f..9bbf0b4 100644 --- a/accounts/models.py +++ b/accounts/models.py @@ -2,6 +2,7 @@ from django.db import models from django.urls import reverse from django.contrib.auth.models import User + class Department(models.Model): name = models.CharField(max_length=200) diff --git a/accounts/templates/accounts/account_detail.html b/accounts/templates/accounts/account_detail.html index 41bd090..91fc0c9 100644 --- a/accounts/templates/accounts/account_detail.html +++ b/accounts/templates/accounts/account_detail.html @@ -10,7 +10,7 @@ {% elif user.instructor %}

{{ user.instructor.department }}

{% endif %} - {% if periods %} + {% if periods and periods.total %}

Total clocked hours: {{ periods.total|timedelta_format }}

{% endif %}

diff --git a/attendance/models.py b/attendance/models.py index 4ea25c5..2e1c889 100644 --- a/attendance/models.py +++ b/attendance/models.py @@ -2,6 +2,8 @@ from datetime import datetime from django.db import models from django.urls import reverse from accounts.models import Student +from django.db.models.signals import post_save +from django.dispatch import receiver class Code(models.Model): student = models.ForeignKey(Student, on_delete=models.CASCADE) @@ -46,3 +48,10 @@ class Period(models.Model): if self.clocked_out != None: self.duration = self.clocked_out - self.clocked_in super(Period, self).save(*args, **kwargs) + +@receiver(post_save, sender=Period) +def auto_clockin_student(sender, instance, created, **kwargs): + if created: + instance.student.is_clocked_in = True + instance.student.current_period_id = instance.pk + instance.student.save() diff --git a/attendance/templates/attendance/attendance_form.html b/attendance/templates/attendance/attendance_form.html index 42446ed..8ff7d2b 100644 --- a/attendance/templates/attendance/attendance_form.html +++ b/attendance/templates/attendance/attendance_form.html @@ -7,7 +7,7 @@ {% csrf_token %} {{ form.as_p }} - + {% endblock %} diff --git a/attendance/templates/attendance/attendance_overview_instructor.html b/attendance/templates/attendance/attendance_overview_instructor.html index 75d2799..25efd98 100644 --- a/attendance/templates/attendance/attendance_overview_instructor.html +++ b/attendance/templates/attendance/attendance_overview_instructor.html @@ -93,7 +93,9 @@ {% for student in student_list %} {{ student.user.first_name }} {{ student.user.last_name }} + {% if student.total_hours %} {{ student.total_hours|timedelta_format }} + {% endif %} {% empty %} No periods yet. diff --git a/attendance/templates/attendance/attendance_overview_student.html b/attendance/templates/attendance/attendance_overview_student.html index 22c9ac4..ebd7338 100644 --- a/attendance/templates/attendance/attendance_overview_student.html +++ b/attendance/templates/attendance/attendance_overview_student.html @@ -20,7 +20,11 @@

Attendance log

-

Total hours for the month: {{ period_total.total|timedelta_format:2 }} (Does not include current session.)

+ {% if monthly_total.duration %} +

Total hours for the month: {{ monthly_total.duration|timedelta_format }} + (Does not include current session.) +

+ {% endif %} {% include 'attendance/_student_periods.html' %}

See previous → diff --git a/attendance/templates/attendance/period_confirm_delete.html b/attendance/templates/attendance/period_confirm_delete.html index 54ca616..1c42b1a 100644 --- a/attendance/templates/attendance/period_confirm_delete.html +++ b/attendance/templates/attendance/period_confirm_delete.html @@ -2,9 +2,13 @@ {% load static %} {% block content %} -

- {% csrf_token %} -

Are you sure you want to delete "{{ object }}"?

- -
+
+

Delete Session

+
+ {% csrf_token %} +

Are you sure you want to delete "{{ object }}"?

+ or + Cancel +
+
{% endblock %} diff --git a/attendance/templates/attendance/period_detail.html b/attendance/templates/attendance/period_detail.html index c13619b..6cf4aa1 100644 --- a/attendance/templates/attendance/period_detail.html +++ b/attendance/templates/attendance/period_detail.html @@ -1,26 +1,32 @@ {% extends 'application.html' %} +{% load timedelta_filter %} {% block content %} -

Period

-
-
+
+

Session

+
← Back
-
+
Student
{{ period.student }}
Clocked in
{{ period.clocked_in }}
+ {% if period.clocked_out %}
Clocked out
{{ period.clocked_out }}
+ {% else %} +
Not clocked out.
+ {% endif %} + {% if period.duration %}
Duration
-
{{ period.duration }}
+
{{ period.duration|timedelta_format }} hours
+ {% endif %}
{% endblock %} diff --git a/attendance/templates/attendance/period_form.html b/attendance/templates/attendance/period_form.html index 3a28c2e..d1f41bd 100644 --- a/attendance/templates/attendance/period_form.html +++ b/attendance/templates/attendance/period_form.html @@ -3,7 +3,7 @@ {% block content %}
-

Generate Period

+

Session

{% csrf_token %} {{ form.as_p }} diff --git a/attendance/views.py b/attendance/views.py index 5f1f675..2fcbd10 100644 --- a/attendance/views.py +++ b/attendance/views.py @@ -16,19 +16,11 @@ from accounts.models import Instructor, Student from .models import Code, Period from .forms import AttendanceUpdateForm, PeriodForm -# 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_queryset(self): - - def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['user'] = self.request.user @@ -50,13 +42,13 @@ class AttendanceOverview(LoginRequiredMixin, TemplateView): student = self.request.user.student # sum all duration fields for student - context['period_total'] = Period.objects.filter( + context['monthly_total'] = Period.objects.filter( student = student ).filter( clocked_in__year=timezone.now().year ).filter( clocked_in__month=timezone.now().month - ).aggregate(total=Sum('duration')) + ).aggregate(duration=Sum('duration')) context['period_list'] = Period.objects.filter( student=student @@ -74,7 +66,6 @@ class AttendanceUpdateView(LoginRequiredMixin, FormView): 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) @@ -86,8 +77,8 @@ class AttendanceUpdateView(LoginRequiredMixin, FormView): period.save() messages.add_message(self.request, messages.INFO, f'{student.user.first_name} {student.user.last_name} clocked out.') else: - c_p = student.period_set.create(student=student, clocked_in=timezone.now(), station_number=station_number) - student.current_period_id = c_p.id + 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.') diff --git a/home/templates/home/home.html b/home/templates/home/home.html index 2117e6b..a43b752 100644 --- a/home/templates/home/home.html +++ b/home/templates/home/home.html @@ -5,18 +5,18 @@

Welcome to
- Btech Time Tracker

+ BTech Time Tracker

Know exactly how many hours you've clocked, anytime, anywhere.

-
+

No more paper

No more reading bad handwriting or putting the wrong date or time.

-
+

No more questions

No more asking your instructor, or being asked by your student how many hours they have.

-
+

No more manual entry

We invented computers to do that for us.

diff --git a/static/scss/_home.scss b/static/scss/_home.scss index 9c2a554..927b601 100644 --- a/static/scss/_home.scss +++ b/static/scss/_home.scss @@ -2,4 +2,8 @@ h1, h2 { text-align: center; } + + &__section { + margin: 0 1rem; + } } diff --git a/static/scss/_periods.scss b/static/scss/_periods.scss index e69de29..602d2e2 100644 --- a/static/scss/_periods.scss +++ b/static/scss/_periods.scss @@ -0,0 +1,6 @@ +.period { + &__header { + display: flex; + justify-content: space-between; + } +} diff --git a/tracker/middleware.py b/tracker/middleware.py index 5b3a01c..a9c8a59 100644 --- a/tracker/middleware.py +++ b/tracker/middleware.py @@ -8,6 +8,11 @@ class TimezoneMiddleware: def __call__(self, request): tzname = request.session.get('django_timezone') + if request.user.is_authenticated: + if hasattr(request.user, 'instructor'): + tzname = request.user.instructor.timezone + if hasattr(request.user, 'student'): + tzname = request.user.student.timezone if tzname: timezone.activate(pytz.timezone(tzname)) else: diff --git a/tracker/settings.py b/tracker/settings.py index 28aea4f..01ff843 100644 --- a/tracker/settings.py +++ b/tracker/settings.py @@ -149,4 +149,4 @@ MEDIA_URL = '/media/' MEDIA_ROOT = BASE_DIR / 'media' -LOGIN_REDIRECT_URL = '/accounts/timezone/' +LOGIN_REDIRECT_URL = '/attendance/'