diff --git a/myproject/customers/views.py b/myproject/customers/views.py index 500a78e..505b422 100644 --- a/myproject/customers/views.py +++ b/myproject/customers/views.py @@ -338,7 +338,7 @@ def api_search_customers(request): # Если ничего не найдено, предлагаем создать нового клиента if not results: results.append({ - 'id': None, + 'id': '__create_new__', # Специальный ID для опции создания 'text': f'Создать клиента: "{query}"', 'is_create_option': True, 'search_text': query, @@ -390,6 +390,7 @@ def api_create_customer(request): 'name': name, 'phone': phone if phone else None, 'email': email if email else None, + 'loyalty_tier': 'no_discount', # Значение по умолчанию для новых клиентов } # Используем форму для валидации и создания @@ -409,18 +410,26 @@ def api_create_customer(request): 'email': customer.email if customer.email else '', }, status=201) else: - # Собираем ошибки валидации + # Собираем ошибки валидации с указанием полей errors = [] - for field, field_errors in form.errors.items(): - for error in field_errors: - errors.append(error) + field_labels = { + 'name': 'Имя клиента', + 'phone': 'Телефон', + 'email': 'Email', + } - # Возвращаем первую ошибку - error_message = errors[0] if errors else 'Ошибка валидации данных' + for field, field_errors in form.errors.items(): + field_label = field_labels.get(field, field) + for error in field_errors: + errors.append(f'{field_label}: {error}') + + # Возвращаем все ошибки + error_message = '
'.join(errors) if errors else 'Ошибка валидации данных' return JsonResponse({ 'success': False, - 'error': error_message + 'error': error_message, + 'errors': form.errors # Добавляем детальную информацию об ошибках }, status=400) except json.JSONDecodeError: diff --git a/myproject/orders/templates/orders/order_form.html b/myproject/orders/templates/orders/order_form.html index 881e166..213c2a3 100644 --- a/myproject/orders/templates/orders/order_form.html +++ b/myproject/orders/templates/orders/order_form.html @@ -181,6 +181,137 @@ + +
+
+
Товары в заказе
+
+
+ {{ formset.management_form }} +
+ {% for item_form in formset %} +
+ {{ item_form.id }} + {{ item_form.product }} + {{ item_form.product_kit }} + {{ item_form.is_custom_price }} + +
+
+
+ + +
+
+
+
+ + {{ item_form.quantity }} +
+
+
+
+ +
+ {{ item_form.price }} + + +
+
+
+
+
+ + {% if formset.can_delete %} + {{ item_form.DELETE }} + {% endif %} + +
+
+
+ {% if item_form.errors %} +
{{ item_form.errors }}
+ {% endif %} +
+ {% endfor %} +
+ + + + + + +
+
+
@@ -324,28 +455,6 @@
Получатель
- -
-
-
- - -
-
-
-
- - -
-
-
-
@@ -425,136 +534,6 @@
- -
-
-
Товары в заказе
-
-
- {{ formset.management_form }} -
- {% for item_form in formset %} -
- {{ item_form.id }} - {{ item_form.product }} - {{ item_form.product_kit }} - {{ item_form.is_custom_price }} - -
-
-
- - -
-
-
-
- - {{ item_form.quantity }} -
-
-
-
- -
- {{ item_form.price }} - - -
-
-
-
-
- - {% if formset.can_delete %} - {{ item_form.DELETE }} - {% endif %} - -
-
-
- {% if item_form.errors %} -
{{ item_form.errors }}
- {% endif %} -
- {% endfor %} -
- - - - - - -
-
@@ -672,19 +651,7 @@ function initCustomerSelect2() { }, templateResult: formatCustomerOption, templateSelection: formatCustomerSelection, - escapeMarkup: function(markup) { return markup; }, - // Очень важно: указываем как отображать уже выбранное значение - matcher: function(params, data) { - // Если нет поискового термина, показываем все результаты - if ($.trim(params.term) === '') { - return data; - } - // Иначе ищем совпадение - if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) > -1) { - return data; - } - return null; - } + escapeMarkup: function(markup) { return markup; } }); console.log('6. Select2 инициализирован'); @@ -726,10 +693,12 @@ function initCustomerSelect2() { const data = e.params.data; console.log('9b. Попытка выбрать элемент (перед выбором):', data); - if (data.is_create_option) { + if (data.is_create_option || data.id === '__create_new__') { console.log('9c. Это опция создания клиента - предотвращаем выбор и открываем модаль'); // Предотвращаем выбор этой опции e.preventDefault(); + // Закрываем dropdown + $customerSelect.select2('close'); // Очищаем значение $customerSelect.val(null).trigger('change.select2'); // Открываем модаль @@ -752,7 +721,7 @@ function initCustomerSelect2() { const data = e.params.data; console.log('10b. Выбран элемент:', data); - if (data.is_create_option) { + if (data.is_create_option || data.id === '__create_new__') { console.log('11. Открываем модальное окно для создания клиента'); this.value = ''; // Триггерим нативное change событие для draft-creator.js @@ -769,12 +738,13 @@ function initCustomerSelect2() { // Форматирование опции в списке function formatCustomerOption(option) { - if (!option.id) { - return option.text; + // ВАЖНО: Проверяем is_create_option или специальный ID ПЕРЕД проверкой !option.id + if (option.is_create_option || option.id === '__create_new__') { + return '
' + option.text + '
'; } - if (option.is_create_option) { - return '
' + option.text + '
'; + if (!option.id) { + return option.text; } let html = '
'; @@ -791,10 +761,10 @@ function initCustomerSelect2() { // Форматирование выбранного значения function formatCustomerSelection(option) { - if (!option.id) { + if (option.is_create_option || option.id === '__create_new__') { return option.text; } - if (option.is_create_option) { + if (!option.id) { return option.text; } // Возвращаем name если есть (из AJAX), иначе text (из DOM опции) @@ -1444,6 +1414,13 @@ document.addEventListener('DOMContentLoaded', function() {