diff --git a/myproject/orders/forms.py b/myproject/orders/forms.py index 5f844de..ed3c454 100644 --- a/myproject/orders/forms.py +++ b/myproject/orders/forms.py @@ -143,6 +143,7 @@ class OrderForm(forms.ModelForm): 'class': 'form-select select2', 'data-placeholder': 'Выберите адрес доставки' }) + # Адрес доставки не обязателен при редактировании (создаётся из отдельных полей) self.fields['delivery_address'].required = False self.fields['pickup_warehouse'].widget.attrs.update({ @@ -221,9 +222,16 @@ class OrderForm(forms.ModelForm): class OrderItemForm(forms.ModelForm): """Форма для позиции заказа""" + # Элегантно переопределяем поле формы, чтобы парсить '277,00' как Decimal + price = forms.CharField( + required=False, + widget=forms.TextInput(attrs={'class': 'form-control', 'step': '0.01', 'min': '0'}) + ) + class Meta: model = OrderItem fields = ['product', 'product_kit', 'quantity', 'price', 'is_custom_price'] + # ВАЖНО: НЕ включаем 'id' в fields - это предотвращает ошибку валидации widgets = { 'quantity': forms.NumberInput(attrs={'min': 1, 'value': 1}), # Скрываем поля product и product_kit - они будут заполняться через JS @@ -254,6 +262,17 @@ class OrderItemForm(forms.ModelForm): # Поле is_custom_price устанавливается через JS self.fields['is_custom_price'].required = False + def clean_price(self): + """Парсим цену с запятой или точкой""" + value = self.cleaned_data.get('price') + if value in (None, ''): + return None + value_str = str(value).strip().replace(',', '.') + try: + return Decimal(value_str) + except Exception: + raise forms.ValidationError('Введите число.') + def clean(self): """Валидация: должен быть выбран либо товар, либо комплект (не оба, не ни один)""" cleaned_data = super().clean() diff --git a/myproject/orders/models/order.py b/myproject/orders/models/order.py index 8636a4e..e9c887b 100644 --- a/myproject/orders/models/order.py +++ b/myproject/orders/models/order.py @@ -263,23 +263,18 @@ class Order(models.Model): """Валидация модели""" super().clean() - # Проверка: для доставки обязателен адрес - if self.is_delivery and not self.delivery_address: - raise ValidationError({ - 'delivery_address': 'Для доставки необходимо указать адрес доставки' - }) - # Проверка: для самовывоза обязателен склад if not self.is_delivery and not self.pickup_warehouse: raise ValidationError({ 'pickup_warehouse': 'Для самовывоза необходимо выбрать склад' }) - # Проверка: время окончания должно быть позже времени начала + # Проверка: время окончания должно быть позже или равно времени начала + # Равные времена означают точное время доставки (например, "к 13:00") if self.delivery_time_start and self.delivery_time_end: - if self.delivery_time_end <= self.delivery_time_start: + if self.delivery_time_end < self.delivery_time_start: raise ValidationError({ - 'delivery_time_end': 'Время окончания должно быть позже времени начала' + 'delivery_time_end': 'Время окончания не может быть раньше времени начала' }) def get_delivery_cost(self): @@ -384,5 +379,8 @@ class Order(models.Model): def delivery_time_window(self): """Временное окно доставки""" if self.delivery_time_start and self.delivery_time_end: + # Если времена равны - это точное время доставки + if self.delivery_time_start == self.delivery_time_end: + return f"к {self.delivery_time_start.strftime('%H:%M')}" return f"{self.delivery_time_start.strftime('%H:%M')} - {self.delivery_time_end.strftime('%H:%M')}" return "Время не указано" diff --git a/myproject/orders/templates/orders/order_form.html b/myproject/orders/templates/orders/order_form.html index eac4271..b6924a3 100644 --- a/myproject/orders/templates/orders/order_form.html +++ b/myproject/orders/templates/orders/order_form.html @@ -843,6 +843,90 @@ diff --git a/myproject/orders/templates/orders/order_list.html b/myproject/orders/templates/orders/order_list.html index 09aebd2..9c9bd3a 100644 --- a/myproject/orders/templates/orders/order_list.html +++ b/myproject/orders/templates/orders/order_list.html @@ -130,13 +130,23 @@ {% endif %}