HH/apps/rca/admin.py

246 lines
7.1 KiB
Python

"""
RCA (Root Cause Analysis) admin configuration
"""
from django.contrib import admin
from django.utils.html import format_html
from .models import (
RCAActionStatus,
RCAActionType,
RCACorrectiveAction,
RCAStatus,
RCASeverity,
RCAAttachment,
RCANote,
RCARootCause,
RootCauseAnalysis,
)
@admin.register(RootCauseAnalysis)
class RootCauseAnalysisAdmin(admin.ModelAdmin):
"""Admin interface for RootCauseAnalysis"""
list_display = [
'title',
'status_badge',
'severity_badge',
'hospital',
'assigned_to',
'created_at',
]
list_filter = ['status', 'severity', 'priority', 'hospital', 'department']
search_fields = ['title', 'description', 'created_by__email']
date_hierarchy = 'created_at'
readonly_fields = [
'created_at',
'updated_at',
'created_by',
'approved_at',
'closed_at',
]
fieldsets = (
('Basic Information', {
'fields': ('title', 'description', 'background')
}),
('Organization', {
'fields': ('hospital', 'department')
}),
('Classification', {
'fields': ('status', 'severity', 'priority')
}),
('Assignment', {
'fields': ('assigned_to', 'assigned_at')
}),
('Root Cause Analysis', {
'fields': ('root_cause_summary',)
}),
('Approval', {
'fields': ('approved_by', 'approved_at', 'approval_notes'),
'classes': ('collapse',)
}),
('Closure', {
'fields': ('closed_by', 'closed_at', 'closure_notes'),
'classes': ('collapse',)
}),
('Timeline', {
'fields': ('target_completion_date', 'actual_completion_date')
}),
('Metadata', {
'fields': ('metadata',),
'classes': ('collapse',)
}),
('System', {
'fields': ('created_at', 'updated_at', 'created_by', 'is_deleted'),
'classes': ('collapse',)
}),
)
def status_badge(self, obj):
colors = {
'draft': 'gray',
'in_progress': 'blue',
'review': 'orange',
'approved': 'green',
'closed': 'gray',
}
color = colors.get(obj.status, 'gray')
return format_html(
'<span style="background-color: {}; color: white; padding: 3px 8px; border-radius: 3px;">{}</span>',
color,
obj.get_status_display()
)
status_badge.short_description = 'Status'
def severity_badge(self, obj):
colors = {
'low': 'green',
'medium': 'blue',
'high': 'orange',
'critical': 'red',
}
color = colors.get(obj.severity, 'gray')
return format_html(
'<span style="background-color: {}; color: white; padding: 3px 8px; border-radius: 3px;">{}</span>',
color,
obj.get_severity_display()
)
severity_badge.short_description = 'Severity'
class RCARootCauseInline(admin.TabularInline):
"""Inline admin for RCARootCause"""
model = RCARootCause
extra = 0
fields = [
'description',
'category',
'likelihood',
'impact',
'risk_score',
'is_verified',
]
readonly_fields = ['risk_score']
@admin.register(RCARootCause)
class RCARootCauseAdmin(admin.ModelAdmin):
"""Admin interface for RCARootCause"""
list_display = [
'rca',
'description_short',
'category',
'risk_score',
'is_verified',
'created_at',
]
list_filter = ['category', 'is_verified']
search_fields = ['description', 'rca__title']
readonly_fields = ['risk_score', 'created_at', 'updated_at']
fieldsets = (
('Basic Information', {
'fields': ('rca', 'description', 'category')
}),
('Analysis', {
'fields': ('contributing_factors', 'evidence')
}),
('Risk Assessment', {
'fields': ('likelihood', 'impact', 'risk_score')
}),
('Verification', {
'fields': ('is_verified', 'verified_by', 'verified_at')
}),
('System', {
'fields': ('created_at', 'updated_at'),
'classes': ('collapse',)
}),
)
def description_short(self, obj):
return obj.description[:50] + '...' if len(obj.description) > 50 else obj.description
description_short.short_description = 'Description'
class RCACorrectiveActionInline(admin.TabularInline):
"""Inline admin for RCACorrectiveAction"""
model = RCACorrectiveAction
extra = 0
fields = [
'description',
'action_type',
'responsible_person',
'status',
'target_date',
'completion_date',
'effectiveness_score',
]
@admin.register(RCACorrectiveAction)
class RCACorrectiveActionAdmin(admin.ModelAdmin):
"""Admin interface for RCACorrectiveAction"""
list_display = [
'rca',
'description_short',
'action_type',
'status',
'responsible_person',
'target_date',
'completion_date',
]
list_filter = ['action_type', 'status', 'root_cause__category']
search_fields = ['description', 'rca__title']
date_hierarchy = 'created_at'
fieldsets = (
('Basic Information', {
'fields': ('rca', 'root_cause', 'description', 'action_type')
}),
('Responsibility', {
'fields': ('responsible_person',)
}),
('Timeline', {
'fields': ('status', 'target_date', 'completion_date')
}),
('Effectiveness', {
'fields': ('effectiveness_measure', 'effectiveness_assessment', 'effectiveness_score')
}),
('Challenges', {
'fields': ('obstacles',)
}),
('Metadata', {
'fields': ('metadata',),
'classes': ('collapse',)
}),
('System', {
'fields': ('created_at', 'updated_at'),
'classes': ('collapse',)
}),
)
def description_short(self, obj):
return obj.description[:50] + '...' if len(obj.description) > 50 else obj.description
description_short.short_description = 'Description'
@admin.register(RCAAttachment)
class RCAAttachmentAdmin(admin.ModelAdmin):
"""Admin interface for RCAAttachment"""
list_display = ['rca', 'filename', 'file_size', 'uploaded_by', 'created_at']
list_filter = ['rca__hospital', 'created_at']
search_fields = ['filename', 'rca__title', 'description']
readonly_fields = ['file_size', 'created_at', 'updated_at']
@admin.register(RCANote)
class RCANoteAdmin(admin.ModelAdmin):
"""Admin interface for RCANote"""
list_display = ['rca', 'note_short', 'created_by', 'is_internal', 'created_at']
list_filter = ['is_internal', 'created_at']
search_fields = ['note', 'rca__title']
readonly_fields = ['created_at', 'updated_at']
def note_short(self, obj):
return obj.note[:50] + '...' if len(obj.note) > 50 else obj.note
note_short.short_description = 'Note'