Merge branch 'release/1.0.0'
This commit is contained in:
		
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -8,3 +8,5 @@ build/
 | 
				
			|||||||
*/*/__pycache__/
 | 
					*/*/__pycache__/
 | 
				
			||||||
caromserver/local_settings.py
 | 
					caromserver/local_settings.py
 | 
				
			||||||
/staticfiles/
 | 
					/staticfiles/
 | 
				
			||||||
 | 
					.venv/
 | 
				
			||||||
 | 
					update.sh
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								Pipfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								Pipfile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					[[source]]
 | 
				
			||||||
 | 
					name = "pypi"
 | 
				
			||||||
 | 
					url = "https://pypi.org/simple"
 | 
				
			||||||
 | 
					verify_ssl = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[dev-packages]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[packages]
 | 
				
			||||||
 | 
					django = "==2.1.5"
 | 
				
			||||||
 | 
					django-crispy-forms = "==1.7.2"
 | 
				
			||||||
 | 
					django-debug-toolbar = "==1.11"
 | 
				
			||||||
 | 
					django-extensions = "==2.1.5"
 | 
				
			||||||
 | 
					django-tables2 = "==2.0.4"
 | 
				
			||||||
 | 
					djangorestframework = "==3.9.1"
 | 
				
			||||||
 | 
					requests = "==2.21.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[requires]
 | 
				
			||||||
 | 
					python_version = "3.5"
 | 
				
			||||||
							
								
								
									
										126
									
								
								Pipfile.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								Pipfile.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,126 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "_meta": {
 | 
				
			||||||
 | 
					        "hash": {
 | 
				
			||||||
 | 
					            "sha256": "de1e65bd4b2342db22fea58996979f48314fcad56bd7b50f4c939035771ef85c"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "pipfile-spec": 6,
 | 
				
			||||||
 | 
					        "requires": {
 | 
				
			||||||
 | 
					            "python_version": "3.5"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "sources": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "name": "pypi",
 | 
				
			||||||
 | 
					                "url": "https://pypi.org/simple",
 | 
				
			||||||
 | 
					                "verify_ssl": true
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "default": {
 | 
				
			||||||
 | 
					        "certifi": {
 | 
				
			||||||
 | 
					            "hashes": [
 | 
				
			||||||
 | 
					                "sha256:47f9c83ef4c0c621eaef743f133f09fa8a74a9b75f037e8624f83bd1b6626cb7",
 | 
				
			||||||
 | 
					                "sha256:993f830721089fef441cdfeb4b2c8c9df86f0c63239f06bd025a76a7daddb033"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "version": "==2018.11.29"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "chardet": {
 | 
				
			||||||
 | 
					            "hashes": [
 | 
				
			||||||
 | 
					                "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
 | 
				
			||||||
 | 
					                "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "version": "==3.0.4"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "django": {
 | 
				
			||||||
 | 
					            "hashes": [
 | 
				
			||||||
 | 
					                "sha256:a32c22af23634e1d11425574dce756098e015a165be02e4690179889b207c7a8",
 | 
				
			||||||
 | 
					                "sha256:d6393918da830530a9516bbbcbf7f1214c3d733738779f06b0f649f49cc698c3"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "index": "pypi",
 | 
				
			||||||
 | 
					            "version": "==2.1.5"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "django-crispy-forms": {
 | 
				
			||||||
 | 
					            "hashes": [
 | 
				
			||||||
 | 
					                "sha256:5952bab971110d0b86c278132dae0aa095beee8f723e625c3d3fa28888f1675f",
 | 
				
			||||||
 | 
					                "sha256:705ededc554ad8736157c666681165fe22ead2dec0d5446d65fc9dd976a5a876"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "index": "pypi",
 | 
				
			||||||
 | 
					            "version": "==1.7.2"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "django-debug-toolbar": {
 | 
				
			||||||
 | 
					            "hashes": [
 | 
				
			||||||
 | 
					                "sha256:89d75b60c65db363fb24688d977e5fbf0e73386c67acf562d278402a10fc3736",
 | 
				
			||||||
 | 
					                "sha256:c2b0134119a624f4ac9398b44f8e28a01c7686ac350a12a74793f3dd57a9eea0"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "index": "pypi",
 | 
				
			||||||
 | 
					            "version": "==1.11"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "django-extensions": {
 | 
				
			||||||
 | 
					            "hashes": [
 | 
				
			||||||
 | 
					                "sha256:6fcedb2ea660c9dbf9ac59441721ffdd4ab5b753fbd6159c3e28f391a65bab46",
 | 
				
			||||||
 | 
					                "sha256:a607459e5fa8c579a672131b63366fa52fab80adb2a862d362f5fb48cd2d2cac"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "index": "pypi",
 | 
				
			||||||
 | 
					            "version": "==2.1.5"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "django-tables2": {
 | 
				
			||||||
 | 
					            "hashes": [
 | 
				
			||||||
 | 
					                "sha256:a893fca1afe2e95b9739c6428cc6c9735a219f65707e24274df3920f61358525",
 | 
				
			||||||
 | 
					                "sha256:b5f7b4c76160ee927005e52ebea633c86d4529cf84757c0acd5d0434d31798a1"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "index": "pypi",
 | 
				
			||||||
 | 
					            "version": "==2.0.4"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "djangorestframework": {
 | 
				
			||||||
 | 
					            "hashes": [
 | 
				
			||||||
 | 
					                "sha256:79c6efbb2514bc50cf25906d7c0a5cfead714c7af667ff4bd110312cd380ae66",
 | 
				
			||||||
 | 
					                "sha256:a4138613b67e3a223be6c97f53b13d759c5b90d2b433bad670b8ebf95402075f"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "index": "pypi",
 | 
				
			||||||
 | 
					            "version": "==3.9.1"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "idna": {
 | 
				
			||||||
 | 
					            "hashes": [
 | 
				
			||||||
 | 
					                "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
 | 
				
			||||||
 | 
					                "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "version": "==2.8"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "pytz": {
 | 
				
			||||||
 | 
					            "hashes": [
 | 
				
			||||||
 | 
					                "sha256:32b0891edff07e28efe91284ed9c31e123d84bea3fd98e1f72be2508f43ef8d9",
 | 
				
			||||||
 | 
					                "sha256:d5f05e487007e29e03409f9398d074e158d920d36eb82eaf66fb1136b0c5374c"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "version": "==2018.9"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "requests": {
 | 
				
			||||||
 | 
					            "hashes": [
 | 
				
			||||||
 | 
					                "sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e",
 | 
				
			||||||
 | 
					                "sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "index": "pypi",
 | 
				
			||||||
 | 
					            "version": "==2.21.0"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "six": {
 | 
				
			||||||
 | 
					            "hashes": [
 | 
				
			||||||
 | 
					                "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
 | 
				
			||||||
 | 
					                "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "version": "==1.12.0"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "sqlparse": {
 | 
				
			||||||
 | 
					            "hashes": [
 | 
				
			||||||
 | 
					                "sha256:ce028444cfab83be538752a2ffdb56bc417b7784ff35bb9a3062413717807dec",
 | 
				
			||||||
 | 
					                "sha256:d9cf190f51cbb26da0412247dfe4fb5f4098edb73db84e02f9fc21fdca31fed4"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "version": "==0.2.4"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "urllib3": {
 | 
				
			||||||
 | 
					            "hashes": [
 | 
				
			||||||
 | 
					                "sha256:61bf29cada3fc2fbefad4fdf059ea4bd1b4a86d2b6d15e1c7c0b582b9752fe39",
 | 
				
			||||||
 | 
					                "sha256:de9529817c93f27c8ccbfead6985011db27bd0ddfcdb2d86f3f663385c6a9c22"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "version": "==1.24.1"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "develop": {}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -35,6 +35,12 @@ class ClientAdmin(admin.ModelAdmin):
 | 
				
			|||||||
    fields = ['location', 'uuid', 'report_user', 'last_seen']
 | 
					    fields = ['location', 'uuid', 'report_user', 'last_seen']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@admin.register(ClientData)
 | 
				
			||||||
 | 
					class ClientDataAdmin(admin.ModelAdmin):
 | 
				
			||||||
 | 
					    list_display = ('uuid', 'last_seen')
 | 
				
			||||||
 | 
					    fields = ['location', 'last_seen']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@admin.register(LocationData)
 | 
					@admin.register(LocationData)
 | 
				
			||||||
class LocationDataAdmin(admin.ModelAdmin):
 | 
					class LocationDataAdmin(admin.ModelAdmin):
 | 
				
			||||||
    def get_urls(self):
 | 
					    def get_urls(self):
 | 
				
			||||||
@@ -46,6 +52,8 @@ class LocationDataAdmin(admin.ModelAdmin):
 | 
				
			|||||||
        return my_urls + urls
 | 
					        return my_urls + urls
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def process_locationdata(self, request):
 | 
					    def process_locationdata(self, request):
 | 
				
			||||||
 | 
					        from .tasks import process_location_data
 | 
				
			||||||
 | 
					        process_location_data(sender=None)
 | 
				
			||||||
        messages.success(request, 'Items processed.')
 | 
					        messages.success(request, 'Items processed.')
 | 
				
			||||||
        return redirect('admin:billard_locationdata_changelist')
 | 
					        return redirect('admin:billard_locationdata_changelist')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								billard/forms.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								billard/forms.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					from django import forms
 | 
				
			||||||
 | 
					from django.contrib.auth.models import User
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class UserInformationUpdateForm(forms.ModelForm):
 | 
				
			||||||
 | 
					    email = forms.EmailField()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Meta:
 | 
				
			||||||
 | 
					        model = User
 | 
				
			||||||
 | 
					        fields = ('first_name', 'last_name', 'email',)
 | 
				
			||||||
							
								
								
									
										24
									
								
								billard/migrations/0027_clientdata.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								billard/migrations/0027_clientdata.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					# Generated by Django 2.0.2 on 2018-02-19 10:23
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('billard', '0026_client_last_seen'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.CreateModel(
 | 
				
			||||||
 | 
					            name='ClientData',
 | 
				
			||||||
 | 
					            fields=[
 | 
				
			||||||
 | 
					                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
 | 
				
			||||||
 | 
					                ('uuid', models.UUIDField(verbose_name='Identifier')),
 | 
				
			||||||
 | 
					                ('last_seen', models.DateTimeField(verbose_name='Letzter Update')),
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            options={
 | 
				
			||||||
 | 
					                'verbose_name': 'Client Data logs',
 | 
				
			||||||
 | 
					                'verbose_name_plural': 'Client Data logs',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
@@ -4,8 +4,6 @@ import uuid
 | 
				
			|||||||
from django.contrib.auth.models import User
 | 
					from django.contrib.auth.models import User
 | 
				
			||||||
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.db.models.signals import post_save
 | 
					 | 
				
			||||||
from django.dispatch import receiver
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
log = logging.getLogger(__name__)
 | 
					log = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -102,7 +100,13 @@ class Accounting(models.Model):
 | 
				
			|||||||
        verbose_name_plural = "Buchhaltungseinträge"
 | 
					        verbose_name_plural = "Buchhaltungseinträge"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@receiver(post_save, sender=LocationData)
 | 
					class ClientData(models.Model):
 | 
				
			||||||
def test(sender, **kwargs):
 | 
					    uuid = models.UUIDField(verbose_name="Identifier")
 | 
				
			||||||
    from .tasks import process_location_data
 | 
					    last_seen = models.DateTimeField(verbose_name="Letzter Update")
 | 
				
			||||||
    process_location_data()
 | 
					
 | 
				
			||||||
 | 
					    def __str__(self):
 | 
				
			||||||
 | 
					        return '{}, {}'.format(self.uuid, self.last_seen)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Meta:
 | 
				
			||||||
 | 
					        verbose_name = "Client Data logs"
 | 
				
			||||||
 | 
					        verbose_name_plural = "Client Data logs"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
from rest_framework import serializers
 | 
					from rest_framework import serializers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from billard.models import LocationData, Client
 | 
					from billard.models import LocationData, ClientData
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class LocationDataSerializer(serializers.HyperlinkedModelSerializer):
 | 
					class LocationDataSerializer(serializers.HyperlinkedModelSerializer):
 | 
				
			||||||
@@ -11,5 +11,5 @@ class LocationDataSerializer(serializers.HyperlinkedModelSerializer):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class ClientUpdateLastSeenSerializer(serializers.HyperlinkedModelSerializer):
 | 
					class ClientUpdateLastSeenSerializer(serializers.HyperlinkedModelSerializer):
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = Client
 | 
					        model = ClientData
 | 
				
			||||||
        fields = ('uuid', 'last_seen')
 | 
					        fields = ('uuid', 'last_seen')
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										22
									
								
								billard/tables.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								billard/tables.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					import django_tables2 as tables
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from .models import Location
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class LocationTable(tables.Table):
 | 
				
			||||||
 | 
					    code = tables.TemplateColumn(template_name='billard/tc_location_detail.html')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Meta:
 | 
				
			||||||
 | 
					        model = Location
 | 
				
			||||||
 | 
					        fields = ('code', 'name', 'street', 'plz', 'city')
 | 
				
			||||||
 | 
					        orderable = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class LocationAccountingTable(tables.Table):
 | 
				
			||||||
 | 
					    code = tables.TemplateColumn(template_name='billard/tc_location_detail.html')
 | 
				
			||||||
 | 
					    accounting = tables.TemplateColumn(template_name='billard/tc_accounting_detail.html')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Meta:
 | 
				
			||||||
 | 
					        model = Location
 | 
				
			||||||
 | 
					        fields = ('code', 'name', 'street', 'plz', 'city', 'accounting')
 | 
				
			||||||
 | 
					        orderable = False
 | 
				
			||||||
@@ -2,13 +2,28 @@ from __future__ import absolute_import, unicode_literals
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import logging
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db.models.signals import post_save
 | 
				
			||||||
 | 
					from django.dispatch import receiver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import billard.utils as utils
 | 
					import billard.utils as utils
 | 
				
			||||||
from billard.models import LocationData, Client, Accounting
 | 
					from billard.models import LocationData, Client, Accounting, ClientData
 | 
				
			||||||
 | 
					
 | 
				
			||||||
log = logging.getLogger(__name__)
 | 
					log = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def process_location_data():
 | 
					@receiver(post_save, sender=ClientData)
 | 
				
			||||||
 | 
					def process_client_data(sender, **kwargs):
 | 
				
			||||||
 | 
					    data = ClientData.objects.all().order_by('last_seen')
 | 
				
			||||||
 | 
					    for cd in data:
 | 
				
			||||||
 | 
					        client = Client.objects.get(uuid=cd.uuid)
 | 
				
			||||||
 | 
					        client.last_seen = cd.last_seen
 | 
				
			||||||
 | 
					        client.save()
 | 
				
			||||||
 | 
					        cd.delete()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@receiver(post_save, sender=LocationData)
 | 
				
			||||||
 | 
					def process_location_data(sender, **kwargs):
 | 
				
			||||||
 | 
					    log.info('Starte die Verarbeitung der Location-Data-Objecte')
 | 
				
			||||||
    data = LocationData.objects.filter(processed=False).order_by('tst')
 | 
					    data = LocationData.objects.filter(processed=False).order_by('tst')
 | 
				
			||||||
    for ld in data:
 | 
					    for ld in data:
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
@@ -64,3 +79,10 @@ def process_location_data():
 | 
				
			|||||||
                        log.error(ld.error_msg)
 | 
					                        log.error(ld.error_msg)
 | 
				
			||||||
        except:
 | 
					        except:
 | 
				
			||||||
            log.exception('', exc_info=True)
 | 
					            log.exception('', exc_info=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@receiver(post_save, sender=Accounting)
 | 
				
			||||||
 | 
					def process_accounting_data(sender, **kwargs):
 | 
				
			||||||
 | 
					    log.info('Starte die Verarbeitung der Accounting-Data-Objecte')
 | 
				
			||||||
 | 
					    data = Accounting.objects.filter(prize=0.0, reporter_uuid__isnull=True).exclude(time_to__isnull=True)
 | 
				
			||||||
 | 
					    data.delete()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
{% 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' %}" title="Verarbeiten der LocationDate Elemente">
 | 
				
			||||||
            LD Verarbeiten
 | 
					            LD Verarbeiten
 | 
				
			||||||
        </a>
 | 
					        </a>
 | 
				
			||||||
    </li>
 | 
					    </li>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,30 +15,33 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    {{ pk }}
 | 
					    {{ pk }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <table class="table">
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
            <th>Start-Datum:</th>
 | 
					 | 
				
			||||||
            <th>Stop-Datum:</th>
 | 
					 | 
				
			||||||
            <th>Preis Normal:</th>
 | 
					 | 
				
			||||||
            <th>Preis Happy Hour:</th>
 | 
					 | 
				
			||||||
            <th>Preis gesamt:</th>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        {% for acc in accounting %}
 | 
					 | 
				
			||||||
            <tr>
 | 
					 | 
				
			||||||
                <td>{{ acc.time_from }}</td>
 | 
					 | 
				
			||||||
                <td>{{ acc.time_to }}</td>
 | 
					 | 
				
			||||||
                <td>{{ acc.prize_normal }}</td>
 | 
					 | 
				
			||||||
                <td>{{ acc.prize_hh }}</td>
 | 
					 | 
				
			||||||
                <td>{{ acc.prize }}</td>
 | 
					 | 
				
			||||||
            </tr>
 | 
					 | 
				
			||||||
        {% endfor %}
 | 
					 | 
				
			||||||
    </table>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <form action="confirm/" method="post" id="accounting">
 | 
					    <form action="confirm/" method="post" id="accounting">
 | 
				
			||||||
        {% csrf_token %}
 | 
					        {% csrf_token %}
 | 
				
			||||||
 | 
					        <table class="table">
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th></th>
 | 
				
			||||||
 | 
					                <th>Start-Datum:</th>
 | 
				
			||||||
 | 
					                <th>Stop-Datum:</th>
 | 
				
			||||||
 | 
					                <th>Preis Normal:</th>
 | 
				
			||||||
 | 
					                <th>Preis Happy Hour:</th>
 | 
				
			||||||
 | 
					                <th>Preis gesamt:</th>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            {% for acc in accounting %}
 | 
				
			||||||
 | 
					                <tr>
 | 
				
			||||||
 | 
					                    <td><input type="checkbox" name="list_acc_id" id="option{{ acc.id }}"
 | 
				
			||||||
 | 
					                               value={{ acc.id }} checked="checked"/></td>
 | 
				
			||||||
 | 
					                    <td>{{ acc.time_from }}</td>
 | 
				
			||||||
 | 
					                    <td>{{ acc.time_to }}</td>
 | 
				
			||||||
 | 
					                    <td>{{ acc.prize_normal }}</td>
 | 
				
			||||||
 | 
					                    <td>{{ acc.prize_hh }}</td>
 | 
				
			||||||
 | 
					                    <td>{{ acc.prize }}</td>
 | 
				
			||||||
 | 
					                </tr>
 | 
				
			||||||
 | 
					            {% endfor %}
 | 
				
			||||||
 | 
					        </table>
 | 
				
			||||||
        <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-danger">Abrechnen</button>
 | 
				
			||||||
    </form>
 | 
					    </form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% endblock %}
 | 
					{% endblock %}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,49 +0,0 @@
 | 
				
			|||||||
{% extends '_base.html' %}
 | 
					 | 
				
			||||||
{% load display_client %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block title %}Location Data{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block content %}
 | 
					 | 
				
			||||||
    {% if not locations|length_is:"1" %}
 | 
					 | 
				
			||||||
        <form action="." method="post" id="location-form">
 | 
					 | 
				
			||||||
            {% csrf_token %}
 | 
					 | 
				
			||||||
            <div id="location-selector" class="alert">
 | 
					 | 
				
			||||||
                <select class="form-control" form="location-form" name="location-selector" id="location-select">
 | 
					 | 
				
			||||||
                    {% for loc in locations %}
 | 
					 | 
				
			||||||
                        <option value="{{ loc.id }}"{% if loc.id == location_id %} selected{% endif %}>{{ loc.code }}
 | 
					 | 
				
			||||||
                            - {{ loc.name }}</option>
 | 
					 | 
				
			||||||
                    {% endfor %}
 | 
					 | 
				
			||||||
                </select>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
        </form>
 | 
					 | 
				
			||||||
    {% endif %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <div id="desk_data">
 | 
					 | 
				
			||||||
        {% include 'billard/index_ajax.html' %}
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
    <div id="modal-wrapper">
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block js %}
 | 
					 | 
				
			||||||
    <script type="text/javascript">
 | 
					 | 
				
			||||||
        var interval;
 | 
					 | 
				
			||||||
        $(document).ready(function () {
 | 
					 | 
				
			||||||
            $.ajaxSetup({cache: false});
 | 
					 | 
				
			||||||
            interval = window.setInterval(refresh_page, 1000);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        function refresh_page() {
 | 
					 | 
				
			||||||
            $('#desk_data').load('#');
 | 
					 | 
				
			||||||
            $('#modal-wrapper').load('{% url 'accountmodal' %}', function () {
 | 
					 | 
				
			||||||
                if ($('#accountsmodal').length) {
 | 
					 | 
				
			||||||
                    window.clearInterval(interval);
 | 
					 | 
				
			||||||
                    $('#accountsmodal').modal('show');
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    </script>
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
@@ -1,10 +0,0 @@
 | 
				
			|||||||
{% load display_client %}
 | 
					 | 
				
			||||||
{% if clients %}
 | 
					 | 
				
			||||||
    {% for cli in clients %}
 | 
					 | 
				
			||||||
        {% for i in range %} {{ cli|display_client:i }} {% endfor %}
 | 
					 | 
				
			||||||
    {% endfor %}
 | 
					 | 
				
			||||||
{% else %}
 | 
					 | 
				
			||||||
    <div class="col-md-12">
 | 
					 | 
				
			||||||
        <div class="col-md-12 alert alert-danger">Keine Tische angelegt!</div>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
{% endif %}
 | 
					 | 
				
			||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
{% load display_client %}
 | 
					{% load display_client display_daily_sale %}
 | 
				
			||||||
{% 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" %}
 | 
				
			||||||
@@ -10,3 +10,8 @@
 | 
				
			|||||||
        <div class="alert alert-danger">Keine Tische angelegt!</div>
 | 
					        <div class="alert alert-danger">Keine Tische angelegt!</div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
{% endif %}
 | 
					{% endif %}
 | 
				
			||||||
 | 
					<div class="col col-12">
 | 
				
			||||||
 | 
					    <div class="alert alert-warning">
 | 
				
			||||||
 | 
					        {{ location|display_daily_sale }}
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
{% extends '_base.html' %}
 | 
					{% extends '_base.html' %}
 | 
				
			||||||
 | 
					{% load render_table from django_tables2 %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% block title %}Standortliste{% endblock %}
 | 
					{% block title %}Standortliste{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -7,37 +8,6 @@
 | 
				
			|||||||
{% endblock %}
 | 
					{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% block content %}
 | 
					{% block content %}
 | 
				
			||||||
 | 
					    <h2>Bitte Standort auswählen:</h2>
 | 
				
			||||||
    {% if location_list %}
 | 
					    {% render_table table %}
 | 
				
			||||||
        <h2>Bitte Standort auswählen:</h2>
 | 
					 | 
				
			||||||
        <table class="table table-hover">
 | 
					 | 
				
			||||||
            <tr>
 | 
					 | 
				
			||||||
                <th>Code</th>
 | 
					 | 
				
			||||||
                <th>Name</th>
 | 
					 | 
				
			||||||
                <th>Strasse</th>
 | 
					 | 
				
			||||||
                <th>Plz</th>
 | 
					 | 
				
			||||||
                <th>Ort</th>
 | 
					 | 
				
			||||||
                {% if perms.billard.change_accounting %}
 | 
					 | 
				
			||||||
                    <th>Accounting</th>
 | 
					 | 
				
			||||||
                {% endif %}
 | 
					 | 
				
			||||||
            </tr>
 | 
					 | 
				
			||||||
            {% for loc in location_list %}
 | 
					 | 
				
			||||||
                <tr>
 | 
					 | 
				
			||||||
                    <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.street|default_if_none:"" }}</td>
 | 
					 | 
				
			||||||
                    <td>{{ loc.plz|default_if_none:"" }}</td>
 | 
					 | 
				
			||||||
                    <td>{{ loc.city|default_if_none:"" }}</td>
 | 
					 | 
				
			||||||
                    {% if perms.billard.change_accounting %}
 | 
					 | 
				
			||||||
                        <td><a href="{% url 'billard:accounting_detail' loc.id %}"
 | 
					 | 
				
			||||||
                               class="btn btn-outline-danger btn-sm">Abrechnen</a></td>
 | 
					 | 
				
			||||||
                    {% endif %}
 | 
					 | 
				
			||||||
                </tr>
 | 
					 | 
				
			||||||
            {% endfor %}
 | 
					 | 
				
			||||||
        </table>
 | 
					 | 
				
			||||||
    {% else %}
 | 
					 | 
				
			||||||
        <p>Keine Standorte Zugeordnet.</p>
 | 
					 | 
				
			||||||
    {% endif %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					{% endblock %}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,17 +0,0 @@
 | 
				
			|||||||
{% extends '_base.html' %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block title %}Location Data{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block content %}
 | 
					 | 
				
			||||||
    {% include 'billard/locationdata_detail_ajax.html' %}
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block js %}
 | 
					 | 
				
			||||||
    <script type="text/javascript">
 | 
					 | 
				
			||||||
        $(document).ready(function () {
 | 
					 | 
				
			||||||
            setInterval(function () {
 | 
					 | 
				
			||||||
                $("#content").load("#")
 | 
					 | 
				
			||||||
            }, 1000);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    </script>
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
@@ -1,51 +0,0 @@
 | 
				
			|||||||
<h1>Locationdata: {{ locationdata.id }}</h1>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<form action="{% url 'index' %}" method="post" class="form-horizontal">
 | 
					 | 
				
			||||||
    {% csrf_token %}
 | 
					 | 
				
			||||||
    <div class="form-group">
 | 
					 | 
				
			||||||
        <label for="location_id" class="col-sm-2 control-label">Location Id</label>
 | 
					 | 
				
			||||||
        <div class="col-sm-10">
 | 
					 | 
				
			||||||
            <input id="location_id" type="text" name="location_id" value="{{ locationdata.location_id }}"
 | 
					 | 
				
			||||||
                   placeholder="Locaton" class="form-control" disabled="disabled"/>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
        <div class="form-group">
 | 
					 | 
				
			||||||
            <label for="table_no" class="col-sm-2 control-label">Table Number</label>
 | 
					 | 
				
			||||||
            <div class="col-sm-10">
 | 
					 | 
				
			||||||
                <input id="table_no" type="number" name="table_no" value="{{ locationdata.table_no }}"
 | 
					 | 
				
			||||||
                       placeholder="Table" class="form-control" min="1" max="8" disabled="disabled"/>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
            <div class="form-group">
 | 
					 | 
				
			||||||
                <label for="tst" class="col-sm-2 control-label">Timestamp</label>
 | 
					 | 
				
			||||||
                <div class="col-sm-10">
 | 
					 | 
				
			||||||
                    <input id="tst" type="datetime" name="tst" value="{{ locationdata.tst }}"
 | 
					 | 
				
			||||||
                           placeholder="Table" class="form-control" disabled="disabled"/>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
            <div class="form-group">
 | 
					 | 
				
			||||||
                <label for="on_off" class="col-sm-2 control-label">On / Off</label>
 | 
					 | 
				
			||||||
                <div class="col-sm-10">
 | 
					 | 
				
			||||||
                    <input id="on_off" type="checkbox" name="on_off" value="{{ locationdata.on_off }}"
 | 
					 | 
				
			||||||
                           placeholder="Table" class="form-control" disabled="disabled"/>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
            <div class="form-group">
 | 
					 | 
				
			||||||
                <label for="processed" class="col-sm-2 control-label">Processed</label>
 | 
					 | 
				
			||||||
                <div class="col-sm-10">
 | 
					 | 
				
			||||||
                    <input id="processed" type="checkbox" name="processed" value="{{ locationdata.processed }}"
 | 
					 | 
				
			||||||
                           placeholder="Table" class="form-control" disabled="disabled"/>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
            <div class="form-group">
 | 
					 | 
				
			||||||
                <label for="error_msg" class="col-sm-2 control-label">Error Message</label>
 | 
					 | 
				
			||||||
                <div class="col-sm-10">
 | 
					 | 
				
			||||||
                    <input id="error_msg" type="text" name="error_msg" value="{{ locationdata.error_msg }}"
 | 
					 | 
				
			||||||
                           placeholder="Table" class="form-control" disabled="disabled"/>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
            <button type="submit" class="btn btn-default">Abschicken</button>
 | 
					 | 
				
			||||||
            <a class="btn btn-default" href=".." role="button">Zurück</a>
 | 
					 | 
				
			||||||
</form>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,17 +0,0 @@
 | 
				
			|||||||
{% extends '_base.html' %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block title %}Location Data{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block content %}
 | 
					 | 
				
			||||||
    {% include 'billard/locationdata_list_ajax.html' %}
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block js %}
 | 
					 | 
				
			||||||
    <script type="text/javascript">
 | 
					 | 
				
			||||||
        $(document).ready(function () {
 | 
					 | 
				
			||||||
            setInterval(function () {
 | 
					 | 
				
			||||||
                $("#content").load("#")
 | 
					 | 
				
			||||||
            }, 1000);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    </script>
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
@@ -1,42 +0,0 @@
 | 
				
			|||||||
{% extends '_base.html' %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block title %}Location Data{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block content %}
 | 
					 | 
				
			||||||
    <div id="location-selector" class="alert">
 | 
					 | 
				
			||||||
        <select class="form-control">
 | 
					 | 
				
			||||||
            <option value="1">Casino 1</option>
 | 
					 | 
				
			||||||
            <option value="2">Casino 2</option>
 | 
					 | 
				
			||||||
        </select>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    {% if object_list %}
 | 
					 | 
				
			||||||
        <h1>Location Data</h1>
 | 
					 | 
				
			||||||
        <table class="table table-hover">
 | 
					 | 
				
			||||||
            <tr>
 | 
					 | 
				
			||||||
                <th>ID</th>
 | 
					 | 
				
			||||||
                <th>Location</th>
 | 
					 | 
				
			||||||
                <th>Table</th>
 | 
					 | 
				
			||||||
                <th>Timestamp</th>
 | 
					 | 
				
			||||||
                <th>On_Off</th>
 | 
					 | 
				
			||||||
                <th>Proc</th>
 | 
					 | 
				
			||||||
                <th>Error</th>
 | 
					 | 
				
			||||||
            </tr>
 | 
					 | 
				
			||||||
            {% for location_data in object_list %}
 | 
					 | 
				
			||||||
                <tr>
 | 
					 | 
				
			||||||
                    <td><a href="{% url 'detail' location_data.id %}">{{ location_data.id }}</a></td>
 | 
					 | 
				
			||||||
                    <td>{{ location_data.location_id }}</td>
 | 
					 | 
				
			||||||
                    <td>{{ location_data.table_no }}</td>
 | 
					 | 
				
			||||||
                    <td>{{ location_data.tst }}</td>
 | 
					 | 
				
			||||||
                    <td>{{ location_data.on_off }}</td>
 | 
					 | 
				
			||||||
                    <td>{{ location_data.processed }}</td>
 | 
					 | 
				
			||||||
                    <td>{{ location_data.error_msg }}</td>
 | 
					 | 
				
			||||||
                </tr>
 | 
					 | 
				
			||||||
            {% endfor %}
 | 
					 | 
				
			||||||
        </table>
 | 
					 | 
				
			||||||
    {% else %}
 | 
					 | 
				
			||||||
        <p>No data available.</p>
 | 
					 | 
				
			||||||
    {% endif %}
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										2
									
								
								billard/templates/billard/tc_accounting_detail.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								billard/templates/billard/tc_accounting_detail.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					{% load static from staticfiles %}
 | 
				
			||||||
 | 
					<a href="{% url 'billard:accounting_detail' record.id %}" class="btn btn-outline-danger btn-sm">Abrechnen</a>
 | 
				
			||||||
							
								
								
									
										3
									
								
								billard/templates/billard/tc_location_detail.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								billard/templates/billard/tc_location_detail.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					{% load static from staticfiles %}
 | 
				
			||||||
 | 
					<a href="{% url 'billard:location_detail' record.id %}"
 | 
				
			||||||
 | 
					   class="btn btn-outline-primary btn-sm">{{ record.code|default_if_none:"" }}</a>
 | 
				
			||||||
@@ -17,28 +17,10 @@ def display_client(client, desk_no):
 | 
				
			|||||||
    loc = desk.client.location
 | 
					    loc = desk.client.location
 | 
				
			||||||
    if not desk.enabled:
 | 
					    if not desk.enabled:
 | 
				
			||||||
        return ''
 | 
					        return ''
 | 
				
			||||||
    alert = 'alert-success'
 | 
					 | 
				
			||||||
    acc = desk.accounting_set.all()[:3][::-1]
 | 
					    acc = desk.accounting_set.all()[:3][::-1]
 | 
				
			||||||
    if acc is not None and len(acc) > 0:
 | 
					    _calc_prize(desk, acc)
 | 
				
			||||||
        a = acc[-1]
 | 
					 | 
				
			||||||
        if a.time_to is None:
 | 
					 | 
				
			||||||
            alert = 'alert-info'
 | 
					 | 
				
			||||||
            prize, u1, u2 = utils.get_prize_for(
 | 
					 | 
				
			||||||
                start=a.time_from,
 | 
					 | 
				
			||||||
                end=datetime.now(),
 | 
					 | 
				
			||||||
                pph=desk.prize,
 | 
					 | 
				
			||||||
                hh_start=loc.happy_hour_start,
 | 
					 | 
				
			||||||
                hh_end=loc.happy_hour_end,
 | 
					 | 
				
			||||||
                pphh=desk.prize_hh,
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
            prize = '{0:.2f}'.format(prize)
 | 
					 | 
				
			||||||
            if prize != a.prize:
 | 
					 | 
				
			||||||
                a.prize = prize
 | 
					 | 
				
			||||||
    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="col col-12 col-lg-6">\n'
 | 
				
			||||||
    html += '    <div class="table-info alert {}">\n'.format(alert)
 | 
					    html += '    <div class="table-info alert {}">\n'.format(_get_alert_name(desk))
 | 
				
			||||||
    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' \
 | 
				
			||||||
@@ -67,3 +49,33 @@ def display_client(client, desk_no):
 | 
				
			|||||||
    html += '</div>\n'
 | 
					    html += '</div>\n'
 | 
				
			||||||
    html = format_html(html)
 | 
					    html = format_html(html)
 | 
				
			||||||
    return html
 | 
					    return html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _get_alert_name(desk):
 | 
				
			||||||
 | 
					    alert = 'alert-success'
 | 
				
			||||||
 | 
					    acc = desk.accounting_set.all()[:3][::-1]
 | 
				
			||||||
 | 
					    if acc is not None and len(acc) > 0:
 | 
				
			||||||
 | 
					        a = acc[-1]
 | 
				
			||||||
 | 
					        if a.time_to is None:
 | 
				
			||||||
 | 
					            alert = 'alert-info'
 | 
				
			||||||
 | 
					    before5min = datetime.now() - timedelta(minutes=5)
 | 
				
			||||||
 | 
					    if desk.client.last_seen is not None and desk.client.last_seen < before5min:
 | 
				
			||||||
 | 
					        alert = 'alert-danger'
 | 
				
			||||||
 | 
					    return alert
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _calc_prize(desk, acc):
 | 
				
			||||||
 | 
					    if acc is not None and len(acc) > 0:
 | 
				
			||||||
 | 
					        a = acc[-1]
 | 
				
			||||||
 | 
					        if a.time_to is None:
 | 
				
			||||||
 | 
					            prize, u1, u2 = utils.get_prize_for(
 | 
				
			||||||
 | 
					                start=a.time_from,
 | 
				
			||||||
 | 
					                end=datetime.now(),
 | 
				
			||||||
 | 
					                pph=desk.prize,
 | 
				
			||||||
 | 
					                hh_start=desk.client.location.happy_hour_start,
 | 
				
			||||||
 | 
					                hh_end=desk.client.location.happy_hour_end,
 | 
				
			||||||
 | 
					                pphh=desk.prize_hh,
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            prize = '{0:.2f}'.format(prize)
 | 
				
			||||||
 | 
					            if prize != a.prize:
 | 
				
			||||||
 | 
					                a.prize = prize
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										19
									
								
								billard/templatetags/display_daily_sale.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								billard/templatetags/display_daily_sale.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					from datetime import datetime, timedelta
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django import template
 | 
				
			||||||
 | 
					from django.db.models import Sum
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from billard.models import Accounting
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					register = template.Library()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@register.filter(is_safe=True)
 | 
				
			||||||
 | 
					def display_daily_sale(location):
 | 
				
			||||||
 | 
					    start_date = datetime.now().replace(hour=5, minute=0, second=0, microsecond=0)
 | 
				
			||||||
 | 
					    end_date = start_date + timedelta(days=1)
 | 
				
			||||||
 | 
					    prize__sum = Accounting.objects.filter(desk__client__location=location,
 | 
				
			||||||
 | 
					                                           time_to__range=(start_date, end_date)).aggregate(Sum('prize'))
 | 
				
			||||||
 | 
					    if prize__sum['prize__sum'] is None:
 | 
				
			||||||
 | 
					        prize__sum['prize__sum'] = 0
 | 
				
			||||||
 | 
					    return "Tagesumsatz: {0:.2f} EUR".format(prize__sum['prize__sum'])
 | 
				
			||||||
@@ -25,6 +25,6 @@ urlpatterns = [
 | 
				
			|||||||
    path('<int:loc_pk>/account_modal/<pks>/confirm/', views.account_modal_confirm_view, name='account_modal_confirm'),
 | 
					    path('<int:loc_pk>/account_modal/<pks>/confirm/', views.account_modal_confirm_view, name='account_modal_confirm'),
 | 
				
			||||||
    # ex. /billard/api/v1/ (rest api)
 | 
					    # ex. /billard/api/v1/ (rest api)
 | 
				
			||||||
    path('api/v1/', include(router.urls)),
 | 
					    path('api/v1/', include(router.urls)),
 | 
				
			||||||
    # ex. /billard/process_location_data/
 | 
					    # ex. /billard/myaccount/
 | 
				
			||||||
    path('process_location_data/', views.process_location_data, name='process_location_data'),
 | 
					    path('my_account', views.UserUpdateView.as_view(), name='my_account'),
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,23 +1,25 @@
 | 
				
			|||||||
import ast
 | 
					 | 
				
			||||||
import logging
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django.contrib.auth.decorators import login_required, permission_required
 | 
					from django.contrib.auth.decorators import login_required, permission_required
 | 
				
			||||||
 | 
					from django.contrib.auth.mixins import LoginRequiredMixin
 | 
				
			||||||
from django.db.models import Sum
 | 
					from django.db.models import Sum
 | 
				
			||||||
from django.http import HttpResponse
 | 
					 | 
				
			||||||
from django.shortcuts import render, redirect
 | 
					from django.shortcuts import render, redirect
 | 
				
			||||||
 | 
					from django.urls import reverse_lazy
 | 
				
			||||||
from django.utils import timezone
 | 
					from django.utils import timezone
 | 
				
			||||||
from django.utils.decorators import method_decorator
 | 
					from django.utils.decorators import method_decorator
 | 
				
			||||||
from django.views import generic
 | 
					from django.views import generic
 | 
				
			||||||
 | 
					from django.views.generic import UpdateView
 | 
				
			||||||
from rest_framework import viewsets
 | 
					from rest_framework import viewsets
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from billard.models import LocationData, Location, Client, Accounting
 | 
					from billard.models import LocationData, Location, Client, Accounting
 | 
				
			||||||
from billard.serializers import LocationDataSerializer, ClientUpdateLastSeenSerializer
 | 
					from billard.serializers import LocationDataSerializer, ClientUpdateLastSeenSerializer
 | 
				
			||||||
from billard.tasks import process_location_data
 | 
					from .forms import UserInformationUpdateForm
 | 
				
			||||||
 | 
					from .tables import LocationTable, LocationAccountingTable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
log = logging.getLogger(__name__)
 | 
					log = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class LocationIndexView(generic.ListView):
 | 
					class LocationIndexView(LoginRequiredMixin, generic.ListView):
 | 
				
			||||||
    template_name = 'billard/location_index.html'
 | 
					    template_name = 'billard/location_index.html'
 | 
				
			||||||
    context_object_name = 'location_list'
 | 
					    context_object_name = 'location_list'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -25,8 +27,17 @@ class LocationIndexView(generic.ListView):
 | 
				
			|||||||
        """Return the last five published questions."""
 | 
					        """Return the last five published questions."""
 | 
				
			||||||
        return Location.objects.filter(users__id=self.request.user.id).order_by('code')
 | 
					        return Location.objects.filter(users__id=self.request.user.id).order_by('code')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_context_data(self, *, object_list=None, **kwargs):
 | 
				
			||||||
 | 
					        context = super().get_context_data(object_list=object_list, **kwargs)
 | 
				
			||||||
 | 
					        table = LocationTable(self.get_queryset())
 | 
				
			||||||
 | 
					        user = self.request.user
 | 
				
			||||||
 | 
					        if user.has_perm('billard.change_accounting'):
 | 
				
			||||||
 | 
					            table = LocationAccountingTable(self.get_queryset())
 | 
				
			||||||
 | 
					        context['table'] = table
 | 
				
			||||||
 | 
					        return context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class LocationDetailView(generic.DetailView):
 | 
					
 | 
				
			||||||
 | 
					class LocationDetailView(LoginRequiredMixin, generic.DetailView):
 | 
				
			||||||
    model = Location
 | 
					    model = Location
 | 
				
			||||||
    template_name = 'billard/location_detail.html'
 | 
					    template_name = 'billard/location_detail.html'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -67,7 +78,7 @@ class AccountingView(generic.ListView):
 | 
				
			|||||||
def accounting_confirm(request, pk):
 | 
					def accounting_confirm(request, pk):
 | 
				
			||||||
    if request.method == 'POST':
 | 
					    if request.method == 'POST':
 | 
				
			||||||
        if 'accountings' in request.POST:
 | 
					        if 'accountings' in request.POST:
 | 
				
			||||||
            acc_ids = ast.literal_eval(request.POST['accountings'])
 | 
					            acc_ids = request.POST.getlist('list_acc_id')
 | 
				
			||||||
            if len(acc_ids) > 0:
 | 
					            if len(acc_ids) > 0:
 | 
				
			||||||
                Accounting.objects.filter(id__in=acc_ids).update(
 | 
					                Accounting.objects.filter(id__in=acc_ids).update(
 | 
				
			||||||
                    billed=True,
 | 
					                    billed=True,
 | 
				
			||||||
@@ -113,6 +124,11 @@ class ClientUpdateLastSeenViewSet(viewsets.ModelViewSet):
 | 
				
			|||||||
    serializer_class = ClientUpdateLastSeenSerializer
 | 
					    serializer_class = ClientUpdateLastSeenSerializer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def process_location_data(request):
 | 
					@method_decorator(login_required, name='dispatch')
 | 
				
			||||||
    process_location_data()
 | 
					class UserUpdateView(UpdateView):
 | 
				
			||||||
    return HttpResponse('DONE')
 | 
					    form_class = UserInformationUpdateForm
 | 
				
			||||||
 | 
					    template_name = 'registration/my_account.html'
 | 
				
			||||||
 | 
					    success_url = reverse_lazy('billard:my_account')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_object(self):
 | 
				
			||||||
 | 
					        return self.request.user
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,10 +35,13 @@ INSTALLED_APPS = [
 | 
				
			|||||||
    'django.contrib.sessions',
 | 
					    'django.contrib.sessions',
 | 
				
			||||||
    'django.contrib.messages',
 | 
					    'django.contrib.messages',
 | 
				
			||||||
    'django.contrib.staticfiles',
 | 
					    'django.contrib.staticfiles',
 | 
				
			||||||
 | 
					    # third party apps
 | 
				
			||||||
 | 
					    'crispy_forms',
 | 
				
			||||||
 | 
					    'debug_toolbar',
 | 
				
			||||||
 | 
					    'django_tables2',
 | 
				
			||||||
    'rest_framework',
 | 
					    'rest_framework',
 | 
				
			||||||
    'rest_framework.authtoken',
 | 
					    'rest_framework.authtoken',
 | 
				
			||||||
    'debug_toolbar',
 | 
					    # carom apps
 | 
				
			||||||
    'crispy_forms',
 | 
					 | 
				
			||||||
    'billard',
 | 
					    'billard',
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -160,10 +163,12 @@ 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_INFO = 'CAROM-DEV'
 | 
				
			||||||
PRODUCT_VERSION = 'v 0.5.1'
 | 
					PRODUCT_VERSION = 'v 1.0.0'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
INTERNAL_IPS = ['127.0.0.1']
 | 
					INTERNAL_IPS = ['127.0.0.1']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DJANGO_TABLES2_TEMPLATE = 'django_tables2/bootstrap4.html'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
try:
 | 
					try:
 | 
				
			||||||
    from local_settings import *
 | 
					    from local_settings import *
 | 
				
			||||||
except ImportError:
 | 
					except ImportError:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,8 +24,6 @@ urlpatterns = [
 | 
				
			|||||||
    path('admin/', admin.site.urls),
 | 
					    path('admin/', admin.site.urls),
 | 
				
			||||||
    path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
 | 
					    path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
 | 
				
			||||||
    path('billard/', include('billard.urls')),
 | 
					    path('billard/', include('billard.urls')),
 | 
				
			||||||
    path('login/', auth_views.login, name='login'),
 | 
					 | 
				
			||||||
    path('logout/', auth_views.logout, name='logout'),
 | 
					 | 
				
			||||||
    path('', include('django.contrib.auth.urls')),
 | 
					    path('', include('django.contrib.auth.urls')),
 | 
				
			||||||
    path('', RedirectView.as_view(url='billard/', permanent=False), name='index')
 | 
					    path('', RedirectView.as_view(url='billard/', permanent=False), name='index')
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +0,0 @@
 | 
				
			|||||||
Django<2.1
 | 
					 | 
				
			||||||
django-crispy-forms==1.7.0
 | 
					 | 
				
			||||||
django-extensions>=1.7.0
 | 
					 | 
				
			||||||
djangorestframework>=3.6.0
 | 
					 | 
				
			||||||
requests>=2.18.0
 | 
					 | 
				
			||||||
django-debug-toolbar<2.0.0
 | 
					 | 
				
			||||||
							
								
								
									
										2050
									
								
								static/css/bootstrap-grid.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2050
									
								
								static/css/bootstrap-grid.css
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										7
									
								
								static/css/bootstrap-grid.min.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								static/css/bootstrap-grid.min.css
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										330
									
								
								static/css/bootstrap-reboot.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										330
									
								
								static/css/bootstrap-reboot.css
									
									
									
									
										vendored
									
									
								
							@@ -1,330 +0,0 @@
 | 
				
			|||||||
/*!
 | 
					 | 
				
			||||||
 * Bootstrap Reboot v4.0.0 (https://getbootstrap.com)
 | 
					 | 
				
			||||||
 * Copyright 2011-2018 The Bootstrap Authors
 | 
					 | 
				
			||||||
 * Copyright 2011-2018 Twitter, Inc.
 | 
					 | 
				
			||||||
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 | 
					 | 
				
			||||||
 * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
*,
 | 
					 | 
				
			||||||
*::before,
 | 
					 | 
				
			||||||
*::after {
 | 
					 | 
				
			||||||
  box-sizing: border-box;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
html {
 | 
					 | 
				
			||||||
  font-family: sans-serif;
 | 
					 | 
				
			||||||
  line-height: 1.15;
 | 
					 | 
				
			||||||
  -webkit-text-size-adjust: 100%;
 | 
					 | 
				
			||||||
  -ms-text-size-adjust: 100%;
 | 
					 | 
				
			||||||
  -ms-overflow-style: scrollbar;
 | 
					 | 
				
			||||||
  -webkit-tap-highlight-color: transparent;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@-ms-viewport {
 | 
					 | 
				
			||||||
  width: device-width;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
article, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section {
 | 
					 | 
				
			||||||
  display: block;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
body {
 | 
					 | 
				
			||||||
  margin: 0;
 | 
					 | 
				
			||||||
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
 | 
					 | 
				
			||||||
  font-size: 1rem;
 | 
					 | 
				
			||||||
  font-weight: 400;
 | 
					 | 
				
			||||||
  line-height: 1.5;
 | 
					 | 
				
			||||||
  color: #212529;
 | 
					 | 
				
			||||||
  text-align: left;
 | 
					 | 
				
			||||||
  background-color: #fff;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[tabindex="-1"]:focus {
 | 
					 | 
				
			||||||
  outline: 0 !important;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
hr {
 | 
					 | 
				
			||||||
  box-sizing: content-box;
 | 
					 | 
				
			||||||
  height: 0;
 | 
					 | 
				
			||||||
  overflow: visible;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
h1, h2, h3, h4, h5, h6 {
 | 
					 | 
				
			||||||
  margin-top: 0;
 | 
					 | 
				
			||||||
  margin-bottom: 0.5rem;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
p {
 | 
					 | 
				
			||||||
  margin-top: 0;
 | 
					 | 
				
			||||||
  margin-bottom: 1rem;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
abbr[title],
 | 
					 | 
				
			||||||
abbr[data-original-title] {
 | 
					 | 
				
			||||||
  text-decoration: underline;
 | 
					 | 
				
			||||||
  -webkit-text-decoration: underline dotted;
 | 
					 | 
				
			||||||
  text-decoration: underline dotted;
 | 
					 | 
				
			||||||
  cursor: help;
 | 
					 | 
				
			||||||
  border-bottom: 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
address {
 | 
					 | 
				
			||||||
  margin-bottom: 1rem;
 | 
					 | 
				
			||||||
  font-style: normal;
 | 
					 | 
				
			||||||
  line-height: inherit;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ol,
 | 
					 | 
				
			||||||
ul,
 | 
					 | 
				
			||||||
dl {
 | 
					 | 
				
			||||||
  margin-top: 0;
 | 
					 | 
				
			||||||
  margin-bottom: 1rem;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ol ol,
 | 
					 | 
				
			||||||
ul ul,
 | 
					 | 
				
			||||||
ol ul,
 | 
					 | 
				
			||||||
ul ol {
 | 
					 | 
				
			||||||
  margin-bottom: 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
dt {
 | 
					 | 
				
			||||||
  font-weight: 700;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
dd {
 | 
					 | 
				
			||||||
  margin-bottom: .5rem;
 | 
					 | 
				
			||||||
  margin-left: 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
blockquote {
 | 
					 | 
				
			||||||
  margin: 0 0 1rem;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
dfn {
 | 
					 | 
				
			||||||
  font-style: italic;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
b,
 | 
					 | 
				
			||||||
strong {
 | 
					 | 
				
			||||||
  font-weight: bolder;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
small {
 | 
					 | 
				
			||||||
  font-size: 80%;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sub,
 | 
					 | 
				
			||||||
sup {
 | 
					 | 
				
			||||||
  position: relative;
 | 
					 | 
				
			||||||
  font-size: 75%;
 | 
					 | 
				
			||||||
  line-height: 0;
 | 
					 | 
				
			||||||
  vertical-align: baseline;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sub {
 | 
					 | 
				
			||||||
  bottom: -.25em;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sup {
 | 
					 | 
				
			||||||
  top: -.5em;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
a {
 | 
					 | 
				
			||||||
  color: #007bff;
 | 
					 | 
				
			||||||
  text-decoration: none;
 | 
					 | 
				
			||||||
  background-color: transparent;
 | 
					 | 
				
			||||||
  -webkit-text-decoration-skip: objects;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
a:hover {
 | 
					 | 
				
			||||||
  color: #0056b3;
 | 
					 | 
				
			||||||
  text-decoration: underline;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
a:not([href]):not([tabindex]) {
 | 
					 | 
				
			||||||
  color: inherit;
 | 
					 | 
				
			||||||
  text-decoration: none;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {
 | 
					 | 
				
			||||||
  color: inherit;
 | 
					 | 
				
			||||||
  text-decoration: none;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
a:not([href]):not([tabindex]):focus {
 | 
					 | 
				
			||||||
  outline: 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pre,
 | 
					 | 
				
			||||||
code,
 | 
					 | 
				
			||||||
kbd,
 | 
					 | 
				
			||||||
samp {
 | 
					 | 
				
			||||||
  font-family: monospace, monospace;
 | 
					 | 
				
			||||||
  font-size: 1em;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pre {
 | 
					 | 
				
			||||||
  margin-top: 0;
 | 
					 | 
				
			||||||
  margin-bottom: 1rem;
 | 
					 | 
				
			||||||
  overflow: auto;
 | 
					 | 
				
			||||||
  -ms-overflow-style: scrollbar;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
figure {
 | 
					 | 
				
			||||||
  margin: 0 0 1rem;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
img {
 | 
					 | 
				
			||||||
  vertical-align: middle;
 | 
					 | 
				
			||||||
  border-style: none;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
svg:not(:root) {
 | 
					 | 
				
			||||||
  overflow: hidden;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
table {
 | 
					 | 
				
			||||||
  border-collapse: collapse;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
caption {
 | 
					 | 
				
			||||||
  padding-top: 0.75rem;
 | 
					 | 
				
			||||||
  padding-bottom: 0.75rem;
 | 
					 | 
				
			||||||
  color: #6c757d;
 | 
					 | 
				
			||||||
  text-align: left;
 | 
					 | 
				
			||||||
  caption-side: bottom;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
th {
 | 
					 | 
				
			||||||
  text-align: inherit;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
label {
 | 
					 | 
				
			||||||
  display: inline-block;
 | 
					 | 
				
			||||||
  margin-bottom: .5rem;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
button {
 | 
					 | 
				
			||||||
  border-radius: 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
button:focus {
 | 
					 | 
				
			||||||
  outline: 1px dotted;
 | 
					 | 
				
			||||||
  outline: 5px auto -webkit-focus-ring-color;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
input,
 | 
					 | 
				
			||||||
button,
 | 
					 | 
				
			||||||
select,
 | 
					 | 
				
			||||||
optgroup,
 | 
					 | 
				
			||||||
textarea {
 | 
					 | 
				
			||||||
  margin: 0;
 | 
					 | 
				
			||||||
  font-family: inherit;
 | 
					 | 
				
			||||||
  font-size: inherit;
 | 
					 | 
				
			||||||
  line-height: inherit;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
button,
 | 
					 | 
				
			||||||
input {
 | 
					 | 
				
			||||||
  overflow: visible;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
button,
 | 
					 | 
				
			||||||
select {
 | 
					 | 
				
			||||||
  text-transform: none;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
button,
 | 
					 | 
				
			||||||
html [type="button"],
 | 
					 | 
				
			||||||
[type="reset"],
 | 
					 | 
				
			||||||
[type="submit"] {
 | 
					 | 
				
			||||||
  -webkit-appearance: button;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
button::-moz-focus-inner,
 | 
					 | 
				
			||||||
[type="button"]::-moz-focus-inner,
 | 
					 | 
				
			||||||
[type="reset"]::-moz-focus-inner,
 | 
					 | 
				
			||||||
[type="submit"]::-moz-focus-inner {
 | 
					 | 
				
			||||||
  padding: 0;
 | 
					 | 
				
			||||||
  border-style: none;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
input[type="radio"],
 | 
					 | 
				
			||||||
input[type="checkbox"] {
 | 
					 | 
				
			||||||
  box-sizing: border-box;
 | 
					 | 
				
			||||||
  padding: 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
input[type="date"],
 | 
					 | 
				
			||||||
input[type="time"],
 | 
					 | 
				
			||||||
input[type="datetime-local"],
 | 
					 | 
				
			||||||
input[type="month"] {
 | 
					 | 
				
			||||||
  -webkit-appearance: listbox;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
textarea {
 | 
					 | 
				
			||||||
  overflow: auto;
 | 
					 | 
				
			||||||
  resize: vertical;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fieldset {
 | 
					 | 
				
			||||||
  min-width: 0;
 | 
					 | 
				
			||||||
  padding: 0;
 | 
					 | 
				
			||||||
  margin: 0;
 | 
					 | 
				
			||||||
  border: 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
legend {
 | 
					 | 
				
			||||||
  display: block;
 | 
					 | 
				
			||||||
  width: 100%;
 | 
					 | 
				
			||||||
  max-width: 100%;
 | 
					 | 
				
			||||||
  padding: 0;
 | 
					 | 
				
			||||||
  margin-bottom: .5rem;
 | 
					 | 
				
			||||||
  font-size: 1.5rem;
 | 
					 | 
				
			||||||
  line-height: inherit;
 | 
					 | 
				
			||||||
  color: inherit;
 | 
					 | 
				
			||||||
  white-space: normal;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
progress {
 | 
					 | 
				
			||||||
  vertical-align: baseline;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[type="number"]::-webkit-inner-spin-button,
 | 
					 | 
				
			||||||
[type="number"]::-webkit-outer-spin-button {
 | 
					 | 
				
			||||||
  height: auto;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[type="search"] {
 | 
					 | 
				
			||||||
  outline-offset: -2px;
 | 
					 | 
				
			||||||
  -webkit-appearance: none;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[type="search"]::-webkit-search-cancel-button,
 | 
					 | 
				
			||||||
[type="search"]::-webkit-search-decoration {
 | 
					 | 
				
			||||||
  -webkit-appearance: none;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
::-webkit-file-upload-button {
 | 
					 | 
				
			||||||
  font: inherit;
 | 
					 | 
				
			||||||
  -webkit-appearance: button;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
output {
 | 
					 | 
				
			||||||
  display: inline-block;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
summary {
 | 
					 | 
				
			||||||
  display: list-item;
 | 
					 | 
				
			||||||
  cursor: pointer;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template {
 | 
					 | 
				
			||||||
  display: none;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[hidden] {
 | 
					 | 
				
			||||||
  display: none !important;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
/*# sourceMappingURL=bootstrap-reboot.css.map */
 | 
					 | 
				
			||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										8
									
								
								static/css/bootstrap-reboot.min.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								static/css/bootstrap-reboot.min.css
									
									
									
									
										vendored
									
									
								
							@@ -1,8 +0,0 @@
 | 
				
			|||||||
/*!
 | 
					 | 
				
			||||||
 * Bootstrap Reboot v4.0.0 (https://getbootstrap.com)
 | 
					 | 
				
			||||||
 * Copyright 2011-2018 The Bootstrap Authors
 | 
					 | 
				
			||||||
 * Copyright 2011-2018 Twitter, Inc.
 | 
					 | 
				
			||||||
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 | 
					 | 
				
			||||||
 * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
 | 
					 | 
				
			||||||
 */*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg:not(:root){overflow:hidden}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}
 | 
					 | 
				
			||||||
/*# sourceMappingURL=bootstrap-reboot.min.css.map */
 | 
					 | 
				
			||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2524
									
								
								static/css/bootstrap.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2524
									
								
								static/css/bootstrap.css
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										4
									
								
								static/css/bootstrap.min.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								static/css/bootstrap.min.css
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										6328
									
								
								static/js/bootstrap.bundle.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6328
									
								
								static/js/bootstrap.bundle.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										7
									
								
								static/js/bootstrap.bundle.min.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								static/js/bootstrap.bundle.min.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2207
									
								
								static/js/bootstrap.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2207
									
								
								static/js/bootstrap.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										4
									
								
								static/js/bootstrap.min.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								static/js/bootstrap.min.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										8269
									
								
								static/js/jquery-3.3.1.slim.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8269
									
								
								static/js/jquery-3.3.1.slim.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2
									
								
								static/js/jquery-3.3.1.slim.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								static/js/jquery-3.3.1.slim.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1
									
								
								static/js/jquery-3.3.1.slim.min.map
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								static/js/jquery-3.3.1.slim.min.map
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -36,11 +36,6 @@
 | 
				
			|||||||
                        <li class="nav-item">
 | 
					                        <li class="nav-item">
 | 
				
			||||||
                            <a class="nav-link" href="{% url 'billard:location_index' %}">Standorte</a>
 | 
					                            <a class="nav-link" href="{% url 'billard:location_index' %}">Standorte</a>
 | 
				
			||||||
                        </li>
 | 
					                        </li>
 | 
				
			||||||
                        {% if user.is_superuser %}
 | 
					 | 
				
			||||||
                            <li class="nav-item">
 | 
					 | 
				
			||||||
                                <a class="nav-link" href="/admin">Administration</a>
 | 
					 | 
				
			||||||
                            </li>
 | 
					 | 
				
			||||||
                        {% endif %}
 | 
					 | 
				
			||||||
                    </ul>
 | 
					                    </ul>
 | 
				
			||||||
                    {% if user.is_authenticated %}
 | 
					                    {% if user.is_authenticated %}
 | 
				
			||||||
                        <ul class="navbar-nav ml-auto">
 | 
					                        <ul class="navbar-nav ml-auto">
 | 
				
			||||||
@@ -50,8 +45,12 @@
 | 
				
			|||||||
                                    {{ user.username }}
 | 
					                                    {{ user.username }}
 | 
				
			||||||
                                </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="{% url 'billard:my_account' %}">My account</a>
 | 
				
			||||||
                                    <a class="disabled dropdown-item" href="#">{% settings_value "PRODUCT_VERSION" %}</a>
 | 
					                                    {% if user.is_superuser %}
 | 
				
			||||||
 | 
					                                        <a class="dropdown-item" href="/admin">Administration</a>
 | 
				
			||||||
 | 
					                                    {% endif %}
 | 
				
			||||||
 | 
					                                    <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,23 +1,28 @@
 | 
				
			|||||||
{% extends '_base_accounts.html' %}
 | 
					{% extends '_base.html' %}
 | 
				
			||||||
 | 
					{% load static from staticfiles %}
 | 
				
			||||||
{% load crispy_forms_tags %}
 | 
					{% load crispy_forms_tags %}
 | 
				
			||||||
 | 
					{% load form_tags %}
 | 
				
			||||||
{% block title %}login{% endblock %}
 | 
					{% block title %}Anmelden{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% block content %}
 | 
					{% block content %}
 | 
				
			||||||
    <div class="row justify-content-center">
 | 
					    <div class="row justify-content-center" style="margin-top: 80px;">
 | 
				
			||||||
        <div class="col-lg-4 col-md-6 col-sm-8">
 | 
					        <div class="col-lg-4 col-md-6 col-sm-8">
 | 
				
			||||||
            <div class="card">
 | 
					            <form method="post" novalidate>
 | 
				
			||||||
                <div class="card-body">
 | 
					                {% csrf_token %}
 | 
				
			||||||
                    <h3 class="card-title">Log in</h3>
 | 
					                <div class="card">
 | 
				
			||||||
                    <form method="post" novalidate>
 | 
					                    <div class="card-header text-center">
 | 
				
			||||||
                        {% csrf_token %}
 | 
					                        <h3>{% settings_value "PRODUCT_INFO" %}</h3>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                    <div class="card-body">
 | 
				
			||||||
 | 
					                        <h3 class="card-title">Login</h3>
 | 
				
			||||||
                        <input type="hidden" name="next" value="{{ next }}">
 | 
					                        <input type="hidden" name="next" value="{{ next }}">
 | 
				
			||||||
                        {{ form|crispy }}
 | 
					                        {{ form|crispy }}
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                    <div class="card-footer">
 | 
				
			||||||
                        <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>
 | 
					                    </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </div>
 | 
					            </form>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
{% endblock %}
 | 
					{% endblock %}
 | 
				
			||||||
							
								
								
									
										21
									
								
								templates/registration/my_account.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								templates/registration/my_account.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					{% extends '_base.html' %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% load crispy_forms_tags %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block title %}My account{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block breadcrumb %}
 | 
				
			||||||
 | 
					  <li class="breadcrumb-item active">My account</li>
 | 
				
			||||||
 | 
					{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block content %}
 | 
				
			||||||
 | 
					  <div class="row">
 | 
				
			||||||
 | 
					    <div class="col-lg-6 col-md-8 col-sm-10">
 | 
				
			||||||
 | 
					      <form method="post" novalidate>
 | 
				
			||||||
 | 
					        {% csrf_token %}
 | 
				
			||||||
 | 
					        {{ form|crispy }}
 | 
				
			||||||
 | 
					        <button type="submit" class="btn btn-success">Save changes</button>
 | 
				
			||||||
 | 
					      </form>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					{% endblock %}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user