Рабочие изменения: улучшения UI, настройки и бэкенд авторизации
Собрал накопившиеся изменения из рабочей директории: UI улучшения: - customer_detail.html: Расширен интерфейс детальной страницы клиента - order_detail.html: Добавлены элементы отображения деталей заказа - order_list.html: Улучшена визуализация списка заказов Бэкенд: - customers/views.py: Доработаны представления для работы с клиентами - products/views/product_views.py: Минорные правки - user_roles/auth_backend.py: Добавлен кастомный бэкенд авторизации Настройки: - myproject/settings.py: Обновлены конфигурации - .gitignore: Добавлен для игнорирования служебных файлов - requirements.txt: Удален (вероятно заменен на poetry/pipenv) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -70,6 +70,28 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Алерт о необходимости возврата -->
|
||||
{% if refund_amount > 0 %}
|
||||
<div class="col-md-12">
|
||||
<div class="alert alert-warning d-flex justify-content-between align-items-center mb-4" role="alert">
|
||||
<div>
|
||||
<h5 class="alert-heading mb-2">
|
||||
<i class="bi bi-exclamation-triangle-fill"></i> Требуется возврат средств
|
||||
</h5>
|
||||
<p class="mb-0">
|
||||
Клиент имеет отменённые заказы с внесённой оплатой.
|
||||
Общая сумма к возврату: <strong>{{ refund_amount|floatformat:2 }} руб.</strong>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<span class="badge bg-warning text-dark" style="font-size: 1.2em;">
|
||||
{{ refund_amount|floatformat:2 }} руб.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Операции с кошельком -->
|
||||
<div class="col-md-6">
|
||||
<div class="card mb-4">
|
||||
@@ -268,12 +290,13 @@
|
||||
<th>Сумма</th>
|
||||
<th>Оплачено</th>
|
||||
<th>Остаток</th>
|
||||
<th>Возврат</th>
|
||||
<th>Действия</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for order in orders_page %}
|
||||
<tr>
|
||||
<tr {% if order.status and order.status.is_negative_end and order.amount_paid > 0 %}class="table-warning"{% endif %}>
|
||||
<td><strong>#{{ order.order_number }}</strong></td>
|
||||
<td><small>{{ order.created_at|date:"d.m.Y H:i" }}</small></td>
|
||||
<td>
|
||||
@@ -313,12 +336,22 @@
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if order.payment_status == 'paid' %}
|
||||
<span class="badge bg-success">Оплачено</span>
|
||||
{% elif order.payment_status == 'partial' %}
|
||||
<span class="badge bg-warning">Частично</span>
|
||||
{% if order.is_paid %}
|
||||
<span class="badge bg-success">
|
||||
<i class="bi bi-check-circle"></i> Оплачено
|
||||
</span>
|
||||
{% elif order.status and order.status.is_negative_end and order.amount_paid > 0 %}
|
||||
<span class="badge bg-warning text-dark" title="Требуется возврат: {{ order.amount_paid|floatformat:2 }} руб.">
|
||||
<i class="bi bi-exclamation-triangle"></i> Возврат
|
||||
</span>
|
||||
{% elif order.amount_paid > 0 %}
|
||||
<span class="badge bg-warning">
|
||||
<i class="bi bi-exclamation-circle"></i> Частично ({{ order.amount_paid|floatformat:2 }} руб.)
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="badge bg-danger">Не оплачено</span>
|
||||
<span class="badge bg-danger">
|
||||
<i class="bi bi-x-circle"></i> Не оплачено
|
||||
</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td><strong>{{ order.total_amount|floatformat:2 }} руб.</strong></td>
|
||||
@@ -330,12 +363,23 @@
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if order.amount_due > 0 %}
|
||||
{% if order.status and order.status.is_negative_end %}
|
||||
<span class="text-muted">—</span>
|
||||
{% elif order.amount_due > 0 %}
|
||||
<span class="text-danger fw-bold">{{ order.amount_due|floatformat:2 }} руб.</span>
|
||||
{% else %}
|
||||
<span class="text-success">0.00 руб.</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if order.status and order.status.is_negative_end and order.amount_paid > 0 %}
|
||||
<span class="badge bg-warning text-dark" title="Требуется возврат">
|
||||
<i class="bi bi-exclamation-triangle"></i> {{ order.amount_paid|floatformat:2 }} руб.
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="text-muted">—</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<a href="{% url 'orders:order-detail' order.order_number %}" class="btn btn-sm btn-outline-primary">
|
||||
<i class="bi bi-eye"></i>
|
||||
|
||||
@@ -87,8 +87,13 @@ def customer_detail(request, pk):
|
||||
if customer.is_system_customer:
|
||||
return render(request, 'customers/customer_system.html')
|
||||
|
||||
# Рассчитываем общий долг по активным заказам на стороне БД
|
||||
total_debt_result = customer.orders.exclude(payment_status='paid').aggregate(
|
||||
# Рассчитываем общий долг по заказам на стороне БД
|
||||
# Долг = все заказы КРОМЕ отмененных и полностью оплаченных
|
||||
# ВКЛЮЧАЕТ завершенные заказы с неполной оплатой!
|
||||
total_debt_result = customer.orders.exclude(
|
||||
Q(status__is_negative_end=True) | # Отмененные → учитываются в refund_amount
|
||||
Q(payment_status='paid') # Полностью оплаченные
|
||||
).aggregate(
|
||||
total_debt=Coalesce(
|
||||
Sum(Greatest(F('total_amount') - F('amount_paid'), Value(0), output_field=DecimalField())),
|
||||
Value(0),
|
||||
@@ -96,9 +101,25 @@ def customer_detail(request, pk):
|
||||
)
|
||||
)
|
||||
total_debt = total_debt_result['total_debt'] or Decimal('0')
|
||||
|
||||
# Количество активных заказов
|
||||
active_orders_count = customer.orders.exclude(payment_status='paid').count()
|
||||
|
||||
# Количество заказов с долгом (с той же логикой)
|
||||
active_orders_count = customer.orders.exclude(
|
||||
Q(status__is_negative_end=True) |
|
||||
Q(payment_status='paid')
|
||||
).count()
|
||||
|
||||
# Сумма к возврату (отмененные заказы с оплатой)
|
||||
refund_amount_result = customer.orders.filter(
|
||||
status__is_negative_end=True, # Отмененные
|
||||
amount_paid__gt=0 # С оплатой
|
||||
).aggregate(
|
||||
total_refund=Coalesce(
|
||||
Sum('amount_paid'),
|
||||
Value(0),
|
||||
output_field=DecimalField()
|
||||
)
|
||||
)
|
||||
refund_amount = refund_amount_result['total_refund'] or Decimal('0')
|
||||
|
||||
# История транзакций кошелька (последние 20)
|
||||
from .models import WalletTransaction
|
||||
@@ -116,6 +137,7 @@ def customer_detail(request, pk):
|
||||
'customer': customer,
|
||||
'total_debt': total_debt,
|
||||
'active_orders_count': active_orders_count,
|
||||
'refund_amount': refund_amount,
|
||||
'wallet_transactions': wallet_transactions,
|
||||
'orders_page': orders_page,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user