Files
octopus/myproject/templates/navbar.html
Andrey Smakotin e831c4fb6e feat(products): реализована система единиц продажи на фронтенде
Добавлена полноценная интеграция единиц измерения (UoM) для продажи
товаров в разных единицах с автоматическим пересчётом цен и остатков.

## Основные изменения:

### Backend
- Расширен API поиска товаров (api_views.py): добавлена сериализация sales_units
- Создан новый endpoint get_product_sales_units_api для загрузки единиц с остатками
- Добавлено поле sales_unit в OrderItemForm и SaleForm с валидацией
- Созданы CRUD views для управления единицами продажи (uom_views.py)
- Обновлена ProductForm: использует base_unit вместо устаревшего unit

### Frontend
- Создан модуль sales-units.js с функциями для работы с единицами
- Интегрирован в select2-product-search.js: автозагрузка единиц при выборе товара
- Добавлены контейнеры для единиц в order_form.html и sale_form.html
- Реализовано автоматическое обновление цены при смене единицы продажи
- При выборе базовой единицы цена возвращается к базовой цене товара

### UI
- Добавлены страницы управления единицами продажи в навбар
- Созданы шаблоны: sales_unit_list.html, sales_unit_form.html, sales_unit_delete.html
- Добавлены фильтры по товару, единице, активности и дефолтности

## Исправленные ошибки:
- Порядок инициализации: обработчики устанавливаются ДО триггера события change
- Цена корректно обновляется при выборе единицы продажи
- При выборе "Базовая единица" возвращается базовая цена товара

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-02 12:35:01 +03:00

122 lines
7.9 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.
<!-- navbar.html - Компонент навигационной панели -->
<style>
.navbar .dropdown:hover > .dropdown-menu {
display: block;
margin-top: 0;
}
</style>
<nav class="navbar navbar-expand-lg navbar-light bg-light fixed-top">
<div class="container">
<!-- Кнопка для мобильного вида -->
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"
aria-controls="navbarNav" aria-expanded="false" aria-label="Переключить навигацию">
<span class="navbar-toggler-icon"></span>
</button>
<!-- Содержимое навигации -->
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav me-auto">
{% if user.is_authenticated %}
{% comment %}Показываем меню tenant приложений только если мы не на странице setup-password (public схема){% endcomment %}
{% if 'setup-password' not in request.path %}
<!-- 📦 Товары -->
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle {% if request.resolver_match.namespace == 'products' %}active{% endif %}" href="#" id="productsDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
📦 Товары
</a>
<ul class="dropdown-menu" aria-labelledby="productsDropdown">
<li><a class="dropdown-item" href="{% url 'products:all-products' %}">Все товары</a></li>
<li><a class="dropdown-item" href="{% url 'products:catalog' %}"><i class="bi bi-grid-3x3-gap"></i> Каталог</a></li>
<li><a class="dropdown-item" href="{% url 'products:configurableproduct-list' %}">Вариативные товары</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="{% url 'products:category-list' %}">Категории</a></li>
<li><a class="dropdown-item" href="{% url 'products:tag-list' %}">Теги</a></li>
<li><a class="dropdown-item" href="{% url 'products:variantgroup-list' %}">Варианты (группы)</a></li>
<li><a class="dropdown-item" href="{% url 'products:attribute-list' %}">Атрибуты</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="{% url 'products:unit-list' %}"><i class="bi bi-rulers"></i> Единицы измерения</a></li>
<li><a class="dropdown-item" href="{% url 'products:sales-unit-list' %}"><i class="bi bi-box-seam"></i> Единицы продажи</a></li>
</ul>
</li>
<!-- 📋 Заказы -->
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle {% if request.resolver_match.namespace == 'orders' %}active{% endif %}" href="{% url 'orders:order-list' %}" id="ordersDropdown">
📋 Заказы
</a>
<ul class="dropdown-menu" aria-labelledby="ordersDropdown">
<li><a class="dropdown-item" href="{% url 'orders:order-list' %}">Список заказов</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="{% url 'orders:status_list' %}">Статусы заказов</a></li>
</ul>
</li>
<!-- 👥 Клиенты -->
<li class="nav-item">
<a class="nav-link {% if request.resolver_match.namespace == 'customers' %}active{% endif %}" href="{% url 'customers:customer-list' %}">
👥 Клиенты
</a>
</li>
<!-- 📦 Склад -->
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle {% if request.resolver_match.namespace == 'inventory' %}active{% endif %}" href="#" id="inventoryDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
🏭 Склад
</a>
<ul class="dropdown-menu" aria-labelledby="inventoryDropdown">
<li><a class="dropdown-item" href="{% url 'inventory:inventory-home' %}">Управление складом</a></li>
<li><a class="dropdown-item" href="{% url 'inventory:showcase-list' %}">Витрины</a></li>
</ul>
</li>
<!-- 💰 Касса -->
<li class="nav-item">
<a class="nav-link {% if request.resolver_match.namespace == 'pos' %}active{% endif %}" href="{% url 'pos:terminal' %}">
💰 Касса
</a>
</li>
{% endif %}
<!-- ⚙️ Настройки (только для owner/superuser) -->
{% if request.user.is_owner or request.user.is_superuser %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="settingsDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
⚙️ Настройки
</a>
<ul class="dropdown-menu" aria-labelledby="settingsDropdown">
<li><a class="dropdown-item" href="{% url 'user_roles:list' %}">Роли пользователей</a></li>
{% if user.is_superuser %}
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="{% url 'inventory:debug_page' %}" style="color: #dc3545; font-weight: bold;">🔧 Debug</a></li>
{% endif %}
</ul>
</li>
{% endif %}
{% endif %}
</ul>
<ul class="navbar-nav align-items-center">
{% if user.is_authenticated %}
<!-- Кнопки профиля и выхода для авторизованных пользователей -->
<li class="nav-item">
<a class="btn btn-outline-primary me-2" href="{% url 'accounts:profile' %}">Профиль</a>
</li>
<li class="nav-item d-flex align-items-center mx-2">
<span class="navbar-text mb-0">
({{ user.name|default:user.email }})
</span>
</li>
<li class="nav-item">
<a class="btn btn-outline-secondary ms-2" href="{% url 'accounts:logout' %}">Выйти</a>
</li>
{% else %}
<!-- Кнопка входа для неавторизованных пользователей -->
<li class="nav-item">
<a class="btn btn-outline-primary me-2" href="{% url 'accounts:login' %}">Вход</a>
</li>
{% endif %}
</ul>
</div>
</div>
</nav>