diff --git a/billard/admin.py b/billard/admin.py
index 535f863..823a2a6 100644
--- a/billard/admin.py
+++ b/billard/admin.py
@@ -10,14 +10,19 @@ class LocationAdmin(admin.ModelAdmin):
@admin.register(Client)
class ClientAdmin(admin.ModelAdmin):
- list_display = ('uuid', 'desk1_name', 'desk2_name')
- fields = ['location', 'uuid', 'desk1_enable', 'desk1_name', 'desk1_prize_nt', 'desk1_prize_ht', 'desk2_enable', 'desk2_name', 'desk2_prize_nt', 'desk2_prize_ht', ]
+ list_display = ('uuid', 'location')
+ fields = ['location', 'uuid']
@admin.register(LocationData)
class LocationDataAdmin(admin.ModelAdmin):
- list_display = ('location_id', 'table_no', 'tst', 'on_off', 'processed', 'error_msg')
- fields = ['location_id', 'table_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']
+
+
+@admin.register(Desk)
+class DeskAdmin(admin.ModelAdmin):
+ list_display = ('client', 'desk_no', 'name', 'enabled', 'prize', 'prize_hh')
@admin.register(Accounting)
diff --git a/billard/migrations/0007_desk.py b/billard/migrations/0007_desk.py
new file mode 100644
index 0000000..4de137c
--- /dev/null
+++ b/billard/migrations/0007_desk.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.5 on 2017-02-10 18:30
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('billard', '0006_auto_20170206_2031'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Desk',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('desk_no', models.IntegerField(verbose_name='Tischnummer')),
+ ('name', models.CharField(blank=True, max_length=32, null=True, verbose_name='Tischbezeichnung')),
+ ('enabled', models.BooleanField(verbose_name='Tisch aktiv')),
+ ('prize', models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True, verbose_name='Normelpreis')),
+ ('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={
+ 'verbose_name_plural': 'Tische',
+ 'verbose_name': 'Tisch',
+ },
+ ),
+ ]
diff --git a/billard/migrations/0008_auto_20170210_1947.py b/billard/migrations/0008_auto_20170210_1947.py
new file mode 100644
index 0000000..b661151
--- /dev/null
+++ b/billard/migrations/0008_auto_20170210_1947.py
@@ -0,0 +1,53 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.5 on 2017-02-10 19:47
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('billard', '0007_desk'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='client',
+ name='desk1_enable',
+ ),
+ migrations.RemoveField(
+ model_name='client',
+ name='desk1_name',
+ ),
+ migrations.RemoveField(
+ model_name='client',
+ name='desk1_prize_ht',
+ ),
+ migrations.RemoveField(
+ model_name='client',
+ name='desk1_prize_nt',
+ ),
+ migrations.RemoveField(
+ model_name='client',
+ name='desk2_enable',
+ ),
+ migrations.RemoveField(
+ model_name='client',
+ name='desk2_name',
+ ),
+ migrations.RemoveField(
+ model_name='client',
+ name='desk2_prize_ht',
+ ),
+ migrations.RemoveField(
+ model_name='client',
+ name='desk2_prize_nt',
+ ),
+ 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'),
+ ),
+ ]
diff --git a/billard/migrations/0009_auto_20170210_1955.py b/billard/migrations/0009_auto_20170210_1955.py
new file mode 100644
index 0000000..4bfb974
--- /dev/null
+++ b/billard/migrations/0009_auto_20170210_1955.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.5 on 2017-02-10 19:55
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('billard', '0008_auto_20170210_1947'),
+ ]
+
+ operations = [
+ migrations.RenameField(
+ model_name='locationdata',
+ old_name='table_no',
+ new_name='desk_no',
+ ),
+ ]
diff --git a/billard/migrations/0010_auto_20170210_2040.py b/billard/migrations/0010_auto_20170210_2040.py
new file mode 100644
index 0000000..f577c7e
--- /dev/null
+++ b/billard/migrations/0010_auto_20170210_2040.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.5 on 2017-02-10 19:40
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('billard', '0009_auto_20170210_1955'),
+ ]
+
+ operations = [
+ migrations.RenameField(
+ model_name='locationdata',
+ old_name='location_id',
+ new_name='client_id',
+ ),
+ ]
diff --git a/billard/models.py b/billard/models.py
index 4ebf838..41b50d3 100644
--- a/billard/models.py
+++ b/billard/models.py
@@ -2,27 +2,29 @@ import uuid
from django.db import models
from django.contrib.auth.models import User
from datetime import datetime, timezone
-from . import utils
-from . import tasks
+from billard import utils, tasks
from django.contrib.auth.models import User
from django.db.models.signals import post_save
+from django.dispatch import receiver
+from celery import shared_task
class LocationData(models.Model):
- location_id = models.UUIDField(blank=False, null=False, verbose_name="Standort-ID")
- table_no = models.IntegerField(blank=False, null=False, verbose_name="Tischnummer")
+ client_id = models.UUIDField(blank=False, null=False, verbose_name="Client-ID")
+ desk_no = models.IntegerField(blank=False, null=False, verbose_name="Tischnummer")
tst = models.DateTimeField(blank=False, null=False, verbose_name="Zeitstempel")
on_off = models.BooleanField(blank=False, null=False, verbose_name="Ein/Ausgebucht")
processed = models.BooleanField(default=False, verbose_name="Verarbeitet")
error_msg = models.TextField(blank=True, null=True, verbose_name="Fehlermeldung")
def __str__(self):
- return str(self.location_id)
+ return str(self.client_id)
class Meta:
verbose_name = "Standortlog"
verbose_name_plural = "Standortlogs"
+
class Location(models.Model):
users = models.ManyToManyField(User, related_name='locations', verbose_name="Benutzer")
code = models.CharField(max_length=16, unique=True, verbose_name="Code")
@@ -45,30 +47,6 @@ class Location(models.Model):
class Client(models.Model):
uuid = models.UUIDField(unique=True, default=uuid.uuid4, verbose_name="Identifier")
location = models.ForeignKey(Location, verbose_name="Standort")
- desk1_enable = models.BooleanField()
- desk1_name = models.CharField(max_length=32, blank=True, null=True)
- desk1_prize_nt = models.DecimalField(max_digits=4, decimal_places=2, blank=True, null=True)
- desk1_prize_ht = models.DecimalField(max_digits=4, decimal_places=2, blank=True, null=True)
- desk2_enable = models.BooleanField()
- desk2_name = models.CharField(max_length=32, blank=True, null=True)
- desk2_prize_nt = models.DecimalField(max_digits=4, decimal_places=2, blank=True, null=True)
- desk2_prize_ht = models.DecimalField(max_digits=4, decimal_places=2, blank=True, null=True)
-
- def accounting_for(self, desk_no, pht, pnt):
- t = Accounting.objects.filter(client_id=self.id, desk_no=desk_no)[:3][::-1]
- if t.__len__() > 0:
- a = t[t.__len__() - 1]
- if a.time_to is None:
- prize = utils.get_prize_for(start=a.time_from, end=datetime.now(timezone.utc), pph=pht)
- if prize != a.prize:
- a.prize = prize
- return t
-
- def accounting_1(self):
- return self.accounting_for(1, self.desk1_prize_ht, self.desk1_prize_nt)
-
- def accounting_2(self):
- return self.accounting_for(2, self.desk2_prize_ht, self.desk2_prize_nt)
def __str__(self):
return '{}, {}'.format(self.location.name, self.uuid)
@@ -77,6 +55,34 @@ class Client(models.Model):
verbose_name = "Client"
verbose_name_plural = "Clienten"
+
+class Desk(models.Model):
+ client = models.ForeignKey(Client, verbose_name='Client', related_name='desks')
+ desk_no = models.IntegerField(verbose_name='Tischnummer')
+ name = models.CharField(max_length=32, blank=True, null=True, verbose_name='Tischbezeichnung')
+ enabled = models.BooleanField(verbose_name='Tisch aktiv')
+ prize = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True, verbose_name="Normelpreis")
+ prize_hh = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True,
+ verbose_name="Preis Happy Hour")
+
+ def accounting_for(self):
+ t = Accounting.objects.filter(client=self.client, desk_no=self.desk_no)[:3][::-1]
+ if t.__len__() > 0:
+ a = t[t.__len__() - 1]
+ if a.time_to is None:
+ prize = utils.get_prize_for(start=a.time_from, end=datetime.now(timezone.utc), pph=self.prize)
+ if prize != a.prize:
+ a.prize = prize
+ return t
+
+ def __str__(self):
+ return '{}, {}'.format(self.client.uuid, self.name)
+
+ class Meta:
+ verbose_name = "Tisch"
+ verbose_name_plural = "Tische"
+
+
class Accounting(models.Model):
client = models.ForeignKey(Client, verbose_name="Client")
desk_no = models.IntegerField(verbose_name="Tischnummer")
@@ -93,7 +99,44 @@ class Accounting(models.Model):
verbose_name_plural = "Buchhaltungseinträge"
-def update_location_data(sender, instance, **kwargs):
- tasks.process_location_data.delay()
+@receiver(post_save, sender=LocationData)
+def test(sender, **kwargs):
+ process_location_data()
-post_save.connect(update_location_data, sender=LocationData)
+
+@shared_task
+def process_location_data():
+ data = LocationData.objects.filter(processed=False)
+ for ld in data:
+ cli = Client.objects.filter(uuid=ld.client_id)
+ if cli.count() < 1:
+ ld.processed = True
+ ld.error_msg = 'No location object found. Stopp processing!'
+ ld.save()
+ # TODO Send error eMail to Admin
+ else:
+ cli = cli[0]
+ desk = cli.desks.filter(desk_no=ld.desk_no)[0]
+ ac = Accounting.objects.filter(client=cli, desk_no=ld.desk_no).order_by('time_from').reverse()
+ if ld.on_off:
+ if ac.count() > 0 and ac[0].time_to is None:
+ ac[0].time_to = datetime.now()
+ ac[0].save()
+ # TODO Send error eMail to Admin
+ acc = Accounting(
+ client=cli,
+ desk_no=ld.desk_no,
+ time_from=ld.tst,
+ )
+ acc.save()
+ ld.delete()
+ else:
+ acc = ac[0]
+ acc.time_to = ld.tst
+ acc.prize = utils.get_prize_for(
+ start=acc.time_from,
+ end=ld.tst,
+ pph=desk.prize
+ )
+ acc.save()
+ ld.delete()
diff --git a/billard/tasks.py b/billard/tasks.py
index 6bcd39f..46d4a18 100644
--- a/billard/tasks.py
+++ b/billard/tasks.py
@@ -1,42 +1,8 @@
from __future__ import absolute_import, unicode_literals
from celery import shared_task
-from . import models
-from datetime import datetime
-from . import utils
+from billard import utils
@shared_task
def process_location_data():
- data = models.LocationData.objects.filter(processed=False)
- for ld in data:
- cli = models.Client.objects.filter(uuid=ld.location_id)
- if cli.count() < 1:
- ld.processed = True
- ld.error_msg = 'No location object found. Stopp processing!'
- ld.save()
- # TODO Send error eMail to Admin
- else:
- cli = cli[0]
- ac = models.Accounting.objects.filter(client=cli, desk_no=ld.table_no).order_by('time_from').reverse()
- if ld.on_off:
- if ac.count() > 0 and ac[0].time_to is None:
- ac[0].time_to = datetime.now()
- ac[0].save()
- # TODO Send error eMail to Admin
- acc = models.Accounting(
- client=cli,
- desk_no=ld.table_no,
- time_from=ld.tst,
- )
- acc.save()
- ld.delete()
- else:
- acc = ac[0]
- acc.time_to = ld.tst
- acc.prize = utils.get_prize_for(
- start=acc.time_from,
- end=ld.tst,
- pph=cli.desk1_prize_ht
- )
- acc.save()
- ld.delete()
+ utils.process_location_data()
diff --git a/billard/templates/billard/index.html b/billard/templates/billard/index.html
index 1987f02..561299a 100644
--- a/billard/templates/billard/index.html
+++ b/billard/templates/billard/index.html
@@ -1,4 +1,5 @@
{% extends 'billard/base.html' %}
+{% load display_client %}
{% block header %}
@@ -19,42 +20,7 @@
{% if clients %}
{% for cli in clients %}
-{% if cli.desk1_enable %}
-
-
-
(1) {{ cli.desk1_name }}
-{% if cli.accounting_1 %}
-
-{% for acc in cli.accounting_1 %}
-
- {{ acc.time_from|date:"d.m.Y H:i:s" }} |
- {% if acc.time_to is not None %}{{ acc.time_to|date:"d.m.Y H:i:s" }}{% endif %} |
- {% if acc.prize is not None %}{{ acc.prize|floatformat:2 }}{% endif %} |
-
-{% endfor %}
-
-{% endif %}
-
-
-{% endif %}
-{% if cli.desk2_enable %}
-
-
-
(2) {{ cli.desk2_name }}
-{% if cli.accounting_2 %}
-
-{% for acc in cli.accounting_2 %}
-
- {{ acc.time_from|date:"d.m.Y H:i:s" }} |
- {% if acc.time_to is not None %}{{ acc.time_to|date:"d.m.Y H:i:s" }}{% endif %} |
- {% if acc.prize is not None %}{{ acc.prize|floatformat:2 }}{% endif %} |
-
-{% endfor %}
-
-{% endif %}
-
-
-{% endif %}
+{% for i in range %} {{ cli|display_client:i }} {% endfor %}
{% endfor %}
{% else %}
diff --git a/billard/templatetags/__init__.py b/billard/templatetags/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/billard/templatetags/display_client.py b/billard/templatetags/display_client.py
new file mode 100644
index 0000000..690164a
--- /dev/null
+++ b/billard/templatetags/display_client.py
@@ -0,0 +1,48 @@
+from django import template
+from django.utils.html import format_html
+from billard.models import Desk, Accounting
+from billard import utils
+from datetime import datetime, timezone
+
+register = template.Library()
+
+
+@register.filter(is_safe=True)
+def display_client(client, desk_no):
+ desks = client.desks.filter(desk_no=desk_no)
+ if len(desks) == 0:
+ return ''
+ desk = desks[0]
+ if not desk.enabled:
+ return ''
+
+ alert = 'alert-success'
+ acc = Accounting.objects.filter(client=client, desk_no=desk_no)[:3][::-1]
+ if acc is not None and len(acc) > 0:
+ a = acc[-1]
+ if a.time_to is None:
+ alert = 'alert-info'
+ prize = utils.get_prize_for(start=a.time_from, end=datetime.now(timezone.utc), pph=desk.prize)
+ prize = '{0:.2f}'.format(prize)
+ if prize != a.prize:
+ a.prize = prize
+
+ html = '
\n'
+ html += '
\n'.format(alert)
+ html += '
({}) {}
\n'.format(desk_no, desk.name)
+ if len(acc) > 0:
+ html += '
\n'
+ for a in acc:
+ html += ' \n'
+ html += ' {} | \n'.format(a.time_from)
+ html += ' {} | \n'.format((a.time_to if a.time_to is not None else ''))
+ html += ' {} | \n'\
+ .format((a.prize if a.prize is not None else ''))
+ html += '
\n'
+ html += '
\n'
+ html += '
\n'
+ html += '
\n'
+ html += '
\n'
+ html += '
\n'
+ html = format_html(html)
+ return html
diff --git a/billard/utils.py b/billard/utils.py
index 4251112..f6f6d8e 100644
--- a/billard/utils.py
+++ b/billard/utils.py
@@ -1,4 +1,5 @@
-from datetime import datetime, date, time
+from datetime import datetime
+#import models
def get_prize_for(start, end, pph=0):
@@ -16,8 +17,38 @@ def get_prize_for(start, end, pph=0):
return prize
-if __name__ == '__main__':
- d = date(2017, 2, 5)
- t = time(16, 00)
- start = datetime.combine(d, t)
- get_prize_for(start=start, pph=8.5)
+def process_location_data():
+ pass
+ #data = models.LocationData.objects.filter(processed=False)
+ #for ld in data:
+ # cli = models.Client.objects.filter(uuid=ld.client_id)
+ # if cli.count() < 1:
+ # ld.processed = True
+ # ld.error_msg = 'No location object found. Stopp processing!'
+ # ld.save()
+ # # TODO Send error eMail to Admin
+ # else:
+ # cli = cli[0]
+ # ac = models.Accounting.objects.filter(client=cli, desk_no=ld.table_no).order_by('time_from').reverse()
+ # if ld.on_off:
+ # if ac.count() > 0 and ac[0].time_to is None:
+ # ac[0].time_to = datetime.now()
+ # ac[0].save()
+ # # TODO Send error eMail to Admin
+ # acc = models.Accounting(
+ # client=cli,
+ # desk_no=ld.table_no,
+ # time_from=ld.tst,
+ # )
+ # acc.save()
+ # ld.delete()
+ # else:
+ # acc = ac[0]
+ # acc.time_to = ld.tst
+ # acc.prize = get_prize_for(
+ # start=acc.time_from,
+ # end=ld.tst,
+ # pph=cli.desk1_prize_ht
+ # )
+ # acc.save()
+ # ld.delete()
diff --git a/billard/views.py b/billard/views.py
index e4c5a75..305ec9c 100644
--- a/billard/views.py
+++ b/billard/views.py
@@ -55,7 +55,7 @@ def index(request):
locations = Location.objects.filter(users__id=request.user.id).order_by('code')
clients = Client.objects.filter(location_id=loc).order_by('id')
context = {
- 'range': range(1, 3),
+ 'range': range(1, 9),
'locations': locations,
'clients': clients,
'location_id': int(loc),
diff --git a/test-client.py b/test-client.py
index b00427f..fa3581e 100644
--- a/test-client.py
+++ b/test-client.py
@@ -17,7 +17,7 @@ def main():
args = parser.parse_args()
payload = {
'location_id': 'a7b47b4b-5b63-3b2f-8af0-4b185843f419',
- 'table_no': args.desk,
+ 'desk_no': args.desk,
'tst': args.date.strftime('%Y-%m-%dT%H:%M:%S%Z')
}
if args.on: