Files
octopus/myproject/COST_PRICE_QUICK_GUIDE.md
Andrey Smakotin 6c8af5ab2c fix: Улучшения системы ценообразования комплектов
Исправлены 4 проблемы:
1. Расчёт цены первого товара - улучшена валидация в getProductPrice и calculateFinalPrice
2. Отображение actual_price в Select2 вместо обычной цены
3. Количество по умолчанию = 1 для новых форм компонентов
4. Auto-select текста при клике на поле количества для удобства редактирования

Изменённые файлы:
- products/forms.py: добавлен __init__ в KitItemForm для quantity.initial = 1
- products/templates/includes/select2-product-init.html: обновлена formatSelectResult
- products/templates/productkit_create.html: добавлен focus handler для auto-select
- products/templates/productkit_edit.html: добавлен focus handler для auto-select

🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-02 19:04:03 +03:00

199 lines
7.7 KiB
Markdown
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.
# Быстрый гид: Динамическая себестоимость товаров
## Как это работает
Себестоимость товара теперь **автоматически рассчитывается** на основе партий товара (StockBatch) по формуле средневзвешенной стоимости:
```
cost_price = Σ(количество × стоимость) / Σ(количество)
```
## Автоматическое обновление
Себестоимость обновляется **автоматически** при:
- ✅ Создании новой партии (поступление товара)
- ✅ Изменении количества в партии
- ✅ Изменении стоимости партии
- ✅ Удалении партии
**Никаких дополнительных действий не требуется!**
## Просмотр деталей
### На странице товара
1. Откройте страницу товара: `http://grach.localhost:8000/products/1/`
2. Найдите строку "Себестоимость"
3. Нажмите кнопку **"Детали расчета"**
4. Увидите:
- Кешированную стоимость (из БД)
- Рассчитанную стоимость (из партий)
- Таблицу с разбивкой по партиям
- Дату создания каждой партии
## Примеры сценариев
### Сценарий 1: Новый товар
```
Товар создан → cost_price = 0.00 (нет партий)
```
### Сценарий 2: Первая поставка
```
Поступление: 10 шт по 100 руб
→ Автоматически: cost_price = 100.00
```
### Сценарий 3: Вторая поставка
```
Текущее: 10 шт по 100 руб (cost_price = 100.00)
Поступление: 10 шт по 120 руб
→ Автоматически: cost_price = 110.00
Расчет: (10×100 + 10×120) / 20 = 110.00
```
### Сценарий 4: Товар закончился
```
Продажа: весь товар продан
→ Автоматически: cost_price = 0.00
```
### Сценарий 5: Новая поставка после опустошения
```
Поступление: 15 шт по 130 руб
→ Автоматически: cost_price = 130.00
```
## Ручной пересчет (если нужно)
Если по какой-то причине себестоимость "слетела", можно пересчитать вручную:
```bash
# Пересчитать для тенанта grach
python manage.py recalculate_product_costs --schema=grach
# С подробным выводом
python manage.py recalculate_product_costs --schema=grach --verbose
# Предварительный просмотр без сохранения
python manage.py recalculate_product_costs --schema=grach --dry-run --verbose
# Показать только изменившиеся товары
python manage.py recalculate_product_costs --schema=grach --only-changed
```
## Влияние на комплекты (ProductKit)
Стоимость комплектов теперь автоматически учитывает актуальную себестоимость компонентов!
```python
# Раньше: использовалась статическая стоимость
# Теперь: использует динамическую стоимость из партий
kit_cost = sum(component.cost_price × quantity)
```
## Проверка синхронизации
На странице товара в секции "Детали расчета":
- 🟢 **Зеленый статус** - все синхронизировано
- 🟡 **Желтый статус** - требуется синхронизация (запустите команду пересчета)
## API для разработчиков
### Получить детали расчета
```python
from products.models import Product
product = Product.objects.get(id=1)
# Получить детали
details = product.cost_price_details
print(f"Кешированная стоимость: {details['cached_cost']}")
print(f"Рассчитанная стоимость: {details['calculated_cost']}")
print(f"Синхронизировано: {details['is_synced']}")
print(f"Всего в партиях: {details['total_quantity']}")
# Перебрать партии
for batch in details['batches']:
print(f"Склад: {batch['warehouse_name']}")
print(f"Количество: {batch['quantity']}")
print(f"Стоимость: {batch['cost_price']}")
```
### Ручное обновление стоимости
```python
from products.services.cost_calculator import ProductCostCalculator
# Рассчитать новую стоимость
new_cost = ProductCostCalculator.calculate_weighted_average_cost(product)
# Обновить в БД
old_cost, new_cost, was_updated = ProductCostCalculator.update_product_cost(product)
if was_updated:
print(f"Стоимость обновлена: {old_cost}{new_cost}")
```
## Логирование
Все операции логируются в стандартный Django logger:
```python
import logging
logger = logging.getLogger('products.services.cost_calculator')
```
Примеры сообщений:
- `INFO: Обновлена себестоимость товара SKU-001: 100.00 -> 110.00`
- `ERROR: Ошибка при расчете себестоимости для товара SKU-001: ...`
## Производительность
### Чтение cost_price
- **0 дополнительных запросов** - значение читается из БД
### Создание/изменение партии
- **1 дополнительный UPDATE** - автоматическое обновление cost_price
### Просмотр деталей (cost_price_details)
- **1 SELECT** - запрос партий товара
## FAQ
**Q: Нужно ли что-то делать после создания партии?**
A: Нет! Себестоимость обновляется автоматически через Django signals.
**Q: Что если у товара нет партий?**
A: cost_price = 0.00 (автоматически)
**Q: Можно ли вручную установить себестоимость?**
A: Можно, но при следующем изменении партий значение пересчитается автоматически.
**Q: Как проверить правильность расчета?**
A: Откройте "Детали расчета" на странице товара - там видна вся математика.
**Q: Влияет ли это на ProductKit?**
A: Да! Стоимость комплектов теперь использует актуальную себестоимость компонентов.
**Q: Что если синхронизация нарушилась?**
A: Запустите `python manage.py recalculate_product_costs --schema=grach`
## Техническая документация
Подробная техническая документация доступна в файле:
`DYNAMIC_COST_PRICE_IMPLEMENTATION.md`
## Контакты и поддержка
При возникновении проблем проверьте:
1. Логи Django (ошибки при расчете)
2. Страницу товара (секция "Детали расчета")
3. Запустите команду с --dry-run для проверки
---
Версия: 1.0
Дата: 2025-01-01