"""Формы портала для аптек и сервисов/поставщиков.""" from __future__ import annotations from django import forms from django.utils.translation import gettext_lazy as _ from core.models import Directory from .models import Location, Pharmacy class HierarchicalRegionChoiceField(forms.ModelChoiceField): """Регион с отступами по иерархии (как в админке).""" def __init__(self, *args, **kwargs): queryset = kwargs.get('queryset') or Directory.objects.filter( directory_type__code__in=['region', 'district', 'city', 'city_district'], is_active=True, ).select_related('directory_type').order_by('_path') kwargs['queryset'] = queryset kwargs.setdefault('required', True) super().__init__(*args, **kwargs) def label_from_instance(self, obj): depth = (getattr(obj, '_path', '') or '').count('.') indent = '\u00A0\u00A0' * depth + ('└ ' if depth else '') return f'{indent}{obj.name}' class PortalPharmacyEditForm(forms.ModelForm): """Редактирование реквизитов аптеки в портале.""" location_region = HierarchicalRegionChoiceField( label=_('Город/район'), empty_label=_('— Выберите регион —'), ) class Meta: model = Pharmacy fields = ( 'organization', 'pharmacy_number', 'status', 'category', 'vat_category', 'working_hours', 'location_region', 'street', 'house_number', 'building', 'apartment', 'location', 'phone', 'license_number', 'license_expiry_date', 'head_pharmacist', 'responsible_manager', 'curator', 'pharmacists_count', 'comments', ) widgets = { 'working_hours': forms.TextInput(attrs={'class': 'input', 'placeholder': '08:00-20:00'}), 'street': forms.TextInput(attrs={'class': 'input'}), 'house_number': forms.TextInput(attrs={'class': 'input'}), 'building': forms.TextInput(attrs={'class': 'input'}), 'apartment': forms.TextInput(attrs={'class': 'input'}), 'phone': forms.TextInput(attrs={'class': 'input', 'placeholder': '+380...'}), 'license_number': forms.TextInput(attrs={'class': 'input'}), 'license_expiry_date': forms.DateInput(attrs={'class': 'input', 'type': 'date'}), 'pharmacists_count': forms.NumberInput(attrs={'class': 'input', 'min': 1}), 'comments': forms.Textarea(attrs={'class': 'input', 'rows': 3}), 'location': forms.TextInput(attrs={ 'class': 'input', 'placeholder': '46.4825,30.7233', }), 'pharmacy_number': forms.NumberInput(attrs={'class': 'input', 'min': 1}), 'organization': forms.Select(attrs={'class': 'input'}), 'status': forms.Select(attrs={'class': 'input'}), 'category': forms.Select(attrs={'class': 'input'}), 'vat_category': forms.Select(attrs={'class': 'input'}), 'head_pharmacist': forms.Select(attrs={'class': 'input'}), 'responsible_manager': forms.Select(attrs={'class': 'input'}), 'curator': forms.Select(attrs={'class': 'input'}), } def __init__(self, *args, user=None, **kwargs): super().__init__(*args, **kwargs) from apps.employees.models import Employee self.fields['organization'].queryset = Directory.objects.filter( directory_type__code='organization', is_active=True, ).order_by('name') self.fields['organization'].widget.attrs['class'] = 'input' self.fields['location_region'].widget.attrs['class'] = 'input' active = Employee.objects.filter(is_active=True).select_related('post').order_by( 'last_name', 'first_name', ) self.fields['head_pharmacist'].queryset = active self.fields['responsible_manager'].queryset = active self.fields['curator'].queryset = active for name in ('head_pharmacist', 'responsible_manager', 'curator'): self.fields[name].required = False self.fields[name].empty_label = '—' self.fields['category'].required = False self.fields['vat_category'].required = False self.fields['license_number'].required = False self.fields['license_expiry_date'].required = False self.fields['phone'].required = False self.fields['comments'].required = False self.fields['building'].required = False self.fields['apartment'].required = False self.fields['location'].required = False if user is not None and not user.has_perm('locations.manage_location_access'): for field in ('head_pharmacist', 'responsible_manager', 'curator'): self.fields.pop(field, None) class PortalVendorForm(forms.ModelForm): """Создание/редактирование сервиса или поставщика (location_type=vendor).""" location_region = HierarchicalRegionChoiceField( label=_('Город/район'), empty_label=_('— Выберите регион —'), required=True, ) class Meta: model = Location fields = ( 'name', 'location_region', 'street', 'house_number', 'building', 'apartment', 'location', 'comments', 'is_active', ) widgets = { 'name': forms.TextInput(attrs={ 'class': 'input', 'placeholder': 'Вайтер Юг', 'required': True, }), 'street': forms.TextInput(attrs={'class': 'input'}), 'house_number': forms.TextInput(attrs={'class': 'input'}), 'building': forms.TextInput(attrs={'class': 'input'}), 'apartment': forms.TextInput(attrs={'class': 'input'}), 'location': forms.TextInput(attrs={ 'class': 'input', 'placeholder': '46.4825,30.7233', }), 'comments': forms.Textarea(attrs={'class': 'input', 'rows': 2}), 'is_active': forms.CheckboxInput(), } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields['name'].required = True self.fields['location_region'].widget.attrs['class'] = 'input' for optional in ('street', 'house_number', 'building', 'apartment', 'comments', 'location'): self.fields[optional].required = False def clean_name(self): name = (self.cleaned_data.get('name') or '').strip() if not name: raise forms.ValidationError(_('Укажите название.')) qs = Location.objects.filter(location_type='vendor', name__iexact=name) if self.instance and self.instance.pk: qs = qs.exclude(pk=self.instance.pk) if qs.exists(): raise forms.ValidationError(_('Такой сервис/поставщик уже есть.')) return name def save(self, commit=True): obj = super().save(commit=False) obj.location_type = 'vendor' obj.name = (obj.name or '').strip() if commit: obj.save() return obj