feat(discounts): добавлен CRUD интерфейс для скидок в настройках

- Добавлена вкладка "Скидки" в страницу настроек
- Созданы views для управления скидками и промокодами с проверкой прав:
  * owner/manager/superuser - полный CRUD
  * florist - только просмотр
  * courier - нет доступа
- Созданы шаблоны: список скидок, форма, подтверждение удаления
- Созданы шаблоны: список промокодов, форма, подтверждение удаления
- Добавлены фильтры по типу, области действия, активности
- Добавлена пагинация

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-11 01:18:26 +03:00
parent f50b47736d
commit b48e6c810d
10 changed files with 1169 additions and 2 deletions

View File

@@ -0,0 +1,45 @@
{% extends "system_settings/base_settings.html" %}
{% block title %}Удаление скидки{% endblock %}
{% block settings_content %}
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card">
<div class="card-header bg-danger text-white">
<h4 class="mb-0"><i class="bi bi-exclamation-triangle"></i> Удаление скидки</h4>
</div>
<div class="card-body">
<p>Вы уверены, что хотите удалить скидку <strong>{{ object.name }}</strong>?</p>
<div class="alert alert-warning">
<i class="bi bi-info-circle"></i>
<strong>Внимание!</strong> Это действие нельзя отменить.
{% if object.promo_codes.count > 0 %}
<br>Также будут удалены связанные промокоды ({{ object.promo_codes.count }} шт.).
{% endif %}
</div>
<div class="mb-3">
<strong>Информация о скидке:</strong>
<ul class="mb-0">
<li>Тип: {% if object.discount_type == 'percentage' %}Процент ({{ object.value }}%){% else %}{{ object.value }} руб.{% endif %}</li>
<li>Область: {% if object.scope == 'order' %}На заказ{% elif object.scope == 'product' %}На товары{% else %}На категории{% endif %}</li>
<li>Использований: {{ object.current_usage_count }} раз</li>
</ul>
</div>
<form method="post">
{% csrf_token %}
<div class="d-flex justify-content-between">
<a href="{% url 'system_settings:discounts:list' %}" class="btn btn-secondary">Отмена</a>
<button type="submit" class="btn btn-danger">
<i class="bi bi-trash"></i> Удалить
</button>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,191 @@
{% extends "system_settings/base_settings.html" %}
{% block title %}{% if is_edit %}Редактирование скидки{% else %}Создание скидки{% endif %}{% endblock %}
{% block settings_content %}
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h4 class="mb-0">
{% if is_edit %}Редактирование скидки{% else %}Создание скидки{% endif %}
</h4>
<a href="{% url 'system_settings:discounts:list' %}" class="btn btn-outline-secondary btn-sm">
<i class="bi bi-arrow-left"></i> Назад
</a>
</div>
<div class="card-body">
{% 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 %}
<form method="post">
{% csrf_token %}
<!-- Основная информация -->
<h5 class="mb-3">Основная информация</h5>
<div class="row mb-3">
<div class="col-md-6">
<label for="id_name" class="form-label">Название * <span class="text-muted small">(макс. 200 символов)</span></label>
<input type="text" class="form-control" id="id_name" name="name"
value="{% if form.name.value %}{{ form.name.value }}{% endif %}"
maxlength="200" required>
</div>
<div class="col-md-6">
<label for="id_priority" class="form-label">Приоритет</label>
<input type="number" class="form-control" id="id_priority" name="priority"
value="{% if form.priority.value %}{{ form.priority.value }}{% else %}0{% endif %}"
min="0">
<div class="form-text">Выше = применяется раньше</div>
</div>
</div>
<div class="mb-3">
<label for="id_description" class="form-label">Описание</label>
<textarea class="form-control" id="id_description" name="description" rows="2">{{ form.description.value }}</textarea>
</div>
<!-- Параметры скидки -->
<h5 class="mb-3 mt-4">Параметры скидки</h5>
<div class="row mb-3">
<div class="col-md-4">
<label for="id_discount_type" class="form-label">Тип скидки *</label>
<select class="form-select" id="id_discount_type" name="discount_type" required>
<option value="">Выберите...</option>
<option value="percentage" {% if form.discount_type.value == 'percentage' %}selected{% endif %}>Процент</option>
<option value="fixed_amount" {% if form.discount_type.value == 'fixed_amount' %}selected{% endif %}>Фиксированная сумма (руб.)</option>
</select>
</div>
<div class="col-md-4">
<label for="id_value" class="form-label">Значение *</label>
<input type="number" class="form-control" id="id_value" name="value"
value="{% if form.value.value %}{{ form.value.value }}{% endif %}"
step="0.01" min="0" required>
</div>
<div class="col-md-4">
<label for="id_scope" class="form-label">Область действия *</label>
<select class="form-select" id="id_scope" name="scope" required>
<option value="">Выберите...</option>
<option value="order" {% if form.scope.value == 'order' %}selected{% endif %}>На весь заказ</option>
<option value="product" {% if form.scope.value == 'product' %}selected{% endif %}>На конкретные товары</option>
<option value="category" {% if form.scope.value == 'category' %}selected{% endif %}>На категории товаров</option>
</select>
</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<div class="form-check form-switch mt-4">
<input class="form-check-input" type="checkbox" id="id_is_auto" name="is_auto"
{% if form.is_auto.value %}checked{% endif %}>
<label class="form-check-label" for="id_is_auto">
Автоматическое применение
</label>
<div class="form-text">Скидка будет применяться автоматически при оформлении заказа</div>
</div>
</div>
<div class="col-md-6">
<div class="form-check form-switch mt-4">
<input class="form-check-input" type="checkbox" id="id_is_active" name="is_active"
{% if form.is_active.value is None or form.is_active.value %}checked{% endif %}>
<label class="form-check-label" for="id_is_active">
Активна
</label>
<div class="form-text">Неактивные скидки не применяются</div>
</div>
</div>
</div>
<!-- Ограничения -->
<h5 class="mb-3 mt-4">Ограничения</h5>
<div class="row mb-3">
<div class="col-md-6">
<label for="id_min_order_amount" class="form-label">Мин. сумма заказа</label>
<input type="number" class="form-control" id="id_min_order_amount" name="min_order_amount"
value="{% if form.min_order_amount.value %}{{ form.min_order_amount.value }}{% endif %}"
step="0.01" min="0">
<div class="form-text">Для скидок на заказ</div>
</div>
<div class="col-md-6">
<label for="id_max_usage_count" class="form-label">Макс. использований</label>
<input type="number" class="form-control" id="id_max_usage_count" name="max_usage_count"
value="{% if form.max_usage_count.value %}{{ form.max_usage_count.value }}{% endif %}"
min="1">
<div class="form-text">Оставьте пустым для безлимитного использования</div>
</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<label for="id_start_date" class="form-label">Дата начала</label>
<input type="datetime-local" class="form-control" id="id_start_date" name="start_date"
value="{% if form.start_date.value %}{{ form.start_date.value|date:'Y-m-d\TH:i' }}{% endif %}">
</div>
<div class="col-md-6">
<label for="id_end_date" class="form-label">Дата окончания</label>
<input type="datetime-local" class="form-control" id="id_end_date" name="end_date"
value="{% if form.end_date.value %}{{ form.end_date.value|date:'Y-m-d\TH:i' }}{% endif %}">
</div>
</div>
<!-- Товары и категории -->
<h5 class="mb-3 mt-4">Применение к товарам</h5>
<div class="mb-3">
<label for="id_products" class="form-label">Товары</label>
<select class="form-select" id="id_products" name="products" multiple>
{% for product in all_products %}
<option value="{{ product.id }}" {% if product.id in selected_products %}selected{% endif %}>
{{ product.name }}
</option>
{% endfor %}
</select>
<div class="form-text">Удерживайте Ctrl для выбора нескольких товаров</div>
</div>
<div class="mb-3">
<label for="id_categories" class="form-label">Категории</label>
<select class="form-select" id="id_categories" name="categories" multiple>
{% for category in all_categories %}
<option value="{{ category.id }}" {% if category.id in selected_categories %}selected{% endif %}>
{{ category.name }}
</option>
{% endfor %}
{% if not all_categories %}
<option value="" disabled>Нет доступных категорий</option>
{% endif %}
%}
</select>
<div class="form-text">Удерживайте Ctrl для выбора нескольких категорий</div>
</div>
<div class="mb-3">
<label for="id_excluded_products" class="form-label">Исключённые товары</label>
<select class="form-select" id="id_excluded_products" name="excluded_products" multiple>
{% for product in all_products %}
<option value="{{ product.id }}" {% if product.id in excluded_products %}selected{% endif %}>
{{ product.name }}
</option>
{% endfor %}
</select>
<div class="form-text">Эти товары не будут участвовать в акции</div>
</div>
<!-- Кнопки -->
<div class="d-flex justify-content-between mt-4">
<a href="{% url 'system_settings:discounts:list' %}" class="btn btn-secondary">Отмена</a>
<button type="submit" class="btn btn-primary">
<i class="bi bi-check-circle"></i>
{% if is_edit %}Сохранить изменения{% else %}Создать скидку{% endif %}
</button>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,221 @@
{% 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-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>
</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.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 %}">&laquo;</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 %}">&lsaquo;</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 %}">&rsaquo;</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 %}">&raquo;</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 %}

View File

@@ -0,0 +1,42 @@
{% extends "system_settings/base_settings.html" %}
{% block title %}Удаление промокода{% endblock %}
{% block settings_content %}
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card">
<div class="card-header bg-danger text-white">
<h4 class="mb-0"><i class="bi bi-exclamation-triangle"></i> Удаление промокода</h4>
</div>
<div class="card-body">
<p>Вы уверены, что хотите удалить промокод <code>{{ object.code }}</code>?</p>
<div class="alert alert-warning">
<i class="bi bi-info-circle"></i>
<strong>Внимание!</strong> Это действие нельзя отменить.
</div>
<div class="mb-3">
<strong>Информация о промокоде:</strong>
<ul class="mb-0">
<li>Скидка: {{ object.discount.name }}</li>
<li>Значение: {% if object.discount.discount_type == 'percentage' %}{{ object.discount.value }}%{% else %}{{ object.discount.value }} руб.{% endif %}</li>
<li>Использований: {{ object.current_uses }} раз</li>
</ul>
</div>
<form method="post">
{% csrf_token %}
<div class="d-flex justify-content-between">
<a href="{% url 'system_settings:discounts:promo-list' %}" class="btn btn-secondary">Отмена</a>
<button type="submit" class="btn btn-danger">
<i class="bi bi-trash"></i> Удалить
</button>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,107 @@
{% extends "system_settings/base_settings.html" %}
{% block title %}{% if is_edit %}Редактирование промокода{% else %}Создание промокода{% endif %}{% endblock %}
{% block settings_content %}
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h4 class="mb-0">
{% if is_edit %}Редактирование промокода{% else %}Создание промокода{% endif %}
</h4>
<a href="{% url 'system_settings:discounts:promo-list' %}" class="btn btn-outline-secondary btn-sm">
<i class="bi bi-arrow-left"></i> Назад
</a>
</div>
<div class="card-body">
{% 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 %}
<form method="post">
{% csrf_token %}
<div class="mb-3">
<label for="id_code" class="form-label">Код промокода * <span class="text-muted small">(макс. 50 символов)</span></label>
<input type="text" class="form-control font-monospace" id="id_code" name="code"
value="{% if form.code.value %}{{ form.code.value }}{% endif %}"
maxlength="50" required
placeholder="Например: ЦВЕТЫ2025">
<div class="form-text">Код, который будут вводить покупатели</div>
</div>
<div class="mb-3">
<label for="id_discount" class="form-label">Скидка *</label>
<select class="form-select" id="id_discount" name="discount" required>
<option value="">Выберите скидку...</option>
{% for discount in all_discounts %}
<option value="{{ discount.id }}"
{% if form.discount.value == discount.id %}selected{% endif %}
data-type="{{ discount.discount_type }}"
data-value="{{ discount.value }}">
{{ discount.name }}
({% if discount.discount_type == 'percentage' %}{{ discount.value }}%{% else %}{{ discount.value }} руб.{% endif %})
</option>
{% endfor %}
</select>
<div class="form-text">Информация о скидке отобразится при применении промокода</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<label for="id_max_uses_per_user" class="form-label">Макс. использований на пользователя</label>
<input type="number" class="form-control" id="id_max_uses_per_user" name="max_uses_per_user"
value="{% if form.max_uses_per_user.value %}{{ form.max_uses_per_user.value }}{% endif %}"
min="1">
<div class="form-text">Оставьте пустым для безлимитного использования</div>
</div>
<div class="col-md-6">
<label for="id_max_total_uses" class="form-label">Макс. всего использований</label>
<input type="number" class="form-control" id="id_max_total_uses" name="max_total_uses"
value="{% if form.max_total_uses.value %}{{ form.max_total_uses.value }}{% endif %}"
min="1">
<div class="form-text">Общий лимит для всех пользователей</div>
</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<label for="id_start_date" class="form-label">Дата начала</label>
<input type="datetime-local" class="form-control" id="id_start_date" name="start_date"
value="{% if form.start_date.value %}{{ form.start_date.value|date:'Y-m-d\TH:i' }}{% endif %}">
</div>
<div class="col-md-6">
<label for="id_end_date" class="form-label">Дата окончания</label>
<input type="datetime-local" class="form-control" id="id_end_date" name="end_date"
value="{% if form.end_date.value %}{{ form.end_date.value|date:'Y-m-d\TH:i' }}{% endif %}">
</div>
</div>
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" id="id_is_active" name="is_active"
{% if form.is_active.value is None or form.is_active.value %}checked{% endif %}>
<label class="form-check-label" for="id_is_active">
Активен
</label>
<div class="form-text">Неактивные промокоды не применяются</div>
</div>
<div class="d-flex justify-content-between">
<a href="{% url 'system_settings:discounts:promo-list' %}" class="btn btn-secondary">Отмена</a>
<button type="submit" class="btn btn-primary">
<i class="bi bi-check-circle"></i>
{% if is_edit %}Сохранить изменения{% else %}Создать промокод{% endif %}
</button>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,202 @@
{% 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:list' %}" class="btn btn-outline-secondary">
<i class="bi bi-arrow-left"></i> К скидкам
</a>
{% if can_edit %}
<a href="{% url 'system_settings:discounts:promo-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 align-items-end">
<div class="col-md-4">
<label class="form-label">Поиск по коду</label>
<input type="text" name="search" class="form-control" placeholder="Код промокода"
value="{{ current_filters.search }}">
</div>
<div class="col-md-3">
<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-5">
<button type="submit" class="btn btn-primary me-2">
<i class="bi bi-funnel"></i> Применить
</button>
<a href="{% url 'system_settings:discounts:promo-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 promocodes %}
<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>
</tr>
</thead>
<tbody>
{% for promo in promocodes %}
<tr>
<td>
<code class="fs-5">{{ promo.code }}</code>
</td>
<td>
<a href="{% url 'system_settings:discounts:update' promo.discount.id %}" class="text-decoration-none">
{{ promo.discount.name }}
</a>
</td>
<td>
{% if promo.discount.discount_type == 'percentage' %}
<span class="badge bg-primary">%</span>
{% else %}
<span class="badge bg-info">руб.</span>
{% endif %}
</td>
<td>
{% if promo.discount.discount_type == 'percentage' %}
{{ promo.discount.value }}%
{% else %}
{{ promo.discount.value }} руб.
{% endif %}
</td>
<td>
{{ promo.current_uses }}
{% if promo.max_total_uses %}
/ {{ promo.max_total_uses }}
{% else %}
/ &infin;
{% endif %}
{% if promo.max_uses_per_user %}
<br><small class="text-muted">макс. {{ promo.max_uses_per_user }} на пользователя</small>
{% endif %}
</td>
<td>
<small class="text-muted">
{% if promo.start_date and promo.end_date %}
с {{ promo.start_date|date:"d.m.Y" }}<br>по {{ promo.end_date|date:"d.m.Y" }}
{% elif promo.start_date %}
с {{ promo.start_date|date:"d.m.Y" }}
{% elif promo.end_date %}
до {{ promo.end_date|date:"d.m.Y" }}
{% else %}
Бессрочный
{% endif %}
</small>
</td>
<td>
{% if promo.is_active %}
<span class="badge bg-success">Активен</span>
{% else %}
<span class="badge bg-secondary">Неактивен</span>
{% endif %}
</td>
<td>
{% if can_edit %}
<div class="btn-group btn-group-sm">
<a href="{% url 'system_settings:discounts:promo-update' promo.pk %}"
class="btn btn-outline-primary" title="Редактировать">
<i class="bi bi-pencil"></i>
</a>
<a href="{% url 'system_settings:discounts:promo-toggle' promo.pk %}"
class="btn btn-outline-{% if promo.is_active %}warning{% else %}success{% endif %}"
title="{% if promo.is_active %}Деактивировать{% else %}Активировать{% endif %}">
<i class="bi bi-{% if promo.is_active %}pause{% else %}play{% endif %}"></i>
</a>
<a href="{% url 'system_settings:discounts:promo-delete' promo.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.is_active %}&is_active={{ current_filters.is_active }}{% endif %}">&laquo;</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.is_active %}&is_active={{ current_filters.is_active }}{% endif %}">&lsaquo;</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.is_active %}&is_active={{ current_filters.is_active }}{% endif %}">&rsaquo;</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.is_active %}&is_active={{ current_filters.is_active }}{% endif %}">&raquo;</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% else %}
<div class="text-center py-5">
<p class="text-muted">Нет промокодов</p>
<i class="bi bi-ticket-perforated display-4 text-muted"></i>
{% if can_edit %}
<div class="mt-3">
<a href="{% url 'system_settings:discounts:promo-create' %}" class="btn btn-primary">
Создать первый промокод
</a>
</div>
{% endif %}
</div>
{% endif %}
</div>
</div>
{% endblock %}