Files
octopus/myproject/discounts/templates/discounts/discount_form.html
Andrey Smakotin 271ac66098 fix(forms): использовать format_decimal для input type=number
Заменён floatformat на format_decimal в полях input type="number",
чтобы числа всегда использовали точку как десятичный разделитель,
независимо от локали. Это исправляет ошибки парсинга в браузере.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 01:20:50 +03:00

258 lines
15 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends "system_settings/base_settings.html" %}
{% load inventory_filters %}
{% 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="{{ form.name.value|default_if_none:'' }}"
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="{{ form.priority.value|default_if_none:0 }}"
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|default_if_none:'' }}</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="{{ form.value.value|format_decimal:2|default_if_none:'' }}"
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 %}checked{% endif %}>
<label class="form-check-label" for="id_is_active">
Активна
</label>
<div class="form-text">Неактивные скидки не применяются</div>
</div>
</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">
<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="{{ form.min_order_amount.value|format_decimal:2|default_if_none:'' }}"
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="{{ form.max_usage_count.value|default_if_none:'' }}"
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="{{ form.start_date.value|date:'Y-m-d\TH:i'|default_if_none:'' }}">
</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="{{ form.end_date.value|date:'Y-m-d\TH:i'|default_if_none:'' }}">
</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>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Заменяем запятые на точки в числовых полях при загрузке страницы
const numberInputs = document.querySelectorAll('input[type="number"]');
numberInputs.forEach(function(input) {
if (input.value && input.value.includes(',')) {
// Сохраняем оригинальное значение с запятой для отображения
const displayValue = input.value;
const actualValue = displayValue.replace(',', '.');
// Устанавливаем значение с точкой для корректной работы HTML5 поля
input.value = actualValue;
// При фокусе возвращаем запятую для удобства пользователя
input.addEventListener('focus', function() {
if (input.value && input.value.includes('.')) {
input.value = input.value.replace('.', ',');
}
});
// При потере фокуса возвращаем точку для корректной отправки
input.addEventListener('blur', function() {
if (input.value && input.value.includes(',')) {
input.value = input.value.replace(',', '.');
}
});
}
});
// Также обрабатываем отправку формы для замены запятых на точки
const form = document.querySelector('form');
form.addEventListener('submit', function() {
const numberInputs = document.querySelectorAll('input[type="number"]');
numberInputs.forEach(function(input) {
if (input.value && input.value.includes(',')) {
input.value = input.value.replace(',', '.');
}
});
});
});
</script>
{% endblock %}