feat(orders): add recipient management and enhance order forms
- Introduced Recipient model to manage order recipients separately from customers. - Updated Order model to link to Recipient, replacing recipient_name and recipient_phone fields. - Enhanced OrderForm to include recipient selection modes: customer, history, and new. - Added AJAX endpoint to fetch recipient history for customers. - Updated admin interface to manage recipients and display recipient information in order details. - Refactored address handling to accommodate new recipient logic. - Improved demo order creation to include random recipients.
This commit is contained in:
@@ -131,7 +131,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Получатель -->
|
||||
{% if not order.customer_is_recipient %}
|
||||
{% if not order.customer_is_recipient and order.recipient %}
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">Получатель</h5>
|
||||
@@ -139,11 +139,11 @@
|
||||
<div class="card-body">
|
||||
<div class="row mb-2">
|
||||
<div class="col-md-4"><strong>Имя получателя:</strong></div>
|
||||
<div class="col-md-8">{{ order.recipient_name|default:"Не указано" }}</div>
|
||||
<div class="col-md-8">{{ order.recipient.name|default:"Не указано" }}</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<div class="col-md-4"><strong>Телефон получателя:</strong></div>
|
||||
<div class="col-md-8">{{ order.recipient_phone|default:"Не указан" }}</div>
|
||||
<div class="col-md-8">{{ order.recipient.phone|default:"Не указан" }}</div>
|
||||
</div>
|
||||
{% if order.is_anonymous %}
|
||||
<div class="row mb-2">
|
||||
|
||||
@@ -504,24 +504,34 @@
|
||||
<div class="border-top pt-3 mt-3">
|
||||
<h6 class="mb-3">Получатель</h6>
|
||||
|
||||
<!-- Крупный переключатель "Покупатель = получатель" -->
|
||||
<!-- Режимы выбора получателя -->
|
||||
<div class="mb-3">
|
||||
<div class="form-check form-switch" style="padding-left: 3.5em;">
|
||||
<input class="form-check-input" type="checkbox" role="switch"
|
||||
id="{{ form.customer_is_recipient.id_for_label }}"
|
||||
name="{{ form.customer_is_recipient.name }}"
|
||||
{% if form.customer_is_recipient.value %}checked{% endif %}
|
||||
style="width: 3em; height: 1.5em; cursor: pointer;">
|
||||
<label class="form-check-label" for="{{ form.customer_is_recipient.id_for_label }}"
|
||||
style="font-size: 1.1em; font-weight: 500; cursor: pointer; padding-left: 0.5em;">
|
||||
<i class="bi bi-person-check-fill text-primary"></i>
|
||||
Покупатель является получателем
|
||||
{% for choice in form.recipient_mode %}
|
||||
<div class="form-check">
|
||||
{{ choice.tag }}
|
||||
<label class="form-check-label" for="{{ choice.id_for_label }}">
|
||||
{{ choice.choice_label }}
|
||||
</label>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% if form.recipient_mode.errors %}
|
||||
<div class="text-danger">{{ form.recipient_mode.errors }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Поля получателя (показываются когда покупатель != получатель) -->
|
||||
<div class="row" id="recipient-fields" style="display: none;">
|
||||
<!-- Выбор получателя из истории -->
|
||||
<div class="mb-3" id="recipient-history-field" style="display: none;">
|
||||
<label for="{{ form.recipient_from_history.id_for_label }}" class="form-label">
|
||||
{{ form.recipient_from_history.label }}
|
||||
</label>
|
||||
{{ form.recipient_from_history }}
|
||||
{% if form.recipient_from_history.errors %}
|
||||
<div class="text-danger">{{ form.recipient_from_history.errors }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Поля нового получателя -->
|
||||
<div class="row" id="recipient-new-fields" style="display: none;">
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="{{ form.recipient_name.id_for_label }}" class="form-label">
|
||||
@@ -1461,18 +1471,32 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
syncUIFromCheckbox();
|
||||
|
||||
// Показ/скрытие полей получателя
|
||||
const customerIsRecipientCheckbox = document.getElementById('{{ form.customer_is_recipient.id_for_label }}');
|
||||
const recipientFields = document.getElementById('recipient-fields');
|
||||
const recipientModeRadios = document.querySelectorAll('input[name="recipient_mode"]');
|
||||
const recipientHistoryField = document.getElementById('recipient-history-field');
|
||||
const recipientNewFields = document.getElementById('recipient-new-fields');
|
||||
|
||||
function toggleRecipientFields() {
|
||||
if (customerIsRecipientCheckbox.checked) {
|
||||
recipientFields.style.display = 'none';
|
||||
} else {
|
||||
recipientFields.style.display = '';
|
||||
const selectedMode = document.querySelector('input[name="recipient_mode"]:checked');
|
||||
if (!selectedMode) return;
|
||||
|
||||
const mode = selectedMode.value;
|
||||
|
||||
// Скрываем все поля
|
||||
recipientHistoryField.style.display = 'none';
|
||||
recipientNewFields.style.display = 'none';
|
||||
|
||||
// Показываем нужные поля
|
||||
if (mode === 'history') {
|
||||
recipientHistoryField.style.display = 'block';
|
||||
} else if (mode === 'new') {
|
||||
recipientNewFields.style.display = 'block';
|
||||
}
|
||||
// Для 'customer' ничего не показываем
|
||||
}
|
||||
|
||||
customerIsRecipientCheckbox.addEventListener('change', toggleRecipientFields);
|
||||
recipientModeRadios.forEach(radio => {
|
||||
radio.addEventListener('change', toggleRecipientFields);
|
||||
});
|
||||
toggleRecipientFields();
|
||||
|
||||
// === РАСЧЁТ ИТОГОВОЙ СУММЫ ТОВАРОВ ===
|
||||
|
||||
Reference in New Issue
Block a user