Добавлена система трансформации товаров

Реализована полная система трансформации товаров (превращение одного товара в другой).
Пример: белая гипсофила → крашеная гипсофила.

Особенности реализации:
- Резервирование входных товаров в статусе 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>
This commit is contained in:
2025-12-25 18:27:31 +03:00
parent 56850e790e
commit 30ee077963
12 changed files with 1682 additions and 4 deletions

View File

@@ -42,6 +42,13 @@ from .views.incoming_document import (
IncomingDocumentAddItemView, IncomingDocumentUpdateItemView, IncomingDocumentRemoveItemView,
IncomingDocumentConfirmView, IncomingDocumentCancelView
)
# Transformation views
from .views.transformation import (
TransformationListView, TransformationCreateView, TransformationDetailView,
TransformationAddInputView, TransformationAddOutputView,
TransformationRemoveInputView, TransformationRemoveOutputView,
TransformationConfirmView, TransformationCancelView
)
# Debug views
from .views.debug_views import debug_inventory_page
from . import views
@@ -146,6 +153,17 @@ urlpatterns = [
path('showcases/<int:pk>/delete/', ShowcaseDeleteView.as_view(), name='showcase-delete'),
path('showcases/<int:pk>/set-default/', SetDefaultShowcaseView.as_view(), name='showcase-set-default'),
# ==================== TRANSFORMATION ====================
path('transformations/', TransformationListView.as_view(), name='transformation-list'),
path('transformations/create/', TransformationCreateView.as_view(), name='transformation-create'),
path('transformations/<int:pk>/', TransformationDetailView.as_view(), name='transformation-detail'),
path('transformations/<int:pk>/add-input/', TransformationAddInputView.as_view(), name='transformation-add-input'),
path('transformations/<int:pk>/add-output/', TransformationAddOutputView.as_view(), name='transformation-add-output'),
path('transformations/<int:pk>/remove-input/<int:item_pk>/', TransformationRemoveInputView.as_view(), name='transformation-remove-input'),
path('transformations/<int:pk>/remove-output/<int:item_pk>/', TransformationRemoveOutputView.as_view(), name='transformation-remove-output'),
path('transformations/<int:pk>/confirm/', TransformationConfirmView.as_view(), name='transformation-confirm'),
path('transformations/<int:pk>/cancel/', TransformationCancelView.as_view(), name='transformation-cancel'),
# ==================== DEBUG (SUPERUSER ONLY) ====================
path('debug/', debug_inventory_page, name='debug_page'),
]