Merge branch 'release/0.5.1'

This commit is contained in:
Robert Einsle 2018-02-11 11:30:28 +01:00
commit 5ec25f0b01
57 changed files with 429 additions and 308 deletions

1
.gitignore vendored
View File

@ -7,3 +7,4 @@ build/
*/__pycache__/ */__pycache__/
*/*/__pycache__/ */*/__pycache__/
caromserver/local_settings.py caromserver/local_settings.py
/staticfiles/

View File

@ -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']

View File

@ -6,7 +6,6 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [

View File

@ -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'),

View File

@ -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'),
] ]

View File

@ -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'),
] ]

View File

@ -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'),
] ]

View File

@ -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',

View File

@ -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',

View File

@ -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'),
), ),
] ]

View File

@ -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'),
] ]

View File

@ -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'),
] ]

View File

@ -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'),
] ]

View File

@ -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'),
] ]

View File

@ -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',

View File

@ -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'),
] ]

View File

@ -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'),
] ]

View File

@ -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'),
] ]

View File

@ -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'),
] ]

View File

@ -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'),
] ]

View File

@ -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'),
), ),
] ]

View File

@ -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'),

View File

@ -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'),

View File

@ -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'),
] ]

View File

@ -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'),
), ),
] ]

View File

@ -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'),
] ]

View File

@ -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'),
), ),
] ]

View 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'),
),
]

View 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'),
),
]

View File

@ -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")

View File

@ -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')

View File

@ -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:

View File

@ -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 %}

View File

@ -23,7 +23,7 @@
<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>
@ -31,11 +31,11 @@
<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>

View File

@ -1,5 +1,5 @@
{% 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">
@ -28,9 +28,10 @@
</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"
href="{% url 'billard:account_modal_confirm' pks=pks loc_pk=loc_pk %}">Schliessen</a>
</div> </div>
</div><!-- /.modal-content --> </div><!-- /.modal-content -->
</div><!-- /.modal-dialog --> </div><!-- /.modal-dialog -->
</div><!-- /.modal --> </div><!-- /.modal -->
{% endif %} {% endif %}

View File

@ -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>
{% endfor %}
</select> </select>
</div> </div>
</form> </form>
{% endif %} {% 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>
@ -30,19 +31,19 @@
{% 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 %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -8,7 +8,7 @@
{% 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>
@ -17,25 +17,27 @@
<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 %}"
class="btn btn-outline-primary btn-sm">{{ loc.code|default_if_none:"" }}</a></td>
<td>{{ loc.name|default_if_none:"" }}</td> <td>{{ loc.name|default_if_none:"" }}</td>
<td>{{ loc.street|default_if_none:"" }}</td> <td>{{ loc.street|default_if_none:"" }}</td>
<td>{{ loc.plz|default_if_none:"" }}</td> <td>{{ loc.plz|default_if_none:"" }}</td>
<td>{{ loc.city|default_if_none:"" }}</td> <td>{{ loc.city|default_if_none:"" }}</td>
{% if perms.billard.change_accounting %} {% if perms.billard.change_accounting %}
<td><a href="{% url 'billard:accounting_detail' loc.id %}" class="btn btn-primary">Abrechnen</a></td> <td><a href="{% url 'billard:accounting_detail' loc.id %}"
{% endif %} class="btn btn-outline-danger btn-sm">Abrechnen</a></td>
{% endif %}
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>
{% else %} {% else %}
<p>Keine Standorte Zugeordnet.</p> <p>Keine Standorte Zugeordnet.</p>
{% endif %} {% endif %}
{% endblock %} {% endblock %}

View File

@ -8,8 +8,10 @@
{% 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 %}

View File

@ -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 %}

View File

@ -10,7 +10,7 @@
</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>
@ -34,9 +34,9 @@
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>
{% else %} {% else %}
<p>No data available.</p> <p>No data available.</p>
{% endif %} {% endif %}
{% endblock %} {% endblock %}

View File

@ -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'

View File

@ -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, '')

View File

@ -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):

View File

@ -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'),
] ]

View File

@ -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):

View File

@ -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')

View 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'

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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>