HH/apps/integrations/admin.py
2026-03-28 14:03:56 +03:00

263 lines
9.4 KiB
Python

"""
Integrations admin
"""
from django.contrib import admin
from django.utils.html import format_html, mark_safe
from .models import (
EventMapping,
HISEventType,
HISTestPatient,
HISTestVisit,
HISPatientVisit,
HISVisitEvent,
InboundEvent,
IntegrationConfig,
SurveyTemplateMapping,
)
@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(SurveyTemplateMapping)
class SurveyTemplateMappingAdmin(admin.ModelAdmin):
"""Survey template mapping admin"""
list_display = ["hospital", "patient_type", "survey_template", "is_active"]
list_filter = ["hospital", "patient_type", "is_active"]
search_fields = ["hospital__name", "survey_template__name"]
ordering = ["hospital", "patient_type"]
fieldsets = (
("Mapping Configuration", {"fields": ("hospital", "patient_type", "survey_template")}),
("Settings", {"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("hospital", "survey_template")
class HISVisitEventInline(admin.TabularInline):
model = HISVisitEvent
extra = 0
fields = ["event_type", "bill_date", "parsed_date", "visit_category"]
readonly_fields = ["event_type", "bill_date", "parsed_date", "visit_category"]
show_change_link = False
@admin.register(HISPatientVisit)
class HISPatientVisitAdmin(admin.ModelAdmin):
"""HIS patient visit admin"""
list_display = [
"patient",
"patient_type",
"admission_id",
"hospital",
"is_visit_complete",
"survey_linked",
"discharge_date",
"last_his_fetch_at",
]
list_filter = ["patient_type", "is_visit_complete", "hospital"]
search_fields = ["admission_id", "reg_code", "patient_id_his", "patient__first_name", "patient__last_name"]
ordering = ["-last_his_fetch_at"]
date_hierarchy = "last_his_fetch_at"
inlines = [HISVisitEventInline]
fieldsets = (
(
"Patient & Hospital",
{"fields": ("patient", "hospital", "admission_id", "reg_code", "patient_id_his", "patient_type")},
),
("Visit Dates", {"fields": ("admit_date", "discharge_date", "effective_discharge_date")}),
("Status", {"fields": ("is_visit_complete", "survey_instance", "last_his_fetch_at")}),
("HIS Data", {"fields": ("visit_data", "visit_timeline"), "classes": ("collapse",)}),
("Doctor & Consultant", {"fields": ("primary_doctor", "consultant_id", "primary_doctor_fk", "consultant_fk")}),
("Insurance & Billing", {"fields": ("company_name", "grade_name", "insurance_company_name", "bill_type")}),
("VIP & Nationality", {"fields": ("is_vip", "nationality")}),
("Timestamps", {"fields": ("created_at", "updated_at")}),
)
readonly_fields = ["created_at", "updated_at"]
def survey_linked(self, obj):
if obj.survey_instance:
return format_html(
'<a href="/admin/surveys/surveyinstance/{}/">{}</a>', obj.survey_instance.id, obj.survey_instance.id
)
return mark_safe('<span class="badge bg-secondary">None</span>')
survey_linked.short_description = "Survey"
def has_add_permission(self, request):
return False
@admin.register(HISVisitEvent)
class HISVisitEventAdmin(admin.ModelAdmin):
"""HIS visit event admin"""
list_display = ["visit", "event_type", "bill_date", "parsed_date", "visit_category", "admission_id"]
list_filter = ["visit_category", "patient_type"]
search_fields = ["admission_id", "patient_id", "event_type"]
ordering = ["-parsed_date"]
date_hierarchy = "parsed_date"
fieldsets = (
("Visit", {"fields": ("visit",)}),
("Event Details", {"fields": ("event_type", "bill_date", "parsed_date", "visit_category")}),
(
"Patient Info",
{"fields": ("patient_type", "admission_id", "patient_id", "reg_code", "ssn", "mobile_no")},
),
("Timestamps", {"fields": ("created_at", "updated_at")}),
)
readonly_fields = ["created_at", "updated_at"]
def has_add_permission(self, request):
return False
@admin.register(HISEventType)
class HISEventTypeAdmin(admin.ModelAdmin):
"""HIS event type admin - auto-populated from HIS data"""
list_display = ["event_type", "patient_types_display", "event_count", "last_seen_at"]
search_fields = ["event_type"]
ordering = ["event_type"]
list_filter = ["last_seen_at"]
readonly_fields = ["event_type", "patient_types", "event_count", "last_seen_at", "created_at", "updated_at"]
def has_add_permission(self, request):
return False
def patient_types_display(self, obj):
if not obj.patient_types:
return mark_safe('<span class="badge bg-secondary">None</span>')
return ", ".join(obj.patient_types)
patient_types_display.short_description = "Patient Types"
@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")
@admin.register(HISTestPatient)
class HISTestPatientAdmin(admin.ModelAdmin):
list_display = ["admission_id", "patient_name", "patient_type", "hospital_name", "admit_date", "discharge_date"]
list_filter = ["patient_type", "hospital_name"]
search_fields = ["admission_id", "patient_id", "ssn", "mobile_no", "patient_name"]
ordering = ["-admit_date"]
date_hierarchy = "admit_date"
readonly_fields = ["created_at", "updated_at"]
def has_add_permission(self, request):
return False
@admin.register(HISTestVisit)
class HISTestVisitAdmin(admin.ModelAdmin):
list_display = ["admission_id", "visit_category", "event_type", "bill_date"]
list_filter = ["visit_category", "event_type"]
search_fields = ["admission_id", "patient_id"]
ordering = ["-bill_date"]
date_hierarchy = "bill_date"
readonly_fields = ["created_at", "updated_at"]
def has_add_permission(self, request):
return False