150 lines
4.9 KiB
Python
150 lines
4.9 KiB
Python
"""
|
|
Billing Module Admin
|
|
"""
|
|
from django.contrib import admin
|
|
from django.utils.html import format_html
|
|
from igny8_core.admin.base import AccountAdminMixin
|
|
from igny8_core.business.billing.models import CreditCostConfig
|
|
from .models import CreditTransaction, CreditUsageLog, AccountPaymentMethod
|
|
|
|
|
|
@admin.register(CreditTransaction)
|
|
class CreditTransactionAdmin(AccountAdminMixin, admin.ModelAdmin):
|
|
list_display = ['id', 'account', 'transaction_type', 'amount', 'balance_after', 'description', 'created_at']
|
|
list_filter = ['transaction_type', 'created_at', 'account']
|
|
search_fields = ['description', 'account__name']
|
|
readonly_fields = ['created_at']
|
|
date_hierarchy = 'created_at'
|
|
|
|
def get_account_display(self, obj):
|
|
"""Safely get account name"""
|
|
try:
|
|
account = getattr(obj, 'account', None)
|
|
return account.name if account else '-'
|
|
except:
|
|
return '-'
|
|
get_account_display.short_description = 'Account'
|
|
|
|
|
|
@admin.register(CreditUsageLog)
|
|
class CreditUsageLogAdmin(AccountAdminMixin, admin.ModelAdmin):
|
|
list_display = ['id', 'account', 'operation_type', 'credits_used', 'cost_usd', 'model_used', 'created_at']
|
|
list_filter = ['operation_type', 'created_at', 'account', 'model_used']
|
|
search_fields = ['account__name', 'model_used']
|
|
readonly_fields = ['created_at']
|
|
date_hierarchy = 'created_at'
|
|
|
|
def get_account_display(self, obj):
|
|
"""Safely get account name"""
|
|
try:
|
|
account = getattr(obj, 'account', None)
|
|
return account.name if account else '-'
|
|
except:
|
|
return '-'
|
|
get_account_display.short_description = 'Account'
|
|
|
|
|
|
@admin.register(AccountPaymentMethod)
|
|
class AccountPaymentMethodAdmin(AccountAdminMixin, admin.ModelAdmin):
|
|
list_display = [
|
|
'display_name',
|
|
'type',
|
|
'account',
|
|
'is_default',
|
|
'is_enabled',
|
|
'is_verified',
|
|
'country_code',
|
|
'updated_at',
|
|
]
|
|
list_filter = ['type', 'is_default', 'is_enabled', 'is_verified', 'country_code']
|
|
search_fields = ['display_name', 'account__name', 'account__id']
|
|
readonly_fields = ['created_at', 'updated_at']
|
|
fieldsets = (
|
|
('Payment Method', {
|
|
'fields': ('account', 'type', 'display_name', 'is_default', 'is_enabled', 'is_verified', 'country_code')
|
|
}),
|
|
('Instructions / Metadata', {
|
|
'fields': ('instructions', 'metadata')
|
|
}),
|
|
('Timestamps', {
|
|
'fields': ('created_at', 'updated_at'),
|
|
'classes': ('collapse',)
|
|
}),
|
|
)
|
|
|
|
|
|
@admin.register(CreditCostConfig)
|
|
class CreditCostConfigAdmin(admin.ModelAdmin):
|
|
list_display = [
|
|
'operation_type',
|
|
'display_name',
|
|
'credits_cost_display',
|
|
'unit',
|
|
'is_active',
|
|
'cost_change_indicator',
|
|
'updated_at',
|
|
'updated_by'
|
|
]
|
|
|
|
list_filter = ['is_active', 'unit', 'updated_at']
|
|
search_fields = ['operation_type', 'display_name', 'description']
|
|
|
|
fieldsets = (
|
|
('Operation', {
|
|
'fields': ('operation_type', 'display_name', 'description')
|
|
}),
|
|
('Cost Configuration', {
|
|
'fields': ('credits_cost', 'unit', 'is_active')
|
|
}),
|
|
('Audit Trail', {
|
|
'fields': ('previous_cost', 'updated_by', 'created_at', 'updated_at'),
|
|
'classes': ('collapse',)
|
|
}),
|
|
)
|
|
|
|
readonly_fields = ['created_at', 'updated_at', 'previous_cost']
|
|
|
|
def credits_cost_display(self, obj):
|
|
"""Show cost with color coding"""
|
|
if obj.credits_cost >= 20:
|
|
color = 'red'
|
|
elif obj.credits_cost >= 10:
|
|
color = 'orange'
|
|
else:
|
|
color = 'green'
|
|
return format_html(
|
|
'<span style="color: {}; font-weight: bold;">{} credits</span>',
|
|
color,
|
|
obj.credits_cost
|
|
)
|
|
credits_cost_display.short_description = 'Cost'
|
|
|
|
def cost_change_indicator(self, obj):
|
|
"""Show if cost changed recently"""
|
|
if obj.previous_cost is not None:
|
|
if obj.credits_cost > obj.previous_cost:
|
|
icon = '📈' # Increased
|
|
color = 'red'
|
|
elif obj.credits_cost < obj.previous_cost:
|
|
icon = '📉' # Decreased
|
|
color = 'green'
|
|
else:
|
|
icon = '➡️' # Same
|
|
color = 'gray'
|
|
|
|
return format_html(
|
|
'{} <span style="color: {};">({} → {})</span>',
|
|
icon,
|
|
color,
|
|
obj.previous_cost,
|
|
obj.credits_cost
|
|
)
|
|
return '—'
|
|
cost_change_indicator.short_description = 'Recent Change'
|
|
|
|
def save_model(self, request, obj, form, change):
|
|
"""Track who made the change"""
|
|
obj.updated_by = request.user
|
|
super().save_model(request, obj, form, change)
|
|
|