635 lines
25 KiB
Python
635 lines
25 KiB
Python
from django.shortcuts import render
|
|
from django.http import HttpResponse
|
|
from django.template.response import TemplateResponse
|
|
from django.shortcuts import redirect
|
|
from django.views.decorators.csrf import csrf_exempt
|
|
from django.contrib.admin.views.decorators import staff_member_required
|
|
from django.contrib.auth.models import User as DjangoUser
|
|
from django.contrib.auth import authenticate
|
|
from django.contrib.auth import login as auth_login, logout as auth_logout
|
|
from django.core.mail import send_mail, mail_admins, EmailMessage
|
|
from django.db.utils import IntegrityError
|
|
from django.db import transaction
|
|
from django.utils.datastructures import MultiValueDictKeyError
|
|
from datetime import date, datetime, timedelta
|
|
from dateutil.relativedelta import relativedelta
|
|
from weasyprint import HTML
|
|
from urllib.parse import parse_qs
|
|
import secrets
|
|
import requests
|
|
import json
|
|
import glob
|
|
import PIL.Image
|
|
import random
|
|
import itertools
|
|
from collections import OrderedDict
|
|
|
|
from .models import (
|
|
User, ALKATOR_CHOICES_DICT, ALKATOR_CLASSES,
|
|
Profile, Racer, Invoice, Product, InvoiceProduct,
|
|
Cart, CartProduct
|
|
)
|
|
from alkator.settings import COMGATE_MERCHANT, COMGATE_SECRET, COMGATE_TEST
|
|
|
|
|
|
DEADLINE = date(2025, 10, 5)
|
|
ALKATOR_CLASS = 3
|
|
|
|
|
|
@csrf_exempt
|
|
def register_user(request):
|
|
if not request.POST['first_name']:
|
|
return HttpResponse('{"reason":"Jméno je povinné!"}', status=400, content_type='application/json')
|
|
if not request.POST['last_name']:
|
|
return HttpResponse('{"reason":"Přijmení je povinné!"}', status=400, content_type='application/json')
|
|
if not request.POST['email']:
|
|
return HttpResponse('{"reason":"Email je povinný!"}', status=400, content_type='application/json')
|
|
if not request.POST['address']:
|
|
return HttpResponse('{"reason":"Adresa je povinná!"}', status=400, content_type='application/json')
|
|
if not request.POST['password1'] or not request.POST['password2']:
|
|
return HttpResponse('{"reason":"Heslo je povinné!"}', status=400, content_type='application/json')
|
|
if request.POST['password1'] != request.POST['password2']:
|
|
return HttpResponse('{"reason":"Hesla se neshodují!"}', status=400, content_type='application/json')
|
|
if not request.POST['phone']:
|
|
return HttpResponse('{"reason":"Telefon je povinný"}', status=400, content_type='application/json')
|
|
if DjangoUser.objects.filter(email=request.POST['email']):
|
|
return HttpResponse('{"reason":"Email je již registrován!"}', status=400, content_type='application/json')
|
|
email = request.POST['email']
|
|
|
|
user = DjangoUser.objects.create_user(
|
|
email, email, request.POST['password1']
|
|
)
|
|
profile = Profile(
|
|
user=user,
|
|
first_name=request.POST['first_name'],
|
|
last_name=request.POST['last_name'],
|
|
address=request.POST['address'],
|
|
phone=request.POST['phone'],
|
|
)
|
|
profile.save()
|
|
auth_login(request, user)
|
|
return HttpResponse('{"success":"Úspěšná registrace!", "redirect":"/#"}', content_type='application/json')
|
|
|
|
|
|
@csrf_exempt
|
|
def forgotten_password(request):
|
|
if not request.POST['email']:
|
|
return HttpResponse('{"reason":"Email je povinný!"}', status=400, content_type='application/json')
|
|
if not request.POST['password1'] or not request.POST['password2']:
|
|
return HttpResponse('{"reason":"Heslo je povinné!"}', status=400, content_type='application/json')
|
|
if request.POST['password1'] != request.POST['password2']:
|
|
return HttpResponse('{"reason":"Hesla se neshodují!"}', status=400, content_type='application/json')
|
|
if not request.POST['code']:
|
|
return HttpResponse('{"reason":"Kód pro obnovení hesla je povinný!"}', status=400, content_type='application/json')
|
|
try:
|
|
user = DjangoUser.objects.get(username=request.POST['email'])
|
|
except DjangoUser.DoesNotExist:
|
|
return HttpResponse('{"reason":"Účet nenalezen!"}', status=404, content_type='application/json')
|
|
if user.profile.forgotten_password_code != request.POST['code']:
|
|
return HttpResponse('{"reason":"Špatný kód!"}', status=400, content_type='application/json')
|
|
user.set_password(request.POST['password1'])
|
|
user.save()
|
|
auth_login(request, user)
|
|
return HttpResponse('{"success":"Úspěšně změněné heslo uživatele ' + user.email + '!", "redirect":"/#"}', content_type='application/json')
|
|
|
|
|
|
@csrf_exempt
|
|
def login(request):
|
|
if "forgotten_password" in request.POST:
|
|
email = request.POST["email"]
|
|
try:
|
|
user = DjangoUser.objects.get(username=email)
|
|
except DjangoUser.DoesNotExist:
|
|
return HttpResponse('{"reason":"Nezadané jméno nebo uživatel neexistuje!"}', status=404, content_type='application/json')
|
|
code = secrets.token_urlsafe(10)
|
|
user.profile.forgotten_password_code = code
|
|
user.profile.save()
|
|
mail = EmailMessage("zapomenuté heslo v Alkátor Race", f"""Zdravím tě Alkátore,
|
|
|
|
kód pro změnu hesla: {code}
|
|
|
|
Změna hesla probíhá na stránce: https://alkator.cz/#forgotten_password
|
|
|
|
Na tento email není třeba odpovídat, protože je generován automaticky. V případě potřeby pište na info@alkator.cz .
|
|
|
|
ALKÁTOR TEAM
|
|
email: info@alkator.cz
|
|
tel: + 420 728 018 088
|
|
web: https://alkator.cz""", "info@alkator.cz", [request.POST["email"]])
|
|
mail.send()
|
|
return HttpResponse('{"success":"Úspěšně poslán kód pro obnovení hesla uživatele '+ user.email + '", "redirect":"/#forgotten_password"}', content_type='application/json')
|
|
else:
|
|
try:
|
|
user = authenticate(request, username=request.POST['email'], password=request.POST['password'])
|
|
except MultiValueDictKeyError:
|
|
return HttpResponse('{"reason":"Nezadané jméno nebo heslo!"}', status=400, content_type='application/json')
|
|
if user is not None:
|
|
auth_login(request, user)
|
|
return HttpResponse('{"success":"Úspěšně přihlášen uživatel '+ user.email + '", "redirect":"/#"}', content_type='application/json')
|
|
else:
|
|
return HttpResponse('{"reason":"Nesprávné jméno nebo heslo!"}', status=400, content_type='application/json')
|
|
|
|
|
|
@csrf_exempt
|
|
def logout(request):
|
|
|
|
auth_logout(request)
|
|
return redirect("/#")
|
|
|
|
|
|
@csrf_exempt
|
|
def register_racer(request):
|
|
if not request.user.is_authenticated:
|
|
return HttpResponse('{"reason":"Je potřeba se přihlásit!"}', status=400, content_type='application/json')
|
|
if date.today() >= DEADLINE:
|
|
return HttpResponse('{"reason":"Too late!"}', status=400, content_type='application/json')
|
|
if not request.POST.get('agreement'):
|
|
return HttpResponse('{"reason":"Je potřeba souhlasit se zpracováním údajů!"}', status=400, content_type='application/json')
|
|
if not request.POST['first_name']:
|
|
return HttpResponse('{"reason":"Jméno je povinné!"}', status=400, content_type='application/json')
|
|
if not request.POST['last_name']:
|
|
return HttpResponse('{"reason":"Přijmení je povinné!"}', status=400, content_type='application/json')
|
|
try:
|
|
dob = datetime.strptime(request.POST['date_of_birth'], "%Y-%m-%d").date()
|
|
if dob > DEADLINE - relativedelta(years=18):
|
|
return HttpResponse('{"reason":"Je potřeba mít 18 let v den závodu!"}', status=400, content_type='application/json')
|
|
elif dob < DEADLINE - relativedelta(years=100):
|
|
return HttpResponse('{"reason":"Opravdu vám je 100 let?"}', status=400, content_type='application/json')
|
|
except:
|
|
return HttpResponse('{"reason":"Špatný formát datu narození!"}', status=400, content_type='application/json')
|
|
|
|
invoice_id = Invoice.next_invoice_id()
|
|
|
|
profile = request.user.profile
|
|
user = request.user
|
|
|
|
product = Product.objects.get(id=1)
|
|
price = product.price
|
|
|
|
if product.quantity <= 0:
|
|
return HttpResponse('{"reason":"Jsme vyprodaní!"}', status=400, content_type='application/json')
|
|
|
|
|
|
invoice = Invoice(
|
|
invoice_id=invoice_id,
|
|
user=user,
|
|
total_price=price,
|
|
address="",
|
|
)
|
|
racer = Racer(
|
|
product=product,
|
|
invoice=invoice,
|
|
quantity=1,
|
|
profile = profile,
|
|
first_name = request.POST['first_name'],
|
|
last_name = request.POST['last_name'],
|
|
email = request.POST['email'],
|
|
team = request.POST['team'],
|
|
phone = request.POST['phone'],
|
|
date_of_birth = dob,
|
|
alkator_class = ALKATOR_CLASS,
|
|
price=price,
|
|
)
|
|
invoice.save()
|
|
racer.save()
|
|
|
|
payment_data = {
|
|
'merchant': COMGATE_MERCHANT,
|
|
'test': 'true' if COMGATE_TEST else 'false',
|
|
'price': price * 100,
|
|
'curr': 'CZK',
|
|
'method': 'ALL',
|
|
'label': 'Startovné na závod Alkátor Race Dolní Čermná 2025',
|
|
'email': user.email,
|
|
'fullName': f"{profile.first_name} {profile.last_name}",
|
|
'refId': f'{invoice.invoice_id}',
|
|
'secret': COMGATE_SECRET,
|
|
'prepareOnly': 'true',
|
|
}
|
|
result = requests.post('https://payments.comgate.cz/v1.0/create', data=payment_data)
|
|
|
|
result = parse_qs(result.text)
|
|
|
|
if result['code'][0] != '0':
|
|
racer.delete()
|
|
invoice.delete()
|
|
return HttpResponse('{"reason":"Chyba na straně platební brány: ' + result['message'][0] + ', zkuste prosím registraci později."}', status=400, content_type='application/json')
|
|
|
|
product.quantity -= 1
|
|
product.save()
|
|
|
|
invoice.trans_id = result['transId'][0]
|
|
invoice.save()
|
|
|
|
return HttpResponse('{"success":"", "redirect":"' + result['redirect'][0] + '"}', content_type='application/json')
|
|
|
|
|
|
def login_status(request):
|
|
if not request.user.is_authenticated:
|
|
return HttpResponse('{}', content_type='application/json')
|
|
|
|
user = request.user
|
|
racers = user.profile.racers.all()
|
|
return HttpResponse(json.dumps({
|
|
"email": user.email,
|
|
"first_name": user.profile.first_name,
|
|
"last_name": user.profile.last_name,
|
|
"address": user.profile.address,
|
|
"racers": [{
|
|
"id": racer.invoice_id,
|
|
"first_name": racer.first_name,
|
|
"last_name": racer.last_name,
|
|
"email": racer.email,
|
|
"phone": racer.phone,
|
|
"team": racer.team,
|
|
"date_of_birth": racer.date_of_birth.strftime("%Y-%m-%d"),
|
|
"paid": racer.invoice.paid,
|
|
} for racer in racers]
|
|
}), content_type='application/json')
|
|
|
|
|
|
@csrf_exempt
|
|
def change_racer(request):
|
|
try:
|
|
racer = Racer.objects.get(invoice_id=request.POST['id'])
|
|
if request.user != racer.profile.user:
|
|
return HttpResponse('{"reason":"Nedostatečná práva!"}', status=400, content_type='application/json')
|
|
if date.today() >= DEADLINE:
|
|
return HttpResponse('{"reason":"Příliš pozdě na změnu účastníka!"}', status=400, content_type='application/json')
|
|
if not request.POST['first_name']:
|
|
return HttpResponse('{"reason":"Jméno je povinné!"}', status=400, content_type='application/json')
|
|
if not request.POST['last_name']:
|
|
return HttpResponse('{"reason":"Přijmení je povinné!"}', status=400, content_type='application/json')
|
|
try:
|
|
dob = datetime.strptime(request.POST['date_of_birth'], "%Y-%m-%d").date()
|
|
if dob > DEADLINE - relativedelta(years=18):
|
|
return HttpResponse('{"reason":"Je potřeba mít 18 let v den závodu!"}', status=400, content_type='application/json')
|
|
elif dob < DEADLINE - relativedelta(years=100):
|
|
return HttpResponse('{"reason":"Opravdu vám je 100 let?"}', status=400, content_type='application/json')
|
|
except:
|
|
return HttpResponse('{"reason":"Špatný formát datu narození!"}', status=400, content_type='application/json')
|
|
racer.first_name = request.POST['first_name']
|
|
racer.last_name = request.POST['last_name']
|
|
racer.email = request.POST['email']
|
|
racer.phone = request.POST['phone']
|
|
racer.team = request.POST['team']
|
|
racer.date_of_birth = dob
|
|
racer.save()
|
|
return HttpResponse('{"success":"Úspěšně uloženo."}', content_type='application/json')
|
|
except MultiValueDictKeyError:
|
|
return HttpResponse('{"reason":"Nějaký údaj chybí!"}', status=400, content_type='application/json')
|
|
except Racer.DoesNotExist:
|
|
return HttpResponse('{"reason":"Upravujete neexistujícího závodníka!"}', status=400, content_type='application/json')
|
|
|
|
|
|
@csrf_exempt
|
|
def payment_result(request):
|
|
result = parse_qs(request.body.decode('utf8'))
|
|
ref_id = int(result['refId'][0])
|
|
paid = result['status'][0]
|
|
secret_match = result['secret'][0] == COMGATE_SECRET
|
|
test = result['test'][0] != 'false'
|
|
if not secret_match or test != COMGATE_TEST:
|
|
return HttpResponse(status=400)
|
|
try:
|
|
invoice = Invoice.objects.get(invoice_id=ref_id)
|
|
user = invoice.user
|
|
except Invoice.DoesNotExist:
|
|
mail_admins('Chyba s platbou!', f'invoice_id={ref_id}&paid={paid}')
|
|
return HttpResponse(status=404)
|
|
if paid == 'PAID':
|
|
invoice.paid = True
|
|
invoice.save()
|
|
try:
|
|
racer = Racer.objects.get(invoice=invoice)
|
|
mail = EmailMessage(
|
|
subject=f"úspěšná registrace do závodu Alkátor race Dolní Čermná ({racer.first_name} {racer.last_name})",
|
|
body=f"""Zdravím tě Alkátore,
|
|
toto je potvrzovací email o účasti v nezapomenutelném závodě Alkátor-race.
|
|
Prosíme kontrolujete si své hromadné schránky a spamy.
|
|
|
|
Závod se koná 5.10.2024 v Dolní Čermné.
|
|
Zajištěno je stanování, občerstvení a také večerní after párty.
|
|
|
|
Připrav na zkoušku své tělo, játra a tvé mozkové buňky.
|
|
Budou tě čekat nevídané překážky.
|
|
|
|
O podrobnostech tě budeme informovat emailem.
|
|
Nezapomeň nás sledovat na Facebooku, Instagramu, YouTube a TikToku.
|
|
|
|
Na tento email není třeba odpovídat, protože je generován automaticky s přijatou platbou. V případě potřeby pište na info@alkator.cz .
|
|
|
|
ALKÁTOR TEAM
|
|
email: info@alkator.cz
|
|
tel: + 420 728 018 088
|
|
web: https://alkator.cz""",
|
|
from_email="info@alkator.cz",
|
|
to=[invoice.user.email, racer.email] if racer.email and invoice.user.email != racer.email else [invoice.user.email],
|
|
bcc=["info@alkator.cz"],
|
|
cc=[]
|
|
)
|
|
except Racer.DoesNotExist:
|
|
mail = EmailMessage(
|
|
subject=f"úspěšně zaplacený nákup v Alkátor shopu",
|
|
body=f"""Zdravím tě Alkátore,
|
|
|
|
úspěšně si zakoupil merch na Alkátor shopu.
|
|
|
|
Na tento email není třeba odpovídat, protože je generován automaticky s přijatou platbou. V případě potřeby pište na info@alkator.cz .
|
|
|
|
ALKÁTOR TEAM
|
|
email: info@alkator.cz
|
|
tel: + 420 728 018 088
|
|
web: https://alkator.cz""",
|
|
from_email="info@alkator.cz",
|
|
to=[invoice.user.email],
|
|
bcc=["info@alkator.cz"],
|
|
cc=[]
|
|
)
|
|
|
|
template = TemplateResponse(
|
|
None,
|
|
'invoice.html',
|
|
{
|
|
'user': user,
|
|
'invoice': invoice,
|
|
'products': InvoiceProduct.objects.filter(invoice=invoice),
|
|
'paid_date': invoice.paid_date + timedelta(days=1),
|
|
}
|
|
)
|
|
template.render()
|
|
pdf_name = f"invoices/{invoice.invoice_id}_{user.profile.last_name}_{user.profile.first_name}.pdf"
|
|
HTML(string=template.content).write_pdf(pdf_name)
|
|
|
|
attach = open(pdf_name, 'rb')
|
|
mail.attach('faktura.pdf', attach.read(), 'application/pdf')
|
|
if not mail.send():
|
|
return HttpResponse(status=500)
|
|
elif paid == 'CANCELLED' and not invoice.paid:
|
|
for ip in InvoiceProduct.objects.filter(invoice=invoice):
|
|
ip.product.quantity += ip.quantity
|
|
ip.product.save()
|
|
ip.delete()
|
|
invoice.delete()
|
|
return HttpResponse(status=200)
|
|
|
|
|
|
def payment_state(request):
|
|
invoice_id = request.GET['refId']
|
|
try:
|
|
if Invoice.objects.get(invoice_id=invoice_id).paid:
|
|
return HttpResponse('{"status":"success", "reason":"Úspěšná platba"}', content_type='application/json')
|
|
else:
|
|
return HttpResponse('{"status":"failed", "reason":"Zatím nemáme informace o provedené platbě. Zkuste reload nebo zkontrolujte email."}', content_type='application/json')
|
|
except Invoice.DoesNotExist:
|
|
return HttpResponse('{"status":"failed", "reason":"Závodník neexistuje, registraci závodníka prosím opakujte."}', content_type='application/json')
|
|
|
|
|
|
def products(request):
|
|
return HttpResponse(json.dumps([
|
|
{
|
|
'id': product.id,
|
|
'name': product.name,
|
|
'description': product.description,
|
|
'img': product.img.url,
|
|
'price': product.price,
|
|
'quantity': product.quantity,
|
|
}
|
|
for product in Product.objects.all() if product.quantity > 0 and not product.hidden
|
|
]), content_type='application/json')
|
|
|
|
|
|
def cart_add(request):
|
|
_id = request.GET['id']
|
|
user = request.user
|
|
if not user.is_authenticated:
|
|
return HttpResponse('{"status": "failed", "reason": "Pro využivání Košíku je třeba se přihlásit!"}')
|
|
try:
|
|
cart = user.cart
|
|
except AttributeError:
|
|
cart = Cart(user=user)
|
|
cart.save()
|
|
product = Product.objects.get(id=_id)
|
|
try:
|
|
cart_product = CartProduct(
|
|
product=product,
|
|
cart=cart,
|
|
quantity=1,
|
|
)
|
|
cart_product.save()
|
|
except IntegrityError as e:
|
|
cart_product = CartProduct.objects.get(cart=cart, product=product)
|
|
cart_product.quantity += 1
|
|
if cart_product.quantity > product.quantity:
|
|
return HttpResponse('{"status": "failed", "reason": "Nemáme dostatek předmětů na skladě!"}')
|
|
cart_product.save()
|
|
return HttpResponse('{"status":"success", "reason":"Úspěšně přidáno do košíku."}', status=200)
|
|
|
|
|
|
def select_delivery(request):
|
|
user = request.user
|
|
cart = user.cart
|
|
cart.address = request.GET['delivery']
|
|
cart.save()
|
|
return HttpResponse('{"status":"success", "reason":"Úspěšně vybraná zásilkovna."}', status=200)
|
|
|
|
|
|
def delivery(request):
|
|
try:
|
|
if request.user.cart.address:
|
|
return HttpResponse('"' + request.user.cart.address + '"', status=200, content_type='application/json')
|
|
return HttpResponse("undefined", status=200, content_type='application/json')
|
|
except AttributeError:
|
|
return HttpResponse("undefined", status=200, content_type='application/json')
|
|
|
|
|
|
@csrf_exempt
|
|
@transaction.atomic
|
|
def cart_buy(request):
|
|
cart = request.user.cart
|
|
user = request.user
|
|
profile = user.profile
|
|
cart_products = CartProduct.objects.filter(cart=cart)
|
|
|
|
for cp in cart_products:
|
|
if cp.quantity > cp.product.quantity:
|
|
return HttpResponse('{"status": "failed", "reason": "Nemáme dostatek ' + cp.product.name + ' na skladě!"}', status=400, content_type='application/json')
|
|
|
|
if not cart.address:
|
|
return HttpResponse('{"status": "failed", "reason": "Je potřeba vybrat výběrní místo!"}', status=400, content_type='application/json')
|
|
|
|
invoice = Invoice(
|
|
user=user,
|
|
address=cart.address,
|
|
invoice_id=Invoice.next_invoice_id(),
|
|
total_price=0,
|
|
)
|
|
total_price = 0
|
|
invoice.save()
|
|
|
|
for cp in itertools.chain(cart_products, [CartProduct(quantity=1, product=Product.objects.get(id=2), cart=cart)]):
|
|
ip = InvoiceProduct(
|
|
invoice=invoice,
|
|
price=cp.product.price,
|
|
quantity=cp.quantity,
|
|
product=cp.product,
|
|
)
|
|
cp.product.quantity -= cp.quantity
|
|
cp.product.save()
|
|
total_price += cp.quantity * cp.product.price
|
|
ip.save()
|
|
|
|
if total_price <= 79:
|
|
return HttpResponse('{"status": "failed", "reason": "Prosím přidejte svoje položky do košíku!"}', status=400, content_type='application/json')
|
|
|
|
payment_data = {
|
|
'merchant': COMGATE_MERCHANT,
|
|
'test': 'true' if COMGATE_TEST else 'false',
|
|
'price': total_price * 100,
|
|
'curr': 'CZK',
|
|
'method': 'ALL',
|
|
'label': 'Merch Alkátor Race',
|
|
'email': user.email,
|
|
'fullName': f"{profile.first_name} {profile.last_name}",
|
|
'refId': f'{invoice.invoice_id}',
|
|
'secret': COMGATE_SECRET,
|
|
'prepareOnly': 'true',
|
|
}
|
|
result = requests.post('https://payments.comgate.cz/v1.0/create', data=payment_data)
|
|
|
|
result = parse_qs(result.text)
|
|
|
|
if result['code'][0] != '0':
|
|
for ip in InvoiceProduct.objects.filter(invoice=invoice):
|
|
ip.delete()
|
|
invoice.delete()
|
|
return HttpResponse('{"reason":"Chyba na straně platební brány: ' + result['message'][0] + ', zkuste prosím nákup později."}', status=400, content_type='application/json')
|
|
|
|
invoice.total_price = total_price
|
|
invoice.trans_id = result['transId'][0]
|
|
cart.delete()
|
|
invoice.save()
|
|
|
|
return HttpResponse('{"success":"", "redirect":"' + result['redirect'][0] + '"}', content_type='application/json')
|
|
|
|
|
|
def cart_delete(request):
|
|
_id = request.GET['id']
|
|
user = request.user
|
|
cart = user.cart
|
|
product = Product.objects.get(id=_id)
|
|
cart_product = CartProduct.objects.get(cart=cart, product=product)
|
|
cart_product.delete()
|
|
return HttpResponse('{"status":"success", "reason":"Úspěšně odstraněno z košíku."}', content_type='application/json')
|
|
|
|
|
|
def cart_decrease(request):
|
|
_id = request.GET['id']
|
|
user = request.user
|
|
cart = user.cart
|
|
product = Product.objects.get(id=_id)
|
|
cart_product = CartProduct.objects.get(cart=cart, product=product)
|
|
cart_product.quantity -= 1
|
|
if cart_product.quantity == 0:
|
|
cart_product.delete()
|
|
else:
|
|
cart_product.save()
|
|
return HttpResponse('{"status":"success", "reason":"Úspěšně sníženo množství v košíku."}', content_type='application/json')
|
|
|
|
|
|
def cart(request):
|
|
user = request.user
|
|
if not user.is_authenticated:
|
|
return HttpResponse("[]", content_type='application/json')
|
|
cart = []
|
|
try:
|
|
for cart_product in CartProduct.objects.filter(cart=user.cart):
|
|
cart.append({
|
|
'id': cart_product.product.id,
|
|
'name': cart_product.product.name,
|
|
'description': cart_product.product.description,
|
|
'quantity': cart_product.quantity,
|
|
'price': cart_product.product.price,
|
|
'img': cart_product.product.img.url,
|
|
})
|
|
except AttributeError:
|
|
return HttpResponse("[]", content_type='application/json')
|
|
return HttpResponse(json.dumps(cart))
|
|
|
|
|
|
def results(request):
|
|
results = []
|
|
n = 1
|
|
for user in User.objects.filter(alkator_class=2).order_by('duration'):
|
|
if user.duration:
|
|
if user.alkator_category == 1:
|
|
order = f'{n}.'
|
|
n += 1
|
|
else:
|
|
order = 'x.'
|
|
results.append({
|
|
'order': order,
|
|
'duration': str(user.duration),
|
|
'alkator_category': ALKATOR_CHOICES_DICT[user.alkator_category],
|
|
'starting_number': user.starting_number,
|
|
})
|
|
for user in User.objects.filter(alkator_class=2).order_by('duration'):
|
|
if not user.duration and user.starting_number:
|
|
results.append({
|
|
'order': 'DNF',
|
|
'duration': 'Nedokončil',
|
|
'starting_number': user.starting_number,
|
|
'alkator_category': ''
|
|
})
|
|
|
|
return HttpResponse(json.dumps(results), content_type='application/json')
|
|
|
|
|
|
def photos(request):
|
|
rtn = []
|
|
for (i, name) in ALKATOR_CLASSES[:2]:
|
|
photos = {}
|
|
rtn.append(photos)
|
|
photos['name'] = name
|
|
photos['index'] = i
|
|
photos['photos'] = []
|
|
files = glob.glob(f"photos/{i}/*.jpg")
|
|
random.shuffle(files)
|
|
for file in files:
|
|
img = PIL.Image.open(file)
|
|
photos['photos'].append({
|
|
'original': '/' + file.replace(".jpg", ".webp"),
|
|
'thumbnail': '/' + file.replace(f'photos/{i}/', f'photos/{i}/thumbnail/').replace(".jpg", ".webp"),
|
|
'original_width': img.width,
|
|
'original_height': img.height,
|
|
})
|
|
|
|
return HttpResponse(json.dumps(rtn), content_type='application/json')
|
|
|
|
|
|
@csrf_exempt
|
|
def upload_files(request):
|
|
for file in request.FILES.getlist('files'):
|
|
rand = random.randint(0, 99999)
|
|
random_name = f'photos/uploads/{rand}_{file.name}'
|
|
with open(random_name, "wb+") as destination:
|
|
for chunk in file.chunks():
|
|
destination.write(chunk)
|
|
return HttpResponse('{"success":"Úspěšně nahráno! Počkejte až dojde ke schválení nahraných souborů."}', content_type='application/json')
|
|
|
|
|
|
@staff_member_required
|
|
def invoice(request):
|
|
invoice = Invoice.objects.get(invoice_id=request.GET['invoice_id'])
|
|
user = DjangoUser.objects.get(id=invoice.user_id)
|
|
return TemplateResponse(
|
|
None,
|
|
'invoice.html',
|
|
{
|
|
'user': user,
|
|
'invoice': invoice,
|
|
'products': InvoiceProduct.objects.filter(invoice=invoice),
|
|
'paid_date': invoice.paid_date + timedelta(days=1),
|
|
}
|
|
)
|