263 lines
9.4 KiB
Python
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
|