- Добавлен параметр lock в get_batches_for_fifo() для блокировки строк
- Используется select_for_update() в write_off_by_fifo() для предотвращения
параллельной перезаписи quantity при одновременном списании из одной партии
- Защита от потери данных при параллельном завершении заказов
Implement functionality to allow sales even when stock is insufficient, tracking pending quantities and resolving them when new stock arrives via incoming documents. This includes new fields in Sale model (is_pending_cost, pending_quantity), updates to batch manager for negative write-offs, and signal handlers for automatic processing.
- Add is_pending_cost and pending_quantity fields to Sale model
- Modify write_off_by_fifo to support allow_negative flag and return pending quantity
- Update incoming document service to allocate pending sales to new batches
- Enhance sale processor and signals to handle pending sales
- Remove outdated tests.py file
- Add migration for new Sale fields
КРИТИЧНО: Все агрегации 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 хранит ссылку на единицу продажи для аудита
Исправлена проблема, когда при отмене проведенной трансформации оба сигнала выполнялись последовательно:
- rollback_transformation_on_cancel возвращал резервы в 'reserved'
- release_reservations_on_draft_cancel ошибочно освобождал их в 'released'
Изменена проверка в release_reservations_on_draft_cancel: вместо проверки наличия партий Output (которые уже удалены) теперь проверяется статус резервов ('converted_to_transformation') или наличие поля converted_at, что работает независимо от порядка выполнения сигналов.
Проблема: При переводе заказа в статус 'completed' возникала ошибка
"Не удалось создать Sale для заказа", т.к. резервы этого же заказа
блокировали списание товара.
Причина: write_off_by_fifo() считал все резервы со статусом 'reserved'
как занятые, включая резервы текущего заказа, которые ещё не были
переведены в 'converted_to_sale'.
Решение:
- Добавлен параметр exclude_order в write_off_by_fifo() для исключения
резервов конкретного заказа из расчёта занятого товара
- SaleProcessor.create_sale() теперь передаёт order в write_off_by_fifo()
- Добавлены транзакции в views для атомарности операций с заказами:
при ошибке в сигналах статус заказа откатывается вместе со всеми
связанными изменениями
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Исправлен метод write_off_by_fifo() для учета зарезервированных партий
- Добавлено автоматическое проставление даты и времени при создании заказов в POS
- Исправлена ошибка фильтрации Product (is_active -> status='active') в transfers
- Предотвращает списание из зарезервированных партий, устраняя отрицательные остатки
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Основные изменения:
- Создана модель IncomingBatch для группировки товаров по документам
- Каждое поступление (Incoming) связано с одной батчем поступления
- Автоматическое создание StockBatch для каждого товара в приходе
- Реализована система нумерации партий (IN-XXXX-XXXX) с поиском максимума в БД
- Обновлены все представления (views) для работы с новой архитектурой
- Добавлены детальные страницы просмотра партий поступлений
- Обновлены шаблоны для отображения информации о партиях и их товарах
- Исправлена логика сигналов для создания StockBatch при приходе товара
- Обновлены формы для работы с новой структурой IncomingBatch
Архитектура FIFO:
- IncomingBatch: одна партия поступления (номер IN-XXXX-XXXX)
- Incoming: товар в партии поступления
- StockBatch: одна партия товара на складе (создается для каждого товара)
Это позволяет системе правильно применять FIFO при продаже товаров.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>