# -*- coding: utf-8 -*- from django import forms from django.core.exceptions import ValidationError from .models import TenantRegistration, Client, RESERVED_SCHEMA_NAMES class TenantRegistrationForm(forms.ModelForm): """ Форма регистрации нового тенанта """ class Meta: model = TenantRegistration fields = ['shop_name', 'schema_name', 'owner_name', 'owner_email', 'phone'] widgets = { 'shop_name': forms.TextInput(attrs={ 'class': 'form-control', 'placeholder': 'Название вашего магазина', 'required': True }), 'schema_name': forms.TextInput(attrs={ 'class': 'form-control', 'placeholder': 'myshop', 'required': True, 'pattern': '[a-z0-9][a-z0-9\-]{1,61}[a-z0-9]', 'title': 'Только латинские буквы в нижнем регистре, цифры и дефис (3-63 символа)' }), 'owner_name': forms.TextInput(attrs={ 'class': 'form-control', 'placeholder': 'Иван Иванов', 'required': True }), 'owner_email': forms.EmailInput(attrs={ 'class': 'form-control', 'placeholder': 'your@email.com', 'required': True }), 'phone': forms.TextInput(attrs={ 'class': 'form-control', 'placeholder': '+375291234567', 'required': True }), } labels = { 'shop_name': 'Название магазина', 'schema_name': 'Желаемый поддомен', 'owner_name': 'Ваше имя', 'owner_email': 'Email', 'phone': 'Телефон', } help_texts = { 'schema_name': 'Будет использоваться как поддомен: yourshop.flowers. ' 'Только латинские буквы, цифры и дефис (3-63 символа)', 'owner_email': 'Это email владельца будущего аккаунта, на этот email придет уведомление об активации', } def clean_schema_name(self): """ Валидация поддомена: 1. Приводим к нижнему регистру 2. Проверяем длину 3. Проверяем, что не зарезервировано 4. Проверяем уникальность """ schema_name = self.cleaned_data.get('schema_name', '').lower().strip() # Проверка длины if len(schema_name) < 3: raise ValidationError("Поддомен должен содержать минимум 3 символа.") if len(schema_name) > 63: raise ValidationError("Поддомен не может быть длиннее 63 символов.") # Проверка на зарезервированные имена if schema_name in RESERVED_SCHEMA_NAMES: raise ValidationError(f"Поддомен '{schema_name}' зарезервирован системой. Выберите другой.") # Проверка уникальности в заявках if TenantRegistration.objects.filter(schema_name=schema_name).exists(): raise ValidationError(f"Поддомен '{schema_name}' уже занят. Выберите другой.") # Проверка уникальности в существующих тенантах if Client.objects.filter(schema_name=schema_name).exists(): raise ValidationError(f"Поддомен '{schema_name}' уже занят. Выберите другой.") return schema_name def clean_owner_email(self): """ Валидация email: проверка на дубликаты для обычных пользователей (супер-админ может иметь несколько тенантов) """ email = self.cleaned_data.get('owner_email', '').lower().strip() # Проверяем, есть ли активные заявки с таким email pending_registrations = TenantRegistration.objects.filter( owner_email=email, status=TenantRegistration.STATUS_PENDING ).count() if pending_registrations > 0: raise ValidationError( f"У вас уже есть заявка на регистрацию с email {email}, ожидающая проверки. " "Дождитесь активации или свяжитесь с поддержкой." ) # Проверяем количество существующих тенантов с таким email # Если больше 0 - это нормально для админов, но для обычных пользователей показываем предупреждение existing_tenants_count = Client.objects.filter(owner_email=email).count() if existing_tenants_count > 0: # Добавляем предупреждение, но не блокируем (на случай если это супер-админ) # В реальности здесь можно добавить более сложную логику pass return email