Добавлена возможность выбора анонимного системного клиента в форме заказа
- Убрана фильтрация системного клиента из результатов поиска (api_search_customers) - Добавлен флаг is_system_customer в результаты API поиска - Создан новый API endpoint api_get_system_customer для быстрого получения системного клиента - Добавлена кнопка 'Аноним' для быстрого выбора системного клиента - Системный клиент выделяется жёлтым цветом и иконкой инкогнито в выпадающем списке - Улучшена компактность результатов поиска (уменьшен шрифт до 13px) - Изменены пропорции полей: клиент 9 колонок, статус 3 колонки (было 6:6) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -45,6 +45,22 @@
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
/* Стили для системного клиента */
|
||||
.system-customer-option {
|
||||
background-color: #fff3cd;
|
||||
padding: 8px 12px;
|
||||
border-radius: 4px;
|
||||
border-left: 3px solid #ffc107;
|
||||
}
|
||||
|
||||
.system-customer-option:hover {
|
||||
background-color: #ffe69c;
|
||||
}
|
||||
|
||||
.system-customer-option i {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
/* Select2 dropdown styling */
|
||||
.select2-results__option.customer-option-item {
|
||||
padding: 8px 8px;
|
||||
@@ -55,6 +71,50 @@
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* Компактные стили для результатов поиска клиентов */
|
||||
.customer-option {
|
||||
padding: 4px 0 !important;
|
||||
font-size: 13px;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.customer-option small {
|
||||
font-size: 11px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.customer-create-option {
|
||||
padding: 6px 10px !important;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.system-customer-option {
|
||||
padding: 6px 10px !important;
|
||||
font-size: 13px;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.system-customer-option small {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
/* Input group с Select2 и кнопкой системного клиента */
|
||||
.customer-select-wrapper {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.customer-select-wrapper .select2-container {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.customer-select-wrapper .btn {
|
||||
flex-shrink: 0;
|
||||
border-radius: 0 4px 4px 0;
|
||||
}
|
||||
|
||||
/* ИСПРАВЛЕНИЕ: Убедимся что Select2 dropdown видим и поверх всех элементов */
|
||||
.select2-container--open {
|
||||
z-index: 9999 !important;
|
||||
@@ -85,10 +145,11 @@
|
||||
.select2-results {
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.select2-results__option {
|
||||
padding: 8px 8px;
|
||||
padding: 6px 8px;
|
||||
color: #212529;
|
||||
}
|
||||
|
||||
@@ -139,48 +200,54 @@
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="col-md-9">
|
||||
<div class="mb-3">
|
||||
<label for="{{ form.customer.id_for_label }}" class="form-label">
|
||||
Клиент <span class="text-danger">*</span>
|
||||
</label>
|
||||
{% if preselected_customer %}
|
||||
<select name="customer"
|
||||
class="form-select customer-select2-auto"
|
||||
id="id_customer"
|
||||
data-ajax-url="{% url 'customers:api-search-customers' %}"
|
||||
data-create-url="{% url 'customers:api-create-customer' %}"
|
||||
data-modal-id="createCustomerModal">
|
||||
<option value="{{ preselected_customer.pk }}" selected
|
||||
data-name="{{ preselected_customer.name }}"
|
||||
data-phone="{{ preselected_customer.phone|default:'' }}"
|
||||
data-email="{{ preselected_customer.email|default:'' }}">
|
||||
{{ preselected_customer.name }}{% if preselected_customer.phone %} ({{ preselected_customer.phone }}){% endif %}
|
||||
</option>
|
||||
</select>
|
||||
{% else %}
|
||||
<select name="customer"
|
||||
class="form-select customer-select2-auto"
|
||||
id="id_customer"
|
||||
data-ajax-url="{% url 'customers:api-search-customers' %}"
|
||||
data-create-url="{% url 'customers:api-create-customer' %}"
|
||||
data-modal-id="createCustomerModal">
|
||||
{% if form.customer.value %}
|
||||
<option value="{{ form.customer.value }}" selected
|
||||
data-name="{{ form.instance.customer.name }}"
|
||||
data-phone="{{ form.instance.customer.phone|default:'' }}"
|
||||
data-email="{{ form.instance.customer.email|default:'' }}">
|
||||
{{ form.instance.customer.name }}{% if form.instance.customer.phone %} ({{ form.instance.customer.phone }}){% endif %}
|
||||
<div class="customer-select-wrapper">
|
||||
{% if preselected_customer %}
|
||||
<select name="customer"
|
||||
class="form-select customer-select2-auto"
|
||||
id="id_customer"
|
||||
data-ajax-url="{% url 'customers:api-search-customers' %}"
|
||||
data-create-url="{% url 'customers:api-create-customer' %}"
|
||||
data-modal-id="createCustomerModal">
|
||||
<option value="{{ preselected_customer.pk }}" selected
|
||||
data-name="{{ preselected_customer.name }}"
|
||||
data-phone="{{ preselected_customer.phone|default:'' }}"
|
||||
data-email="{{ preselected_customer.email|default:'' }}">
|
||||
{{ preselected_customer.name }}{% if preselected_customer.phone %} ({{ preselected_customer.phone }}){% endif %}
|
||||
</option>
|
||||
{% endif %}
|
||||
</select>
|
||||
{% endif %}
|
||||
</select>
|
||||
{% else %}
|
||||
<select name="customer"
|
||||
class="form-select customer-select2-auto"
|
||||
id="id_customer"
|
||||
data-ajax-url="{% url 'customers:api-search-customers' %}"
|
||||
data-create-url="{% url 'customers:api-create-customer' %}"
|
||||
data-modal-id="createCustomerModal">
|
||||
{% if form.customer.value %}
|
||||
<option value="{{ form.customer.value }}" selected
|
||||
data-name="{{ form.instance.customer.name }}"
|
||||
data-phone="{{ form.instance.customer.phone|default:'' }}"
|
||||
data-email="{{ form.instance.customer.email|default:'' }}">
|
||||
{{ form.instance.customer.name }}{% if form.instance.customer.phone %} ({{ form.instance.customer.phone }}){% endif %}
|
||||
</option>
|
||||
{% endif %}
|
||||
</select>
|
||||
{% endif %}
|
||||
<button type="button" class="btn btn-outline-warning" id="select-system-customer-btn"
|
||||
title="Выбрать анонимного покупателя" data-system-url="{% url 'customers:api-get-system-customer' %}">
|
||||
<i class="bi bi-incognito"></i> Аноним
|
||||
</button>
|
||||
</div>
|
||||
{% if form.customer.errors %}
|
||||
<div class="text-danger">{{ form.customer.errors }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="col-md-3">
|
||||
<div class="mb-3">
|
||||
<label for="{{ form.status.id_for_label }}" class="form-label">
|
||||
Статус <span class="text-danger">*</span>
|
||||
@@ -1015,6 +1082,79 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
<!-- Customer Select2 Widget -->
|
||||
<script src="{% static 'orders/js/customer_select2.js' %}" defer></script>
|
||||
|
||||
<!-- System Customer Button Script -->
|
||||
<script>
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
function initSystemCustomerButton() {
|
||||
const button = document.getElementById('select-system-customer-btn');
|
||||
if (!button) return;
|
||||
|
||||
const systemUrl = button.dataset.systemUrl;
|
||||
const customerSelect = document.getElementById('id_customer');
|
||||
if (!customerSelect) return;
|
||||
|
||||
button.addEventListener('click', function() {
|
||||
// Показываем индикатор загрузки
|
||||
const originalHTML = button.innerHTML;
|
||||
button.disabled = true;
|
||||
button.innerHTML = '<span class="spinner-border spinner-border-sm"></span> Загрузка...';
|
||||
|
||||
fetch(systemUrl)
|
||||
.then(function(response) { return response.json(); })
|
||||
.then(function(data) {
|
||||
if (data.success && data.customer) {
|
||||
// Обновляем Select2
|
||||
if (typeof $ !== 'undefined') {
|
||||
const $select = $(customerSelect);
|
||||
// Удаляем текущую опцию, если есть
|
||||
$select.empty();
|
||||
// Добавляем нового клиента
|
||||
const newOption = new Option(
|
||||
data.customer.name,
|
||||
data.customer.id,
|
||||
true,
|
||||
true
|
||||
);
|
||||
// Добавляем data-атрибуты
|
||||
$(newOption).attr({
|
||||
'data-name': data.customer.name,
|
||||
'data-phone': data.customer.phone,
|
||||
'data-email': data.customer.email,
|
||||
'data-is-system-customer': 'true'
|
||||
});
|
||||
$select.append(newOption).trigger('change');
|
||||
}
|
||||
|
||||
// Показываем уведомление
|
||||
if (window.showNotification) {
|
||||
window.showNotification('Выбран анонимный покупатель', 'success');
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(function(error) {
|
||||
console.error('Error loading system customer:', error);
|
||||
if (window.showNotification) {
|
||||
window.showNotification('Ошибка при загрузке системного клиента', 'error');
|
||||
}
|
||||
})
|
||||
.finally(function() {
|
||||
button.disabled = false;
|
||||
button.innerHTML = originalHTML;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Инициализация при загрузке DOM
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', initSystemCustomerButton);
|
||||
} else {
|
||||
initSystemCustomerButton();
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
|
||||
<script>
|
||||
// Инициализация Select2 для остальных полей (после jQuery загружен)
|
||||
if (typeof $ !== 'undefined') {
|
||||
|
||||
Reference in New Issue
Block a user