diff --git a/.gitignore b/.gitignore index b4fce52..b1795cc 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ build/ */*/__pycache__/ caromserver/local_settings.py /staticfiles/ +.venv/ +update.sh diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..09f7b98 --- /dev/null +++ b/Pipfile @@ -0,0 +1,18 @@ +[[source]] +name = "pypi" +url = "https://pypi.org/simple" +verify_ssl = true + +[dev-packages] + +[packages] +django = "==2.1.5" +django-crispy-forms = "==1.7.2" +django-debug-toolbar = "==1.11" +django-extensions = "==2.1.5" +django-tables2 = "==2.0.4" +djangorestframework = "==3.9.1" +requests = "==2.21.0" + +[requires] +python_version = "3.5" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 0000000..d969b37 --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,126 @@ +{ + "_meta": { + "hash": { + "sha256": "de1e65bd4b2342db22fea58996979f48314fcad56bd7b50f4c939035771ef85c" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.5" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "certifi": { + "hashes": [ + "sha256:47f9c83ef4c0c621eaef743f133f09fa8a74a9b75f037e8624f83bd1b6626cb7", + "sha256:993f830721089fef441cdfeb4b2c8c9df86f0c63239f06bd025a76a7daddb033" + ], + "version": "==2018.11.29" + }, + "chardet": { + "hashes": [ + "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", + "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + ], + "version": "==3.0.4" + }, + "django": { + "hashes": [ + "sha256:a32c22af23634e1d11425574dce756098e015a165be02e4690179889b207c7a8", + "sha256:d6393918da830530a9516bbbcbf7f1214c3d733738779f06b0f649f49cc698c3" + ], + "index": "pypi", + "version": "==2.1.5" + }, + "django-crispy-forms": { + "hashes": [ + "sha256:5952bab971110d0b86c278132dae0aa095beee8f723e625c3d3fa28888f1675f", + "sha256:705ededc554ad8736157c666681165fe22ead2dec0d5446d65fc9dd976a5a876" + ], + "index": "pypi", + "version": "==1.7.2" + }, + "django-debug-toolbar": { + "hashes": [ + "sha256:89d75b60c65db363fb24688d977e5fbf0e73386c67acf562d278402a10fc3736", + "sha256:c2b0134119a624f4ac9398b44f8e28a01c7686ac350a12a74793f3dd57a9eea0" + ], + "index": "pypi", + "version": "==1.11" + }, + "django-extensions": { + "hashes": [ + "sha256:6fcedb2ea660c9dbf9ac59441721ffdd4ab5b753fbd6159c3e28f391a65bab46", + "sha256:a607459e5fa8c579a672131b63366fa52fab80adb2a862d362f5fb48cd2d2cac" + ], + "index": "pypi", + "version": "==2.1.5" + }, + "django-tables2": { + "hashes": [ + "sha256:a893fca1afe2e95b9739c6428cc6c9735a219f65707e24274df3920f61358525", + "sha256:b5f7b4c76160ee927005e52ebea633c86d4529cf84757c0acd5d0434d31798a1" + ], + "index": "pypi", + "version": "==2.0.4" + }, + "djangorestframework": { + "hashes": [ + "sha256:79c6efbb2514bc50cf25906d7c0a5cfead714c7af667ff4bd110312cd380ae66", + "sha256:a4138613b67e3a223be6c97f53b13d759c5b90d2b433bad670b8ebf95402075f" + ], + "index": "pypi", + "version": "==3.9.1" + }, + "idna": { + "hashes": [ + "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", + "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c" + ], + "version": "==2.8" + }, + "pytz": { + "hashes": [ + "sha256:32b0891edff07e28efe91284ed9c31e123d84bea3fd98e1f72be2508f43ef8d9", + "sha256:d5f05e487007e29e03409f9398d074e158d920d36eb82eaf66fb1136b0c5374c" + ], + "version": "==2018.9" + }, + "requests": { + "hashes": [ + "sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e", + "sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b" + ], + "index": "pypi", + "version": "==2.21.0" + }, + "six": { + "hashes": [ + "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", + "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" + ], + "version": "==1.12.0" + }, + "sqlparse": { + "hashes": [ + "sha256:ce028444cfab83be538752a2ffdb56bc417b7784ff35bb9a3062413717807dec", + "sha256:d9cf190f51cbb26da0412247dfe4fb5f4098edb73db84e02f9fc21fdca31fed4" + ], + "version": "==0.2.4" + }, + "urllib3": { + "hashes": [ + "sha256:61bf29cada3fc2fbefad4fdf059ea4bd1b4a86d2b6d15e1c7c0b582b9752fe39", + "sha256:de9529817c93f27c8ccbfead6985011db27bd0ddfcdb2d86f3f663385c6a9c22" + ], + "version": "==1.24.1" + } + }, + "develop": {} +} diff --git a/billard/admin.py b/billard/admin.py index b06774c..f06665e 100644 --- a/billard/admin.py +++ b/billard/admin.py @@ -35,6 +35,12 @@ class ClientAdmin(admin.ModelAdmin): fields = ['location', 'uuid', 'report_user', 'last_seen'] +@admin.register(ClientData) +class ClientDataAdmin(admin.ModelAdmin): + list_display = ('uuid', 'last_seen') + fields = ['location', 'last_seen'] + + @admin.register(LocationData) class LocationDataAdmin(admin.ModelAdmin): def get_urls(self): @@ -46,6 +52,8 @@ class LocationDataAdmin(admin.ModelAdmin): return my_urls + urls def process_locationdata(self, request): + from .tasks import process_location_data + process_location_data(sender=None) messages.success(request, 'Items processed.') return redirect('admin:billard_locationdata_changelist') diff --git a/billard/forms.py b/billard/forms.py new file mode 100644 index 0000000..dd82d79 --- /dev/null +++ b/billard/forms.py @@ -0,0 +1,10 @@ +from django import forms +from django.contrib.auth.models import User + + +class UserInformationUpdateForm(forms.ModelForm): + email = forms.EmailField() + + class Meta: + model = User + fields = ('first_name', 'last_name', 'email',) diff --git a/billard/migrations/0027_clientdata.py b/billard/migrations/0027_clientdata.py new file mode 100644 index 0000000..94c86b5 --- /dev/null +++ b/billard/migrations/0027_clientdata.py @@ -0,0 +1,24 @@ +# Generated by Django 2.0.2 on 2018-02-19 10:23 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ('billard', '0026_client_last_seen'), + ] + + operations = [ + migrations.CreateModel( + name='ClientData', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('uuid', models.UUIDField(verbose_name='Identifier')), + ('last_seen', models.DateTimeField(verbose_name='Letzter Update')), + ], + options={ + 'verbose_name': 'Client Data logs', + 'verbose_name_plural': 'Client Data logs', + }, + ), + ] diff --git a/billard/models.py b/billard/models.py index 5ce0cde..7fa7236 100644 --- a/billard/models.py +++ b/billard/models.py @@ -4,8 +4,6 @@ import uuid from django.contrib.auth.models import User from django.contrib.auth.models import User from django.db import models -from django.db.models.signals import post_save -from django.dispatch import receiver log = logging.getLogger(__name__) @@ -102,7 +100,13 @@ class Accounting(models.Model): verbose_name_plural = "Buchhaltungseinträge" -@receiver(post_save, sender=LocationData) -def test(sender, **kwargs): - from .tasks import process_location_data - process_location_data() +class ClientData(models.Model): + uuid = models.UUIDField(verbose_name="Identifier") + last_seen = models.DateTimeField(verbose_name="Letzter Update") + + def __str__(self): + return '{}, {}'.format(self.uuid, self.last_seen) + + class Meta: + verbose_name = "Client Data logs" + verbose_name_plural = "Client Data logs" diff --git a/billard/serializers.py b/billard/serializers.py index dd40344..f5a06e1 100644 --- a/billard/serializers.py +++ b/billard/serializers.py @@ -1,6 +1,6 @@ from rest_framework import serializers -from billard.models import LocationData, Client +from billard.models import LocationData, ClientData class LocationDataSerializer(serializers.HyperlinkedModelSerializer): @@ -11,5 +11,5 @@ class LocationDataSerializer(serializers.HyperlinkedModelSerializer): class ClientUpdateLastSeenSerializer(serializers.HyperlinkedModelSerializer): class Meta: - model = Client + model = ClientData fields = ('uuid', 'last_seen') diff --git a/billard/tables.py b/billard/tables.py new file mode 100644 index 0000000..d8959b8 --- /dev/null +++ b/billard/tables.py @@ -0,0 +1,22 @@ +import django_tables2 as tables + +from .models import Location + + +class LocationTable(tables.Table): + code = tables.TemplateColumn(template_name='billard/tc_location_detail.html') + + class Meta: + model = Location + fields = ('code', 'name', 'street', 'plz', 'city') + orderable = False + + +class LocationAccountingTable(tables.Table): + code = tables.TemplateColumn(template_name='billard/tc_location_detail.html') + accounting = tables.TemplateColumn(template_name='billard/tc_accounting_detail.html') + + class Meta: + model = Location + fields = ('code', 'name', 'street', 'plz', 'city', 'accounting') + orderable = False diff --git a/billard/tasks.py b/billard/tasks.py index 98cd688..77c356d 100644 --- a/billard/tasks.py +++ b/billard/tasks.py @@ -2,13 +2,28 @@ from __future__ import absolute_import, unicode_literals import logging +from django.db.models.signals import post_save +from django.dispatch import receiver + import billard.utils as utils -from billard.models import LocationData, Client, Accounting +from billard.models import LocationData, Client, Accounting, ClientData log = logging.getLogger(__name__) -def process_location_data(): +@receiver(post_save, sender=ClientData) +def process_client_data(sender, **kwargs): + data = ClientData.objects.all().order_by('last_seen') + for cd in data: + client = Client.objects.get(uuid=cd.uuid) + client.last_seen = cd.last_seen + client.save() + cd.delete() + + +@receiver(post_save, sender=LocationData) +def process_location_data(sender, **kwargs): + log.info('Starte die Verarbeitung der Location-Data-Objecte') data = LocationData.objects.filter(processed=False).order_by('tst') for ld in data: try: @@ -64,3 +79,10 @@ def process_location_data(): log.error(ld.error_msg) except: log.exception('', exc_info=True) + + +@receiver(post_save, sender=Accounting) +def process_accounting_data(sender, **kwargs): + log.info('Starte die Verarbeitung der Accounting-Data-Objecte') + data = Accounting.objects.filter(prize=0.0, reporter_uuid__isnull=True).exclude(time_to__isnull=True) + data.delete() diff --git a/billard/templates/admin/billard/locationdata/change_list.html b/billard/templates/admin/billard/locationdata/change_list.html index eb84b2f..2191925 100644 --- a/billard/templates/admin/billard/locationdata/change_list.html +++ b/billard/templates/admin/billard/locationdata/change_list.html @@ -2,7 +2,7 @@ {% load i18n admin_urls static admin_list %} {% block object-tools-items %}
Start-Datum: | -Stop-Datum: | -Preis Normal: | -Preis Happy Hour: | -Preis gesamt: | -
---|---|---|---|---|
{{ acc.time_from }} | -{{ acc.time_to }} | -{{ acc.prize_normal }} | -{{ acc.prize_hh }} | -{{ acc.prize }} | -
Code | -Name | -Strasse | -Plz | -Ort | - {% if perms.billard.change_accounting %} -Accounting | - {% endif %} -
---|---|---|---|---|---|
{{ loc.code|default_if_none:"" }} | -{{ loc.name|default_if_none:"" }} | -{{ loc.street|default_if_none:"" }} | -{{ loc.plz|default_if_none:"" }} | -{{ loc.city|default_if_none:"" }} | - {% if perms.billard.change_accounting %} -Abrechnen | - {% endif %} -
Keine Standorte Zugeordnet.
- {% endif %} - +{{ error_message }}
{% endif %} - -