Fixed bugs and added yearly target

This commit is contained in:
Claudio Maggioni (maggicl) 2019-07-26 23:32:50 +02:00
parent 32ff5b7ea0
commit 36fcc8d9c9
10 changed files with 134 additions and 15 deletions

2
.gitignore vendored
View file

@ -76,7 +76,7 @@ coverage.xml
docs/_build/ docs/_build/
# PyBuilder # PyBuilder
target/ /target/
### Django ### ### Django ###

View file

@ -1,6 +1,6 @@
from django import forms from django import forms
from django.conf import settings from django.conf import settings
from .models import ArrowCount from .models import ArrowCount, Target
class ArrowCountForm(forms.ModelForm): class ArrowCountForm(forms.ModelForm):
date = forms.DateField(widget=forms.DateInput( date = forms.DateField(widget=forms.DateInput(
@ -10,3 +10,9 @@ class ArrowCountForm(forms.ModelForm):
class Meta: class Meta:
model = ArrowCount model = ArrowCount
fields = ['date', 'count'] fields = ['date', 'count']
class TargetForm(forms.ModelForm):
class Meta:
model = Target
fields = ['target']

View file

@ -0,0 +1,28 @@
# Generated by Django 2.2.3 on 2019-07-26 20:44
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('user', '0001_initial'),
('counter', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Target',
fields=[
('target', models.PositiveIntegerField(verbose_name='Target to reach')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL)),
],
),
migrations.AlterField(
model_name='arrowcount',
name='date',
field=models.DateField(verbose_name='Training date'),
),
]

View file

@ -2,6 +2,14 @@ from django.db import models
from django.conf import settings from django.conf import settings
from django.contrib.auth.models import User from django.contrib.auth.models import User
class Target(models.Model):
target = models.PositiveIntegerField('Target to reach')
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
primary_key = True
)
class ArrowCount(models.Model): class ArrowCount(models.Model):
user = models.ForeignKey( user = models.ForeignKey(
settings.AUTH_USER_MODEL, settings.AUTH_USER_MODEL,

View file

@ -36,14 +36,14 @@ form ul, form span.helptext {
} }
form ul { form ul {
background: #ffecb3; background: #ffecb3;
} }
form ul.errorlist { form ul.errorlist {
background: #ffcdd2; background: #ffcdd2;
} }
form .card-action button[type=submit] { form .card-action button {
background: none !important; background: none !important;
border: none; border: none;
cursor: pointer; cursor: pointer;
@ -57,11 +57,13 @@ form .card-action button[type=submit] {
margin-right: auto; margin-right: auto;
} }
#edit-arrowcount-form input { #edit-arrowcount-form input,
#edit-target-form input {
text-align: center text-align: center
} }
#edit-arrowcount-form #id_count { #edit-arrowcount-form #id_count,
#edit-target-form #id_target {
font-size: 3em; font-size: 3em;
padding: .25em 0; padding: .25em 0;
} }

View file

@ -5,17 +5,23 @@
{% block content %} {% block content %}
<h1 class="center">Arrow counter</h1> <h1 class="center">Arrow counter</h1>
<h5 class="center">A simple online arrow counter</h5> <h5 class="center">A simple online arrow counter</h5>
{% if user.is_authenticated %}
<p class="center" style="margin-bottom: 3rem"> <p class="center" style="margin-bottom: 3rem">
<a class="btn waves-effect waves-light" href="{% url "count_export" %}"> <a class="btn waves-effect waves-light" href="{% url "count_export" %}">
Excel Data (CSV) <i class="material-icons right">file_download</i> Excel Data (CSV) <i class="material-icons right">file_download</i>
</a> </a>
</p> </p>
{% if user.is_authenticated %}
<div class="card-panel grey lighten-2"> <div class="card-panel grey lighten-2">
<h5 class="center">Arrows shot this year:</h5> <h5 class="center">Arrows shot this year:</h5>
<p class="center"><strong style="font-size: 2.7rem">{{ yearArrows }}</strong></p> <p class="center"><strong style="font-size: 2.7rem">{{ yearArrows }}</strong></p>
</div> </div>
{% if diffTarget is not False %}
<div class="card-panel lighten-2 {% if diffTarget < 0 %}red{% elif diffTarget is 0 %}yellow
{% else %}green{% endif %}">
<h5 class="center">Difference with target:</h5>
<p class="center"><strong style="font-size: 2.7rem">{{ diffTarget }}</strong></p>
</div>
{% endif %}
<div class="card-panel grey lighten-2"> <div class="card-panel grey lighten-2">
<h5 class="center">Arrows shot this month:</h5> <h5 class="center">Arrows shot this month:</h5>
<p class="center"><strong style="font-size: 2.7rem">{{ monthArrows }}</strong></p> <p class="center"><strong style="font-size: 2.7rem">{{ monthArrows }}</strong></p>

View file

@ -14,6 +14,7 @@
<li class="divider" tabindex="-1"></li> <li class="divider" tabindex="-1"></li>
{% if user.is_authenticated %} {% if user.is_authenticated %}
<li><a href="{% url "count_list" %}">Counts</a></li> <li><a href="{% url "count_list" %}">Counts</a></li>
<li><a href="{% url "target_edit" %}">Set yearly target</a></li>
<li><a href="{% url "stats" %}">Weekly stats</a></li> <li><a href="{% url "stats" %}">Weekly stats</a></li>
<li class="divider" tabindex="-1"></li> <li class="divider" tabindex="-1"></li>
{% if user.is_superuser %} {% if user.is_superuser %}

View file

@ -0,0 +1,23 @@
{% extends "base.html" %}
{% load static %}
{% block title %}Set yearly target{% endblock %}
{% block content %}
<h1 class="center">Set yearly target</h1>
<form method="post" id="edit-target-form">
<div class="col s12 card">
<div class="card-content">
{% csrf_token %}
<div class="row">
{{ form.as_p }}
</div>
</div>
<div class="card-action">
<a href="#"><button type="submit">Save</button></a>
<a href="{% url "target_delete" %}"><button type="button">Remove</button></a>
</div>
</div>
</form>
{% endblock %}

View file

@ -11,6 +11,10 @@ urlpatterns = [
name='count_new'), name='count_new'),
path('count/edit/<int:id>', login_required(views.EditArrowCount.as_view()), path('count/edit/<int:id>', login_required(views.EditArrowCount.as_view()),
name='count_edit'), name='count_edit'),
path('target/edit', login_required(views.EditTarget.as_view()),
name='target_edit'),
path('target/delete', views.target_delete,
name='target_delete'),
path('count/delete/<int:id>', login_required(views.DeleteArrowCount.as_view()), path('count/delete/<int:id>', login_required(views.DeleteArrowCount.as_view()),
name='count_delete'), name='count_delete'),
path('count/edit/<int:ac_id>/ajax', login_required(views \ path('count/edit/<int:ac_id>/ajax', login_required(views \

View file

@ -1,12 +1,12 @@
# vim: set ts=4 sw=4 et tw=80: # vim: set ts=4 sw=4 et tw=80:
from django.shortcuts import render from django.shortcuts import render, redirect
from django.http import HttpResponse, JsonResponse from django.http import HttpResponse, JsonResponse
from django.views import generic from django.views import generic
from django.template import loader from django.template import loader
from django.urls import reverse_lazy from django.urls import reverse_lazy
from .models import ArrowCount from .models import ArrowCount, Target
from .forms import ArrowCountForm from .forms import ArrowCountForm, TargetForm
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.conf import settings from django.conf import settings
from django.core.exceptions import SuspiciousOperation from django.core.exceptions import SuspiciousOperation
@ -35,20 +35,32 @@ def index(request):
yearArrows = ArrowCount.objects.filter(user=request.user) \ yearArrows = ArrowCount.objects.filter(user=request.user) \
.filter(date__range=(date(now.year, 1, 1), date(now.year, 12, 31))) \ .filter(date__range=(date(now.year, 1, 1), date(now.year, 12, 31))) \
.aggregate(s=Sum('count')) .aggregate(s=Sum('count'))
yearArrows = yearArrows['s'] if yearArrows['s'] is not None else 0
diff_target = False
try:
target = Target.objects.get(user=request.user).target
days_this_year = (date(now.year + 1, 1, 1) - date(now.year, 1, 1)).days
diff_target = round(yearArrows - (now.timetuple().tm_yday / days_this_year) * \
target)
except Target.DoesNotExist:
pass
monthArrows = ArrowCount.objects.filter(user=request.user) \ monthArrows = ArrowCount.objects.filter(user=request.user) \
.filter(date__year=now.year, date__month=now.month) \ .filter(date__year=now.year, date__month=now.month) \
.aggregate(s=Sum('count')) .aggregate(s=Sum('count'))
weekday = now.isoweekday() weekday = now.isoweekday() - 1
weekArrows = ArrowCount.objects.filter(user=request.user) \ weekArrows = ArrowCount.objects.filter(user=request.user) \
.filter(date__range=(now - timedelta(days=weekday), now + timedelta(days=6-weekday))) \ .filter(date__range=(now - timedelta(days=weekday), \
now + timedelta(days=6-weekday))) \
.aggregate(s=Sum('count')) .aggregate(s=Sum('count'))
return HttpResponse(template.render({ return HttpResponse(template.render({
'yearArrows': 0 if yearArrows['s'] is None else yearArrows['s'], 'yearArrows': yearArrows,
'monthArrows': 0 if monthArrows['s'] is None else monthArrows['s'], 'monthArrows': 0 if monthArrows['s'] is None else monthArrows['s'],
'weekArrows': 0 if weekArrows['s'] is None else weekArrows['s'] 'weekArrows': 0 if weekArrows['s'] is None else weekArrows['s'],
'diffTarget': diff_target
}, request)) }, request))
else: else:
return HttpResponse(template.render({}), request) return HttpResponse(template.render({}), request)
@ -143,6 +155,26 @@ class EditArrowCount(generic.UpdateView):
context_data.update(ac_id=self.kwargs['id']) context_data.update(ac_id=self.kwargs['id'])
return self.render_to_response(context_data) return self.render_to_response(context_data)
class EditTarget(generic.UpdateView):
form_class = TargetForm
success_url = reverse_lazy('index')
template_name = 'target/edit.html'
def get_object(self, queryset=None):
try:
obj = Target.objects.get(user=self.request.user)
except Target.DoesNotExist:
obj = Target(user=self.request.user, target=0)
obj.save()
return obj
def get(self, request, *args, **kwargs):
super().get(self, request, *args, **kwargs)
context_data = self.get_context_data()
context_data.update(ac_id=self.request.user)
return self.render_to_response(context_data)
class DeleteArrowCount(generic.DeleteView): class DeleteArrowCount(generic.DeleteView):
model = ArrowCount model = ArrowCount
success_url = reverse_lazy('count_list') success_url = reverse_lazy('count_list')
@ -151,6 +183,15 @@ class DeleteArrowCount(generic.DeleteView):
obj = ArrowCount.objects.get(id=self.kwargs['id']) obj = ArrowCount.objects.get(id=self.kwargs['id'])
return obj return obj
@login_required
def target_delete(request):
try:
to_delete = Target.objects.get(user=request.user)
to_delete.delete()
except Target.DoesNotExist:
pass
return redirect('index')
@login_required @login_required
def arrow_count_update_ajax(request, ac_id): def arrow_count_update_ajax(request, ac_id):
try: try: