Corp/backend/commerce/admin.py

150 lines
4.3 KiB
Python

from django.contrib import admin
from .models import (
Cost,
IntegrationConnection,
IntegrationSyncRun,
Product,
ProductBinding,
ProductImage,
Sale,
SaleLine,
SourceRecord,
SourceSystem,
StockSnapshot,
)
@admin.register(IntegrationConnection)
class IntegrationConnectionAdmin(admin.ModelAdmin):
list_display = ["provider", "source", "status", "account_name", "updated_at"]
list_filter = ["provider", "status"]
readonly_fields = ["encrypted_credentials", "last_stats", "task_id"]
@admin.register(IntegrationSyncRun)
class IntegrationSyncRunAdmin(admin.ModelAdmin):
list_display = ["connection", "status", "processed", "created_at", "finished_at"]
list_filter = ["status", "connection__provider"]
readonly_fields = [field.name for field in IntegrationSyncRun._meta.fields]
class ProductBindingInline(admin.TabularInline):
model = ProductBinding
extra = 0
autocomplete_fields = ["source"]
class ProductImageInline(admin.TabularInline):
model = ProductImage
extra = 0
readonly_fields = ["file", "thumbnail", "source_updated_at"]
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
list_display = ["sku", "name", "kind", "parent", "is_active", "updated_at"]
list_filter = ["kind", "is_active"]
search_fields = ["sku", "name", "barcode", "bindings__external_sku"]
autocomplete_fields = ["parent"]
inlines = [ProductBindingInline, ProductImageInline]
@admin.register(ProductImage)
class ProductImageAdmin(admin.ModelAdmin):
list_display = ["product", "source", "filename", "is_primary", "position"]
list_filter = ["source", "is_primary"]
search_fields = ["product__sku", "product__name", "filename", "external_id"]
autocomplete_fields = ["product", "source"]
@admin.register(SourceSystem)
class SourceSystemAdmin(admin.ModelAdmin):
list_display = ["code", "name", "is_active", "updated_at"]
list_filter = ["is_active"]
search_fields = ["code", "name"]
@admin.register(SourceRecord)
class SourceRecordAdmin(admin.ModelAdmin):
list_display = ["source", "entity_type", "external_id", "received_at"]
list_filter = ["source", "entity_type"]
search_fields = ["external_id"]
readonly_fields = ["payload_hash", "received_at", "created_at"]
autocomplete_fields = ["source"]
@admin.register(ProductBinding)
class ProductBindingAdmin(admin.ModelAdmin):
list_display = ["product", "source", "external_id", "external_sku", "is_primary"]
list_filter = ["source", "is_primary"]
search_fields = ["product__sku", "external_id", "external_sku"]
autocomplete_fields = ["product", "source"]
class SaleLineInline(admin.TabularInline):
model = SaleLine
extra = 0
autocomplete_fields = ["product"]
@admin.register(SaleLine)
class SaleLineAdmin(admin.ModelAdmin):
list_display = ["sale", "product", "external_sku", "quantity", "gross_amount"]
search_fields = [
"external_id",
"external_sku",
"name",
"sale__number",
"product__sku",
]
autocomplete_fields = ["sale", "product"]
@admin.register(Sale)
class SaleAdmin(admin.ModelAdmin):
list_display = [
"number",
"source",
"event_type",
"channel",
"status",
"counts_as_sale",
"occurred_at",
]
list_filter = ["source", "event_type", "channel", "counts_as_sale", "currency"]
search_fields = ["number", "external_id", "lines__external_sku"]
autocomplete_fields = ["source", "source_record"]
inlines = [SaleLineInline]
@admin.register(Cost)
class CostAdmin(admin.ModelAdmin):
list_display = [
"cost_type",
"product",
"source",
"channel",
"amount",
"currency",
"occurred_at",
]
list_filter = ["cost_type", "source", "channel", "currency"]
search_fields = ["external_id", "product__sku", "product__name"]
autocomplete_fields = ["source", "product", "sale_line"]
@admin.register(StockSnapshot)
class StockSnapshotAdmin(admin.ModelAdmin):
list_display = [
"product",
"source",
"warehouse_name",
"quantity",
"reserved",
"captured_at",
]
list_filter = ["source", "warehouse_name"]
search_fields = ["product__sku", "product__name", "warehouse_external_id"]
autocomplete_fields = ["product", "source"]