Merge branch 'release/0.5.1'
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -7,3 +7,4 @@ build/ | |||||||
| */__pycache__/ | */__pycache__/ | ||||||
| */*/__pycache__/ | */*/__pycache__/ | ||||||
| caromserver/local_settings.py | caromserver/local_settings.py | ||||||
|  | /staticfiles/ | ||||||
|   | |||||||
| @@ -1,11 +1,10 @@ | |||||||
|  | from django import forms | ||||||
| from django.conf.urls import url | from django.conf.urls import url | ||||||
| from django.contrib import admin, messages | from django.contrib import admin, messages | ||||||
|  | from django.core.exceptions import ValidationError | ||||||
| from django.shortcuts import redirect | from django.shortcuts import redirect | ||||||
| from django.template.response import TemplateResponse |  | ||||||
|  |  | ||||||
| from .models import * | from .models import * | ||||||
| from django import forms |  | ||||||
| from django.core.exceptions import ValidationError |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class LocationAdminForm(forms.ModelForm): | class LocationAdminForm(forms.ModelForm): | ||||||
| @@ -26,13 +25,14 @@ class LocationAdminForm(forms.ModelForm): | |||||||
| class LocationAdmin(admin.ModelAdmin): | class LocationAdmin(admin.ModelAdmin): | ||||||
|     form = LocationAdminForm |     form = LocationAdminForm | ||||||
|     list_display = ('code', 'name', 'city', 'happy_hour_start', 'happy_hour_end') |     list_display = ('code', 'name', 'city', 'happy_hour_start', 'happy_hour_end') | ||||||
|     fields = ['users', 'code', 'happy_hour_start', 'happy_hour_end', 'name', 'street', 'plz', 'city', 'phone', 'email', 'url', ] |     fields = ['users', 'code', 'happy_hour_start', 'happy_hour_end', 'name', 'street', 'plz', 'city', 'phone', 'email', | ||||||
|  |               'url', ] | ||||||
|  |  | ||||||
|  |  | ||||||
| @admin.register(Client) | @admin.register(Client) | ||||||
| class ClientAdmin(admin.ModelAdmin): | class ClientAdmin(admin.ModelAdmin): | ||||||
|     list_display = ('uuid', 'location', 'report_user') |     list_display = ('uuid', 'location', 'report_user', 'last_seen') | ||||||
|     fields = ['location', 'uuid', 'report_user'] |     fields = ['location', 'uuid', 'report_user', 'last_seen'] | ||||||
|  |  | ||||||
|  |  | ||||||
| @admin.register(LocationData) | @admin.register(LocationData) | ||||||
| @@ -40,13 +40,15 @@ class LocationDataAdmin(admin.ModelAdmin): | |||||||
|     def get_urls(self): |     def get_urls(self): | ||||||
|         urls = super().get_urls() |         urls = super().get_urls() | ||||||
|         my_urls = [ |         my_urls = [ | ||||||
|             url(r'^process_locationdata/$', self.admin_site.admin_view(self.process_locationdata), name='process_locationdata'), |             url(r'^process_locationdata/$', self.admin_site.admin_view(self.process_locationdata), | ||||||
|  |                 name='process_locationdata'), | ||||||
|         ] |         ] | ||||||
|         return my_urls + urls |         return my_urls + urls | ||||||
|  |  | ||||||
|     def process_locationdata(self, request): |     def process_locationdata(self, request): | ||||||
|         messages.success(request, 'Items processed.') |         messages.success(request, 'Items processed.') | ||||||
|         return redirect('admin:billard_locationdata_changelist') |         return redirect('admin:billard_locationdata_changelist') | ||||||
|  |  | ||||||
|     list_display = ('client_id', 'desk_no', 'tst', 'on_off', 'processed', 'error_msg') |     list_display = ('client_id', 'desk_no', 'tst', 'on_off', 'processed', 'error_msg') | ||||||
|     fields = ['client_id', 'desk_no', 'tst', 'on_off', 'processed', 'error_msg'] |     fields = ['client_id', 'desk_no', 'tst', 'on_off', 'processed', 'error_msg'] | ||||||
|  |  | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ from django.db import migrations, models | |||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     initial = True |     initial = True | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|   | |||||||
| @@ -7,7 +7,6 @@ from django.db import migrations, models | |||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         migrations.swappable_dependency(settings.AUTH_USER_MODEL), |         migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||||||
|         ('billard', '0001_initial'), |         ('billard', '0001_initial'), | ||||||
|   | |||||||
| @@ -2,13 +2,13 @@ | |||||||
| # Generated by Django 1.10.5 on 2017-02-04 05:48 | # Generated by Django 1.10.5 on 2017-02-04 05:48 | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
|  |  | ||||||
| from django.db import migrations, models |  | ||||||
| import django.db.models.deletion |  | ||||||
| import uuid | import uuid | ||||||
|  |  | ||||||
|  | import django.db.models.deletion | ||||||
|  | from django.db import migrations, models | ||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ('billard', '0002_location'), |         ('billard', '0002_location'), | ||||||
|     ] |     ] | ||||||
|   | |||||||
| @@ -2,12 +2,11 @@ | |||||||
| # Generated by Django 1.10.5 on 2017-02-04 10:17 | # Generated by Django 1.10.5 on 2017-02-04 10:17 | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
|  |  | ||||||
| from django.db import migrations, models |  | ||||||
| import django.db.models.deletion | import django.db.models.deletion | ||||||
|  | from django.db import migrations, models | ||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ('billard', '0003_client'), |         ('billard', '0003_client'), | ||||||
|     ] |     ] | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ from django.db import migrations, models | |||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ('billard', '0004_accounting'), |         ('billard', '0004_accounting'), | ||||||
|     ] |     ] | ||||||
|   | |||||||
| @@ -2,14 +2,14 @@ | |||||||
| # Generated by Django 1.10.5 on 2017-02-06 19:31 | # Generated by Django 1.10.5 on 2017-02-06 19:31 | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
|  |  | ||||||
|  | import uuid | ||||||
|  |  | ||||||
|  | import django.db.models.deletion | ||||||
| from django.conf import settings | from django.conf import settings | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
| import django.db.models.deletion |  | ||||||
| import uuid |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ('billard', '0005_auto_20170206_1926'), |         ('billard', '0005_auto_20170206_1926'), | ||||||
|     ] |     ] | ||||||
| @@ -17,7 +17,8 @@ class Migration(migrations.Migration): | |||||||
|     operations = [ |     operations = [ | ||||||
|         migrations.AlterModelOptions( |         migrations.AlterModelOptions( | ||||||
|             name='accounting', |             name='accounting', | ||||||
|             options={'ordering': ['-time_from'], 'verbose_name': 'Buchhaltungseintrag', 'verbose_name_plural': 'Buchhaltungseinträge'}, |             options={'ordering': ['-time_from'], 'verbose_name': 'Buchhaltungseintrag', | ||||||
|  |                      'verbose_name_plural': 'Buchhaltungseinträge'}, | ||||||
|         ), |         ), | ||||||
|         migrations.AlterModelOptions( |         migrations.AlterModelOptions( | ||||||
|             name='client', |             name='client', | ||||||
| @@ -34,7 +35,8 @@ class Migration(migrations.Migration): | |||||||
|         migrations.AlterField( |         migrations.AlterField( | ||||||
|             model_name='accounting', |             model_name='accounting', | ||||||
|             name='client', |             name='client', | ||||||
|             field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='billard.Client', verbose_name='Client'), |             field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='billard.Client', | ||||||
|  |                                     verbose_name='Client'), | ||||||
|         ), |         ), | ||||||
|         migrations.AlterField( |         migrations.AlterField( | ||||||
|             model_name='accounting', |             model_name='accounting', | ||||||
| @@ -59,7 +61,8 @@ class Migration(migrations.Migration): | |||||||
|         migrations.AlterField( |         migrations.AlterField( | ||||||
|             model_name='client', |             model_name='client', | ||||||
|             name='location', |             name='location', | ||||||
|             field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='billard.Location', verbose_name='Standort'), |             field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='billard.Location', | ||||||
|  |                                     verbose_name='Standort'), | ||||||
|         ), |         ), | ||||||
|         migrations.AlterField( |         migrations.AlterField( | ||||||
|             model_name='client', |             model_name='client', | ||||||
| @@ -109,7 +112,8 @@ class Migration(migrations.Migration): | |||||||
|         migrations.AlterField( |         migrations.AlterField( | ||||||
|             model_name='location', |             model_name='location', | ||||||
|             name='users', |             name='users', | ||||||
|             field=models.ManyToManyField(related_name='locations', to=settings.AUTH_USER_MODEL, verbose_name='Benutzer'), |             field=models.ManyToManyField(related_name='locations', to=settings.AUTH_USER_MODEL, | ||||||
|  |                                          verbose_name='Benutzer'), | ||||||
|         ), |         ), | ||||||
|         migrations.AlterField( |         migrations.AlterField( | ||||||
|             model_name='locationdata', |             model_name='locationdata', | ||||||
|   | |||||||
| @@ -2,12 +2,11 @@ | |||||||
| # Generated by Django 1.10.5 on 2017-02-10 18:30 | # Generated by Django 1.10.5 on 2017-02-10 18:30 | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
|  |  | ||||||
| from django.db import migrations, models |  | ||||||
| import django.db.models.deletion | import django.db.models.deletion | ||||||
|  | from django.db import migrations, models | ||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ('billard', '0006_auto_20170206_2031'), |         ('billard', '0006_auto_20170206_2031'), | ||||||
|     ] |     ] | ||||||
| @@ -20,9 +19,12 @@ class Migration(migrations.Migration): | |||||||
|                 ('desk_no', models.IntegerField(verbose_name='Tischnummer')), |                 ('desk_no', models.IntegerField(verbose_name='Tischnummer')), | ||||||
|                 ('name', models.CharField(blank=True, max_length=32, null=True, verbose_name='Tischbezeichnung')), |                 ('name', models.CharField(blank=True, max_length=32, null=True, verbose_name='Tischbezeichnung')), | ||||||
|                 ('enabled', models.BooleanField(verbose_name='Tisch aktiv')), |                 ('enabled', models.BooleanField(verbose_name='Tisch aktiv')), | ||||||
|                 ('prize', models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True, verbose_name='Normelpreis')), |                 ('prize', models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True, | ||||||
|                 ('prize_hh', models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True, verbose_name='Preis Happy Hour')), |                                               verbose_name='Normelpreis')), | ||||||
|                 ('client', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='billard.Client', verbose_name='Client')), |                 ('prize_hh', models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True, | ||||||
|  |                                                  verbose_name='Preis Happy Hour')), | ||||||
|  |                 ('client', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='billard.Client', | ||||||
|  |                                              verbose_name='Client')), | ||||||
|             ], |             ], | ||||||
|             options={ |             options={ | ||||||
|                 'verbose_name_plural': 'Tische', |                 'verbose_name_plural': 'Tische', | ||||||
|   | |||||||
| @@ -2,12 +2,11 @@ | |||||||
| # Generated by Django 1.10.5 on 2017-02-10 19:47 | # Generated by Django 1.10.5 on 2017-02-10 19:47 | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
|  |  | ||||||
| from django.db import migrations, models |  | ||||||
| import django.db.models.deletion | import django.db.models.deletion | ||||||
|  | from django.db import migrations, models | ||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ('billard', '0007_desk'), |         ('billard', '0007_desk'), | ||||||
|     ] |     ] | ||||||
| @@ -48,6 +47,7 @@ class Migration(migrations.Migration): | |||||||
|         migrations.AlterField( |         migrations.AlterField( | ||||||
|             model_name='desk', |             model_name='desk', | ||||||
|             name='client', |             name='client', | ||||||
|             field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='desks', to='billard.Client', verbose_name='Client'), |             field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='desks', | ||||||
|  |                                     to='billard.Client', verbose_name='Client'), | ||||||
|         ), |         ), | ||||||
|     ] |     ] | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ from django.db import migrations | |||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ('billard', '0008_auto_20170210_1947'), |         ('billard', '0008_auto_20170210_1947'), | ||||||
|     ] |     ] | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ from django.db import migrations | |||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ('billard', '0009_auto_20170210_1955'), |         ('billard', '0009_auto_20170210_1955'), | ||||||
|     ] |     ] | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ from django.db import migrations, models | |||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ('billard', '0010_auto_20170210_2040'), |         ('billard', '0010_auto_20170210_2040'), | ||||||
|     ] |     ] | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ from django.db import migrations | |||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ('billard', '0011_auto_20170210_2122'), |         ('billard', '0011_auto_20170210_2122'), | ||||||
|     ] |     ] | ||||||
|   | |||||||
| @@ -2,12 +2,11 @@ | |||||||
| # Generated by Django 1.10.5 on 2017-02-11 09:03 | # Generated by Django 1.10.5 on 2017-02-11 09:03 | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
|  |  | ||||||
| from django.db import migrations, models |  | ||||||
| import django.db.models.deletion | import django.db.models.deletion | ||||||
|  | from django.db import migrations, models | ||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ('billard', '0012_auto_20170211_1003'), |         ('billard', '0012_auto_20170211_1003'), | ||||||
|     ] |     ] | ||||||
| @@ -19,9 +18,11 @@ class Migration(migrations.Migration): | |||||||
|                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||||||
|                 ('time_from', models.DateTimeField(verbose_name='Beginn')), |                 ('time_from', models.DateTimeField(verbose_name='Beginn')), | ||||||
|                 ('time_to', models.DateTimeField(blank=True, null=True, verbose_name='Ende')), |                 ('time_to', models.DateTimeField(blank=True, null=True, verbose_name='Ende')), | ||||||
|                 ('prize', models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True, verbose_name='Preis')), |                 ('prize', | ||||||
|  |                  models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True, verbose_name='Preis')), | ||||||
|                 ('billed', models.BooleanField(default=False, verbose_name='Abgerechnet')), |                 ('billed', models.BooleanField(default=False, verbose_name='Abgerechnet')), | ||||||
|                 ('desk', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='billard.Desk', verbose_name='Tisch')), |                 ('desk', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='billard.Desk', | ||||||
|  |                                            verbose_name='Tisch')), | ||||||
|             ], |             ], | ||||||
|             options={ |             options={ | ||||||
|                 'verbose_name_plural': 'Buchhaltungseinträge', |                 'verbose_name_plural': 'Buchhaltungseinträge', | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ from django.db import migrations, models | |||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ('billard', '0013_accounting'), |         ('billard', '0013_accounting'), | ||||||
|     ] |     ] | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ from django.db import migrations, models | |||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ('billard', '0014_auto_20170211_2008'), |         ('billard', '0014_auto_20170211_2008'), | ||||||
|     ] |     ] | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ from django.db import migrations, models | |||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ('billard', '0015_auto_20170222_1023'), |         ('billard', '0015_auto_20170222_1023'), | ||||||
|     ] |     ] | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ from django.db import migrations, models | |||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ('billard', '0016_auto_20170225_1822'), |         ('billard', '0016_auto_20170225_1822'), | ||||||
|     ] |     ] | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ from django.db import migrations, models | |||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ('billard', '0016_auto_20170225_1822'), |         ('billard', '0016_auto_20170225_1822'), | ||||||
|     ] |     ] | ||||||
|   | |||||||
| @@ -2,13 +2,12 @@ | |||||||
| # Generated by Django 1.10.5 on 2017-03-02 20:58 | # Generated by Django 1.10.5 on 2017-03-02 20:58 | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
|  |  | ||||||
|  | import django.db.models.deletion | ||||||
| from django.conf import settings | from django.conf import settings | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
| import django.db.models.deletion |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         migrations.swappable_dependency(settings.AUTH_USER_MODEL), |         migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||||||
|         ('billard', '0017_accounting_reporter_uuid'), |         ('billard', '0017_accounting_reporter_uuid'), | ||||||
| @@ -18,16 +17,20 @@ class Migration(migrations.Migration): | |||||||
|         migrations.AddField( |         migrations.AddField( | ||||||
|             model_name='accounting', |             model_name='accounting', | ||||||
|             name='prize_hh', |             name='prize_hh', | ||||||
|             field=models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True, verbose_name='Preis Happy Hour'), |             field=models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True, | ||||||
|  |                                       verbose_name='Preis Happy Hour'), | ||||||
|         ), |         ), | ||||||
|         migrations.AddField( |         migrations.AddField( | ||||||
|             model_name='accounting', |             model_name='accounting', | ||||||
|             name='prize_normal', |             name='prize_normal', | ||||||
|             field=models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True, verbose_name='Preis Normalzeit'), |             field=models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True, | ||||||
|  |                                       verbose_name='Preis Normalzeit'), | ||||||
|         ), |         ), | ||||||
|         migrations.AddField( |         migrations.AddField( | ||||||
|             model_name='client', |             model_name='client', | ||||||
|             name='report_user', |             name='report_user', | ||||||
|             field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reporting_clients', to=settings.AUTH_USER_MODEL, verbose_name='Reporting Benutzer'), |             field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, | ||||||
|  |                                     related_name='reporting_clients', to=settings.AUTH_USER_MODEL, | ||||||
|  |                                     verbose_name='Reporting Benutzer'), | ||||||
|         ), |         ), | ||||||
|     ] |     ] | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ from django.db import migrations | |||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ('billard', '0018_auto_20170302_2058'), |         ('billard', '0018_auto_20170302_2058'), | ||||||
|         ('billard', '0017_auto_20170302_1610'), |         ('billard', '0017_auto_20170302_1610'), | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ from __future__ import unicode_literals | |||||||
|  |  | ||||||
| from django.db import migrations | from django.db import migrations | ||||||
|  |  | ||||||
|  |  | ||||||
| def create_default_groups_permissions(apps, schema_editor): | def create_default_groups_permissions(apps, schema_editor): | ||||||
|     # We can't import the Person model directly as it may be a newer |     # We can't import the Person model directly as it may be a newer | ||||||
|     # version than this migration expects. We use the historical version. |     # version than this migration expects. We use the historical version. | ||||||
| @@ -16,6 +17,7 @@ def create_default_groups_permissions(apps, schema_editor): | |||||||
|     ag.save() |     ag.save() | ||||||
|     ag.permissions.add(Permission.objects.get(codename="change_accounting")) |     ag.permissions.add(Permission.objects.get(codename="change_accounting")) | ||||||
|  |  | ||||||
|  |  | ||||||
| def delete_default_groups_permissions(apps, schema_editor): | def delete_default_groups_permissions(apps, schema_editor): | ||||||
|     Group = apps.get_model("auth", "Group") |     Group = apps.get_model("auth", "Group") | ||||||
|     Group.objects.get(name='Location').delete() |     Group.objects.get(name='Location').delete() | ||||||
| @@ -23,7 +25,6 @@ def delete_default_groups_permissions(apps, schema_editor): | |||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ('billard', '0019_merge_20170310_1941'), |         ('billard', '0019_merge_20170310_1941'), | ||||||
|         ('sessions', '0001_initial'), |         ('sessions', '0001_initial'), | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ from django.db import migrations, models | |||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ('billard', '0020_auto_20170410_1853'), |         ('billard', '0020_auto_20170410_1853'), | ||||||
|     ] |     ] | ||||||
|   | |||||||
| @@ -2,12 +2,11 @@ | |||||||
| # Generated by Django 1.11 on 2017-04-27 08:35 | # Generated by Django 1.11 on 2017-04-27 08:35 | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
|  |  | ||||||
| from django.db import migrations, models |  | ||||||
| import django.db.models.deletion | import django.db.models.deletion | ||||||
|  | from django.db import migrations, models | ||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ('billard', '0021_accounting_account_user'), |         ('billard', '0021_accounting_account_user'), | ||||||
|     ] |     ] | ||||||
| @@ -16,6 +15,7 @@ class Migration(migrations.Migration): | |||||||
|         migrations.AlterField( |         migrations.AlterField( | ||||||
|             model_name='client', |             model_name='client', | ||||||
|             name='location', |             name='location', | ||||||
|             field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='clients', to='billard.Location', verbose_name='Standort'), |             field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='clients', | ||||||
|  |                                     to='billard.Location', verbose_name='Standort'), | ||||||
|         ), |         ), | ||||||
|     ] |     ] | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ from django.db import migrations, models | |||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ('billard', '0022_auto_20170427_0835'), |         ('billard', '0022_auto_20170427_0835'), | ||||||
|     ] |     ] | ||||||
|   | |||||||
| @@ -1,12 +1,11 @@ | |||||||
| # Generated by Django 2.0.2 on 2018-02-10 11:05 | # Generated by Django 2.0.2 on 2018-02-10 11:05 | ||||||
|  |  | ||||||
|  | import django.db.models.deletion | ||||||
| from django.conf import settings | from django.conf import settings | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
| import django.db.models.deletion |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ('billard', '0023_accounting_account_tst'), |         ('billard', '0023_accounting_account_tst'), | ||||||
|     ] |     ] | ||||||
| @@ -15,21 +14,26 @@ class Migration(migrations.Migration): | |||||||
|         migrations.AlterField( |         migrations.AlterField( | ||||||
|             model_name='accounting', |             model_name='accounting', | ||||||
|             name='desk', |             name='desk', | ||||||
|             field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='billard.Desk', verbose_name='Tisch'), |             field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='billard.Desk', | ||||||
|  |                                     verbose_name='Tisch'), | ||||||
|         ), |         ), | ||||||
|         migrations.AlterField( |         migrations.AlterField( | ||||||
|             model_name='client', |             model_name='client', | ||||||
|             name='location', |             name='location', | ||||||
|             field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='clients', to='billard.Location', verbose_name='Standort'), |             field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='clients', | ||||||
|  |                                     to='billard.Location', verbose_name='Standort'), | ||||||
|         ), |         ), | ||||||
|         migrations.AlterField( |         migrations.AlterField( | ||||||
|             model_name='client', |             model_name='client', | ||||||
|             name='report_user', |             name='report_user', | ||||||
|             field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='reporting_clients', to=settings.AUTH_USER_MODEL, verbose_name='Reporting Benutzer'), |             field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, | ||||||
|  |                                     related_name='reporting_clients', to=settings.AUTH_USER_MODEL, | ||||||
|  |                                     verbose_name='Reporting Benutzer'), | ||||||
|         ), |         ), | ||||||
|         migrations.AlterField( |         migrations.AlterField( | ||||||
|             model_name='desk', |             model_name='desk', | ||||||
|             name='client', |             name='client', | ||||||
|             field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='desks', to='billard.Client', verbose_name='Client'), |             field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='desks', | ||||||
|  |                                     to='billard.Client', verbose_name='Client'), | ||||||
|         ), |         ), | ||||||
|     ] |     ] | ||||||
|   | |||||||
							
								
								
									
										31
									
								
								billard/migrations/0025_auto_20180211_1059.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								billard/migrations/0025_auto_20180211_1059.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | |||||||
|  | # Generated by Django 2.0.2 on 2018-02-11 10:59 | ||||||
|  |  | ||||||
|  | import django.db.models.deletion | ||||||
|  | from django.db import migrations, models | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class Migration(migrations.Migration): | ||||||
|  |     dependencies = [ | ||||||
|  |         ('billard', '0024_auto_20180210_1105'), | ||||||
|  |     ] | ||||||
|  |  | ||||||
|  |     operations = [ | ||||||
|  |         migrations.AlterField( | ||||||
|  |             model_name='accounting', | ||||||
|  |             name='desk', | ||||||
|  |             field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='billard.Desk', | ||||||
|  |                                     verbose_name='Tisch'), | ||||||
|  |         ), | ||||||
|  |         migrations.AlterField( | ||||||
|  |             model_name='client', | ||||||
|  |             name='location', | ||||||
|  |             field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='clients', | ||||||
|  |                                     to='billard.Location', verbose_name='Standort'), | ||||||
|  |         ), | ||||||
|  |         migrations.AlterField( | ||||||
|  |             model_name='desk', | ||||||
|  |             name='client', | ||||||
|  |             field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='desks', | ||||||
|  |                                     to='billard.Client', verbose_name='Client'), | ||||||
|  |         ), | ||||||
|  |     ] | ||||||
							
								
								
									
										17
									
								
								billard/migrations/0026_client_last_seen.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								billard/migrations/0026_client_last_seen.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | # Generated by Django 2.0.2 on 2018-02-11 11:10 | ||||||
|  |  | ||||||
|  | from django.db import migrations, models | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class Migration(migrations.Migration): | ||||||
|  |     dependencies = [ | ||||||
|  |         ('billard', '0025_auto_20180211_1059'), | ||||||
|  |     ] | ||||||
|  |  | ||||||
|  |     operations = [ | ||||||
|  |         migrations.AddField( | ||||||
|  |             model_name='client', | ||||||
|  |             name='last_seen', | ||||||
|  |             field=models.DateTimeField(blank=True, null=True, verbose_name='Letzter Update'), | ||||||
|  |         ), | ||||||
|  |     ] | ||||||
| @@ -1,8 +1,9 @@ | |||||||
| import uuid |  | ||||||
| import logging | import logging | ||||||
|  | import uuid | ||||||
|  |  | ||||||
|  | from django.contrib.auth.models import User | ||||||
|  | from django.contrib.auth.models import User | ||||||
| from django.db import models | from django.db import models | ||||||
| from django.contrib.auth.models import User |  | ||||||
| from django.contrib.auth.models import User |  | ||||||
| from django.db.models.signals import post_save | from django.db.models.signals import post_save | ||||||
| from django.dispatch import receiver | from django.dispatch import receiver | ||||||
|  |  | ||||||
| @@ -48,8 +49,10 @@ class Location(models.Model): | |||||||
|  |  | ||||||
| class Client(models.Model): | class Client(models.Model): | ||||||
|     uuid = models.UUIDField(unique=True, default=uuid.uuid4, verbose_name="Identifier") |     uuid = models.UUIDField(unique=True, default=uuid.uuid4, verbose_name="Identifier") | ||||||
|     location = models.ForeignKey(Location, related_name="clients", verbose_name="Standort", on_delete=models.DO_NOTHING) |     location = models.ForeignKey(Location, related_name="clients", verbose_name="Standort", on_delete=models.CASCADE) | ||||||
|     report_user = models.ForeignKey(User, blank=True, null=True, verbose_name="Reporting Benutzer", related_name='reporting_clients', on_delete=models.DO_NOTHING) |     report_user = models.ForeignKey(User, blank=True, null=True, verbose_name="Reporting Benutzer", | ||||||
|  |                                     related_name='reporting_clients', on_delete=models.DO_NOTHING) | ||||||
|  |     last_seen = models.DateTimeField(blank=True, null=True, verbose_name="Letzter Update") | ||||||
|  |  | ||||||
|     def __str__(self): |     def __str__(self): | ||||||
|         return '{}, {}'.format(self.location.name, self.uuid) |         return '{}, {}'.format(self.location.name, self.uuid) | ||||||
| @@ -60,7 +63,7 @@ class Client(models.Model): | |||||||
|  |  | ||||||
|  |  | ||||||
| class Desk(models.Model): | class Desk(models.Model): | ||||||
|     client = models.ForeignKey(Client, verbose_name='Client', related_name='desks', on_delete=models.DO_NOTHING) |     client = models.ForeignKey(Client, verbose_name='Client', related_name='desks', on_delete=models.CASCADE) | ||||||
|     desk_no = models.IntegerField(verbose_name='Tischnummer') |     desk_no = models.IntegerField(verbose_name='Tischnummer') | ||||||
|     name = models.CharField(max_length=32, blank=True, null=True, verbose_name='Tischbezeichnung') |     name = models.CharField(max_length=32, blank=True, null=True, verbose_name='Tischbezeichnung') | ||||||
|     enabled = models.BooleanField(verbose_name='Tisch aktiv') |     enabled = models.BooleanField(verbose_name='Tisch aktiv') | ||||||
| @@ -77,14 +80,16 @@ class Desk(models.Model): | |||||||
|  |  | ||||||
|  |  | ||||||
| class Accounting(models.Model): | class Accounting(models.Model): | ||||||
|     desk = models.ForeignKey(Desk, verbose_name="Tisch", on_delete=models.DO_NOTHING) |     desk = models.ForeignKey(Desk, verbose_name="Tisch", on_delete=models.CASCADE) | ||||||
|     time_from = models.DateTimeField(verbose_name="Beginn") |     time_from = models.DateTimeField(verbose_name="Beginn") | ||||||
|     time_to = models.DateTimeField(blank=True, null=True, verbose_name="Ende") |     time_to = models.DateTimeField(blank=True, null=True, verbose_name="Ende") | ||||||
|     prize = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True, verbose_name="Preis") |     prize = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True, verbose_name="Preis") | ||||||
|     billed = models.BooleanField(default=False, verbose_name="Abgerechnet") |     billed = models.BooleanField(default=False, verbose_name="Abgerechnet") | ||||||
|     reporter_uuid = models.UUIDField(blank=True, null=True, verbose_name='Reporter UUID') |     reporter_uuid = models.UUIDField(blank=True, null=True, verbose_name='Reporter UUID') | ||||||
|     prize_normal = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True, verbose_name="Preis Normalzeit") |     prize_normal = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True, | ||||||
|     prize_hh = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True, verbose_name="Preis Happy Hour") |                                        verbose_name="Preis Normalzeit") | ||||||
|  |     prize_hh = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True, | ||||||
|  |                                    verbose_name="Preis Happy Hour") | ||||||
|     account_user = models.CharField(blank=True, null=True, max_length=128, verbose_name="Abr. Benutzer") |     account_user = models.CharField(blank=True, null=True, max_length=128, verbose_name="Abr. Benutzer") | ||||||
|     account_tst = models.DateTimeField(blank=True, null=True, verbose_name="Abr. TST") |     account_tst = models.DateTimeField(blank=True, null=True, verbose_name="Abr. TST") | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,8 +1,15 @@ | |||||||
| from billard.models import LocationData |  | ||||||
| from rest_framework import serializers | from rest_framework import serializers | ||||||
|  |  | ||||||
|  | from billard.models import LocationData, Client | ||||||
|  |  | ||||||
|  |  | ||||||
| class LocationDataSerializer(serializers.HyperlinkedModelSerializer): | class LocationDataSerializer(serializers.HyperlinkedModelSerializer): | ||||||
|     class Meta: |     class Meta: | ||||||
|         model = LocationData |         model = LocationData | ||||||
|         fields = ('client_id', 'desk_no', 'tst', 'on_off',) |         fields = ('client_id', 'desk_no', 'tst', 'on_off',) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class ClientUpdateLastSeenSerializer(serializers.HyperlinkedModelSerializer): | ||||||
|  |     class Meta: | ||||||
|  |         model = Client | ||||||
|  |         fields = ('uuid', 'last_seen') | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| from __future__ import absolute_import, unicode_literals | from __future__ import absolute_import, unicode_literals | ||||||
|  |  | ||||||
| import logging | import logging | ||||||
| import billard.utils as utils |  | ||||||
|  |  | ||||||
|  | import billard.utils as utils | ||||||
| from billard.models import LocationData, Client, Accounting | from billard.models import LocationData, Client, Accounting | ||||||
|  |  | ||||||
| log = logging.getLogger(__name__) | log = logging.getLogger(__name__) | ||||||
| @@ -58,7 +58,8 @@ def process_location_data(): | |||||||
|                         ld.delete() |                         ld.delete() | ||||||
|                     else: |                     else: | ||||||
|                         ld.processed = True |                         ld.processed = True | ||||||
|                         ld.error_msg = 'No existing accountings found. Stopp processing! {}, {}'.format(ld.client_id, ld.desk_no) |                         ld.error_msg = 'No existing accountings found. Stopp processing! {}, {}'.format(ld.client_id, | ||||||
|  |                                                                                                         ld.desk_no) | ||||||
|                         ld.save() |                         ld.save() | ||||||
|                         log.error(ld.error_msg) |                         log.error(ld.error_msg) | ||||||
|         except: |         except: | ||||||
|   | |||||||
| @@ -1,10 +1,10 @@ | |||||||
| {% extends "admin/change_list.html" %} | {% extends "admin/change_list.html" %} | ||||||
| {% load i18n admin_urls static admin_list %} | {% load i18n admin_urls static admin_list %} | ||||||
| {% block object-tools-items %} | {% block object-tools-items %} | ||||||
| <li> |     <li> | ||||||
|   <a href="{% url 'admin:process_locationdata' %}"> |         <a href="{% url 'admin:process_locationdata' %}"> | ||||||
|       LD Verarbeiten |             LD Verarbeiten | ||||||
|   </a> |         </a> | ||||||
| </li> |     </li> | ||||||
| {{ block.super }} |     {{ block.super }} | ||||||
| {% endblock %} | {% endblock %} | ||||||
| @@ -4,9 +4,9 @@ | |||||||
| {% block title %}Abrechnung{% endblock %} | {% block title %}Abrechnung{% endblock %} | ||||||
|  |  | ||||||
| {% block breadcrumb %} | {% block breadcrumb %} | ||||||
|   <li class="breadcrumb-item"><a href="{% url 'billard:location_index' %}">Standorte</a></li> |     <li class="breadcrumb-item"><a href="{% url 'billard:location_index' %}">Standorte</a></li> | ||||||
|   <li class="breadcrumb-item"><a href="{% url 'billard:location_detail' location.id %}">{{ location.code }}</a></li> |     <li class="breadcrumb-item"><a href="{% url 'billard:location_detail' location.id %}">{{ location.code }}</a></li> | ||||||
|   <li class="breadcrumb-item active">Abrechnung</li> |     <li class="breadcrumb-item active">Abrechnung</li> | ||||||
| {% endblock %} | {% endblock %} | ||||||
|  |  | ||||||
| {% block content %} | {% block content %} | ||||||
| @@ -23,19 +23,19 @@ | |||||||
|             <th>Preis Happy Hour:</th> |             <th>Preis Happy Hour:</th> | ||||||
|             <th>Preis gesamt:</th> |             <th>Preis gesamt:</th> | ||||||
|         </tr> |         </tr> | ||||||
| {% for acc in accounting %} |         {% for acc in accounting %} | ||||||
|         <tr> |             <tr> | ||||||
|             <td>{{ acc.time_from }}</td> |                 <td>{{ acc.time_from }}</td> | ||||||
|             <td>{{ acc.time_to }}</td> |                 <td>{{ acc.time_to }}</td> | ||||||
|             <td>{{ acc.prize_normal }}</td> |                 <td>{{ acc.prize_normal }}</td> | ||||||
|             <td>{{ acc.prize_hh }}</td> |                 <td>{{ acc.prize_hh }}</td> | ||||||
|             <td>{{ acc.prize }}</td> |                 <td>{{ acc.prize }}</td> | ||||||
|         </tr> |             </tr> | ||||||
| {% endfor %} |         {% endfor %} | ||||||
|     </table> |     </table> | ||||||
|  |  | ||||||
|     <form action="confirm/" method="post" id="accounting"> |     <form action="confirm/" method="post" id="accounting"> | ||||||
| {% csrf_token %} |         {% csrf_token %} | ||||||
|         <input type="hidden" name="location-selector" value="{{ location_id }}"> |         <input type="hidden" name="location-selector" value="{{ location_id }}"> | ||||||
|         <input type="hidden" name="accountings" value="{{ acc_ids }}"> |         <input type="hidden" name="accountings" value="{{ acc_ids }}"> | ||||||
|         <button type="submit" class="btn btn-default">Abrechnen</button> |         <button type="submit" class="btn btn-default">Abrechnen</button> | ||||||
|   | |||||||
| @@ -1,36 +1,37 @@ | |||||||
| {% if accounts %} | {% if accounts %} | ||||||
| <div id="accountsmodal" class="modal" tabindex="-1" role="dialog"> |     <div id="accountsmodal" class="modal" tabindex="-1" role="dialog"> | ||||||
|   <div class="modal-dialog" role="document"> |         <div class="modal-dialog" role="document"> | ||||||
|     <div class="modal-content"> |             <div class="modal-content"> | ||||||
|       <div class="modal-header"> |                 <div class="modal-header"> | ||||||
|         <h4 class="modal-title">Abrechnung</h4> |                     <h4 class="modal-title">Abrechnung</h4> | ||||||
|       </div> |                 </div> | ||||||
|       <div class="modal-body"> |                 <div class="modal-body"> | ||||||
|         <table class="table table-striped"> |                     <table class="table table-striped"> | ||||||
|             <thead> |                         <thead> | ||||||
|             <tr> |                         <tr> | ||||||
|                 <td>Tisch #</td> |                             <td>Tisch #</td> | ||||||
|                 <td>Tisch Name</td> |                             <td>Tisch Name</td> | ||||||
|                 <td class="text-right">Normalpreis</td> |                             <td class="text-right">Normalpreis</td> | ||||||
|                 <td class="text-right">Preis HH</td> |                             <td class="text-right">Preis HH</td> | ||||||
|                 <td class="text-right">Gesamt</td> |                             <td class="text-right">Gesamt</td> | ||||||
|             </tr> |                         </tr> | ||||||
|             </thead> |                         </thead> | ||||||
|             {% for account in accounts %} |                         {% for account in accounts %} | ||||||
|           <tr> |                             <tr> | ||||||
|               <td>{{ account.desk.desk_no }}</td> |                                 <td>{{ account.desk.desk_no }}</td> | ||||||
|               <td>{{ account.desk.name }}</td> |                                 <td>{{ account.desk.name }}</td> | ||||||
|               <td class="text-right">{{ account.prize_normal }}</td> |                                 <td class="text-right">{{ account.prize_normal }}</td> | ||||||
|               <td class="text-right">{{ account.prize_hh }}</td> |                                 <td class="text-right">{{ account.prize_hh }}</td> | ||||||
|               <td class="text-right"><strong>{{ account.prize }}</strong></td> |                                 <td class="text-right"><strong>{{ account.prize }}</strong></td> | ||||||
|           </tr> |                             </tr> | ||||||
|             {% endfor %} |                         {% endfor %} | ||||||
|         </table> |                     </table> | ||||||
|       </div> |                 </div> | ||||||
|       <div class="modal-footer"> |                 <div class="modal-footer"> | ||||||
|         <a class="btn btn-default btn-primary" href="{% url 'billard:account_modal_confirm' pks=pks loc_pk=loc_pk %}">Schliessen</a> |                     <a class="btn btn-default btn-primary" | ||||||
|       </div> |                        href="{% url 'billard:account_modal_confirm' pks=pks loc_pk=loc_pk %}">Schliessen</a> | ||||||
|     </div><!-- /.modal-content --> |                 </div> | ||||||
|   </div><!-- /.modal-dialog --> |             </div><!-- /.modal-content --> | ||||||
| </div><!-- /.modal --> |         </div><!-- /.modal-dialog --> | ||||||
|  |     </div><!-- /.modal --> | ||||||
| {% endif %} | {% endif %} | ||||||
| @@ -4,24 +4,25 @@ | |||||||
| {% block title %}Location Data{% endblock %} | {% block title %}Location Data{% endblock %} | ||||||
|  |  | ||||||
| {% block content %} | {% block content %} | ||||||
| {% if not locations|length_is:"1" %} |     {% if not locations|length_is:"1" %} | ||||||
|     <form action="." method="post" id="location-form"> |         <form action="." method="post" id="location-form"> | ||||||
| {% csrf_token %} |             {% csrf_token %} | ||||||
|         <div id="location-selector" class="alert"> |             <div id="location-selector" class="alert"> | ||||||
|             <select class="form-control" form="location-form" name="location-selector" id="location-select"> |                 <select class="form-control" form="location-form" name="location-selector" id="location-select"> | ||||||
| {% for loc in locations %} |                     {% for loc in locations %} | ||||||
|                 <option value="{{ loc.id }}"{%  if loc.id == location_id %} selected{% endif %}>{{ loc.code }} - {{ loc.name }}</option> |                         <option value="{{ loc.id }}"{% if loc.id == location_id %} selected{% endif %}>{{ loc.code }} | ||||||
| {% endfor %} |                             - {{ loc.name }}</option> | ||||||
|             </select> |                     {% endfor %} | ||||||
|         </div> |                 </select> | ||||||
|     </form> |             </div> | ||||||
| {% endif %} |         </form> | ||||||
|  |     {% endif %} | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     <div id="desk_data"> |     <div id="desk_data"> | ||||||
| {% include 'billard/index_ajax.html' %} |         {% include 'billard/index_ajax.html' %} | ||||||
|     </div> |     </div> | ||||||
|     <div id="modal-wrapper"> |     <div id="modal-wrapper"> | ||||||
|     </div> |     </div> | ||||||
| @@ -29,20 +30,20 @@ | |||||||
|  |  | ||||||
| {% block js %} | {% block js %} | ||||||
|     <script type="text/javascript"> |     <script type="text/javascript"> | ||||||
|     var interval; |         var interval; | ||||||
| $(document).ready(function() { |         $(document).ready(function () { | ||||||
|     $.ajaxSetup({ cache: false }); |             $.ajaxSetup({cache: false}); | ||||||
|     interval = window.setInterval(refresh_page, 1000); |             interval = window.setInterval(refresh_page, 1000); | ||||||
| }); |         }); | ||||||
|  |  | ||||||
| function refresh_page() { |         function refresh_page() { | ||||||
|     $('#desk_data').load('#'); |             $('#desk_data').load('#'); | ||||||
|     $('#modal-wrapper').load('{% url 'accountmodal' %}', function() { |             $('#modal-wrapper').load('{% url 'accountmodal' %}', function () { | ||||||
|         if ( $('#accountsmodal').length ) { |                 if ($('#accountsmodal').length) { | ||||||
|             window.clearInterval(interval); |                     window.clearInterval(interval); | ||||||
|             $('#accountsmodal').modal('show'); |                     $('#accountsmodal').modal('show'); | ||||||
|  |                 } | ||||||
|  |             }); | ||||||
|         } |         } | ||||||
|     }); |     </script> | ||||||
| } |  | ||||||
| </script> |  | ||||||
| {% endblock %} | {% endblock %} | ||||||
|   | |||||||
| @@ -1,10 +1,10 @@ | |||||||
| {% load display_client %} | {% load display_client %} | ||||||
| {% if clients %} | {% if clients %} | ||||||
| {% for cli in clients %} |     {% for cli in clients %} | ||||||
| {% for i in range %} {{ cli|display_client:i }} {% endfor %} |         {% for i in range %} {{ cli|display_client:i }} {% endfor %} | ||||||
| {% endfor %} |     {% endfor %} | ||||||
| {% else %} | {% else %} | ||||||
| <div class="col-md-12"> |     <div class="col-md-12"> | ||||||
|     <div class="col-md-12 alert alert-danger">Keine Tische angelegt!</div> |         <div class="col-md-12 alert alert-danger">Keine Tische angelegt!</div> | ||||||
| </div> |     </div> | ||||||
| {% endif %} | {% endif %} | ||||||
| @@ -11,6 +11,14 @@ | |||||||
|     <div id="desk_data" class="row"> |     <div id="desk_data" class="row"> | ||||||
|         {% include 'billard/location_detail_ajax.html' %} |         {% include 'billard/location_detail_ajax.html' %} | ||||||
|     </div> |     </div> | ||||||
|  |     <div class="row"> | ||||||
|  |         <div class="col"> | ||||||
|  |             {% if perms.billard.change_accounting %} | ||||||
|  |                 <a href="{% url 'billard:accounting_detail' location.id %}" | ||||||
|  |                    class="btn btn-outline-danger btn-sm">Abrechnen</a> | ||||||
|  |             {% endif %} | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|     <div id="modal-wrapper"> |     <div id="modal-wrapper"> | ||||||
|     </div> |     </div> | ||||||
| {% endblock %} | {% endblock %} | ||||||
|   | |||||||
| @@ -1,12 +1,12 @@ | |||||||
| {% load display_client %} | {% load display_client %} | ||||||
| {% if location.clients.all %} | {% if location.clients.all %} | ||||||
| {% for cli in location.clients.all %} |     {% for cli in location.clients.all %} | ||||||
| {% for i in "12345678" %} |         {% for i in "12345678" %} | ||||||
|     {{ cli|display_client:i }} |             {{ cli|display_client:i }} | ||||||
| {% endfor %} |         {% endfor %} | ||||||
| {% endfor %} |     {% endfor %} | ||||||
| {% else %} | {% else %} | ||||||
| <div class="col"> |     <div class="col"> | ||||||
|     <div class="alert alert-danger">Keine Tische angelegt!</div> |         <div class="alert alert-danger">Keine Tische angelegt!</div> | ||||||
| </div> |     </div> | ||||||
| {% endif %} | {% endif %} | ||||||
|   | |||||||
| @@ -3,39 +3,41 @@ | |||||||
| {% block title %}Standortliste{% endblock %} | {% block title %}Standortliste{% endblock %} | ||||||
|  |  | ||||||
| {% block breadcrumb %} | {% block breadcrumb %} | ||||||
|   <li class="breadcrumb-item active">Standorte</li> |     <li class="breadcrumb-item active">Standorte</li> | ||||||
| {% endblock %} | {% endblock %} | ||||||
|  |  | ||||||
| {% block content %} | {% block content %} | ||||||
|  |  | ||||||
| {% if location_list %} |     {% if location_list %} | ||||||
|     <h2>Bitte Standort auswählen:</h2> |         <h2>Bitte Standort auswählen:</h2> | ||||||
|     <table class="table table-hover"> |         <table class="table table-hover"> | ||||||
|         <tr> |             <tr> | ||||||
|             <th>Code</th> |                 <th>Code</th> | ||||||
|             <th>Name</th> |                 <th>Name</th> | ||||||
|             <th>Strasse</th> |                 <th>Strasse</th> | ||||||
|             <th>Plz</th> |                 <th>Plz</th> | ||||||
|             <th>Ort</th> |                 <th>Ort</th> | ||||||
| {% if perms.billard.change_accounting %} |                 {% if perms.billard.change_accounting %} | ||||||
|             <th>Accounting</th> |                     <th>Accounting</th> | ||||||
| {% endif %} |                 {% endif %} | ||||||
|         </tr> |             </tr> | ||||||
| {% for loc in location_list %} |             {% for loc in location_list %} | ||||||
|         <tr> |                 <tr> | ||||||
|             <td><a href="{% url 'billard:location_detail' loc.id %}" class="btn btn-primary">{{ loc.code|default_if_none:"" }}</a></td> |                     <td><a href="{% url 'billard:location_detail' loc.id %}" | ||||||
|             <td>{{ loc.name|default_if_none:"" }}</td> |                            class="btn btn-outline-primary btn-sm">{{ loc.code|default_if_none:"" }}</a></td> | ||||||
|             <td>{{ loc.street|default_if_none:"" }}</td> |                     <td>{{ loc.name|default_if_none:"" }}</td> | ||||||
|             <td>{{ loc.plz|default_if_none:"" }}</td> |                     <td>{{ loc.street|default_if_none:"" }}</td> | ||||||
|             <td>{{ loc.city|default_if_none:"" }}</td> |                     <td>{{ loc.plz|default_if_none:"" }}</td> | ||||||
| {% if perms.billard.change_accounting %} |                     <td>{{ loc.city|default_if_none:"" }}</td> | ||||||
|             <td><a href="{% url 'billard:accounting_detail' loc.id %}" class="btn btn-primary">Abrechnen</a></td> |                     {% if perms.billard.change_accounting %} | ||||||
| {% endif %} |                         <td><a href="{% url 'billard:accounting_detail' loc.id %}" | ||||||
|         </tr> |                                class="btn btn-outline-danger btn-sm">Abrechnen</a></td> | ||||||
| {% endfor %} |                     {% endif %} | ||||||
|     </table> |                 </tr> | ||||||
| {% else %} |             {% endfor %} | ||||||
|     <p>Keine Standorte Zugeordnet.</p> |         </table> | ||||||
| {% endif %} |     {% else %} | ||||||
|  |         <p>Keine Standorte Zugeordnet.</p> | ||||||
|  |     {% endif %} | ||||||
|  |  | ||||||
| {% endblock %} | {% endblock %} | ||||||
|   | |||||||
| @@ -3,13 +3,15 @@ | |||||||
| {% block title %}Location Data{% endblock %} | {% block title %}Location Data{% endblock %} | ||||||
|  |  | ||||||
| {% block content %} | {% block content %} | ||||||
|    {% include 'billard/locationdata_detail_ajax.html' %} |     {% include 'billard/locationdata_detail_ajax.html' %} | ||||||
| {% endblock %} | {% endblock %} | ||||||
|  |  | ||||||
| {% block js %} | {% block js %} | ||||||
|     <script type="text/javascript"> |     <script type="text/javascript"> | ||||||
| $( document ).ready(function() { |         $(document).ready(function () { | ||||||
| setInterval(function(){$( "#content" ).load( "#")},1000); |             setInterval(function () { | ||||||
| }); |                 $("#content").load("#") | ||||||
| </script> |             }, 1000); | ||||||
|  |         }); | ||||||
|  |     </script> | ||||||
| {% endblock %} | {% endblock %} | ||||||
| @@ -3,13 +3,15 @@ | |||||||
| {% block title %}Location Data{% endblock %} | {% block title %}Location Data{% endblock %} | ||||||
|  |  | ||||||
| {% block content %} | {% block content %} | ||||||
| {% include 'billard/locationdata_list_ajax.html' %} |     {% include 'billard/locationdata_list_ajax.html' %} | ||||||
| {% endblock %} | {% endblock %} | ||||||
|  |  | ||||||
| {% block js %} | {% block js %} | ||||||
|     <script type="text/javascript"> |     <script type="text/javascript"> | ||||||
| $( document ).ready(function() { |         $(document).ready(function () { | ||||||
| setInterval(function(){$( "#content" ).load( "#")},1000); |             setInterval(function () { | ||||||
| }); |                 $("#content").load("#") | ||||||
| </script> |             }, 1000); | ||||||
|  |         }); | ||||||
|  |     </script> | ||||||
| {% endblock %} | {% endblock %} | ||||||
| @@ -10,33 +10,33 @@ | |||||||
|         </select> |         </select> | ||||||
|     </div> |     </div> | ||||||
|  |  | ||||||
| {% if object_list %} |     {% if object_list %} | ||||||
|     <h1>Location Data</h1> |         <h1>Location Data</h1> | ||||||
|     <table class="table table-hover"> |         <table class="table table-hover"> | ||||||
|         <tr> |             <tr> | ||||||
|             <th>ID</th> |                 <th>ID</th> | ||||||
|             <th>Location</th> |                 <th>Location</th> | ||||||
|             <th>Table</th> |                 <th>Table</th> | ||||||
|             <th>Timestamp</th> |                 <th>Timestamp</th> | ||||||
|             <th>On_Off</th> |                 <th>On_Off</th> | ||||||
|             <th>Proc</th> |                 <th>Proc</th> | ||||||
|             <th>Error</th> |                 <th>Error</th> | ||||||
|         </tr> |             </tr> | ||||||
|     {% for location_data in object_list %} |             {% for location_data in object_list %} | ||||||
|         <tr> |                 <tr> | ||||||
|             <td><a href="{% url 'detail' location_data.id %}">{{ location_data.id }}</a></td> |                     <td><a href="{% url 'detail' location_data.id %}">{{ location_data.id }}</a></td> | ||||||
|             <td>{{ location_data.location_id }}</td> |                     <td>{{ location_data.location_id }}</td> | ||||||
|             <td>{{ location_data.table_no }}</td> |                     <td>{{ location_data.table_no }}</td> | ||||||
|             <td>{{ location_data.tst }}</td> |                     <td>{{ location_data.tst }}</td> | ||||||
|             <td>{{ location_data.on_off }}</td> |                     <td>{{ location_data.on_off }}</td> | ||||||
|             <td>{{ location_data.processed }}</td> |                     <td>{{ location_data.processed }}</td> | ||||||
|             <td>{{ location_data.error_msg }}</td> |                     <td>{{ location_data.error_msg }}</td> | ||||||
|         </tr> |                 </tr> | ||||||
|     {% endfor %} |             {% endfor %} | ||||||
|     </table> |         </table> | ||||||
| {% else %} |     {% else %} | ||||||
|     <p>No data available.</p> |         <p>No data available.</p> | ||||||
| {% endif %} |     {% endif %} | ||||||
| {% endblock %} | {% endblock %} | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,7 +1,9 @@ | |||||||
|  | from datetime import datetime, timedelta | ||||||
|  |  | ||||||
| from django import template | from django import template | ||||||
| from django.utils.html import format_html | from django.utils.html import format_html | ||||||
|  |  | ||||||
| from billard import utils | from billard import utils | ||||||
| from datetime import datetime |  | ||||||
|  |  | ||||||
| register = template.Library() | register = template.Library() | ||||||
|  |  | ||||||
| @@ -32,19 +34,22 @@ def display_client(client, desk_no): | |||||||
|             prize = '{0:.2f}'.format(prize) |             prize = '{0:.2f}'.format(prize) | ||||||
|             if prize != a.prize: |             if prize != a.prize: | ||||||
|                 a.prize = prize |                 a.prize = prize | ||||||
|     html = '<div class="col col-md-6">\n' |     before5min = datetime.now() - timedelta(minutes=5) | ||||||
|  |     if client.last_seen is not None and client.last_seen < before5min: | ||||||
|  |         alert = 'alert-danger' | ||||||
|  |     html = '<div class="col col-12 col-lg-6">\n' | ||||||
|     html += '    <div class="table-info alert {}">\n'.format(alert) |     html += '    <div class="table-info alert {}">\n'.format(alert) | ||||||
|     html += '        <h4 style="text-align: center">({}) {}</h4>\n'.format(desk_no, desk.name) |     html += '        <h4 style="text-align: center">({}) {}</h4>\n'.format(desk_no, desk.name) | ||||||
|     if loc.happy_hour_start is not None and desk.prize_hh is not None: |     if loc.happy_hour_start is not None and desk.prize_hh is not None: | ||||||
|         html += '        <h6 style="text-align: center">Preis: {:.2f} € / Stunde | {} - {}: {:.2f} / € Stunde</h6>\n'\ |         html += '        <h6 style="text-align: center">Preis: {:.2f} € / Stunde | {} - {}: {:.2f} / € Stunde</h6>\n' \ | ||||||
|             .format( |             .format( | ||||||
|                 desk.prize, |             desk.prize, | ||||||
|                 loc.happy_hour_start.strftime('%H:%M'), |             loc.happy_hour_start.strftime('%H:%M'), | ||||||
|                 loc.happy_hour_end.strftime('%H:%M'), |             loc.happy_hour_end.strftime('%H:%M'), | ||||||
|                 desk.prize_hh,) |             desk.prize_hh, ) | ||||||
|     else: |     else: | ||||||
|         html += '        <h6 style="text-align: center">Preis: {0:.2f} / Stunde</h6>\n'.format( |         html += '        <h6 style="text-align: center">Preis: {0:.2f} / Stunde</h6>\n'.format( | ||||||
|             desk.prize,) |             desk.prize, ) | ||||||
|     if len(acc) > 0: |     if len(acc) > 0: | ||||||
|         html += '        <table class="table">\n' |         html += '        <table class="table">\n' | ||||||
|         for a in acc: |         for a in acc: | ||||||
| @@ -52,7 +57,7 @@ def display_client(client, desk_no): | |||||||
|             html += '                <td>{}</td>\n'.format(a.time_from.strftime('%d.%m.%Y %H:%M:%S')) |             html += '                <td>{}</td>\n'.format(a.time_from.strftime('%d.%m.%Y %H:%M:%S')) | ||||||
|             html += '                <td>{}</td>\n'.format( |             html += '                <td>{}</td>\n'.format( | ||||||
|                 (a.time_to.strftime('%d.%m.%Y %H:%M:%S') if a.time_to is not None else '')) |                 (a.time_to.strftime('%d.%m.%Y %H:%M:%S') if a.time_to is not None else '')) | ||||||
|             html += '                <td style="text-align: center;">{}</td>\n'\ |             html += '                <td style="text-align: center;">{}</td>\n' \ | ||||||
|                 .format((a.prize if a.prize is not None else '')) |                 .format((a.prize if a.prize is not None else '')) | ||||||
|             html += '            <tr>\n' |             html += '            <tr>\n' | ||||||
|             html += '            <tr>\n' |             html += '            <tr>\n' | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| from django import template | from django import template | ||||||
|  | from django.conf import settings | ||||||
|  |  | ||||||
| register = template.Library() | register = template.Library() | ||||||
|  |  | ||||||
| @@ -17,3 +18,8 @@ def input_class(bound_field): | |||||||
|         elif field_type(bound_field) != 'PasswordInput': |         elif field_type(bound_field) != 'PasswordInput': | ||||||
|             css_class = 'is-valid' |             css_class = 'is-valid' | ||||||
|     return 'form-control {}'.format(css_class) |     return 'form-control {}'.format(css_class) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @register.simple_tag | ||||||
|  | def settings_value(name): | ||||||
|  |     return getattr(settings, name, '') | ||||||
|   | |||||||
| @@ -38,7 +38,7 @@ class PrizeCalculationTestCase(TestCase): | |||||||
|  |  | ||||||
|  |  | ||||||
| class PrizeGetTestCase(TestCase): | class PrizeGetTestCase(TestCase): | ||||||
|     def get_prize_for(self, start, end, pph=0, hh_start=None, hh_end=None, pphh=0, expected=(0,0,0)): |     def get_prize_for(self, start, end, pph=0, hh_start=None, hh_end=None, pphh=0, expected=(0, 0, 0)): | ||||||
|         self.assertEqual(get_prize_for(start, end, pph, hh_start, hh_end, pphh), expected) |         self.assertEqual(get_prize_for(start, end, pph, hh_start, hh_end, pphh), expected) | ||||||
|  |  | ||||||
|     def test_gpf_1(self): |     def test_gpf_1(self): | ||||||
|   | |||||||
| @@ -1,28 +1,30 @@ | |||||||
| from django.conf.urls import url, include | from django.conf.urls import include | ||||||
| from django.contrib.auth.decorators import login_required | from django.contrib.auth.decorators import login_required | ||||||
|  | from django.urls import path | ||||||
| from rest_framework import routers | from rest_framework import routers | ||||||
|  |  | ||||||
| from billard import views | from billard import views | ||||||
|  |  | ||||||
| router = routers.DefaultRouter() | router = routers.DefaultRouter() | ||||||
| router.register(r'locationdata', views.LocationDataViewSet) | router.register(r'locationdata', views.LocationDataViewSet) | ||||||
|  | router.register(r'last_seen', views.ClientUpdateLastSeenViewSet) | ||||||
|  |  | ||||||
| app_name = 'billard' | app_name = 'billard' | ||||||
| urlpatterns = [ | urlpatterns = [ | ||||||
|     # ex. /billard/ |     # ex. /billard/ | ||||||
|     url(r'^$', login_required(views.LocationIndexView.as_view()), name='location_index'), |     path('', login_required(views.LocationIndexView.as_view()), name='location_index'), | ||||||
|     # ex. /billard/1/ |     # ex. /billard/1/ | ||||||
|     url(r'^(?P<pk>[0-9]+)/$', login_required(views.LocationDetailView.as_view()), name='location_detail'), |     path('<int:pk>/', login_required(views.LocationDetailView.as_view()), name='location_detail'), | ||||||
|     # ex. /billard/1/accounting/ |     # ex. /billard/1/accounting/ | ||||||
|     url(r'^(?P<pk>[0-9]+)/accounting/$', views.AccountingView.as_view(), name='accounting_detail'), |     path('<int:pk>/accounting/', views.AccountingView.as_view(), name='accounting_detail'), | ||||||
|     # ex. /billard/1/accounting/confirm |     # ex. /billard/1/accounting/confirm | ||||||
|     url(r'^(?P<pk>[0-9]+)/accounting/confirm/$', views.accounting_confirm, name='accounting_detail_confirm'), |     path('<int:pk>/accounting/confirm/', views.accounting_confirm, name='accounting_detail_confirm'), | ||||||
|     # ex. /billard/1/account_modal/ |     # ex. /billard/1/account_modal/ | ||||||
|     url(r'^(?P<loc_pk>[0-9]+)/account_modal/$', views.account_modal_view, name='account_modal'), |     path('<int:loc_pk>/account_modal/', views.account_modal_view, name='account_modal'), | ||||||
|     # ex. /billard/1/account_modal/confirm/ |     # ex. /billard/1/account_modal/confirm/ | ||||||
|     url(r'^(?P<loc_pk>[0-9]+)/account_modal/(?P<pks>[0-9]+(,[0-9]+)*)/confirm/$', views.account_modal_confirm_view, |     path('<int:loc_pk>/account_modal/<pks>/confirm/', views.account_modal_confirm_view, name='account_modal_confirm'), | ||||||
|         name='account_modal_confirm'), |  | ||||||
|     # ex. /billard/api/v1/ (rest api) |     # ex. /billard/api/v1/ (rest api) | ||||||
|     url(r'api/v1/', include(router.urls)), |     path('api/v1/', include(router.urls)), | ||||||
|     # ex. /billard/process_location_data/ |     # ex. /billard/process_location_data/ | ||||||
|     url(r'^process_location_data/$', views.process_location_data, name='process_location_data'), |     path('process_location_data/', views.process_location_data, name='process_location_data'), | ||||||
| ] | ] | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| from datetime import datetime, date, time, timedelta | from datetime import datetime, date, timedelta | ||||||
|  |  | ||||||
|  |  | ||||||
| def get_prize_for(start, end, pph=0, hh_start=None, hh_end=None, pphh=0): | def get_prize_for(start, end, pph=0, hh_start=None, hh_end=None, pphh=0): | ||||||
|   | |||||||
| @@ -1,18 +1,18 @@ | |||||||
| import ast | import ast | ||||||
| import logging | import logging | ||||||
|  |  | ||||||
| from billard.serializers import LocationDataSerializer |  | ||||||
| from billard.models import LocationData, Location, Client, Accounting |  | ||||||
| from billard.tasks import process_location_data |  | ||||||
| from rest_framework import viewsets |  | ||||||
| from django.shortcuts import render, redirect |  | ||||||
| from django.views import generic |  | ||||||
| from django.contrib.auth.decorators import login_required, permission_required | from django.contrib.auth.decorators import login_required, permission_required | ||||||
| from django.db.models import Sum | from django.db.models import Sum | ||||||
| from django.http import HttpResponse | from django.http import HttpResponse | ||||||
| from django.utils.decorators import method_decorator | from django.shortcuts import render, redirect | ||||||
| from django.utils import timezone | from django.utils import timezone | ||||||
|  | from django.utils.decorators import method_decorator | ||||||
|  | from django.views import generic | ||||||
|  | from rest_framework import viewsets | ||||||
|  |  | ||||||
|  | from billard.models import LocationData, Location, Client, Accounting | ||||||
|  | from billard.serializers import LocationDataSerializer, ClientUpdateLastSeenSerializer | ||||||
|  | from billard.tasks import process_location_data | ||||||
|  |  | ||||||
| log = logging.getLogger(__name__) | log = logging.getLogger(__name__) | ||||||
|  |  | ||||||
| @@ -47,7 +47,7 @@ class AccountingView(generic.ListView): | |||||||
|     context_object_name = 'accounting' |     context_object_name = 'accounting' | ||||||
|  |  | ||||||
|     def get_queryset(self): |     def get_queryset(self): | ||||||
|         return Accounting.objects.filter(billed=False).filter(desk__client__location_id=self.kwargs['pk'])\ |         return Accounting.objects.filter(billed=False).filter(desk__client__location_id=self.kwargs['pk']) \ | ||||||
|             .exclude(time_to__isnull=True).order_by('time_from') |             .exclude(time_to__isnull=True).order_by('time_from') | ||||||
|  |  | ||||||
|     def dispatch(self, request, *args, **kwargs): |     def dispatch(self, request, *args, **kwargs): | ||||||
| @@ -108,6 +108,11 @@ class LocationDataViewSet(viewsets.ModelViewSet): | |||||||
|     serializer_class = LocationDataSerializer |     serializer_class = LocationDataSerializer | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class ClientUpdateLastSeenViewSet(viewsets.ModelViewSet): | ||||||
|  |     queryset = LocationData.objects.all() | ||||||
|  |     serializer_class = ClientUpdateLastSeenSerializer | ||||||
|  |  | ||||||
|  |  | ||||||
| def process_location_data(request): | def process_location_data(request): | ||||||
|     process_location_data() |     process_location_data() | ||||||
|     return HttpResponse('DONE') |     return HttpResponse('DONE') | ||||||
|   | |||||||
							
								
								
									
										33
									
								
								caromserver/local_settings_example.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								caromserver/local_settings_example.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | |||||||
|  | import os | ||||||
|  |  | ||||||
|  | SECRET_KEY = '@-9++2z_6%^vr(f0wax0aq8-pd@0u$*))w!5l^sv#wxrn7k!v-' | ||||||
|  | DEBUG = True | ||||||
|  | ALLOWED_HOSTS = ['carom-dev.einsle.de'] | ||||||
|  | ADMINS = [('Robert Einsle', 'robert@einsle.de'),] | ||||||
|  |  | ||||||
|  | DATABASES = { | ||||||
|  |     'default': { | ||||||
|  |         'ENGINE': 'django.db.backends.mysql', | ||||||
|  |         'NAME': 'carom-dev', | ||||||
|  |         'USER': 'carom-dev', | ||||||
|  |         'PASSWORD': 'jex290bjDB4djf0iVKYs', | ||||||
|  |         'HOST': '127.0.0.1', | ||||||
|  |         'OPTIONS': { | ||||||
|  |             'init_command': "SET sql_mode='STRICT_TRANS_TABLES'" | ||||||
|  |             }, | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | STATIC_ROOT = "/srv/carom-dev/carom-server/staticfiles/" | ||||||
|  |  | ||||||
|  | EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' | ||||||
|  | EMAIL_HOST = 'mail.einsle.de' | ||||||
|  | EMAIL_PORT = 587 | ||||||
|  | EMAIL_HOST_USER = 'relay@einsle.de' | ||||||
|  | EMAIL_HOST_PASSWORD = 'Boaghi0thaiH' | ||||||
|  | EMAIL_USE_TLS = True | ||||||
|  | DEFAULT_FROM_EMAIL = "webmaster@einsle.de" | ||||||
|  |  | ||||||
|  | URL_LOCATION_PROCESSOR = 'https://carom-dev.einsle.de/billard/process_locationdata' | ||||||
|  |  | ||||||
|  | PRODUCT_INFO = 'carom-dev' | ||||||
| @@ -37,14 +37,15 @@ INSTALLED_APPS = [ | |||||||
|     'django.contrib.staticfiles', |     'django.contrib.staticfiles', | ||||||
|     'rest_framework', |     'rest_framework', | ||||||
|     'rest_framework.authtoken', |     'rest_framework.authtoken', | ||||||
|  |     'debug_toolbar', | ||||||
|     'crispy_forms', |     'crispy_forms', | ||||||
|     'widget_tweaks', |  | ||||||
|     'billard', |     'billard', | ||||||
| ] | ] | ||||||
|  |  | ||||||
| MIDDLEWARE = [ | MIDDLEWARE = [ | ||||||
|     'django.middleware.security.SecurityMiddleware', |     'django.middleware.security.SecurityMiddleware', | ||||||
|     'django.contrib.sessions.middleware.SessionMiddleware', |     'django.contrib.sessions.middleware.SessionMiddleware', | ||||||
|  |     'debug_toolbar.middleware.DebugToolbarMiddleware', | ||||||
|     'django.middleware.common.CommonMiddleware', |     'django.middleware.common.CommonMiddleware', | ||||||
|     'django.middleware.csrf.CsrfViewMiddleware', |     'django.middleware.csrf.CsrfViewMiddleware', | ||||||
|     'django.contrib.auth.middleware.AuthenticationMiddleware', |     'django.contrib.auth.middleware.AuthenticationMiddleware', | ||||||
| @@ -158,6 +159,11 @@ EMAIL_PORT = 25 | |||||||
|  |  | ||||||
| URL_LOCATION_PROCESSOR = 'http://127.0.0.1:8000/billard/process_locationdata' | URL_LOCATION_PROCESSOR = 'http://127.0.0.1:8000/billard/process_locationdata' | ||||||
|  |  | ||||||
|  | PRODUCT_INFO = 'CAROM-DEV' | ||||||
|  | PRODUCT_VERSION = 'v 0.5.1' | ||||||
|  |  | ||||||
|  | INTERNAL_IPS = ['127.0.0.1'] | ||||||
|  |  | ||||||
| try: | try: | ||||||
|     from local_settings import * |     from local_settings import * | ||||||
| except ImportError: | except ImportError: | ||||||
|   | |||||||
| @@ -13,17 +13,26 @@ Including another URLconf | |||||||
|     1. Import the include() function: from django.conf.urls import url, include |     1. Import the include() function: from django.conf.urls import url, include | ||||||
|     2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls')) |     2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls')) | ||||||
| """ | """ | ||||||
| from django.conf.urls import url, include | from django.conf import settings | ||||||
|  | from django.conf.urls import include | ||||||
| from django.contrib import admin | from django.contrib import admin | ||||||
| from django.contrib.auth import views as auth_views | from django.contrib.auth import views as auth_views | ||||||
|  | from django.urls import path | ||||||
| from django.views.generic import RedirectView | from django.views.generic import RedirectView | ||||||
|  |  | ||||||
| urlpatterns = [ | urlpatterns = [ | ||||||
|     url(r'^admin/', admin.site.urls), |     path('admin/', admin.site.urls), | ||||||
|     url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), |     path('api-auth/', include('rest_framework.urls', namespace='rest_framework')), | ||||||
|     url(r'^billard/', include('billard.urls')), |     path('billard/', include('billard.urls')), | ||||||
|     url(r'^login/$', auth_views.login, name='login'), |     path('login/', auth_views.login, name='login'), | ||||||
|     url(r'^logout/$', auth_views.logout, name='logout'), |     path('logout/', auth_views.logout, name='logout'), | ||||||
|     url(r'^', include('django.contrib.auth.urls')), |     path('', include('django.contrib.auth.urls')), | ||||||
|     url(r'^$', RedirectView.as_view(url='billard/', permanent=False), name='index') |     path('', RedirectView.as_view(url='billard/', permanent=False), name='index') | ||||||
| ] | ] | ||||||
|  |  | ||||||
|  | if settings.DEBUG: | ||||||
|  |     import debug_toolbar | ||||||
|  |  | ||||||
|  |     urlpatterns = [ | ||||||
|  |                       path('__debug__/', include(debug_toolbar.urls)), | ||||||
|  |                   ] + urlpatterns | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| Django<2.0 | Django<2.1 | ||||||
| django-crispy-forms==1.7.0 | django-crispy-forms==1.7.0 | ||||||
| django-extensions>=1.7.0 | django-extensions>=1.7.0 | ||||||
| djangorestframework>=3.6.0 | djangorestframework>=3.6.0 | ||||||
| requests>=2.18.0 | requests>=2.18.0 | ||||||
| django-widget-tweaks==1.4.1 | django-debug-toolbar<2.0.0 | ||||||
|   | |||||||
| @@ -1,10 +1,10 @@ | |||||||
| {% load static %}<!DOCTYPE html> | {% load static form_tags %}<!DOCTYPE html> | ||||||
| <html lang="de"> | <html lang="de"> | ||||||
| <head> | <head> | ||||||
|     <meta charset="utf-8"> |     <meta charset="utf-8"> | ||||||
|     <meta http-equiv="X-UA-Compatible" content="IE=edge"> |     <meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||||||
|     <meta name="viewport" content="width=device-width, initial-scale=1"> |     <meta name="viewport" content="width=device-width, initial-scale=1"> | ||||||
|     <title>carom - {% block title %}TITLE SETZEN{% endblock %}</title> |     <title>{% settings_value "PRODUCT_INFO" %} - {% block title %}TITLE SETZEN{% endblock %}</title> | ||||||
|     <meta name="description" content="carom billard management"> |     <meta name="description" content="carom billard management"> | ||||||
|     <meta name="author" content="Robert Einsle <robert@einsle.de>"> |     <meta name="author" content="Robert Einsle <robert@einsle.de>"> | ||||||
|     <meta http-equiv="X-UA-Compatible" content="IE=edge"> |     <meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||||||
| @@ -26,7 +26,7 @@ | |||||||
|     <div class="wrapper"> |     <div class="wrapper"> | ||||||
|         <nav class="navbar navbar-expand-sm navbar-dark bg-dark"> |         <nav class="navbar navbar-expand-sm navbar-dark bg-dark"> | ||||||
|             <div class="container"> |             <div class="container"> | ||||||
|                 <a class="navbar-brand" href="{% url 'index' %}">carom</a> |                 <a class="navbar-brand" href="{% url 'index' %}">{% settings_value "PRODUCT_INFO" %}</a> | ||||||
|                 <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#mainMenu" |                 <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#mainMenu" | ||||||
|                         aria-controls="mainMenu" aria-expanded="false" aria-label="Toggle navigation"> |                         aria-controls="mainMenu" aria-expanded="false" aria-label="Toggle navigation"> | ||||||
|                     <span class="navbar-toggler-icon"></span> |                     <span class="navbar-toggler-icon"></span> | ||||||
| @@ -51,7 +51,7 @@ | |||||||
|                                 </a> |                                 </a> | ||||||
|                                 <div class="dropdown-menu dropdown-menu-right" aria-labelledby="userMenu"> |                                 <div class="dropdown-menu dropdown-menu-right" aria-labelledby="userMenu"> | ||||||
|                                     <!-- <a class="dropdown-item" href="#">My account</a> --> |                                     <!-- <a class="dropdown-item" href="#">My account</a> --> | ||||||
|                                     <a class="disabled dropdown-item" href="#">v0.5.0</a> |                                     <a class="disabled dropdown-item" href="#">{% settings_value "PRODUCT_VERSION" %}</a> | ||||||
|                                     <div class="dropdown-divider"></div> |                                     <div class="dropdown-divider"></div> | ||||||
|                                     <a class="dropdown-item" href="{% url 'logout' %}">Log out</a> |                                     <a class="dropdown-item" href="{% url 'logout' %}">Log out</a> | ||||||
|                                 </div> |                                 </div> | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| {% extends '_base.html' %} | {% extends '_base.html' %} | ||||||
|  |  | ||||||
| {% load static %} | {% load static form_tags %} | ||||||
|  |  | ||||||
| {% block stylesheet %} | {% block stylesheet %} | ||||||
|   <link rel="stylesheet" href="{% static 'css/login.css' %}"> |   <link rel="stylesheet" href="{% static 'css/login.css' %}"> | ||||||
| @@ -9,7 +9,7 @@ | |||||||
| {% block body %} | {% block body %} | ||||||
|   <div class="container"> |   <div class="container"> | ||||||
|     <h1 class="text-center logo my-4"> |     <h1 class="text-center logo my-4"> | ||||||
|       <a href="{% url 'billard:location_index' %}">carom</a> |       <a href="{% url 'billard:location_index' %}">{% settings_value "PRODUCT_INFO" %}</a> | ||||||
|     </h1> |     </h1> | ||||||
|     {% block content %} |     {% block content %} | ||||||
|     {% endblock %} |     {% endblock %} | ||||||
|   | |||||||
| @@ -1,26 +0,0 @@ | |||||||
| {% load form_tags widget_tweaks %} |  | ||||||
|  |  | ||||||
| {% if form.non_field_errors %} |  | ||||||
|     <div class="alert alert-danger" role="alert"> |  | ||||||
|         {% for error in form.non_field_errors %} |  | ||||||
|             <p{% if forloop.last %} class="mb-0"{% endif %}>{{ error }}</p> |  | ||||||
|         {% endfor %} |  | ||||||
|     </div> |  | ||||||
| {% endif %} |  | ||||||
|  |  | ||||||
| {% for field in form %} |  | ||||||
|     <div class="form-group"> |  | ||||||
|         {{ field.label_tag }} |  | ||||||
|         {% render_field field class=field|input_class %} |  | ||||||
|         {% for error in field.errors %} |  | ||||||
|             <div class="invalid-feedback"> |  | ||||||
|                 {{ error }} |  | ||||||
|             </div> |  | ||||||
|         {% endfor %} |  | ||||||
|         {% if field.help_text %} |  | ||||||
|             <small class="form-text text-muted"> |  | ||||||
|                 {{ field.help_text|safe }} |  | ||||||
|             </small> |  | ||||||
|         {% endif %} |  | ||||||
|     </div> |  | ||||||
| {% endfor %} |  | ||||||
| @@ -1,5 +1,7 @@ | |||||||
| {% extends '_base_accounts.html' %} | {% extends '_base_accounts.html' %} | ||||||
|  |  | ||||||
|  | {% load crispy_forms_tags %} | ||||||
|  |  | ||||||
| {% block title %}login{% endblock %} | {% block title %}login{% endblock %} | ||||||
|  |  | ||||||
| {% block content %} | {% block content %} | ||||||
| @@ -11,7 +13,7 @@ | |||||||
|                     <form method="post" novalidate> |                     <form method="post" novalidate> | ||||||
|                         {% csrf_token %} |                         {% csrf_token %} | ||||||
|                         <input type="hidden" name="next" value="{{ next }}"> |                         <input type="hidden" name="next" value="{{ next }}"> | ||||||
|                         {% include 'includes/form.html' %} |                         {{ form|crispy }} | ||||||
|                         <button type="submit" class="btn btn-primary btn-block">Log in</button> |                         <button type="submit" class="btn btn-primary btn-block">Log in</button> | ||||||
|                     </form> |                     </form> | ||||||
|                 </div> |                 </div> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user