feat(discounts, orders): рефакторинг системы скидок - единый источник правды
- Добавлен combine_mode в форму создания/редактирования скидок - Добавлена колонка "Объединение" в список скидок с иконками - Добавлен фильтр по режиму объединения скидок - Добавлена валидация: только одна exclusive скидка на заказ - Удалены дублирующие поля из Order и OrderItem: - applied_discount, applied_promo_code, discount_amount - Скидки теперь хранятся только в DiscountApplication - Добавлены свойства для обратной совместимости Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -101,6 +101,22 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="id_combine_mode" class="form-label">Режим объединения с другими скидками</label>
|
||||
<select class="form-select" id="id_combine_mode" name="combine_mode">
|
||||
<option value="max_only" {% if form.combine_mode.value == 'max_only' or not form.combine_mode.value %}selected{% endif %}>
|
||||
🏆 Только максимум (применяется лучшая скидка)
|
||||
</option>
|
||||
<option value="stack" {% if form.combine_mode.value == 'stack' %}selected{% endif %}>
|
||||
📚 Складывать (суммировать с другими)
|
||||
</option>
|
||||
<option value="exclusive" {% if form.combine_mode.value == 'exclusive' %}selected{% endif %}>
|
||||
🚫 Исключающая (отменяет остальные скидки)
|
||||
</option>
|
||||
</select>
|
||||
<div class="form-text">Как эта скидка взаимодействует с другими активными скидками</div>
|
||||
</div>
|
||||
|
||||
<!-- Ограничения -->
|
||||
<h5 class="mb-3 mt-4">Ограничения</h5>
|
||||
<div class="row mb-3">
|
||||
|
||||
@@ -60,6 +60,15 @@
|
||||
<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> Применить
|
||||
@@ -84,6 +93,7 @@
|
||||
<th>Значение</th>
|
||||
<th>Область</th>
|
||||
<th>Авто</th>
|
||||
<th>Объединение</th>
|
||||
<th>Статус</th>
|
||||
<th>Промокоды</th>
|
||||
<th>Использований</th>
|
||||
@@ -129,6 +139,15 @@
|
||||
<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>
|
||||
@@ -180,10 +199,10 @@
|
||||
<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 %}">«</a>
|
||||
<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 %}">‹</a>
|
||||
<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 %}
|
||||
|
||||
@@ -193,10 +212,10 @@
|
||||
|
||||
{% 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 %}">›</a>
|
||||
<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 %}">»</a>
|
||||
<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>
|
||||
|
||||
Reference in New Issue
Block a user