Change templates, update timedelta filter
This commit is contained in:
parent
2065c6d1ee
commit
ee472fb9a0
@ -1,12 +1,15 @@
|
|||||||
{% extends 'application.html' %}
|
{% extends 'application.html' %}
|
||||||
|
{% load timedelta_filter %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>User</h1>
|
<section class="panel">
|
||||||
<section>
|
<h1>{{ user.first_name }} {{ user.last_name }}</h1>
|
||||||
<h3>{{ user.first_name }} {{ user.last_name }}</h3>
|
|
||||||
<p>{{ user.email }}</p>
|
<p>{{ user.email }}</p>
|
||||||
|
{% if periods %}
|
||||||
|
<p>Total clocked hours: <strong>{{ periods.total|timedelta_format }}</strong></p>
|
||||||
|
{% endif %}
|
||||||
<p>
|
<p>
|
||||||
<a href="{% url 'account-update' user.id %}">Update</a>
|
<a href="{% url 'account-update' user.id %}">Update</a>
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@ -1,15 +1,24 @@
|
|||||||
{% extends 'application.html' %}
|
{% extends 'application.html' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Users</h1>
|
<section class="panel">
|
||||||
<section>
|
<h1>Users</h1>
|
||||||
<table>
|
<table>
|
||||||
|
<thead>
|
||||||
|
<th>Username</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Role</th>
|
||||||
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for user in user_list %}
|
{% for user in user_list %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ user.username }}</td>
|
<td>{{ user.username }}</td>
|
||||||
<td>{{user.first_name}} {{user.last_name}}</td>
|
<td><a href="{% url 'account-detail' user.id %}">{{user.first_name}} {{user.last_name}}</a></td>
|
||||||
<td><a href="{% url 'account-detail' user.id %}">Update</a></td>
|
{% if user.student %}
|
||||||
|
<td>Student</td>
|
||||||
|
{% elif user.instructor %}
|
||||||
|
<td>Instructor</td>
|
||||||
|
{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<tr><td>No users yet.</td></tr>
|
<tr><td>No users yet.</td></tr>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import pytz
|
import pytz
|
||||||
from django.shortcuts import render, reverse, redirect
|
from django.shortcuts import render, reverse, redirect
|
||||||
|
from django.db.models import Avg, Count, Min, Sum
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from django.views.generic.edit import FormView, CreateView, UpdateView, DeleteView
|
from django.views.generic.edit import FormView, CreateView, UpdateView, DeleteView
|
||||||
from django.views.generic.detail import DetailView
|
from django.views.generic.detail import DetailView
|
||||||
@ -8,6 +9,7 @@ from django.contrib.auth.decorators import login_required
|
|||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.contrib.auth.forms import PasswordChangeForm
|
from django.contrib.auth.forms import PasswordChangeForm
|
||||||
|
from attendance.models import Period
|
||||||
|
|
||||||
def set_timezone(request):
|
def set_timezone(request):
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
@ -29,6 +31,14 @@ class AccountDetailView(LoginRequiredMixin, DetailView):
|
|||||||
model = User
|
model = User
|
||||||
template_name = 'accounts/account_detail.html'
|
template_name = 'accounts/account_detail.html'
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
if hasattr(context['object'], 'student'):
|
||||||
|
context['periods'] = Period.objects.filter(
|
||||||
|
student = context['object'].student
|
||||||
|
).aggregate(total=Sum('duration'))
|
||||||
|
return context
|
||||||
|
|
||||||
class AccountUpdateView(LoginRequiredMixin, UpdateView):
|
class AccountUpdateView(LoginRequiredMixin, UpdateView):
|
||||||
model = User
|
model = User
|
||||||
# form_class = PasswordChangeForm
|
# form_class = PasswordChangeForm
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
{% if user.student.code_set.last %}
|
{% if user.student.code_set.last %}
|
||||||
<p class="student__code code">
|
|
||||||
<a class="code__button action-button" href="{% url 'code-update' user.student.code_set.last.id %}">
|
<a class="code__button action-button" href="{% url 'code-update' user.student.code_set.last.id %}">
|
||||||
{% if clocked_in %}
|
{% if clocked_in %}
|
||||||
Clock out →
|
Clock out →
|
||||||
@ -7,9 +6,7 @@
|
|||||||
Clock in →
|
Clock in →
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</a>
|
</a>
|
||||||
</p>
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<p class="student__code code">
|
|
||||||
<a class="action-button" href="{% url 'code-create' %}">
|
<a class="action-button" href="{% url 'code-create' %}">
|
||||||
{% if clocked_in %}
|
{% if clocked_in %}
|
||||||
Clock out →
|
Clock out →
|
||||||
@ -17,5 +14,4 @@
|
|||||||
Clock in →
|
Clock in →
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</a>
|
</a>
|
||||||
</p>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@ -2,15 +2,10 @@
|
|||||||
<article class="instructor">
|
<article class="instructor">
|
||||||
<section class="instructor__header panel">
|
<section class="instructor__header panel">
|
||||||
<h1 class="instructor__department">{{ user.instructor.department.name }}</h1>
|
<h1 class="instructor__department">{{ user.instructor.department.name }}</h1>
|
||||||
<p>
|
|
||||||
<a class="instructor__generate-reports" href="">Generate Reports</a>
|
|
||||||
</p>
|
|
||||||
</header>
|
</header>
|
||||||
<div class="instructor__active_periods">
|
<div class="instructor__active_periods">
|
||||||
<h3>Students clocked-in</h3>
|
<h3>Students clocked-in</h3>
|
||||||
<p>
|
<a class="action-button instructor__add_period" href="{% url 'period-create' %}">+ Add new session</a>
|
||||||
<a class="action-button" href="{% url 'period-create' %}">+ Add new session</a>
|
|
||||||
</p>
|
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -46,6 +41,7 @@
|
|||||||
<section class="instructor__attendance_log">
|
<section class="instructor__attendance_log">
|
||||||
<div>
|
<div>
|
||||||
<h3>Attendance log</h3>
|
<h3>Attendance log</h3>
|
||||||
|
<a class="instructor__generate_reports action-button" href="">Generate Reports</a>
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -80,6 +76,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="instructor__total_hours">
|
<section class="instructor__total_hours">
|
||||||
|
<h3>Total hours</h3>
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -91,7 +88,7 @@
|
|||||||
{% for student in student_list %}
|
{% for student in student_list %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ student.user.first_name }} {{ student.user.last_name }}</td>
|
<td>{{ student.user.first_name }} {{ student.user.last_name }}</td>
|
||||||
<td>{{ student.total_hours|dimedelta_format }}</td>
|
<td><strong>{{ student.total_hours|timedelta_format }}</strong></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<tr><td colspan="2">No periods yet.</td></tr>
|
<tr><td colspan="2">No periods yet.</td></tr>
|
||||||
|
|||||||
@ -12,13 +12,15 @@
|
|||||||
</div>
|
</div>
|
||||||
{% include 'attendance/_student_code.html' with clocked_in=True %}
|
{% include 'attendance/_student_code.html' with clocked_in=True %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="status__clocked"></div>You are not clocked in.</p>
|
<div class="status__clocked">
|
||||||
|
<p>You are not clocked in.</p>
|
||||||
{% include 'attendance/_student_code.html' with clocked_in=False %}
|
{% include 'attendance/_student_code.html' with clocked_in=False %}
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</section>
|
</section>
|
||||||
<section class="student__attendance attendance">
|
<section class="student__attendance attendance">
|
||||||
<h2 class="attendance__title">Attendance log</h2>
|
<h2 class="attendance__title">Attendance log</h2>
|
||||||
<p class="attendance__total">Total hours for the month: <strong>{{ period_total.total|dimedelta_format:2 }}</strong><br>
|
<p class="attendance__total">Total hours for the month: <strong>{{ period_total.total|timedelta_format:2 }}</strong><br>
|
||||||
<small>(Does not include current session.)</small></p>
|
<small>(Does not include current session.)</small></p>
|
||||||
{% include 'attendance/_student_periods.html' %}
|
{% include 'attendance/_student_periods.html' %}
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@ -3,9 +3,8 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<section class="code-detail panel">
|
<section class="code-detail panel">
|
||||||
<h1>Clock in</h1>
|
<h1>Scan code</h1>
|
||||||
<p class="code-detail__instructions"><em>Scan code at clock-in station</em></p>
|
<span class="code-detail__qrcode">{% qr_from_text code.qr_code_str size=18 version=2 %}</span>
|
||||||
<span class="code-detail__qrcode">{% qr_from_text code.qr_code_str size=24 version=2 %}</span>
|
<a class="code-detail__done action-button" href="{% url 'attendance-overview' %}">Done</a>
|
||||||
<span class="code-detail__done"><a class="action-button" href="{% url 'attendance-overview' %}">Done</a></span>
|
|
||||||
</section>
|
</section>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
{% extends 'application.html' %}
|
{% extends 'application.html' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Generate Period</h1>
|
|
||||||
|
|
||||||
<section>
|
<section class="period panel">
|
||||||
|
<h1>Generate Period</h1>
|
||||||
<form method="post" action="">
|
<form method="post" action="">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form.as_p }}
|
{{ form.as_p }}
|
||||||
|
|
||||||
<input type="submit" value="Save changes" /> or
|
<input type="submit" value="Save changes" /> or
|
||||||
<a href="{{request.META.HTTP_REFERER}}">Cancel</a>
|
<a href="{% url 'attendance-overview' %}">Cancel</a>
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@ -3,6 +3,10 @@ from django import template
|
|||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
|
||||||
@register.filter()
|
@register.filter()
|
||||||
def dimedelta_format(value, arg=2):
|
def timedelta_format(value, arg=2):
|
||||||
"""Format timedelta"""
|
"""Returns timedelta as float rounded to arg, with default of 2"""
|
||||||
return round((value).seconds / 3600, arg)
|
if value.days:
|
||||||
|
return round((value.days*24) + value.seconds/3600, arg)
|
||||||
|
elif value.seconds:
|
||||||
|
return round(value.seconds/3600, arg)
|
||||||
|
return 0
|
||||||
|
|||||||
@ -29,12 +29,16 @@ class AttendanceOverview(LoginRequiredMixin, TemplateView):
|
|||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
context['user'] = self.request.user
|
context['user'] = self.request.user
|
||||||
if hasattr(self.request.user, 'instructor'):
|
if hasattr(self.request.user, 'instructor'):
|
||||||
|
instructor = self.request.user.instructor
|
||||||
context['student_list'] = Student.objects.filter(
|
context['student_list'] = Student.objects.filter(
|
||||||
department=self.request.user.instructor.department
|
department=instructor
|
||||||
).annotate(total_hours=Sum('period__duration'))
|
).annotate(total_hours=Sum('period__duration'))
|
||||||
|
|
||||||
context['period_list'] = Period.objects.order_by('-clocked_in')
|
context['period_list'] = Period.objects.order_by('-clocked_in')
|
||||||
|
|
||||||
elif hasattr(self.request.user, 'student'):
|
elif hasattr(self.request.user, 'student'):
|
||||||
student = self.request.user.student
|
student = self.request.user.student
|
||||||
|
|
||||||
# sum all duration fields for student
|
# sum all duration fields for student
|
||||||
context['period_total'] = Period.objects.filter(
|
context['period_total'] = Period.objects.filter(
|
||||||
student = student
|
student = student
|
||||||
@ -44,11 +48,6 @@ class AttendanceOverview(LoginRequiredMixin, TemplateView):
|
|||||||
clocked_in__month=timezone.now().month
|
clocked_in__month=timezone.now().month
|
||||||
).aggregate(total=Sum('duration'))
|
).aggregate(total=Sum('duration'))
|
||||||
|
|
||||||
# hours = 0
|
|
||||||
# # Convert to hours floating point
|
|
||||||
# if periods_duration_sum['total_duration'] != None:
|
|
||||||
# hours = round((periods_duration_sum['total_duration'].total_seconds() / 3600), 2)
|
|
||||||
|
|
||||||
context['period_list'] = Period.objects.filter(
|
context['period_list'] = Period.objects.filter(
|
||||||
student=student
|
student=student
|
||||||
).filter(
|
).filter(
|
||||||
|
|||||||
@ -0,0 +1,14 @@
|
|||||||
|
.clockin {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&__form {
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
input[type=text] {
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -45,7 +45,7 @@ textarea {
|
|||||||
input[type=submit],
|
input[type=submit],
|
||||||
.action-button {
|
.action-button {
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
padding: 0.5em 1em;
|
padding: 0.2rem 1rem;
|
||||||
border: none;
|
border: none;
|
||||||
background-color: $blue;
|
background-color: $blue;
|
||||||
color: white;
|
color: white;
|
||||||
@ -91,5 +91,8 @@ textarea {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.action-button {
|
.action-button {
|
||||||
|
// margin-bottom: 1rem;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0.2rem 1rem;
|
||||||
border-radius: 3.75rem;
|
border-radius: 3.75rem;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,7 +22,10 @@
|
|||||||
<span class="navbar__logo">BTech Time Tracker</span>
|
<span class="navbar__logo">BTech Time Tracker</span>
|
||||||
<nav class="navbar__nav nav">
|
<nav class="navbar__nav nav">
|
||||||
{% if user.is_authenticated %}
|
{% if user.is_authenticated %}
|
||||||
<a class="nav__user" href="{% url 'account-update' user.id %}">{{ user.first_name }} {{ user.last_name }}</a> /
|
<a class="nav__user" href="{% url 'account-detail' user.id %}">{{ user.first_name }} {{ user.last_name }}</a> /
|
||||||
|
<a href="{% url 'attendance-overview' %}">Attendance</a> /
|
||||||
|
<a href="{% url 'attendance-update' %}">Clock</a> /
|
||||||
|
<a href="{% url 'account-list' %}">Users</a> /
|
||||||
<a class="nav__logout" class="logout" href="{% url 'logout' %}">Logout</a>
|
<a class="nav__logout" class="logout" href="{% url 'logout' %}">Logout</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a class="nav__login" class="login" href="{% url 'login' %}">Login</a>
|
<a class="nav__login" class="login" href="{% url 'login' %}">Login</a>
|
||||||
|
|||||||
@ -8,11 +8,8 @@ class TimezoneMiddleware:
|
|||||||
|
|
||||||
def __call__(self, request):
|
def __call__(self, request):
|
||||||
tzname = request.session.get('django_timezone')
|
tzname = request.session.get('django_timezone')
|
||||||
print(tzname)
|
|
||||||
if tzname:
|
if tzname:
|
||||||
timezone.activate(pytz.timezone(tzname))
|
timezone.activate(pytz.timezone(tzname))
|
||||||
print("tz activated")
|
|
||||||
else:
|
else:
|
||||||
timezone.deactivate()
|
timezone.deactivate()
|
||||||
print("tz deactivated")
|
|
||||||
return self.get_response(request)
|
return self.get_response(request)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user