carom-server/billard/views.py

135 lines
4.9 KiB
Python

import logging
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.shortcuts import render, redirect
from django.urls import reverse_lazy
from django.utils import timezone
from django.utils.decorators import method_decorator
from django.views import generic
from django.views.generic import UpdateView
from rest_framework import viewsets
from billard.models import LocationData, Location, Client, Accounting
from billard.serializers import LocationDataSerializer, ClientUpdateLastSeenSerializer
from .forms import UserInformationUpdateForm
from .tables import LocationTable, LocationAccountingTable
log = logging.getLogger(__name__)
class LocationIndexView(LoginRequiredMixin, generic.ListView):
template_name = 'billard/location_index.html'
context_object_name = 'location_list'
def get_queryset(self):
"""Return the last five published questions."""
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(LoginRequiredMixin, generic.DetailView):
model = Location
template_name = 'billard/location_detail.html'
def dispatch(self, request, *args, **kwargs):
if request.is_ajax():
context = {
'location': self.get_object(),
}
return render(request, template_name='billard/location_detail_ajax.html', context=context)
result = super(LocationDetailView, self).dispatch(request, *args, **kwargs)
result.context_data['pk'] = self.kwargs['pk']
return result
@method_decorator(login_required, name='dispatch')
class AccountingView(generic.ListView):
template_name = 'billard/accounting.html'
context_object_name = 'accounting'
def get_queryset(self):
return Accounting.objects.filter(billed=False).filter(desk__client__location_id=self.kwargs['pk']) \
.exclude(time_to__isnull=True).order_by('time_from')
def dispatch(self, request, *args, **kwargs):
result = super(AccountingView, self).dispatch(request, *args, **kwargs)
acc_sum = self.get_queryset().aggregate(Sum('prize'))
if acc_sum['prize__sum'] is None:
result.context_data['acc_sum'] = 0
else:
result.context_data['acc_sum'] = acc_sum['prize__sum']
result.context_data['acc_ids'] = [acc.id for acc in self.get_queryset().all()]
result.context_data['location'] = Location.objects.get(pk=self.kwargs['pk'])
return result
@login_required
@permission_required('billard.change_accounting')
def accounting_confirm(request, pk):
if request.method == 'POST':
if 'accountings' in request.POST:
acc_ids = request.POST.getlist('list_acc_id')
if len(acc_ids) > 0:
Accounting.objects.filter(id__in=acc_ids).update(
billed=True,
account_user=request.user.username,
account_tst=timezone.now(),
)
resp = redirect('billard:accounting_detail', pk=pk)
return resp
@login_required
def account_modal_view(request, loc_pk):
try:
uuids = Client.objects.filter(report_user=request.user).values_list('uuid')
accounts = Accounting.objects.filter(reporter_uuid__in=uuids)
# TODO: support multiple account objects
except Client.DoesNotExist:
accounts = None
context = {
'accounts': accounts,
'loc_pk': loc_pk,
'pks': ','.join([str(account.pk) for account in accounts]),
}
return render(request, 'billard/accountmodal.html', context=context)
@login_required
def account_modal_confirm_view(request, loc_pk, pks):
for pk in pks.split(','):
account = Accounting.objects.get(pk=pk)
account.reporter_uuid = None
account.save()
return redirect('billard:location_detail', pk=loc_pk)
class LocationDataViewSet(viewsets.ModelViewSet):
queryset = LocationData.objects.all()
serializer_class = LocationDataSerializer
class ClientUpdateLastSeenViewSet(viewsets.ModelViewSet):
queryset = LocationData.objects.all()
serializer_class = ClientUpdateLastSeenSerializer
@method_decorator(login_required, name='dispatch')
class UserUpdateView(UpdateView):
form_class = UserInformationUpdateForm
template_name = 'registration/my_account.html'
success_url = reverse_lazy('billard:my_account')
def get_object(self):
return self.request.user