Commit Graph

688 Commits

Author SHA1 Message Date
f55f358e8f Исправлено: Sale теперь использует quantity_base вместо quantity
КРИТИЧНО: При создании Sale использовалось неправильное поле!

Проблема:

- При проведении заказа Sale создавался с reservation.quantity

- Это количество в ЕДИНИЦАХ ПРОДАЖИ, а не в базовых!

- Пример: 1 ветка списывала 1 банч вместо 0.05 банча

Решение:

- Строка 410: sale_quantity = reservation.quantity_base (для товаров)

- Строка 368: quantity=reservation.quantity_base (для комплектов)

- Fallback на .quantity для обратной совместимости

Теперь:

- Sale.quantity всегда в базовых единицах

- FIFO списание корректно

- StockBatch уменьшается на правильное количество
2026-01-02 15:06:03 +03:00
4ee7c0d23b Улучшено: оптимизация сигнала обновления Stock
- Добавлено 'quantity_base' в список полей, влияющих на Stock

- Теперь Stock пересчитывается при изменении quantity_base

- Обновлена документация сигнала update_stock_on_reservation_change
2026-01-02 14:47:16 +03:00
d2b49cca56 Исправлено: агрегация резервов теперь использует quantity_base
КРИТИЧНО: Все агрегации Reservation.quantity заменены на quantity_base

Проблемы и решения:

🔴 КРИТИЧНО - BatchManager.write_off_by_fifo():

  - Проблема: суммировал quantity вместо quantity_base

  - Влияние: FIFO расчет свободного товара был некорректен

  - Решение: aggregate(Sum('quantity_base')) в строках 118, 125

🟡 СРЕДНЯЯ ВАЖНОСТЬ - ShowcaseManager:

  - reserve_showcase_item(): обновление quantity и quantity_base (строка 403)

  - release_showcase_reservation(): обновление обоих полей (строка 481)

  - Теперь витринные резервы полностью консистентны

🟡 СРЕДНЯЯ ВАЖНОСТЬ - TransformationService:

  - confirm(): проверка доступности через quantity_base (строка 254)

  - Корректная валидация при трансформации товаров

🟢 НИЗКАЯ ВАЖНОСТЬ - WriteOffDocumentService:

  - update_item(): синхронизация quantity и quantity_base (строка 175)

  - Полнота данных в резервах документов списания

🟢 НИЗКАЯ ВАЖНОСТЬ - Сигналы (signals.py):

  - update_order_item_reservation(): обновление обоих полей для товаров

  - Для обычных товаров: quantity_base = quantity_in_base_units (строка 1081)

  - Для комплектов: quantity_base = quantity (компоненты в базовых) (строка 1107)

  - Добавлено обновление sales_unit при изменении OrderItem

Архитектура:

- Принцип: quantity_base ВСЕГДА содержит количество в базовых единицах

- Все агрегации резервов используют quantity_base для корректных расчетов

- quantity сохраняется для совместимости и отображения

- sales_unit хранит ссылку на единицу продажи для аудита
2026-01-02 14:46:02 +03:00
f34cfaeca0 Исправлено: отображение резервов и расчет quantity_reserved
- Проблема: debug_page показывал quantity вместо quantity_base для резервов

- Проблема: Stock.refresh_from_batches() суммировал quantity вместо quantity_base

- Решение:

  - debug_page.html: добавлены колонки для единиц продажи и базовых единиц

  - debug_page.html: теперь показывается quantity (ед.прод.) и quantity_base (базовые)

  - models.py: Stock.refresh_from_batches() теперь суммирует quantity_base

- Теперь quantity_reserved и quantity_free отображаются корректно в базовых единицах
2026-01-02 14:40:53 +03:00
25f2ba6b82 Исправлено: резервирование теперь работает с единицами продажи
- Проблема: сигнал на Order срабатывал ДО вычисления quantity_in_base_units в OrderItem.save()

- Решение: переместили резервирование на сигнал post_save для OrderItem

- Теперь quantity_in_base_units гарантированно вычислено перед резервированием

- Изменения:

  - signals.py: reserve_stock_on_order_create → reserve_stock_on_item_create

  - Сигнал теперь на OrderItem вместо Order

  - Резервы создаются для каждой позиции отдельно после её сохранения
2026-01-02 14:36:13 +03:00
baa9780ce1 Исправлено: quantity обнуляется при смене единицы продажи
- Проблема: при смене единицы продажи с базовой на другую поле quantity визуально показывало 1, но при отправке формы значение терялось

- Решение: при смене единицы проверяем quantity и устанавливаем минимальное значение если оно пустое/нулевое

- Изменения:

  - sales-units.js: добавлена проверка и установка min_quantity при смене единицы
2026-01-02 14:01:42 +03:00
c5e1ea06f9 Исправлено: резервирование и списание с учетом единиц продажи
- Проблема: при заказе 1 ветки резервировался 1 банч вместо 1/15

- Решение: используем quantity_in_base_units из OrderItem

- Изменения:

  - signals.py: reserve_stock_on_order_create использует quantity_in_base_units

  - signals.py: _create_or_update_reservation сохраняет sales_unit

  - signals.py: create_sale_on_order_completion берет quantity из резерва

  - sale_processor.py: уточнена документация параметра quantity
2026-01-02 13:45:22 +03:00
0d801680d7 Исправлено: ProductSearchPicker динамически создает <option> для HTML select
- Проблема: при выборе товара через ProductSearchPicker, select оставался пустым
- Решение: динамическое создание <option> элемента с выбранным товаром
- Затронутые файлы:
  - incoming_document_detail.html: функции selectProduct() и clearSelectedProduct()
  - writeoff_document/detail.html: аналогичные исправления
- Теперь компонент корректно работает во всех документах системы
2026-01-02 13:40:18 +03:00
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
5b68f14bb4 feat(products): add support for product sales units
Add new models UnitOfMeasure and ProductSalesUnit to enable selling products in different units (e.g., bunches, kg). Update Product model with base_unit field and methods for unit conversions and availability. Extend Sale, Reservation, and OrderItem models with sales_unit fields and snapshots. Modify SaleProcessor to handle quantity conversions. Include admin interfaces for managing units. Add corresponding database migrations.
2026-01-02 02:09:44 +03:00
ca308ae2a2 Убраны временные утилитарные скрипты и личные заметки из отслеживания Git
- Удалены из версионирования: check_duplicates.py, cleanup_stuck_photos.py, cleanup_commands.txt, start_all.bat, ГИД ПО ЗАПУСКУ
- Обновлён .gitignore для предотвращения отслеживания временных скриптов обслуживания
- Добавлены шаблоны для исключения личных заметок и руководств
- Файлы сохранены локально для использования при необходимости

Эти файлы являются временными инструментами диагностики и личными заметками разработчика, которые не должны находиться под контролем версий.
2026-01-01 14:01:39 +03:00
ff1c29baae refactor(inventory): redesign inventory home layout with compact cards
- Replace large operation cards with smaller, uniform inventory-card components
- Update icon sizes and text styles for better visual hierarchy
- Group operations into a cleaner 4x3 grid layout using Bootstrap columns
- Simplify card hover effects with subtler shadows and background gradients
- Remove unused purple utility classes and old card-body styles
- Add focus outline support for accessibility on inventory cards

fix(customers): show total debt only when applicable and add external links

- Display total debt row only if debt is greater than zero in customer detail
- Remove redundant conditional inside debt display cell
- Add target="_blank" and rel attributes to order detail links to open in new tab
2025-12-31 23:11:11 +03:00
6971f58d45 ю 2025-12-31 01:34:12 +03:00
eb6a3c1874 Исправлена ошибка public admin для мультитенантной архитектуры
Проблема: при входе в localhost/admin/ (public схема) возникала ошибка
"relation user_roles_userrole does not exist", так как tenant-only
таблицы не существуют в public схеме.

Решение:
- Создан TenantAdminOnlyMixin для скрытия tenant-only моделей от public admin
- Применён миксин ко всем ModelAdmin классам в tenant-only приложениях:
  user_roles, customers, orders, inventory, products
- Добавлена проверка _is_public_schema() в RoleBasedPermissionBackend
  для предотвращения запросов к tenant-only таблицам в public схеме

Теперь:
- localhost/admin/ показывает только public модели (Client, Domain, User)
- shop.localhost/admin/ показывает все модели магазина

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 01:05:47 +03:00
b59ad725cb Рефакторинг: вынос логики онбординга тенанта в сервисный слой
Создан TenantOnboardingService как единый источник истины для:
- Активации заявки на регистрацию тенанта
- Создания Client, Domain, Subscription
- Инициализации системных данных (Customer, статусы, способы оплаты, склад, витрина)

Новые сервисы:
- TenantOnboardingService (tenants/services/onboarding.py)
- WarehouseService (inventory/services/warehouse_service.py)
- ShowcaseService (inventory/services/showcase_service.py)
- PaymentMethodService (orders/services/payment_method_service.py)

Рефакторинг:
- admin.py: 220 строк → 5 строк (делегирование сервису)
- init_tenant_data.py: 259 строк → 68 строк
- activate_registration.py: использует сервис
- Тесты обновлены для вызова сервиса напрямую

При создании тенанта автоматически создаются склад и витрина по умолчанию.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 14:52:55 +03:00
658cd59511 Добавлена регистрация ConfigurableProduct в админке Django
Добавлены imports для ConfigurableProduct, ConfigurableProductOption, ConfigurableProductAttribute.
Создан ConfigurableProductAdmin с инлайнами для вариантов и атрибутов.
Поля variant_sku отображается в readonly режиме.
Добавлен счетчик вариантов в list_display с цветовой индикацией.
Организованы fieldsets для удобного редактирования.
2025-12-30 11:37:42 +03:00
4cbc2f23e3 Добавлена автогенерация артикулов вариантов для ConfigurableProduct
Добавлено поле variant_sku в модель ConfigurableProductOption.
Артикул варианта генерируется автоматически в формате VAR-XXXXXX-V1, VAR-XXXXXX-V2 и т.д.
Счетчик не переиспользуется при удалении вариантов для защиты интеграций.
Переименован property variant_sku в variant_base_sku для основного SKU.
Обновлен шаблон с колонкой артикула варианта.
Создана миграция для добавления поля и data migration для существующих записей.
Назначение: дополнительный артикул для интеграций с внешними площадками.
2025-12-30 11:20:02 +03:00
889834c694 Добавлена защита зарезервированных префиксов артикулов от ручного ввода
- В миксин SKUUniqueMixin добавлен словарь RESERVED_PREFIXES
- Префиксы PROD-, KIT-, CAT-, VAR- зарезервированы для автогенерации
- При попытке ручного ввода артикула с зарезервированным префиксом выдается понятная ошибка
- Проверка регистронезависимая (prod-123 тоже будет заблокирован)
- Пользователю предлагается либо использовать другой артикул, либо оставить поле пустым для автогенерации
- Решение элегантное, централизованное в миксине, работает для всех форм товаров
2025-12-30 10:59:16 +03:00
577401447b Добавлена автогенерация и валидация уникальности артикулов для всех типов товаров
- Добавлен миксин SKUUniqueMixin для единообразной валидации артикулов
- Валидация проверяет уникальность SKU среди Product, ProductKit, ProductCategory, ConfigurableProduct
- Реализована автогенерация артикулов для ConfigurableProduct (формат VAR-XXXXXX)
- Добавлен новый тип счетчика 'configurable' в SKUCounter
- Обновлены формы Product, ProductKit, ProductCategory, ConfigurableProduct
- Рефакторинг методов clean() в формах: валидация имени вынесена в clean_name()
- Добавлена функция generate_configurable_sku() в sku_generator.py
- Обновлена функция ensure_sku_unique() для проверки ConfigurableProduct
- Добавлен метод save() в модель ConfigurableProduct для автогенерации SKU
- Обновлен шаблон configurableproduct_form.html с отображением help_text для SKU

Код стал чистым, без дублирования логики валидации.
2025-12-30 10:47:03 +03:00
a95bd56b2b Замена простого select на autocomplete с поиском для привязки атрибутов к товарам/комплектам
- Переиспользован модуль select2-product-search.js из orders
- Заменен простой select на Select2 с AJAX поиском через API search_products_and_variants
- Добавлена поддержка привязки как ProductKit, так и Product к значениям атрибутов
- Обновлен метод _save_attributes_from_cards для обработки item_ids и item_types
- Удалены дублирующиеся подключения jQuery и Select2 (используются из base.html)
- Улучшен UX: живой поиск, отображение типа товара (🌹/💐), цены и наличия
2025-12-30 02:59:45 +03:00
a3f2185714 Добавлено API для получения списка атрибутов и их значений; обновлены формы для работы с атрибутами через JavaScript 2025-12-30 02:41:30 +03:00
f39ee5f15d Переименование URL configurablekit-* → configurableproduct-*
- URL paths: configurable-kits/ → configurable/
- URL names: configurablekit-list → configurableproduct-list и т.д.
- Обновлены все ссылки в шаблонах и views

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 02:05:13 +03:00
7954f85e05 Переименование файлов configurablekit_* → configurableproduct_*
- Шаблоны: configurablekit_*.html → configurableproduct_*.html
- Views: configurablekit_views.py → configurableproduct_views.py
- JS: configurablekit_detail.js → configurableproduct_detail.js
- Обновлены все template_name и импорты

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 01:52:57 +03:00
79ff523adb Рефакторинг системы вариативных товаров и справочник атрибутов
Основные изменения:
- Переименование ConfigurableKitProduct → ConfigurableProduct
- Добавлена поддержка Product как варианта (не только ProductKit)
- Создан справочник атрибутов (ProductAttribute, ProductAttributeValue)
- CRUD для управления атрибутами с inline редактированием значений
- Пересозданы миграции с нуля для всех приложений
- Добавлена ссылка на атрибуты в навигацию

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 01:44:34 +03:00
277a514a82 Добавлены правила LF для Docker-файлов в .gitattributes
Dockerfile, *.yml, *.yaml теперь принудительно с LF окончаниями
для совместимости с Linux/Docker окружением.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 01:47:35 +03:00
54f362eb23 Добавлено управление выбором даты через календарь в компонент фильтрации по диапазону дат 2025-12-29 01:36:39 +03:00
d66ea020f6 Добавлено подключение обработчиков для кнопок "Сегодня", "Завтра" и "Сбросить" в компоненте фильтрации по датам 2025-12-29 01:31:14 +03:00
1f8fd54c10 Добавлена проверка на транзакции кошелька при удалении заказа
Удаление заказа теперь блокируется если есть связанные
WalletTransaction (on_delete=PROTECT).

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 00:37:27 +03:00
07829f867b Защита удаления заказов и улучшение интерфейса клиентов
Orders:
- Удаление разрешено только для черновиков (draft)
- Запрет удаления заказов с оплатой (amount_paid > 0)
- Кнопка "Удалить" скрыта для недопустимых заказов

Customers:
- Inline-редактирование полей клиента
- Улучшен дизайн карточки клиента
- Добавлена история заказов и кошелька

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 23:59:57 +03:00
6c1b1c4aa2 Обновлён анализ тестов customers - учтена реорганизация структуры
- Добавлены ссылки на файлы с тестами в каждом разделе
- Исправлена нумерация разделов (было дублирование)
- Добавлен раздел о реорганизации структуры тестов
- Отмечено, что защита системного клиента теперь покрыта тестами
- Обновлена статистика: 50 тестов (было 45), 6 пробелов (было 7)
- Добавлена информация о новой модульной структуре customers/tests/
- Исправлен блок 'Защита системного клиента НЕ ПРОТЕСТИРОВАНА' - теперь выполнено
2025-12-28 00:38:23 +03:00
dbbac933af Добавлены тесты защиты системного клиента и рефакторинг структуры тестов
- Создан новый класс SystemCustomerProtectionTestCase с 5 критичными тестами
- Тест создания системного клиента с правильными атрибутами
- Тест защиты от удаления системного клиента (ValidationError)
- Тест защиты email системного клиента от изменения
- Тест защиты флага is_system_customer от изменения
- Тест что обычные клиенты не затронуты защитой

- Исправлена логика в Customer.save(): проверка теперь использует original.is_system_customer
- Добавлен импорт ValidationError из django.core.exceptions

- Рефакторинг структуры тестов customers:
  - Разделены тесты по отдельным модулям в папке customers/tests/
  - test_search_strategies.py - тесты стратегий поиска
  - test_system_customer.py - тесты защиты системного клиента
  - test_wallet_balance.py - тесты баланса кошелька
  - test_wallet_service.py - тесты WalletService
  - test_wallet_model.py - тесты модели WalletTransaction

- Обновлён анализ тестов: 50 тестов (было 45), все проходят успешно
- Критичная функциональность POS системы теперь покрыта тестами
- Учтена tenant-система (используется TenantTestCase)
2025-12-28 00:32:45 +03:00
b1855cc9f0 Рефакторинг системы кошелька клиентов
Основные изменения:
- Переход от денормализованного поля wallet_balance к вычисляемому балансу
- Баланс теперь вычисляется как SUM(signed_amount) транзакций
- Добавлено кеширование баланса для производительности (5 минут)
- Новая модель WalletTransaction с полем signed_amount (может быть +/-)
- WalletService для всех операций с кошельком (deposit, spend, adjustment)
- Защита от отрицательного баланса и race conditions через select_for_update
- Добавлен balance_after в каждую транзакцию для аудита
- Обновлены миграции для переноса данных из старой схемы

Улучшения безопасности:
- Атомарные транзакции для всех операций с балансом
- Блокировка строк при модификации баланса
- Валидация недостаточности средств
- Обязательное описание для корректировок баланса

UI/UX изменения:
- Обновлён вывод баланса кошелька в деталях клиента
- Добавлена история транзакций с типами и описаниями
- Цветовая индикация положительных транзакций (зелёный)

Техническая документация:
- Добавлены docstrings для всех методов WalletService
- Комментарии к критичным участкам кода
- Примеры использования в docstrings
2025-12-28 00:02:09 +03:00
65b3055755 Добавлен отчёт по анализу и улучшению тестов customers
- Исходный анализ: 59 тестов с избыточностью
- После оптимизации: 45 тестов (сокращение на 24%)
- Задокументированы выполненные улучшения
- Обновлён список критических пробелов в покрытии
2025-12-27 23:58:59 +03:00
0bc13dc7b7 Рефакторинг тестов customers: оптимизация и исправление логики
- Сокращено количество тестов с 59 до 45 через параметризацию
- Объединены дублирующиеся тесты поиска в компактные параметризованные
- Добавлен вспомогательный метод _test_strategy() для устранения дублирования
- Исправлена логика is_query_phone_only(): пробелы теперь возвращают False
- Добавлено требование наличия хотя бы одной цифры для распознавания телефона
- Все 45 тестов успешно проходят
- Покрытие функционала осталось на том же уровне 100%
2025-12-27 23:58:48 +03:00
2e607a3b38 Исправлено отображение товаров в каталоге - добавлены товары без категорий
Проблема: после оптимизации товары показывались только из категорий,
товары без категорий не отображались.

Решение: теперь загружаются все активные товары и комплекты напрямую,
дополняя список товарами, которые не были загружены через категории.

Логика загрузки:
1. Сначала из категорий (используя prefetch кеш) - оптимизация
2. Затем все активные товары напрямую - полнота данных
3. Дедупликация через словари (products_dict, kits_dict)
2025-12-27 21:01:30 +03:00
978e97afaf Добавлена информация об остатках на складе в каталоге и оптимизированы SQL-запросы
- Добавлено отображение свободных и общих остатков товаров в карточках каталога
- Информация показывается с цветовой индикацией (зеленый/красный)
- Формат: X свободно / Y всего (X = доступно - зарезервировано, Y = общее количество)

Оптимизация производительности:
- Устранена N+1 проблема с загрузкой фото товаров (вложенный Prefetch)
- Устранена N+1 проблема с загрузкой категорий товаров
- Удалено дублирование запросов - товары извлекаются из уже загруженных категорий
- Аннотации остатков добавлены в Prefetch для товаров
- Добавлен оптимизированный Prefetch для ProductKitPhoto

Результат: сокращение количества SQL-запросов с ~13 до ~6-7 (на 50%)
2025-12-27 20:40:22 +03:00
7d7038e67b Улучшение календаря фильтра дат: выбранные даты теперь всегда видны на экране 2025-12-27 02:42:26 +03:00
1654962ba2 feat(inventory): add validation for item availability in released reservations
- Implement `check_released_reservations_available` function to verify if items from released reservations are still available for re-sale when attempting to change a returned order's status
- Update `create_sale_on_order_completion` signal to use this check, allowing transitions to positive statuses only if items are available, otherwise blocking with ValidationError
- Wrap Order.save() in transaction.atomic() to ensure ValidationError in signals rolls back the save operation
- Add comprehensive tests for scenarios where items are available or used in other orders
- Update date carousel in order to always center on today's date and remove unnecessary saving logic
- Add test flag to Django Debug Toolbar settings

Closes #123 (assuming related issue)
2025-12-27 02:31:43 +03:00
44d115b356 refactor(inventory): remove individual writeoff views and templates, shift to document-based writeoffs
- Remove WriteOffForm from forms.py and add comment directing to WriteOffDocumentForm
- Update navigation templates to remove writeoff links and sections
- Add 'Сумма' column to sale list with multiplication filter
- Delete writeoff-related templates (list, form, confirm delete)
- Add 'multiply' filter to inventory_filters.py for calculations
- Comment out writeoff URLs in urls.py, keeping WriteOff model for automatic creation
- Remove WriteOff views from __init__.py and delete writeoff.py view file

This change simplifies writeoff management by removing direct individual writeoff operations and enforcing use of WriteOffDocument for all writeoffs, with WriteOff records created automatically upon document processing.
2025-12-27 01:04:41 +03:00
1eaee7de5e refactor: remove price column from category list table 2025-12-26 23:59:11 +03:00
607afd6af5 fix: удалены ссылки на удалённый URL movement-list
Удалены все упоминания URL-паттерна 'movement-list' после удаления
модели StockMovement:
- Карточка "Журнал" на главной странице inventory
- Пункт меню "Журнал" в навигации base_inventory_minimal
- Экспорт StockMovementListView из views/__init__.py

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 21:42:53 +03:00
08bae834c8 refactor: стандартизация моделей документов перемещения
Приведение к единому паттерну именования документов:
- TransferBatch → TransferDocument
- TransferItem → TransferDocumentItem
- Удалена устаревшая модель Transfer (одиночные перемещения)
- Удалена неиспользуемая модель StockMovement

Изменения:
- models.py: переименование классов, обновление related_names
- admin.py: удаление регистраций Transfer/StockMovement
- forms.py: обновление TransferHeaderForm
- views/transfer.py: обновление всех view классов
- templates: замена transfer_batch → transfer_document
- urls.py: удаление путей для movements
- views/__init__.py: удаление импорта StockMovementListView
- views/movements.py: удален файл

Миграция: 0005_refactor_transfer_models
- RenameModel операции для сохранения данных
- DeleteModel для Transfer и StockMovement

Единый паттерн: *Document + *DocumentItem
(WriteOffDocument, IncomingDocument, TransferDocument)

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 20:29:11 +03:00
c534e27c41 refactor: подготовка к стандартизации Transfer моделей
Текущее состояние перед рефакторингом Transfer → TransferDocument.
Все изменения с последнего коммита по улучшению системы поступлений.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 19:55:50 +03:00
0da2995a74 docs: добавлен план критичных улучшений системы поступления
Документ содержит приоритизированный план улучшений:

Высокий приоритет:
- Добавить проверку прав доступа в views
- Покрыть тестами критические пути
- Оптимизировать N+1 запросы в списках

Средний приоритет:
- Рефакторинг избыточности моделей
- Bulk операции для массового импорта
- Улучшение документации

Низкий приоритет:
- Асинхронная обработка больших документов
- Аудит и история изменений

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 17:38:51 +03:00
c9ff778630 refactor: мигрировать на новую систему документов поступления
Удалена старая одноэтапная система incoming и оставлена только новая
двухэтапная система IncomingDocument (черновик → проведение).

Изменения:
- URL структура изменена с /incoming-documents/ на /incoming/
- URL names: incoming-document-* → incoming-*
- Удалены старые views, forms, templates для Incoming/IncomingBatch
- Обновлена навигация и все ссылки в шаблонах
- Модели IncomingBatch/Incoming сохранены как внутренняя архитектура

Удалено ~1590 строк кода:
- inventory/views/incoming.py (389 строк)
- inventory/forms.py (206 строк старых форм)
- inventory/admin.py (56 строк)
- 4 шаблона incoming/*.html (895 строк)

Обновлено:
- inventory/urls.py - новая URL структура
- inventory/views/incoming_document.py - обновлены redirects
- Все шаблоны с ссылками на incoming

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 17:33:00 +03:00
d2384394c8 fix(signals): обновление Stock после удаления партии Output в процессе отмены трансформации 2025-12-26 16:02:54 +03:00
131d078ac4 Запрет редактирования приходов после создания складской партии
- Добавлено свойство can_edit в модель Incoming
- Добавлена проверка в IncomingUpdateView для запрета редактирования обработанных приходов
- Скрыта кнопка редактирования в списке приходов для обработанных записей
- Добавлено предупреждение в форму редактирования

Это предотвращает проблемы с целостностью данных при FIFO-списаниях, когда партия уже может быть использована в продажах.
2025-12-25 23:01:12 +03:00
bc13750d16 Исправление конфликта сигналов при отмене трансформации
Исправлена проблема, когда при отмене проведенной трансформации оба сигнала выполнялись последовательно:
- rollback_transformation_on_cancel возвращал резервы в 'reserved'
- release_reservations_on_draft_cancel ошибочно освобождал их в 'released'

Изменена проверка в release_reservations_on_draft_cancel: вместо проверки наличия партий Output (которые уже удалены) теперь проверяется статус резервов ('converted_to_transformation') или наличие поля converted_at, что работает независимо от порядка выполнения сигналов.
2025-12-25 22:54:39 +03:00
30ee077963 Добавлена система трансформации товаров
Реализована полная система трансформации товаров (превращение одного товара в другой).
Пример: белая гипсофила → крашеная гипсофила.

Особенности реализации:
- Резервирование входных товаров в статусе draft
- FIFO списание входных товаров при проведении
- Автоматический расчёт себестоимости выходных товаров
- Возможность отмены как черновиков, так и проведённых трансформаций

Модели (inventory/models.py):
- Transformation: документ трансформации (draft/completed/cancelled)
- TransformationInput: входные товары (списание)
- TransformationOutput: выходные товары (оприходование)
- Добавлен статус 'converted_to_transformation' в Reservation
- Добавлен тип 'transformation' в DocumentCounter

Бизнес-логика (inventory/services/transformation_service.py):
- TransformationService с методами CRUD
- Валидация наличия товаров
- Автоматическая генерация номеров документов

Сигналы (inventory/signals.py):
- Автоматическое резервирование входных товаров
- FIFO списание при проведении
- Создание партий выходных товаров
- Откат операций при отмене

Интерфейс без Django Admin:
- Список трансформаций (list.html)
- Форма создания (form.html)
- Детальный просмотр с добавлением товаров (detail.html)
- Интеграция с компонентом поиска товаров
- 8 views для полного CRUD + проведение/отмена

Миграция:
- 0003_alter_documentcounter_counter_type_and_more.py

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 18:27:31 +03:00
56850e790e feat(orders): добавить отображение статуса возврата, изменяющего, автосохранения и требований к фото в шаблоне order_detail
Добавлены условные блоки для отображения:
- значка "Возвращен" при возврате заказа
- информации об изменяющем заказ пользователе
- времени последнего автосохранения для черновиков
- требований к фотографиям товара и вручения

Это улучшает детализацию страницы заказа, соответствуя новым полям модели Order.
2025-12-25 16:22:49 +03:00