Реализована система управления стоимостью доставки и исправлен баг выбора клиента

Изменения:

1. **Стоимость доставки (автоматическая/ручная)**:
   - Добавлено поле `is_custom_delivery_cost` в модель Order для отслеживания ручной стоимости
   - Создан сервис DeliveryCostCalculator для автоматического расчета стоимости доставки
   - Реализована логика: бесплатная доставка от 100 руб., иначе 15 руб.
   - В форме поле "Ручная стоимость доставки" - если заполнено, используется ручная стоимость, если пустое - автоматический расчет
   - Добавлены методы Order.get_delivery_cost(), set_delivery_cost(), reset_delivery_cost(), recalculate_delivery_cost()

2. **Исправление бага выбора клиента в Select2**:
   - Удален избыточный обработчик события select2:opening, который блокировал клики
   - Добавлены проверки на наличие e.params.data в обработчиках select2:selecting и select2:select
   - Теперь выбор клиента работает корректно, создается черновик заказа и происходит редирект

3. **Опциональные поля адреса**:
   - Поля recipient_name, street, building_number в модели Address сделаны необязательными (blank=True, null=True)
   - Обновлены методы __str__ и full_address для безопасной работы с None значениями

4. **UI улучшения**:
   - Удалена звездочка обязательности с полей адреса
   - Добавлена подсказка под полем ручной стоимости доставки о правилах автоматического расчета

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-11 15:48:50 +03:00
parent 6c207e9451
commit 885ac839e2
5 changed files with 351 additions and 60 deletions

View File

@@ -164,6 +164,11 @@ class OrderForm(forms.ModelForm):
self.fields['recipient_name'].required = False
self.fields['recipient_phone'].required = False
# Поле ручной стоимости доставки опционально
self.fields['delivery_cost'].required = False
self.fields['delivery_cost'].label = 'Ручная стоимость доставки'
self.fields['delivery_cost'].help_text = 'Оставьте пустым для автоматического расчета'
# Инициализируем queryset для address_from_history
# Это будет переопределено в представлении после выбора клиента
if self.instance.pk and self.instance.customer:
@@ -176,6 +181,30 @@ class OrderForm(forms.ModelForm):
order__in=customer_orders
).distinct().order_by('-created_at')
def save(self, commit=True):
"""
Сохраняет форму с учетом автоматического/ручного расчета стоимости доставки.
Логика:
- Если delivery_cost заполнено → используется ручное значение (is_custom_delivery_cost = True)
- Если delivery_cost пустое → автоматический расчет (is_custom_delivery_cost = False)
"""
instance = super().save(commit=False)
# Получаем значение ручной стоимости доставки
delivery_cost = self.cleaned_data.get('delivery_cost')
if delivery_cost is not None and delivery_cost > 0:
# Ручное значение указано
instance.set_delivery_cost(delivery_cost, is_custom=True)
else:
# Пустое поле или 0 → автоматический расчет
instance.reset_delivery_cost()
if commit:
instance.save()
return instance
class OrderItemForm(forms.ModelForm):
"""Форма для позиции заказа"""