This commit is contained in:
2025-10-02 00:54:34 +02:00
commit 84b34c9615
200 changed files with 42048 additions and 0 deletions

199
backend/account/models.py Normal file
View File

@@ -0,0 +1,199 @@
import uuid
from django.db import models
from django.contrib.auth.models import AbstractUser, Group, Permission
from django.core.validators import RegexValidator, MinLengthValidator, MaxValueValidator, MinValueValidator
from django.conf import settings
from django.db import models
from django.utils import timezone
from datetime import timedelta
from trznice.models import SoftDeleteModel
from django.contrib.auth.models import UserManager
import logging
logger = logging.getLogger(__name__)
# Custom User Manager to handle soft deletion
class CustomUserActiveManager(UserManager):
def get_queryset(self):
return super().get_queryset().filter(is_deleted=False)
# Custom User Manager to handle all users, including soft deleted
class CustomUserAllManager(UserManager):
def get_queryset(self):
return super().get_queryset()
class CustomUser(SoftDeleteModel, AbstractUser):
groups = models.ManyToManyField(
Group,
related_name="customuser_set", # <- přidáš related_name
blank=True,
help_text="The groups this user belongs to.",
related_query_name="customuser",
)
user_permissions = models.ManyToManyField(
Permission,
related_name="customuser_set", # <- přidáš related_name
blank=True,
help_text="Specific permissions for this user.",
related_query_name="customuser",
)
ROLE_CHOICES = (
('admin', 'Administrátor'),
('seller', 'Prodejce'),
('squareManager', 'Správce tržiště'),
('cityClerk', 'Úředník'),
('checker', 'Kontrolor'),
)
role = models.CharField(max_length=32, choices=ROLE_CHOICES, null=True, blank=True)
ACCOUNT_TYPES = (
('company', 'Firma'),
('individual', 'Fyzická osoba')
)
account_type = models.CharField(max_length=32, choices=ACCOUNT_TYPES, null=True, blank=True)
email_verified = models.BooleanField(default=False)
phone_number = models.CharField(
unique=True,
max_length=16,
blank=True,
validators=[RegexValidator(r'^\+?\d{9,15}$', message="Zadejte platné telefonní číslo.")]
)
email = models.EmailField(unique=True, db_index=True)
create_time = models.DateTimeField(auto_now_add=True)
var_symbol = models.PositiveIntegerField(null=True, blank=True, validators=[
MaxValueValidator(9999999999),
MinValueValidator(0)
],
)
bank_account = models.CharField(
max_length=255,
null=True,
blank=True,
validators=[
RegexValidator(
regex=r'^(\d{0,6}-)?\d{10}/\d{4}$', # r'^(\d{0,6}-)?\d{2,10}/\d{4}$' for range 2-10 digits
message="Zadejte platné číslo účtu ve formátu [prefix-]číslo_účtu/kód_banky, např. 1234567890/0100 nebo 123-4567890/0100.",
code='invalid_bank_account'
)
],
)
ICO = models.CharField(
max_length=8,
blank=True,
null=True,
validators=[
RegexValidator(
regex=r'^\d{8}$',
message="IČO musí obsahovat přesně 8 číslic.",
code='invalid_ico'
)
]
)
RC = models.CharField(
max_length=11,
blank=True,
null=True,
validators=[
RegexValidator(
regex=r'^\d{6}\/\d{3,4}$',
message="Rodné číslo musí být ve formátu 123456/7890.",
code='invalid_rc'
)
]
)
city = models.CharField(null=True, blank=True, max_length=100)
street = models.CharField(null=True, blank=True, max_length=200)
PSC = models.CharField(
max_length=5,
blank=True,
null=True,
validators=[
RegexValidator(
regex=r'^\d{5}$',
message="PSČ musí obsahovat přesně 5 číslic.",
code='invalid_psc'
)
]
)
GDPR = models.BooleanField(default=False)
is_active = models.BooleanField(default=False)
objects = CustomUserActiveManager()
all_objects = CustomUserAllManager()
REQUIRED_FIELDS = ['email']
def __str__(self):
return f"{self.email} at {self.create_time.strftime('%d-%m-%Y %H:%M:%S')}"
def generate_login(self, first_name, last_name):
"""
Vygeneruje login ve formátu: prijmeni + 2 písmena jména bez diakritiky.
Přidá číslo pokud už login existuje.
"""
from django.utils.text import slugify
base_login = slugify(f"{last_name}{first_name[:2]}")
login = base_login
counter = 1
while CustomUser.objects.filter(username=login).exists():
login = f"{base_login}{counter}"
counter += 1
return login
def delete(self, *args, **kwargs):
self.is_active = False
self.tickets.all().update(is_deleted=True, deleted_at=timezone.now())
self.user_reservations.all().update(is_deleted=True, deleted_at=timezone.now())
self.orders.all().update(is_deleted=True, deleted_at=timezone.now())
return super().delete(*args, **kwargs)
def save(self, *args, **kwargs):
is_new = self.pk is None # check BEFORE saving
if is_new:
# Ensure first_name and last_name are provided before generating login
if self.first_name and self.last_name:
self.username = self.generate_login(self.first_name, self.last_name)
if self.is_superuser or self.role in ["admin", "cityClerk", "squareManager"]:
# self.is_staff = True
self.is_active = True
if self.role == 'admin':
self.is_staff = True
self.is_superuser = True
if self.is_superuser:
self.role = 'admin'
else:
self.is_staff = False
return super().save(*args, **kwargs)
# NEMAZAT prozatim to nechame, kdybychom to potrebovali
# Now assign permissions after user exists
# if is_new and self.role:
if self.role:
from account.utils import assign_permissions_based_on_role
logger.debug(f"Assigning permissions to: {self.email} with role {self.role}")
assign_permissions_based_on_role(self)
# super().save(*args, **kwargs) # save once, after prep