11 Commits

Author SHA1 Message Date
1071f3cacc fix(inventory): учитывать скидки при расчёте цены продажи с единицами измерения
- Пересчитывать цену в базовые единицы: price * conversion_factor
- Вычислять скидку как разницу между subtotal и total_amount
- Распределять скидку пропорционально долям позиций
- Использовать refresh_from_db() для актуального total_amount

Пример: 20 ед. (коэфф. 5) по 7₽ со скидкой 10% → Sale: 4 шт. по 31.5₽

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 00:35:43 +03:00
6b327fa7e0 fix(inventory): учитывать скидки на позицию и заказ при расчёте цены продажи
Расширяем логику расчёта цены продажи для учёта как скидок на отдельные позиции,
так и скидок на весь заказ. Скидка на заказ распределяется пропорционально доле
каждой позиции в общей сумме заказа.

Изменения внесены в SaleProcessor и сигнал создания продажи при завершении заказа.
2026-01-20 23:40:27 +03:00
0938878e67 fix(inventory): учитывать скидку при расчёте цены продажи
Внесены изменения в SaleProcessor и сигнал создания продажи для корректного
расчёта цены с учётом скидки на товар. Теперь при наличии discount_amount
производится пересчёт цены за единицу товара с учётом скидки перед
конвертацией в базовые единицы измерения.

Это исправляет ошибку, при которой скидка не учитывалась в итоговой цене продажи.
2026-01-20 23:20:55 +03:00
9cd3796527 feat(woocommerce): реализовать проверку соединения с WooCommerce API
- Добавлена реализация метода test_connection() с обработкой различных HTTP статусов
- Реализованы вспомогательные методы _get_api_url() и _get_auth() для работы с API
- Добавлена интеграция WooCommerceService в get_integration_service()
- Настроены поля формы для WooCommerceIntegration в get_form_fields_meta()

fix(inventory): исправить расчет цены продажи в базовых единицах

- Исправлен расчет sale_price в SaleProcessor с учетом conversion_factor_snapshot
- Обновлен расчет цены в сигнале create_sale_on_order_completion для корректной работы с sales_unit
2026-01-20 23:05:18 +03:00
a03f3df086 feat(inventory): add support for selling in negative stock
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
2026-01-04 12:27:10 +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
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
936d2275e4 Исправлена ошибка списания товара при завершении заказа
Проблема: При переводе заказа в статус '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>
2025-12-09 12:04:03 +03:00
e0437cdb5a Исправлено двойное списание товаров при смене статуса заказа
Проблема:
- При изменении статуса заказа на 'Выполнен' товар списывался дважды
- Заказ на 10 шт создавал Sale на 10 шт, но со склада уходило 20 шт

Найдено ДВЕ причины:

1. Повторное обновление резервов через .save() (inventory/signals.py)
   - Резервы обновлялись через res.save() каждый раз при сохранении заказа
   - Это вызывало сигнал update_stock_on_reservation_change
   - При повторном сохранении заказа происходило двойное срабатывание

   Решение:
   - Проверка дубликатов ПЕРЕД обновлением резервов
   - Замена .save() на .update() для массового обновления без вызова сигналов
   - Ручное обновление Stock после .update()

2. Двойное FIFO-списание (inventory/services/sale_processor.py)
   - Sale создавалась с processed=False
   - Сигнал process_sale_fifo срабатывал и списывал товар (1-й раз)
   - Затем SaleProcessor.create_sale() тоже списывал товар (2-й раз)

   Решение:
   - Sale создаётся сразу с processed=True
   - Сигнал не срабатывает, списание только в сервисе

Дополнительно:
- Ограничен выбор статусов при создании заказа только промежуточными
- Статус 'Черновик' установлен по умолчанию
- Убран пустой выбор '-------' из поля статуса

Изменённые файлы:
- myproject/orders/forms.py - настройки статусов для формы заказа
- myproject/inventory/signals.py - исправление сигнала create_sale_on_order_completion
- myproject/inventory/services/sale_processor.py - исправление create_sale
- myproject/test_order_status_default.py - обновлён тест
- DOUBLE_SALE_FIX.md - документация по исправлению
2025-12-01 00:56:26 +03:00
8f6acfb364 Добавлена функциональность витрин для POS: модели, сервисы, UI
- Создана модель Showcase (витрина) привязанная к складу
- Расширена Reservation для поддержки витринных резервов
- Добавлены поля в OrderItem для маркировки витринных продаж
- Реализован ShowcaseManager с методами резервирования, продажи и разбора
- Обновлён админ-интерфейс для управления витринами
- Добавлена кнопка Витрина в POS (категории) и API для просмотра
- Добавлена кнопка На витрину в панели действий POS
- Миграции готовы к применению
2025-11-16 21:12:22 +03:00
6735be9b08 feat: Реализовать систему поступления товаров с партиями (IncomingBatch)
Основные изменения:
- Создана модель 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>
2025-10-29 03:26:06 +03:00