Coverage for src/backend/InvenTree/stock/admin.py: 87%
38 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 17:47 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 17:47 +0000
1"""Admin for stock app."""
3from django.contrib import admin
4from django.db.models import Count
6from .models import (
7 StockItem,
8 StockItemTestResult,
9 StockItemTracking,
10 StockLocation,
11 StockLocationType,
12)
15class LocationInline(admin.TabularInline):
16 """Inline for sub-locations."""
18 model = StockLocation
21@admin.register(StockLocation)
22class LocationAdmin(admin.ModelAdmin):
23 """Admin class for Location."""
25 list_display = ('name', 'pathstring', 'description')
27 search_fields = ('name', 'description')
29 inlines = [LocationInline]
31 autocomplete_fields = ['parent']
34@admin.register(StockLocationType)
35class LocationTypeAdmin(admin.ModelAdmin):
36 """Admin class for StockLocationType."""
38 list_display = ('name', 'description', 'icon', 'location_count')
39 readonly_fields = ('location_count',)
41 def get_queryset(self, request):
42 """Annotate queryset to fetch location count."""
43 return (
44 super()
45 .get_queryset(request)
46 .annotate(location_count=Count('stock_locations'))
47 )
49 def location_count(self, obj):
50 """Returns the number of locations this location type is assigned to."""
51 return obj.location_count
54@admin.register(StockItem)
55class StockItemAdmin(admin.ModelAdmin):
56 """Admin class for StockItem."""
58 list_display = ('part', 'quantity', 'location', 'status', 'updated')
60 # A list of search fields which can be used for lookup on matching 'autocomplete' fields
61 search_fields = ['part__name', 'part__description', 'serial', 'batch']
63 autocomplete_fields = [
64 'belongs_to',
65 'build',
66 'customer',
67 'location',
68 'parent',
69 'part',
70 'purchase_order',
71 'sales_order',
72 'stocktake_user',
73 'supplier_part',
74 'consumed_by',
75 ]
78@admin.register(StockItemTracking)
79class StockTrackingAdmin(admin.ModelAdmin):
80 """Admin class for StockTracking - read-only to preserve audit trail integrity."""
82 list_display = ('item', 'date', 'label')
84 autocomplete_fields = ['item']
86 def has_add_permission(self, request):
87 """Prevent addition of new tracking entries via the admin interface."""
88 return False
90 def has_change_permission(self, request, obj=None):
91 """Prevent modification of tracking entries via the admin interface."""
92 return False
94 def has_delete_permission(self, request, obj=None):
95 """Prevent deletion of tracking entries via the admin interface."""
96 return False
99@admin.register(StockItemTestResult)
100class StockItemTestResultAdmin(admin.ModelAdmin):
101 """Admin class for StockItemTestResult."""
103 list_display = ('stock_item', 'test_name', 'result', 'value')
105 autocomplete_fields = ['stock_item']