138 lines
4.2 KiB
Python
138 lines
4.2 KiB
Python
"""
|
|
Integrations admin
|
|
"""
|
|
from django.contrib import admin
|
|
from django.utils.html import format_html
|
|
|
|
from .models import EventMapping, InboundEvent, IntegrationConfig
|
|
|
|
|
|
@admin.register(InboundEvent)
|
|
class InboundEventAdmin(admin.ModelAdmin):
|
|
"""Inbound event admin"""
|
|
list_display = [
|
|
'source_system', 'event_code', 'encounter_id',
|
|
'status_badge', 'processing_attempts', 'received_at'
|
|
]
|
|
list_filter = ['status', 'source_system', 'received_at']
|
|
search_fields = ['encounter_id', 'patient_identifier', 'event_code']
|
|
ordering = ['-received_at']
|
|
date_hierarchy = 'received_at'
|
|
|
|
fieldsets = (
|
|
('Event Information', {
|
|
'fields': ('source_system', 'event_code', 'encounter_id', 'patient_identifier')
|
|
}),
|
|
('Payload', {
|
|
'fields': ('payload_json',),
|
|
'classes': ('collapse',)
|
|
}),
|
|
('Processing Status', {
|
|
'fields': ('status', 'processing_attempts', 'error')
|
|
}),
|
|
('Extracted Context', {
|
|
'fields': ('physician_license', 'department_code'),
|
|
'classes': ('collapse',)
|
|
}),
|
|
('Timestamps', {
|
|
'fields': ('received_at', 'processed_at', 'created_at', 'updated_at')
|
|
}),
|
|
('Metadata', {
|
|
'fields': ('metadata',),
|
|
'classes': ('collapse',)
|
|
}),
|
|
)
|
|
|
|
readonly_fields = ['received_at', 'processed_at', 'created_at', 'updated_at']
|
|
|
|
def status_badge(self, obj):
|
|
"""Display status with color badge"""
|
|
colors = {
|
|
'pending': 'warning',
|
|
'processing': 'info',
|
|
'processed': 'success',
|
|
'failed': 'danger',
|
|
'ignored': 'secondary',
|
|
}
|
|
color = colors.get(obj.status, 'secondary')
|
|
return format_html(
|
|
'<span class="badge bg-{}">{}</span>',
|
|
color,
|
|
obj.get_status_display()
|
|
)
|
|
status_badge.short_description = 'Status'
|
|
|
|
def has_add_permission(self, request):
|
|
# Events should only be created via API
|
|
return False
|
|
|
|
|
|
class EventMappingInline(admin.TabularInline):
|
|
"""Inline admin for event mappings"""
|
|
model = EventMapping
|
|
extra = 1
|
|
fields = ['external_event_code', 'internal_event_code', 'is_active']
|
|
|
|
|
|
@admin.register(IntegrationConfig)
|
|
class IntegrationConfigAdmin(admin.ModelAdmin):
|
|
"""Integration configuration admin"""
|
|
list_display = ['name', 'source_system', 'is_active', 'last_sync_at', 'created_at']
|
|
list_filter = ['source_system', 'is_active']
|
|
search_fields = ['name', 'description']
|
|
ordering = ['name']
|
|
inlines = [EventMappingInline]
|
|
|
|
fieldsets = (
|
|
(None, {
|
|
'fields': ('name', 'source_system', 'description')
|
|
}),
|
|
('Connection', {
|
|
'fields': ('api_url', 'api_key'),
|
|
'classes': ('collapse',)
|
|
}),
|
|
('Configuration', {
|
|
'fields': ('is_active', 'config_json'),
|
|
'classes': ('collapse',)
|
|
}),
|
|
('Metadata', {
|
|
'fields': ('last_sync_at', 'created_at', 'updated_at')
|
|
}),
|
|
)
|
|
|
|
readonly_fields = ['last_sync_at', 'created_at', 'updated_at']
|
|
|
|
|
|
@admin.register(EventMapping)
|
|
class EventMappingAdmin(admin.ModelAdmin):
|
|
"""Event mapping admin"""
|
|
list_display = [
|
|
'integration_config', 'external_event_code',
|
|
'internal_event_code', 'is_active'
|
|
]
|
|
list_filter = ['integration_config', 'is_active']
|
|
search_fields = ['external_event_code', 'internal_event_code']
|
|
ordering = ['integration_config', 'external_event_code']
|
|
|
|
fieldsets = (
|
|
(None, {
|
|
'fields': ('integration_config', 'external_event_code', 'internal_event_code')
|
|
}),
|
|
('Field Mappings', {
|
|
'fields': ('field_mappings',),
|
|
'classes': ('collapse',)
|
|
}),
|
|
('Configuration', {
|
|
'fields': ('is_active',)
|
|
}),
|
|
('Metadata', {
|
|
'fields': ('created_at', 'updated_at')
|
|
}),
|
|
)
|
|
|
|
readonly_fields = ['created_at', 'updated_at']
|
|
|
|
def get_queryset(self, request):
|
|
qs = super().get_queryset(request)
|
|
return qs.select_related('integration_config')
|