Унификация генерации номеров документов и оптимизация кода

- Унифицирован формат номеров документов: IN-XXXXXX (6 цифр), как WO-XXXXXX и MOVE-XXXXXX
- Убрано дублирование функции _extract_number_from_document_number
- Оптимизирована инициализация счетчика incoming: быстрая проверка перед полной инициализацией
- Удален неиспользуемый файл utils.py (функциональность перенесена в document_generator.py)
- Все функции генерации номеров используют единый подход через DocumentCounter.get_next_value()
This commit is contained in:
2025-12-21 00:51:08 +03:00
parent 78dc9e9801
commit 375ec5366a
14 changed files with 1873 additions and 147 deletions

View File

@@ -7,7 +7,8 @@ from decimal import Decimal
from inventory.models import (
Warehouse, StockBatch, Incoming, IncomingBatch, Sale, WriteOff, Transfer,
Inventory, InventoryLine, Reservation, Stock, StockMovement,
SaleBatchAllocation, Showcase, WriteOffDocument, WriteOffDocumentItem
SaleBatchAllocation, Showcase, WriteOffDocument, WriteOffDocumentItem,
IncomingDocument, IncomingDocumentItem
)
@@ -428,3 +429,77 @@ class WriteOffDocumentItemAdmin(admin.ModelAdmin):
list_filter = ('reason', 'document__status', 'created_at')
search_fields = ('product__name', 'document__document_number')
raw_id_fields = ('product', 'document', 'reservation')
# ===== INCOMING DOCUMENT (документы поступления) =====
class IncomingDocumentItemInline(admin.TabularInline):
model = IncomingDocumentItem
extra = 0
fields = ('product', 'quantity', 'cost_price', 'notes')
raw_id_fields = ('product',)
@admin.register(IncomingDocument)
class IncomingDocumentAdmin(admin.ModelAdmin):
list_display = ('document_number', 'warehouse', 'status_display', 'receipt_type_display', 'date', 'items_count', 'total_quantity_display', 'created_by', 'created_at')
list_filter = ('status', 'warehouse', 'receipt_type', 'date', 'created_at')
search_fields = ('document_number', 'warehouse__name', 'supplier_name')
date_hierarchy = 'date'
readonly_fields = ('document_number', 'created_at', 'updated_at', 'confirmed_at', 'confirmed_by')
inlines = [IncomingDocumentItemInline]
fieldsets = (
('Документ', {
'fields': ('document_number', 'warehouse', 'status', 'date', 'receipt_type', 'supplier_name', 'notes')
}),
('Аудит', {
'fields': ('created_by', 'created_at', 'confirmed_by', 'confirmed_at', 'updated_at'),
'classes': ('collapse',)
}),
)
def status_display(self, obj):
colors = {
'draft': '#ff9900',
'confirmed': '#008000',
'cancelled': '#ff0000',
}
return format_html(
'<span style="color: {}; font-weight: bold;">{}</span>',
colors.get(obj.status, '#000000'),
obj.get_status_display()
)
status_display.short_description = 'Статус'
def receipt_type_display(self, obj):
colors = {
'supplier': '#0d6efd',
'inventory': '#0dcaf0',
'adjustment': '#198754',
}
return format_html(
'<span style="color: {}; font-weight: bold;">{}</span>',
colors.get(obj.receipt_type, '#6c757d'),
obj.get_receipt_type_display()
)
receipt_type_display.short_description = 'Тип поступления'
def items_count(self, obj):
return obj.items.count()
items_count.short_description = 'Позиций'
def total_quantity_display(self, obj):
return f"{obj.total_quantity} шт"
total_quantity_display.short_description = 'Всего'
@admin.register(IncomingDocumentItem)
class IncomingDocumentItemAdmin(admin.ModelAdmin):
list_display = ('document', 'product', 'quantity', 'cost_price', 'total_cost_display', 'created_at')
list_filter = ('document__status', 'document__receipt_type', 'created_at')
search_fields = ('product__name', 'document__document_number')
raw_id_fields = ('product', 'document')
def total_cost_display(self, obj):
return f"{obj.total_cost:.2f}"
total_cost_display.short_description = 'Сумма'