246 lines
7.1 KiB
Python
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' |