Files
ProdMan/stock/admin.py
ackFromRedmi 56dd6644e2
All checks were successful
Auto-Deploy-prodman / deploy (push) Successful in 6s
Добавил приложение склад и модели заготовок
2026-02-16 08:00:16 +03:00

135 lines
4.9 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 django.utils.html import format_html
from polymorphic.admin import (
PolymorphicChildModelAdmin,
PolymorphicParentModelAdmin,
PolymorphicChildModelFilter
)
from .models import Gost, MaterialGrade, BaseMaterial, SheetMaterial, ProfileMaterial, StockItem
# --- 1. Справочники (ГОСТ и Марки) ---
@admin.register(Gost)
class GostAdmin(admin.ModelAdmin):
list_display = ('name', 'description', 'get_pdf_link')
search_fields = ('name',)
def get_pdf_link(self, obj):
if obj.pdf_file:
return format_html('<a href="{}" target="_blank">📄 PDF</a>', obj.pdf_file.url)
return ""
get_pdf_link.short_description = "Файл"
@admin.register(MaterialGrade)
class MaterialGradeAdmin(admin.ModelAdmin):
list_display = ('name', 'gost', 'density')
search_fields = ('name', 'gost__name')
# --- 2. Дочерние админки для заготовок ---
class BaseChildAdmin(PolymorphicChildModelAdmin):
base_model = BaseMaterial
# Делаем название кликабельным и в дочерних списках
list_display_links = ('title',)
@admin.register(SheetMaterial)
class SheetMaterialAdmin(BaseChildAdmin):
list_display = ('title', 'thickness', 'grade', 'gost')
@admin.register(ProfileMaterial)
class ProfileMaterialAdmin(BaseChildAdmin):
list_display = ('title', 'profile_type', 'weight_per_meter', 'grade', 'gost')
# --- 3. Главная (родительская) админка заготовок ---
@admin.register(BaseMaterial)
class BaseMaterialParentAdmin(PolymorphicParentModelAdmin):
base_model = BaseMaterial
child_models = (SheetMaterial, ProfileMaterial)
# Заменяем обычный title на наш кликабельный метод
list_display = ('clickable_title', 'grade', 'gost', 'get_specs')
list_display_links = ('clickable_title',)
list_filter = (PolymorphicChildModelFilter, 'grade', 'gost')
search_fields = ('title',)
def clickable_title(self, obj):
"""Объединяет иконку и название в одну ссылку"""
# Безопасно получаем реальный тип (Лист или Профиль)
real_obj = obj.get_real_instance()
icon = ""
if isinstance(real_obj, SheetMaterial):
icon = "📄"
elif isinstance(real_obj, ProfileMaterial):
icon = "🏗️"
return format_html(
'<span style="margin-right: 8px; font-size: 1.1rem;">{}</span> <b>{}</b>',
icon,
obj.title
)
clickable_title.short_description = "Наименование заготовки"
clickable_title.admin_order_field = 'title' # Чтобы работала сортировка
def get_specs(self, obj):
"""Вывод ключевых параметров в общий список"""
real_obj = obj.get_real_instance()
if isinstance(real_obj, SheetMaterial):
return f"t = {real_obj.thickness} мм"
if isinstance(real_obj, ProfileMaterial):
return f"{real_obj.get_profile_type_display()}: {real_obj.weight_per_meter} кг/м"
return "-"
get_specs.short_description = "Характеристики"
# --- 4. Складской учет ---
@admin.register(StockItem)
class StockItemAdmin(admin.ModelAdmin):
list_display = (
'get_material_name',
'display_dimensions',
'quantity',
'colored_status',
'order_reference',
'location'
)
list_display_links = ('get_material_name',)
list_filter = ('is_scrap', 'material__grade', 'material')
search_fields = ('order_reference', 'material__title', 'location')
def get_material_name(self, obj):
return obj.material.title
get_material_name.short_description = "Заготовка"
def display_dimensions(self, obj):
"""Красивое отображение габаритов"""
if obj.width:
return format_html(f"<b>{obj.length} × {obj.width}</b>")
return format_html(f"L = <b>{obj.length}</b>")
display_dimensions.short_description = "Размеры (мм)"
def colored_status(self, obj):
"""Цветовая маркировка остатков"""
if obj.is_scrap:
return format_html('<b style="color: #ca8a04;">ОБРЕЗОК</b>')
return format_html('<b style="color: #16a34a;">ЦЕЛЫЙ</b>')
colored_status.short_description = "Статус"
fieldsets = (
(None, {
'fields': ('material', 'quantity')
}),
('Габариты (мм)', {
'fields': (('length', 'width'),)
}),
('Учет и хранение', {
'fields': ('is_scrap', 'order_reference', 'location')
}),
)