Files
ProdMan/bom_manager/admin.py

159 lines
5.1 KiB
Python
Raw Permalink 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.

from django.contrib import admin
from mptt.admin import DraggableMPTTAdmin
from polymorphic.admin import (
PolymorphicChildModelAdmin,
PolymorphicParentModelAdmin,
PolymorphicChildModelFilter,
PolymorphicInlineSupportMixin,
StackedPolymorphicInline
)
from .models import (
Item, BOMNode, EntityType, WorkCenter,
BaseOperation, LaserCutSheet, LaserCutTube,
Turning, Weld, Paint, Coating
)
from django import forms
# создаем форму с фильтром для dxf и dwg файлов
class LaserCutSheetForm(forms.ModelForm):
class Meta:
model = LaserCutSheet
fields = '__all__'
widgets = {
'dxf_file': forms.FileInput(attrs={'accept': '.dxf,.DXF'}),
}
# создаем форму с фильтром для iges и igs файлов
class LaserCutTubeForm(forms.ModelForm):
class Meta:
model = LaserCutTube
fields = '__all__'
widgets = {
'iges_file': forms.FileInput(attrs={'accept': '.iges,.IGS'}),
}
# --- 1. ИНЛАЙНЫ ДЛЯ ОПЕРАЦИЙ (ДЛЯ КАРТОЧКИ ITEM) ---
class LaserCutSheetInline(StackedPolymorphicInline.Child):
model = LaserCutSheet
form = LaserCutSheetForm
class LaserCutTubeInline(StackedPolymorphicInline.Child):
model = LaserCutTube
form = LaserCutTubeForm
class TurningInline(StackedPolymorphicInline.Child):
model = Turning
class WeldInline(StackedPolymorphicInline.Child):
model = Weld
class PaintInline(StackedPolymorphicInline.Child):
model = Paint
class BaseOperationInline(StackedPolymorphicInline):
model = BaseOperation
child_inlines = (
LaserCutSheetInline,
LaserCutTubeInline,
TurningInline,
WeldInline,
PaintInline,
)
# --- 2. ДОЧЕРНИЕ АДМИНКИ (НУЖНЫ ДЛЯ РАБОТЫ ПОЛИМОРФИЗМА) ---
@admin.register(LaserCutSheet)
class LaserCutSheetAdmin(PolymorphicChildModelAdmin):
base_model = BaseOperation
form = LaserCutSheetForm
@admin.register(LaserCutTube)
class LaserCutTubeAdmin(PolymorphicChildModelAdmin):
base_model = BaseOperation
form = LaserCutTubeForm
@admin.register(Turning)
class TurningAdmin(PolymorphicChildModelAdmin):
base_model = BaseOperation
@admin.register(Weld)
class WeldAdmin(PolymorphicChildModelAdmin):
base_model = BaseOperation
@admin.register(Paint)
class PaintAdmin(PolymorphicChildModelAdmin):
base_model = BaseOperation
# --- 3. РОДИТЕЛЬСКАЯ АДМИНКА ОПЕРАЦИЙ ---
@admin.register(BaseOperation)
class BaseOperationParentAdmin(PolymorphicParentModelAdmin):
base_model = BaseOperation
# Здесь указываем именно МОДЕЛИ, а не классы админок
child_models = (LaserCutSheet, LaserCutTube, Turning, Weld, Paint)
list_filter = (PolymorphicChildModelFilter,)
list_display = ('item', 'order', 'polymorphic_ctype')
# --- 4. ИНЛАЙН ДЛЯ BOM (СОСТАВ ИЗДЕЛИЯ) ---
class BOMNodeInline(admin.TabularInline):
model = BOMNode
# fk_name = 'parent'
fields = ('item', 'quantity')
extra = 1
autocomplete_fields = ['item']
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "parent":
kwargs["queryset"] = BOMNode.objects.filter(
item__entity_type__in=[EntityType.UNIT, EntityType.ASSEMBLY, EntityType.COMPLEX]
)
return super().formfield_for_foreignkey(db_field, request, **kwargs)
# --- 5. ОСНОВНАЯ АДМИНКА КОМПОНЕНТА (ITEM) ---
@admin.register(Item)
class ItemAdmin(PolymorphicInlineSupportMixin, admin.ModelAdmin):
list_display = ('get_full_name', 'entity_type', 'drawing')
list_filter = ('entity_type', 'is_assembly')
search_fields = ['designation', 'title']
@admin.display(description='Наименование')
def get_full_name(self, obj):
return f"{obj.designation or ''} {obj.title}".strip()
# Добавляем оба инлайна: и состав, и техпроцесс
inlines = [BOMNodeInline, BaseOperationInline]
# --- 6. АДМИНКА ДЛЯ ДЕРЕВА BOM ---
@admin.register(BOMNode)
class BOMNodeAdmin(DraggableMPTTAdmin):
mptt_level_indent = 40
fields = ('parent', 'item', 'quantity')
list_display = ('tree_actions', 'indented_title', 'get_designation', 'quantity')
list_display_links = ('indented_title',)
def get_designation(self, obj):
return obj.item.designation
get_designation.short_description = 'Децимальный номер'
def get_queryset(self, request):
return super().get_queryset(request).select_related('item', 'parent')
def get_inlines(self, request, obj=None):
if obj and obj.item.entity_type in [EntityType.UNIT, EntityType.ASSEMBLY, EntityType.COMPLEX]:
return [BOMNodeInline]
return []
# --- 7. ПРОЧИЕ СПРАВОЧНИКИ ---
@admin.register(WorkCenter)
class WorkCenterAdmin(admin.ModelAdmin):
list_display = ('name', 'rate_per_hour')
@admin.register(Coating)
class CoatingAdmin(admin.ModelAdmin):
list_display = ('name', 'consumption')