- Добавлен combine_mode в форму создания/редактирования скидок - Добавлена колонка "Объединение" в список скидок с иконками - Добавлен фильтр по режиму объединения скидок - Добавлена валидация: только одна exclusive скидка на заказ - Удалены дублирующие поля из Order и OrderItem: - applied_discount, applied_promo_code, discount_amount - Скидки теперь хранятся только в DiscountApplication - Добавлены свойства для обратной совместимости Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
241 lines
13 KiB
HTML
241 lines
13 KiB
HTML
{% extends "system_settings/base_settings.html" %}
|
||
|
||
{% block title %}Скидки{% endblock %}
|
||
|
||
{% block settings_content %}
|
||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||
<h3>Скидки</h3>
|
||
<div class="d-flex gap-2">
|
||
<a href="{% url 'system_settings:discounts:promo-list' %}" class="btn btn-outline-primary">
|
||
<i class="bi bi-ticket-perforated"></i> Промокоды
|
||
</a>
|
||
{% if can_edit %}
|
||
<a href="{% url 'system_settings:discounts:create' %}" class="btn btn-primary">
|
||
<i class="bi bi-plus-circle"></i> Создать скидку
|
||
</a>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
|
||
{% if messages %}
|
||
{% for message in messages %}
|
||
<div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
|
||
{{ message }}
|
||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||
</div>
|
||
{% endfor %}
|
||
{% endif %}
|
||
|
||
<!-- Фильтры -->
|
||
<div class="card mb-3">
|
||
<div class="card-body">
|
||
<form method="get" class="row g-3">
|
||
<div class="col-md-3">
|
||
<label class="form-label">Поиск</label>
|
||
<input type="text" name="search" class="form-control" placeholder="Название или описание"
|
||
value="{{ current_filters.search }}">
|
||
</div>
|
||
<div class="col-md-2">
|
||
<label class="form-label">Тип скидки</label>
|
||
<select name="type" class="form-select">
|
||
<option value="">Все</option>
|
||
<option value="percentage" {% if current_filters.type == 'percentage' %}selected{% endif %}>Процент</option>
|
||
<option value="fixed_amount" {% if current_filters.type == 'fixed_amount' %}selected{% endif %}>Фиксированная сумма</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-2">
|
||
<label class="form-label">Область действия</label>
|
||
<select name="scope" class="form-select">
|
||
<option value="">Все</option>
|
||
<option value="order" {% if current_filters.scope == 'order' %}selected{% endif %}>На заказ</option>
|
||
<option value="product" {% if current_filters.scope == 'product' %}selected{% endif %}>На товар</option>
|
||
<option value="category" {% if current_filters.scope == 'category' %}selected{% endif %}>На категорию</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-2">
|
||
<label class="form-label">Статус</label>
|
||
<select name="is_active" class="form-select">
|
||
<option value="">Все</option>
|
||
<option value="active" {% if current_filters.is_active == 'active' %}selected{% endif %}>Активные</option>
|
||
<option value="inactive" {% if current_filters.is_active == 'inactive' %}selected{% endif %}>Неактивные</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-2">
|
||
<label class="form-label">Объединение</label>
|
||
<select name="combine_mode" class="form-select">
|
||
<option value="">Все</option>
|
||
<option value="stack" {% if current_filters.combine_mode == 'stack' %}selected{% endif %}>Складывать</option>
|
||
<option value="max_only" {% if current_filters.combine_mode == 'max_only' %}selected{% endif %}>Максимум</option>
|
||
<option value="exclusive" {% if current_filters.combine_mode == 'exclusive' %}selected{% endif %}>Исключающая</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-3 d-flex align-items-end">
|
||
<button type="submit" class="btn btn-primary me-2">
|
||
<i class="bi bi-funnel"></i> Применить
|
||
</button>
|
||
<a href="{% url 'system_settings:discounts:list' %}" class="btn btn-outline-secondary">
|
||
<i class="bi bi-x-circle"></i> Сбросить
|
||
</a>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-body">
|
||
{% if discounts %}
|
||
<div class="table-responsive">
|
||
<table class="table table-hover">
|
||
<thead>
|
||
<tr>
|
||
<th>Название</th>
|
||
<th>Тип</th>
|
||
<th>Значение</th>
|
||
<th>Область</th>
|
||
<th>Авто</th>
|
||
<th>Объединение</th>
|
||
<th>Статус</th>
|
||
<th>Промокоды</th>
|
||
<th>Использований</th>
|
||
<th>Действия</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for discount in discounts %}
|
||
<tr>
|
||
<td>
|
||
<strong>{{ discount.name }}</strong>
|
||
{% if discount.description %}
|
||
<br><small class="text-muted">{{ discount.description|truncatewords:10 }}</small>
|
||
{% endif %}
|
||
</td>
|
||
<td>
|
||
{% if discount.discount_type == 'percentage' %}
|
||
<span class="badge bg-primary">Процент</span>
|
||
{% else %}
|
||
<span class="badge bg-info">Фиксированная</span>
|
||
{% endif %}
|
||
</td>
|
||
<td>
|
||
{% if discount.discount_type == 'percentage' %}
|
||
{{ discount.value }}%
|
||
{% else %}
|
||
{{ discount.value }} руб.
|
||
{% endif %}
|
||
</td>
|
||
<td>
|
||
{% if discount.scope == 'order' %}
|
||
<span class="badge bg-success">Заказ</span>
|
||
{% elif discount.scope == 'product' %}
|
||
<span class="badge bg-warning text-dark">Товар</span>
|
||
{% else %}
|
||
<span class="badge bg-secondary">Категория</span>
|
||
{% endif %}
|
||
</td>
|
||
<td>
|
||
{% if discount.is_auto %}
|
||
<i class="bi bi-check-circle text-success"></i>
|
||
{% else %}
|
||
<i class="bi bi-dash-circle text-muted"></i>
|
||
{% endif %}
|
||
</td>
|
||
<td>
|
||
{% if discount.combine_mode == 'stack' %}
|
||
<span class="badge bg-secondary" title="Складывать (суммировать)">📚 Склад.</span>
|
||
{% elif discount.combine_mode == 'max_only' %}
|
||
<span class="badge bg-info" title="Только максимум">🏆 Макс.</span>
|
||
{% elif discount.combine_mode == 'exclusive' %}
|
||
<span class="badge bg-danger" title="Исключающая (отменяет остальные)">🚫 Исключ.</span>
|
||
{% endif %}
|
||
</td>
|
||
<td>
|
||
{% if discount.is_active %}
|
||
<span class="badge bg-success">Активна</span>
|
||
{% else %}
|
||
<span class="badge bg-secondary">Неактивна</span>
|
||
{% endif %}
|
||
</td>
|
||
<td>
|
||
<a href="{% url 'system_settings:discounts:promo-list' %}?search={{ discount.id|lower }}" class="text-decoration-none">
|
||
{{ discount.promo_count }}
|
||
</a>
|
||
</td>
|
||
<td>
|
||
{{ discount.current_usage_count }}
|
||
{% if discount.max_usage_count %}
|
||
/ {{ discount.max_usage_count }}
|
||
{% endif %}
|
||
</td>
|
||
<td>
|
||
{% if can_edit %}
|
||
<div class="btn-group btn-group-sm">
|
||
<a href="{% url 'system_settings:discounts:update' discount.pk %}"
|
||
class="btn btn-outline-primary" title="Редактировать">
|
||
<i class="bi bi-pencil"></i>
|
||
</a>
|
||
<a href="{% url 'system_settings:discounts:toggle' discount.pk %}"
|
||
class="btn btn-outline-{% if discount.is_active %}warning{% else %}success{% endif %}"
|
||
title="{% if discount.is_active %}Деактивировать{% else %}Активировать{% endif %}">
|
||
<i class="bi bi-{% if discount.is_active %}pause{% else %}play{% endif %}"></i>
|
||
</a>
|
||
<a href="{% url 'system_settings:discounts:delete' discount.pk %}"
|
||
class="btn btn-outline-danger" title="Удалить">
|
||
<i class="bi bi-trash"></i>
|
||
</a>
|
||
</div>
|
||
{% else %}
|
||
<span class="text-muted small"><i class="bi bi-lock"></i></span>
|
||
{% endif %}
|
||
</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- Пагинация -->
|
||
{% if is_paginated %}
|
||
<nav aria-label="Page navigation">
|
||
<ul class="pagination justify-content-center">
|
||
{% if page_obj.has_previous %}
|
||
<li class="page-item">
|
||
<a class="page-link" href="?page=1{% if current_filters.search %}&search={{ current_filters.search }}{% endif %}{% if current_filters.type %}&type={{ current_filters.type }}{% endif %}{% if current_filters.scope %}&scope={{ current_filters.scope }}{% endif %}{% if current_filters.is_active %}&is_active={{ current_filters.is_active }}{% endif %}{% if current_filters.combine_mode %}&combine_mode={{ current_filters.combine_mode }}{% endif %}">«</a>
|
||
</li>
|
||
<li class="page-item">
|
||
<a class="page-link" href="?page={{ page_obj.previous_page_number }}{% if current_filters.search %}&search={{ current_filters.search }}{% endif %}{% if current_filters.type %}&type={{ current_filters.type }}{% endif %}{% if current_filters.scope %}&scope={{ current_filters.scope }}{% endif %}{% if current_filters.is_active %}&is_active={{ current_filters.is_active }}{% endif %}{% if current_filters.combine_mode %}&combine_mode={{ current_filters.combine_mode }}{% endif %}">‹</a>
|
||
</li>
|
||
{% endif %}
|
||
|
||
<li class="page-item active">
|
||
<span class="page-link">{{ page_obj.number }}</span>
|
||
</li>
|
||
|
||
{% if page_obj.has_next %}
|
||
<li class="page-item">
|
||
<a class="page-link" href="?page={{ page_obj.next_page_number }}{% if current_filters.search %}&search={{ current_filters.search }}{% endif %}{% if current_filters.type %}&type={{ current_filters.type }}{% endif %}{% if current_filters.scope %}&scope={{ current_filters.scope }}{% endif %}{% if current_filters.is_active %}&is_active={{ current_filters.is_active }}{% endif %}{% if current_filters.combine_mode %}&combine_mode={{ current_filters.combine_mode }}{% endif %}">›</a>
|
||
</li>
|
||
<li class="page-item">
|
||
<a class="page-link" href="?page={{ page_obj.paginator.num_pages }}{% if current_filters.search %}&search={{ current_filters.search }}{% endif %}{% if current_filters.type %}&type={{ current_filters.type }}{% endif %}{% if current_filters.scope %}&scope={{ current_filters.scope }}{% endif %}{% if current_filters.is_active %}&is_active={{ current_filters.is_active }}{% endif %}{% if current_filters.combine_mode %}&combine_mode={{ current_filters.combine_mode }}{% endif %}">»</a>
|
||
</li>
|
||
{% endif %}
|
||
</ul>
|
||
</nav>
|
||
{% endif %}
|
||
|
||
{% else %}
|
||
<div class="text-center py-5">
|
||
<p class="text-muted">Нет скидок</p>
|
||
<i class="bi bi-tag display-4 text-muted"></i>
|
||
{% if can_edit %}
|
||
<div class="mt-3">
|
||
<a href="{% url 'system_settings:discounts:create' %}" class="btn btn-primary">
|
||
Создать первую скидку
|
||
</a>
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
{% endblock %}
|