167 lines
6.2 KiB
Python
167 lines
6.2 KiB
Python
from django.db import models
|
|
from django.contrib import admin
|
|
from django.contrib.auth.models import User as DjangoUser
|
|
from django.core.exceptions import ValidationError
|
|
|
|
from datetime import datetime
|
|
|
|
|
|
ALKATOR_CHOICES = (
|
|
(1, "Alkátor"),
|
|
(2, "Alkátor light"),
|
|
(3, "Nealkátor"),
|
|
)
|
|
|
|
|
|
ALKATOR_CLASSES = (
|
|
(1, "Jaro 2024 Sobkovice"),
|
|
(2, "Podzim 2024 Studené"),
|
|
(3, "Jaro 2025 Dolní Čermná")
|
|
)
|
|
|
|
|
|
ALKATOR_CHOICES_DICT = {
|
|
alkator_choice[0]: alkator_choice[1]
|
|
for alkator_choice in ALKATOR_CHOICES
|
|
}
|
|
|
|
|
|
ALKATOR_CLASSES_DICT = {
|
|
alkator_class[0]: alkator_class[1]
|
|
for alkator_class in ALKATOR_CLASSES
|
|
}
|
|
|
|
|
|
class User(models.Model):
|
|
first_name = models.CharField(max_length=120)
|
|
last_name = models.CharField(max_length=120)
|
|
address = models.CharField(max_length=255, null=True, blank=True)
|
|
email = models.EmailField(max_length=120, null=True, blank=True)
|
|
phone = models.CharField(max_length=120, null=True, blank=True)
|
|
date_of_birth = models.DateField(null=True, blank=True)
|
|
register_date = models.DateTimeField(auto_now=True)
|
|
duration = models.DurationField(null=True, blank=True)
|
|
starting_number = models.IntegerField(null=True, blank=True)
|
|
alkator_category = models.IntegerField(choices=ALKATOR_CHOICES, default=1)
|
|
alkator_class = models.IntegerField(choices=ALKATOR_CLASSES)
|
|
trans_id = models.CharField(null=True, blank=True, max_length=120)
|
|
price = models.IntegerField(default=690)
|
|
paid = models.BooleanField(default=False)
|
|
invoice_id = models.IntegerField(null=True, blank=True, unique=True)
|
|
|
|
def __str__(self):
|
|
return f"<User {self.starting_number} {self.first_name} {self.last_name} {self.email} {self.duration} {ALKATOR_CHOICES_DICT[self.alkator_category]} {ALKATOR_CLASSES_DICT[self.alkator_class]} {self.paid}>"
|
|
|
|
|
|
class Profile(models.Model):
|
|
user = models.OneToOneField(DjangoUser, related_name='profile', on_delete=models.CASCADE)
|
|
first_name = models.CharField(max_length=120)
|
|
last_name = models.CharField(max_length=120)
|
|
phone = models.CharField(max_length=120, null=True, blank=True)
|
|
address = models.CharField(max_length=255, null=True, blank=True)
|
|
|
|
def __str__(self):
|
|
return f"<Profile {self.user.email} {self.first_name} {self.last_name}>"
|
|
|
|
|
|
class Product(models.Model):
|
|
name = models.CharField(max_length=120)
|
|
description = models.TextField()
|
|
img = models.ImageField(upload_to="photos")
|
|
price = models.IntegerField()
|
|
hidden = models.BooleanField(default=False)
|
|
quantity = models.IntegerField()
|
|
|
|
def __str__(self):
|
|
return f"<Product {self.name} {self.price} Kč zbývá {self.quantity}>"
|
|
|
|
|
|
class Cart(models.Model):
|
|
user = models.OneToOneField(DjangoUser, on_delete=models.RESTRICT, related_name='cart')
|
|
items = models.ManyToManyField(Product, through='CartProduct')
|
|
|
|
|
|
class CartProduct(models.Model):
|
|
product = models.ForeignKey(Product, on_delete=models.RESTRICT)
|
|
cart = models.ForeignKey('Cart', on_delete=models.RESTRICT)
|
|
class Meta:
|
|
unique_together = ('product', 'cart')
|
|
quantity = models.IntegerField()
|
|
|
|
def clean(self):
|
|
data = self.cleaned_data
|
|
if data['quantity'] <= 0:
|
|
raise ValidationError("Počet předmětů v košíku musí být kladný!")
|
|
|
|
|
|
class Invoice(models.Model):
|
|
invoice_id = models.IntegerField(unique=True)
|
|
user = models.ForeignKey(DjangoUser, on_delete=models.RESTRICT)
|
|
items = models.ManyToManyField(Product, through='InvoiceProduct')
|
|
total_price = models.IntegerField()
|
|
paid_date = models.DateTimeField(auto_now=True)
|
|
paid = models.BooleanField(default=False)
|
|
trans_id = models.CharField(null=True, blank=True, max_length=120)
|
|
address = models.CharField(max_length=255, null=True, blank=True)
|
|
|
|
@classmethod
|
|
def next_invoice_id(cls):
|
|
invoice_date = datetime.today()
|
|
invoice_id = invoice_date.year * 1000000 + invoice_date.month * 10000 + invoice_date.day * 100
|
|
|
|
try:
|
|
latest_invoice = cls.objects.latest("invoice_id")
|
|
if latest_invoice.invoice_id is None or latest_invoice.invoice_id < invoice_id:
|
|
invoice_id = invoice_id + 1
|
|
else:
|
|
invoice_id = latest_invoice.invoice_id + 1
|
|
except Invoice.DoesNotExist:
|
|
invoice_id = invoice_id + 1
|
|
return invoice_id
|
|
|
|
def calculate_total_price(self):
|
|
total_price = 0
|
|
for item in InvoiceProduct.objects.filter(invoice=self):
|
|
total_price += item.price * item.quantity
|
|
return total_price
|
|
|
|
|
|
class InvoiceProduct(models.Model):
|
|
product = models.ForeignKey(Product, on_delete=models.RESTRICT)
|
|
invoice = models.ForeignKey(Invoice, on_delete=models.RESTRICT)
|
|
class Meta:
|
|
unique_together = ('product', 'invoice')
|
|
quantity = models.IntegerField()
|
|
price = models.IntegerField(default=1)
|
|
|
|
def clean(self):
|
|
data = self.cleaned_data
|
|
if data['quantity'] <= 0:
|
|
raise ValidationError("Počet předmětů ve faktuře musí být kladný!")
|
|
|
|
def __str__(self):
|
|
return f"<InvoiceProduct {self.product.name} {self.invoice.invoice_id} *{self.quantity}"
|
|
|
|
|
|
class Racer(InvoiceProduct):
|
|
profile = models.ForeignKey(Profile, related_name='racers', on_delete=models.RESTRICT)
|
|
first_name = models.CharField(max_length=120)
|
|
last_name = models.CharField(max_length=120)
|
|
email = models.EmailField(max_length=120, null=True, blank=True)
|
|
team = models.CharField(max_length=120, null=True, blank=True)
|
|
phone = models.CharField(max_length=120, null=True, blank=True)
|
|
date_of_birth = models.DateField(null=True, blank=True)
|
|
duration = models.DurationField(null=True, blank=True)
|
|
starting_number = models.IntegerField(null=True, blank=True)
|
|
alkator_category = models.IntegerField(choices=ALKATOR_CHOICES, default=1)
|
|
alkator_class = models.IntegerField(choices=ALKATOR_CLASSES)
|
|
|
|
def clean(self):
|
|
super(self).clean()
|
|
data = self.cleaned_data
|
|
if data['quantity'] != 1:
|
|
raise ValidationError("Počet přihlášek v jedné objednávce musí být právě 1!")
|
|
|
|
def __str__(self):
|
|
return f"<Racer {self.email} {self.first_name} {self.last_name} {self.team}>"
|