Merge branch 'feature/#3_accounting_dialog' into develop

# Conflicts:
#	billard/models.py
#	billard/views.py
This commit is contained in:
Robert Einsle 2017-03-09 20:52:12 +01:00
commit 201c347fcc
12 changed files with 148 additions and 36 deletions

View File

@ -27,8 +27,8 @@ class LocationAdmin(admin.ModelAdmin):
@admin.register(Client)
class ClientAdmin(admin.ModelAdmin):
list_display = ('uuid', 'location')
fields = ['location', 'uuid']
list_display = ('uuid', 'location', 'report_user')
fields = ['location', 'uuid', 'report_user']
@admin.register(LocationData)

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-02-27 07:57
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('billard', '0016_auto_20170225_1822'),
]
operations = [
migrations.AddField(
model_name='accounting',
name='reporter_uuid',
field=models.UUIDField(blank=True, null=True, verbose_name='Reporter UUID'),
),
]

View File

@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-03-02 20:58
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('billard', '0017_accounting_reporter_uuid'),
]
operations = [
migrations.AddField(
model_name='accounting',
name='prize_hh',
field=models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True, verbose_name='Preis Happy Hour'),
),
migrations.AddField(
model_name='accounting',
name='prize_normal',
field=models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True, verbose_name='Preis Normalzeit'),
),
migrations.AddField(
model_name='client',
name='report_user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reporting_clients', to=settings.AUTH_USER_MODEL, verbose_name='Reporting Benutzer'),
),
]

View File

@ -51,6 +51,7 @@ class Location(models.Model):
class Client(models.Model):
uuid = models.UUIDField(unique=True, default=uuid.uuid4, verbose_name="Identifier")
location = models.ForeignKey(Location, verbose_name="Standort")
report_user = models.ForeignKey(User, blank=True, null=True, verbose_name="Reporting Benutzer", related_name='reporting_clients')
def __str__(self):
return '{}, {}'.format(self.location.name, self.uuid)
@ -69,24 +70,6 @@ class Desk(models.Model):
prize_hh = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True,
verbose_name="Preis Happy Hour")
def accounting_for(self):
t = Accounting.objects.filter(client=self.client, desk_no=self.desk_no)[:3][::-1]
client = self.client
location = client.location
if t.__len__() > 0:
a = t[t.__len__() - 1]
if a.time_to is None:
prize = utils.get_prize_for(
start=a.time_from,
end=datetime.now(timezone.utc),
pph=self.prize,
hh_start=location.happy_hour_start,
hh_end=location.happy_hour_end,
pphh=self.prize_hh,
)
if prize != a.prize:
a.prize = prize
return t
def __str__(self):
return '{}, {}'.format(self.client.uuid, self.name)
@ -102,6 +85,9 @@ class Accounting(models.Model):
time_to = models.DateTimeField(blank=True, null=True, verbose_name="Ende")
prize = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True, verbose_name="Preis")
billed = models.BooleanField(default=False, verbose_name="Abgerechnet")
reporter_uuid = models.UUIDField(blank=True, null=True, verbose_name='Reporter UUID')
prize_normal = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True, verbose_name="Preis Normalzeit")
prize_hh = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True, verbose_name="Preis Happy Hour")
def __str__(self):
return '{}: {} -> {}, {}, {}'.format(self.desk, self.time_from, self.time_to, self.prize, self.billed)
@ -116,5 +102,3 @@ class Accounting(models.Model):
def test(sender, **kwargs):
from .tasks import process_location_data
process_location_data.delay()

View File

@ -1,4 +1,4 @@
from billard.models import *
from billard.models import LocationData
from rest_framework import serializers

View File

@ -0,0 +1,30 @@
{% if account %}
<div id="accountsmodal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Abrechnung: ({{ account.desk.desk_no }}) {{ account.desk.name }} </h4>
</div>
<div class="modal-body">
<table class="table">
<tr>
<td>Normalpreis:</td>
<td>{{ account.prize_normal }}</td>
</tr>
<tr>
<td>Preis Happy Hour:</td>
<td>{{ account.prize_hh }}</td>
</tr>
<tr>
<td>Gesamt:</td>
<td>{{ account.prize }}</td>
</tr>
</table>
</div>
<div class="modal-footer">
<a class="btn btn-default btn-primary" href="{% url 'accountmodalconfirm' account.pk %}">Schliessen</a>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
{% endif %}

View File

@ -19,16 +19,25 @@
<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 });
window.setInterval(refresh_page, 1000);
interval = window.setInterval(refresh_page, 1000);
});
function refresh_page() {
$('#desk_data').load('#')
$('#desk_data').load('#');
$('#modal-wrapper').load('{% url 'accountmodal' %}', function() {
if ( $('#accountsmodal').length ) {
window.clearInterval(interval);
$('#accountsmodal').modal('show');
}
});
}
</script>
{% endblock %}

View File

@ -22,7 +22,7 @@ def display_client(client, desk_no):
a = acc[-1]
if a.time_to is None:
alert = 'alert-info'
prize = utils.get_prize_for(
prize, u1, u2 = utils.get_prize_for(
start=a.time_from,
end=datetime.now(),
pph=desk.prize,

View File

@ -9,5 +9,7 @@ urlpatterns = [
url(r'^$', views.index, name='carom_index'),
url(r'^(?P<pk>[0-9]+)/$', views.LocationDataDetailView.as_view(), name='detail'),
url(r'api/v1/', include(router.urls)),
url(r'process_locationdata', views.process_locationdata, name='process_locationdata')
url(r'process_locationdata', views.process_locationdata, name='process_locationdata'),
url(r'accountmodal$', views.accountmodalview, name='accountmodal'),
url(r'accoutmodal/confirm/(?P<pk>[0-9]+)$', views.accountmodalconfirmview, name="accountmodalconfirm")
]

View File

@ -16,6 +16,8 @@ def get_prize_for(start, end, pph=0, hh_start=None, hh_end=None, pphh=0):
if end <= start:
raise ValueError('end date must be after start date')
prize = 0
prize_normal = 0
prize_hh = 0
if hh_start is not None and hh_end is not None and pphh is not None:
d = start.date()
t = start.time()
@ -24,35 +26,46 @@ def get_prize_for(start, end, pph=0, hh_start=None, hh_end=None, pphh=0):
while True:
if t < hh_start:
if end_time < hh_start and d == end_date:
prize += calculate_prize_for(start=t, end=end_time, pph=pph)
p = calculate_prize_for(start=t, end=end_time, pph=pph)
prize += p
prize_normal += p
break
else:
prize += calculate_prize_for(start=t, end=hh_start, pph=pph)
p += calculate_prize_for(start=t, end=hh_start, pph=pph)
prize += p
prize_normal += p
t = hh_start
elif hh_start <= t < hh_end:
if end_time < hh_end and d == end_date:
prize += calculate_prize_for(start=t, end=end_time, pph=pphh)
p += calculate_prize_for(start=t, end=end_time, pph=pphh)
prize += p
prize_hh += p
break
else:
prize += calculate_prize_for(start=t, end=hh_end, pph=pphh)
p += calculate_prize_for(start=t, end=hh_end, pph=pphh)
prize += p
prize_hh += p
t = hh_end
else:
if d == end_date:
prize += calculate_prize_for(start=t, end=end_time, pph=pph)
p += calculate_prize_for(start=t, end=end_time, pph=pph)
prize += p
prize_normal += p
break
else:
prize += calculate_prize_for(start=t, end=datetime.strptime('23:59:59', '%H:%M:%S').time(), pph=pph)
p += calculate_prize_for(start=t, end=datetime.strptime('23:59:59', '%H:%M:%S').time(), pph=pph)
prize += p
prize_normal += p
t = datetime.strptime('00:00:00', '%H:%M:%S').time()
d = (datetime.combine(d, t) + timedelta(days=1)).date()
else:
prize = calculate_prize_for(start=start, end=end, pph=pph)
return prize
return prize, prize_normal, prize_hh
def calculate_prize_for(start, end, pph=0):
pps = pph / 3600
d = date.today()
seconds = 0
if isinstance(start, datetime):
seconds = (end - start).seconds
else:

View File

@ -23,6 +23,7 @@ class IndexView(generic.ListView):
return ('billard/locationdata_list_ajax.html',)
return super().get_template_names()
class LocationDataDetailView(DetailView):
model = LocationData
@ -32,6 +33,26 @@ class LocationDataDetailView(DetailView):
return super().get_template_names()
@login_required
def accountmodalview(request):
try:
account = Accounting.objects.filter(reporter_uuid=Client.objects.get(report_user=request.user).uuid).first
except Client.DoesNotExist:
account = None
context = {
'account': account
}
return render(request, 'billard/accountmodal.html', context=context)
@login_required
def accountmodalconfirmview(request, pk):
account = Accounting.objects.get(pk=pk)
account.reporter_uuid = None
account.save()
return redirect('carom_index')
@login_required
def index(request):
if request.method == 'GET':

View File

@ -1,6 +1,6 @@
celery==4.0.2
Django==1.10.5
django-crispy-forms==1.6.1
django-extensions==1.7.6
django-extensions==1.7.7
djangorestframework==3.5.4
requests==2.13.0