""" Admin classes for services and service offerings """ from django.contrib import admin from django.utils.html import format_html from ..models import ( Service, ServiceOffering, ExternalLink, ExternalLinkOffering, Plan, PlanPrice, ) class ExternalLinkInline(admin.TabularInline): """Inline admin for ExternalLink model""" model = ExternalLink extra = 1 fields = ("description", "url", "order") ordering = ("order", "description") class ExternalLinkOfferingInline(admin.TabularInline): """Inline admin for ExternalLinkOffering model""" model = ExternalLinkOffering extra = 1 fields = ("description", "url", "order") ordering = ("order", "description") class PlanPriceInline(admin.TabularInline): """Inline admin for PlanPrice model""" model = PlanPrice extra = 1 fields = ("currency", "amount") ordering = ("currency",) class PlanInline(admin.StackedInline): """Inline admin for Plan model with sortable ordering""" model = Plan extra = 1 fieldsets = ( (None, {"fields": ("name", "description", "plan_description")}), ("Display Options", {"fields": ("is_best", "order")}), ) show_change_link = True class OfferingInline(admin.StackedInline): """Inline admin for ServiceOffering model""" model = ServiceOffering extra = 1 fieldsets = ( ( None, { "fields": ( "description", "service", "cloud_provider", "offer_description", ) }, ), ) show_change_link = True @admin.register(Service) class ServiceAdmin(admin.ModelAdmin): """Admin configuration for Service model""" list_display = ( "name", "logo_preview", "category_list", "is_featured", "is_coming_soon", "disable_listing", ) list_filter = ("categories",) search_fields = ("name", "description", "slug") prepopulated_fields = {"slug": ("name",)} filter_horizontal = ("categories",) inlines = [ExternalLinkInline, OfferingInline] fieldsets = ( (None, {"fields": ("name", "slug", "description", "tagline")}), ( "Images", { "fields": ( "image_library", "logo", ), # New image library field and legacy field "description": "Use the Image Library field for new images. Legacy field will be removed after migration.", }, ), ( "Configuration", { "fields": ( "categories", "features", "is_featured", "is_coming_soon", "disable_listing", ) }, ), ) def logo_preview(self, obj): """Display logo preview in admin list view""" logo = obj.get_logo if logo: return format_html('', logo.url) return "No logo" logo_preview.short_description = "Logo" def category_list(self, obj): """Display categories as comma-separated list""" return ", ".join([cat.name for cat in obj.categories.all()]) category_list.short_description = "Categories" def partner_list(self, obj): """Display consulting partners as comma-separated list""" return ", ".join([partner.name for partner in obj.consulting_partners.all()]) partner_list.short_description = "Consulting Partners" @admin.register(ServiceOffering) class ServiceOfferingAdmin(admin.ModelAdmin): """Admin configuration for ServiceOffering model""" list_display = ("service", "cloud_provider", "plan_count", "total_prices") list_filter = ("service", "cloud_provider") search_fields = ("service__name", "cloud_provider__name", "description") inlines = [ExternalLinkOfferingInline, PlanInline] def plan_count(self, obj): """Display number of plans for this offering""" return obj.plans.count() plan_count.short_description = "Plans" def total_prices(self, obj): """Display total number of plan prices for this offering""" total = sum(plan.plan_prices.count() for plan in obj.plans.all()) return f"{total} prices" total_prices.short_description = "Total Prices" @admin.register(Plan) class PlanAdmin(admin.ModelAdmin): """Admin configuration for Plan model with sortable ordering""" list_display = ("name", "offering", "is_best", "price_summary", "order") list_filter = ("offering__service", "offering__cloud_provider", "is_best") search_fields = ("name", "description", "offering__service__name") list_editable = ("is_best",) inlines = [PlanPriceInline] fieldsets = ( (None, {"fields": ("name", "offering", "description", "plan_description")}), ("Display Options", {"fields": ("is_best", "order")}), ) def price_summary(self, obj): """Display a summary of prices for this plan""" prices = obj.plan_prices.all() if prices: price_strs = [f"{price.amount} {price.currency}" for price in prices] return ", ".join(price_strs) return "No prices set" price_summary.short_description = "Prices" @admin.register(PlanPrice) class PlanPriceAdmin(admin.ModelAdmin): """Admin configuration for PlanPrice model""" list_display = ("plan", "currency", "amount") list_filter = ( "currency", "plan__offering__service", "plan__offering__cloud_provider", ) search_fields = ("plan__name", "plan__offering__service__name") ordering = ("plan__offering__service__name", "plan__name", "currency")