Browse Source

Added the ability to edit a time entry.

Adam Day 4 years ago
parent
commit
2e3b9b0884

+ 19 - 3
app/forms.py

@@ -69,11 +69,27 @@ class TimeEntryForm(forms.Form):
 
 
 class SettingsForm(forms.Form):
-    max_daily_hours = forms.CharField(required=True, validators=[max_daily_hours_length])
-    max_daily_entries = forms.CharField(required=True)
-    session_timeout = forms.CharField(required=True, validators=[session_timeout_length])
+    max_daily_hours = forms.CharField(
+        required=True,
+        validators=[max_daily_hours_length],
+        help_text="Sets the maximum hour value for the Hours select box."
+    )
+
+    max_daily_entries = forms.CharField(
+        required=True,
+        help_text="Sets the maximum number of time entries for a given calendar day."
+    )
+
+    session_timeout = forms.CharField(
+        required=True,
+        validators=[session_timeout_length],
+        label="Session Timeout (Minutes)",
+        help_text="Sets the automatic logout time limit in minutes"
+    )
+
     projects = forms.BooleanField(required=False, label="Enable Projects",
                                   help_text="Allows for time entries to be attached to projects.")
 
 
 
+

+ 1 - 1
app/templates/create_user.html

@@ -1,4 +1,4 @@
-{% extends 'layout.html' %}
+{% extends 'layout_auth.html' %}
 
 {% block content %}
     <div class="row justify-content-center">

+ 27 - 0
app/templates/edit.html

@@ -0,0 +1,27 @@
+{% extends 'layout_auth.html' %}
+{% load crispy_forms_tags %}
+{% block content %}
+
+    <div class="row mb-3">
+        <div class="col-sm-12 col-md-12 col-lg-6 text-sm-center text-lg-start">
+            <h2>{{ user.first_name | title }} {{ user.last_name | title }}</h2>
+        </div>
+        <div class="col-sm-12 col-md-12 col-lg-6 text-sm-center text-lg-end">
+            <a href="#!" class="btn btn-lg btn-secondary"><span class="oi" data-glyph="arrow-thick-left"></span> Back</a>
+        </div>
+    </div>
+
+    <div class="row mb-3">
+        <div class="col-sm-12 text-center">
+            <h1>{{ entry.date }}</h1>
+        </div>
+        <div class="col-sm-12">
+            {% if projects == "True" %}
+                {% include 'forms/entry_edit_projects.html' %}
+            {% else %}
+                {% include 'forms/entry_edit.html' %}
+            {% endif %}
+        </div>
+    </div>
+
+{% endblock %}

+ 17 - 0
app/templates/forms/entry_edit.html

@@ -0,0 +1,17 @@
+{% load crispy_forms_tags %}
+
+<form action="{% url 'edit_entry' entry_id=entry.id %}" method="post">
+    <div class="row">
+        <div class="col-sm-12 col-md-4">
+            {{ form.hours | as_crispy_field }}
+        </div>
+        <div class="col-sm-12 col-md-4">
+            {{ form.minutes | as_crispy_field }}
+        </div>
+        <div class="col-sm-12 col-md-4">
+            <label class="form-label">&nbsp;</label>
+            <input type="submit" value="Submit" class="form-control form-control-lg btn btn-lg btn-dark">
+        </div>
+        {% csrf_token %}
+    </div>
+</form>

+ 22 - 0
app/templates/forms/entry_edit_projects.html

@@ -0,0 +1,22 @@
+{% load crispy_forms_tags %}
+
+<form action="{% url 'edit_entry' entry_id=entry.id %}" method="post">
+    <div class="row">
+        <div class="col-sm-12 col-md-6">
+            {{ form.hours | as_crispy_field }}
+        </div>
+        <div class="col-sm-12 col-md-6">
+            {{ form.minutes | as_crispy_field }}
+        </div>
+        <div class="col-sm-12 col-md-6">
+            {{ form.project | as_crispy_field }}
+        </div>
+        <div class="col-sm-12 col-md-6">
+            <label class="form-label">&nbsp;</label>
+            <input type="submit" value="Submit" class="form-control form-control-lg btn btn-lg btn-dark">
+        </div>
+        {% csrf_token %}
+    </div>
+</form>
+
+

+ 40 - 0
app/templates/layout_auth.html

@@ -0,0 +1,40 @@
+{% load static %}
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <meta http-equiv="refresh" content="{{ session_timeout }};url={% url 'logout' %}" />
+    <title>TimeSheet</title>
+    <link href="{% static 'bootstrap-5.0.0-beta1-dist/css/bootstrap.css' %}" rel="stylesheet">
+    <link href="{% static 'open-iconic/css/open-iconic.min.css' %}" rel="stylesheet">
+    <link href="{% static 'app/css/app.css' %}" rel="stylesheet">
+    <script src="{% static 'jquery-3.5.1/jquery-3.5.1.min.js' %}"></script>
+    <script src="{% static 'bootstrap-5.0.0-beta1-dist/js/bootstrap.bundle.min.js' %}"></script>
+    <script src="{% static 'app/js/keypad.js' %}"></script>
+</head>
+<body>
+    <div class="d-flex align-items-center min-vh-100">
+        <div class="container-fluid">
+            <div class="row justify-content-center">
+                <div class="col-12 text-center mt-2 mb-2">
+                    <h1 class="display-3"><span class="oi" data-glyph="clock"></span> Time Sheet Station</h1>
+                </div>
+            </div>
+            <div class="row justify-content-center">
+                <div class="col-sm-12 col-md-7">
+                    <div class="card shadow">
+                        <div class="card-body">
+                            <div class="row">
+                                <div class="col-12">
+                                    {% block content %}{% endblock %}
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</body>
+</html>

+ 16 - 9
app/templates/setup.html

@@ -2,20 +2,27 @@
 {% load crispy_forms_tags %}
 {% block content %}
 
-    <div class="row">
-        <div class="col-12 text-center">
+    <div class="row justify-content-center">
+        <div class="col-sm-12 col-md-4 text-center">
             <h1>System Setup</h1>
         </div>
-        <div class="col-12">
-            <form action="{% url 'setup' %}" method="post">
-                {{ form | crispy }}
-                {% csrf_token %}
-                <input type="submit" class="form-control btn btn-lg btn-dark" value="Submit">
-            </form>
+    </div>
+    <div class="row justify-content-center">
+        <div class="col-sm-12 col-md-6">
+            <div class="card shadow">
+                <div class="card-body">
+                    <form action="{% url 'setup' %}" method="post">
+                        {{ form | crispy }}
+                        {% csrf_token %}
+                        <input type="submit" class="form-control btn btn-lg btn-dark" value="Submit">
+                    </form>
+                </div>
+            </div>
         </div>
-        <div class="col-12 mt-5">
+        <div class="col-sm-12 mt-5">
             {% include 'tools/keyboard.html' %}
         </div>
+
     </div>
 
 {% endblock %}

+ 3 - 3
app/templates/timesheet.html

@@ -1,4 +1,4 @@
-{% extends 'layout.html' %}
+{% extends 'layout_auth.html' %}
 {% load crispy_forms_tags %}
 {% block content %}
 
@@ -34,7 +34,7 @@
         <div class="col-12">
             <div class="card">
                 <div class="card-body text-center">
-                    <p class="lead"><span class="oi" data-glyph="warning"></span> Maximum daily entries met.</p>
+                    <p class="lead pt-1"><span class="oi" data-glyph="warning"></span> Maximum daily entries met.</p>
                 </div>
             </div>
         </div>
@@ -92,7 +92,7 @@
                                 {% endif %}
                             </div>
                             <div class="col-sm-6 col-md-4 text-end">
-                                <a href="#!" class="btn btn-secondary"><span class="oi" data-glyph="pencil"></span></a>
+                                <a href="{% url 'edit_entry' entry_id=entry.id %}" class="btn btn-secondary"><span class="oi" data-glyph="pencil"></span></a>
                                 <a href="#!" data-bs-toggle="modal" data-bs-target="#entry-{{ entry.id }}" class="btn btn-danger"><span class="oi" data-glyph="trash"></span></a>
                             </div>
                             <div class="modal fade" id="entry-{{ entry.id }}" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">

+ 1 - 0
app/urls.py

@@ -23,4 +23,5 @@ urlpatterns = [
     path('logout', views.logout_user, name="logout"),
     path('create/user', views.create_user, name="create_user"),
     path('remove/<int:entry_id>', views.remove, name='remove_entry'),
+    path('edit/<int:entry_id>', views.edit, name='edit_entry'),
 ]

+ 58 - 1
app/views.py

@@ -93,8 +93,10 @@ def create_user(request):
             else:
                 form.add_error('pin', 'PIN already exists')
 
+    auth_timeout = int(Setting.objects.get(setting="Session Timeout").value) * 60
     context = {
-        'form': form
+        'form': form,
+        'auth_timeout': auth_timeout
     }
 
     return render(request, 'create_user.html', context=context)
@@ -183,6 +185,8 @@ def timesheet(request):
         time_entries.append(e)
         total_time_worked = float(total_time_worked) + time_worked
 
+    auth_timeout = int(Setting.objects.get(setting="Session Timeout").value) * 60
+
     context = {
         'user': user,
         'form': form,
@@ -190,6 +194,7 @@ def timesheet(request):
         'total_time_worked': total_time_worked,
         'max_daily_entries_quota': max_daily_entries_quota,
         'projects': projects.value,
+        'session_timeout': auth_timeout
     }
 
     return render(request, 'timesheet.html', context=context)
@@ -206,3 +211,55 @@ def remove(request, entry_id):
     entry = Entry.objects.filter(id=entry_id, user=user)
     entry.delete()
     return redirect('timesheet')
+
+
+def edit(request, entry_id):
+    if requires_auth(request) is False:
+        request.session['authenticated'] = False
+        return redirect('home')
+
+    uid = request.session.get('uid')
+    user = get_user(uid)
+
+    form = TimeEntryForm()
+
+    if request.method == "POST":
+        form = TimeEntryForm(request.POST)
+        if form.is_valid():
+            data = form.cleaned_data
+            if data['hours'] == '0' and data['minutes'] == '0':
+                form.add_error('hours', 'Hours and Minutes may not be both 0')
+                form.add_error('minutes', 'Hours and Minutes may not be both 0')
+            else:
+                entry = Entry.objects.filter(id=entry_id, user=user).first()
+                entry.hours = data['hours']
+                entry.minutes = data['minutes']
+                entry.project = data['project']
+                entry.save()
+
+                return redirect('timesheet')
+
+    entry = Entry.objects.filter(id=entry_id, user=user).first()
+    projects = Setting.objects.get(setting="Projects")
+    auth_timeout = int(Setting.objects.get(setting="Session Timeout").value) * 60
+
+    if entry:
+        form.fields['hours'].initial = entry.hours
+        form.fields['minutes'].initial = entry.minutes
+        if projects.value == "True":
+            form.fields['project'].initial = entry.project
+        else:
+            del form.fields['project']
+    else:
+        return redirect('timesheet')
+
+    context = {
+        'form': form,
+        'user': user,
+        'entry': entry,
+        'projects': projects.value,
+        'session_timeout': auth_timeout
+    }
+
+    return render(request, 'edit.html', context=context)
+