Updates
This commit is contained in:
266
ETB-API/compliance_governance/admin.py
Normal file
266
ETB-API/compliance_governance/admin.py
Normal file
@@ -0,0 +1,266 @@
|
||||
"""
|
||||
Django admin configuration for compliance_governance app
|
||||
"""
|
||||
from django.contrib import admin
|
||||
from django.utils.html import format_html
|
||||
from django.urls import reverse
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.db.models import Count, Q
|
||||
from django.utils import timezone
|
||||
from datetime import timedelta
|
||||
|
||||
from .models import (
|
||||
RegulatoryFramework,
|
||||
ComplianceRequirement,
|
||||
RegulatoryWorkflow,
|
||||
WorkflowInstance,
|
||||
EvidenceCollection,
|
||||
RetentionPolicy,
|
||||
ExportRequest,
|
||||
ComplianceReport,
|
||||
LegalHold,
|
||||
)
|
||||
|
||||
|
||||
@admin.register(RegulatoryFramework)
|
||||
class RegulatoryFrameworkAdmin(admin.ModelAdmin):
|
||||
"""Admin interface for Regulatory Framework"""
|
||||
|
||||
list_display = [
|
||||
'name', 'framework_type', 'version', 'is_active', 'effective_date',
|
||||
'requirements_count', 'created_at'
|
||||
]
|
||||
list_filter = [
|
||||
'framework_type', 'is_active', 'effective_date', 'created_at'
|
||||
]
|
||||
search_fields = ['name', 'description', 'applicable_regions', 'industry_sectors']
|
||||
readonly_fields = ['id', 'created_at', 'updated_at']
|
||||
fieldsets = (
|
||||
('Basic Information', {
|
||||
'fields': ('id', 'name', 'framework_type', 'version', 'description')
|
||||
}),
|
||||
('Framework Details', {
|
||||
'fields': ('applicable_regions', 'industry_sectors', 'compliance_requirements')
|
||||
}),
|
||||
('Status and Dates', {
|
||||
'fields': ('is_active', 'effective_date', 'review_date')
|
||||
}),
|
||||
('Metadata', {
|
||||
'fields': ('created_by', 'created_at', 'updated_at'),
|
||||
'classes': ('collapse',)
|
||||
}),
|
||||
)
|
||||
|
||||
def requirements_count(self, obj):
|
||||
"""Display count of requirements"""
|
||||
count = obj.requirements.count()
|
||||
if count > 0:
|
||||
url = reverse('admin:compliance_governance_compliancerequirement_changelist')
|
||||
return format_html('<a href="{}?framework__id__exact={}">{} requirements</a>', url, obj.id, count)
|
||||
return '0 requirements'
|
||||
requirements_count.short_description = 'Requirements'
|
||||
|
||||
|
||||
@admin.register(ComplianceRequirement)
|
||||
class ComplianceRequirementAdmin(admin.ModelAdmin):
|
||||
"""Admin interface for Compliance Requirement"""
|
||||
|
||||
list_display = [
|
||||
'requirement_id', 'title', 'framework', 'requirement_type', 'priority',
|
||||
'compliance_status', 'is_implemented', 'assigned_to', 'next_assessment_date'
|
||||
]
|
||||
list_filter = [
|
||||
'framework', 'requirement_type', 'priority', 'compliance_status',
|
||||
'is_implemented', 'assigned_to', 'next_assessment_date'
|
||||
]
|
||||
search_fields = ['requirement_id', 'title', 'description', 'responsible_team']
|
||||
readonly_fields = ['id', 'created_at', 'updated_at']
|
||||
fieldsets = (
|
||||
('Basic Information', {
|
||||
'fields': ('id', 'framework', 'requirement_id', 'title', 'description')
|
||||
}),
|
||||
('Requirement Details', {
|
||||
'fields': ('requirement_type', 'priority', 'implementation_guidance', 'evidence_requirements', 'testing_procedures')
|
||||
}),
|
||||
('Compliance Tracking', {
|
||||
'fields': ('is_implemented', 'implementation_date', 'last_assessment_date', 'next_assessment_date', 'compliance_status')
|
||||
}),
|
||||
('Assignment', {
|
||||
'fields': ('responsible_team', 'assigned_to')
|
||||
}),
|
||||
('Metadata', {
|
||||
'fields': ('created_at', 'updated_at'),
|
||||
'classes': ('collapse',)
|
||||
}),
|
||||
)
|
||||
|
||||
def get_queryset(self, request):
|
||||
return super().get_queryset(request).select_related('framework', 'assigned_to')
|
||||
|
||||
|
||||
@admin.register(RegulatoryWorkflow)
|
||||
class RegulatoryWorkflowAdmin(admin.ModelAdmin):
|
||||
"""Admin interface for Regulatory Workflow"""
|
||||
|
||||
list_display = [
|
||||
'name', 'workflow_type', 'status', 'version', 'is_template',
|
||||
'instances_count', 'created_by', 'created_at'
|
||||
]
|
||||
list_filter = [
|
||||
'workflow_type', 'status', 'is_template', 'created_at'
|
||||
]
|
||||
search_fields = ['name', 'description']
|
||||
readonly_fields = ['id', 'created_at', 'updated_at']
|
||||
filter_horizontal = ['applicable_frameworks']
|
||||
|
||||
def instances_count(self, obj):
|
||||
"""Display count of workflow instances"""
|
||||
count = obj.instances.count()
|
||||
if count > 0:
|
||||
url = reverse('admin:compliance_governance_workflowinstance_changelist')
|
||||
return format_html('<a href="{}?workflow__id__exact={}">{} instances</a>', url, obj.id, count)
|
||||
return '0 instances'
|
||||
instances_count.short_description = 'Instances'
|
||||
|
||||
|
||||
@admin.register(WorkflowInstance)
|
||||
class WorkflowInstanceAdmin(admin.ModelAdmin):
|
||||
"""Admin interface for Workflow Instance"""
|
||||
|
||||
list_display = [
|
||||
'title', 'workflow', 'status', 'assigned_to', 'related_incident',
|
||||
'started_at', 'due_date', 'is_overdue'
|
||||
]
|
||||
list_filter = [
|
||||
'workflow', 'status', 'assigned_to', 'started_at', 'due_date'
|
||||
]
|
||||
search_fields = ['title', 'description', 'current_step']
|
||||
readonly_fields = ['id', 'started_at', 'updated_at']
|
||||
filter_horizontal = ['stakeholders']
|
||||
|
||||
def is_overdue(self, obj):
|
||||
"""Check if workflow instance is overdue"""
|
||||
if obj.due_date and obj.status in ['PENDING', 'IN_PROGRESS']:
|
||||
if timezone.now() > obj.due_date:
|
||||
return format_html('<span style="color: red;">Yes</span>')
|
||||
return 'No'
|
||||
is_overdue.short_description = 'Overdue'
|
||||
|
||||
|
||||
@admin.register(EvidenceCollection)
|
||||
class EvidenceCollectionAdmin(admin.ModelAdmin):
|
||||
"""Admin interface for Evidence Collection"""
|
||||
|
||||
list_display = [
|
||||
'title', 'evidence_type', 'status', 'incident', 'collected_by',
|
||||
'collection_timestamp', 'file_size_display'
|
||||
]
|
||||
list_filter = [
|
||||
'evidence_type', 'status', 'collected_by', 'collection_timestamp'
|
||||
]
|
||||
search_fields = ['title', 'description', 'collection_notes']
|
||||
readonly_fields = ['id', 'collection_timestamp', 'created_at', 'updated_at']
|
||||
|
||||
def file_size_display(self, obj):
|
||||
"""Display file size in human readable format"""
|
||||
if not obj.file_size:
|
||||
return 'N/A'
|
||||
|
||||
size = obj.file_size
|
||||
for unit in ['B', 'KB', 'MB', 'GB', 'TB']:
|
||||
if size < 1024.0:
|
||||
return f"{size:.1f} {unit}"
|
||||
size /= 1024.0
|
||||
return f"{size:.1f} PB"
|
||||
file_size_display.short_description = 'File Size'
|
||||
|
||||
|
||||
@admin.register(RetentionPolicy)
|
||||
class RetentionPolicyAdmin(admin.ModelAdmin):
|
||||
"""Admin interface for Retention Policy"""
|
||||
|
||||
list_display = [
|
||||
'name', 'policy_type', 'retention_period', 'retention_unit',
|
||||
'is_active', 'effective_date', 'created_by'
|
||||
]
|
||||
list_filter = [
|
||||
'policy_type', 'is_active', 'effective_date', 'created_at'
|
||||
]
|
||||
search_fields = ['name', 'description']
|
||||
readonly_fields = ['id', 'created_at', 'updated_at']
|
||||
filter_horizontal = ['applicable_frameworks']
|
||||
|
||||
|
||||
@admin.register(ExportRequest)
|
||||
class ExportRequestAdmin(admin.ModelAdmin):
|
||||
"""Admin interface for Export Request"""
|
||||
|
||||
list_display = [
|
||||
'title', 'request_type', 'status', 'requester_name', 'requester_organization',
|
||||
'requested_at', 'due_date', 'is_overdue'
|
||||
]
|
||||
list_filter = [
|
||||
'request_type', 'status', 'requester_organization', 'requested_at', 'due_date'
|
||||
]
|
||||
search_fields = ['title', 'description', 'requester_name', 'requester_email']
|
||||
readonly_fields = ['id', 'requested_at', 'updated_at']
|
||||
filter_horizontal = ['applicable_frameworks']
|
||||
|
||||
def is_overdue(self, obj):
|
||||
"""Check if export request is overdue"""
|
||||
if obj.due_date and obj.status not in ['COMPLETED', 'CANCELLED']:
|
||||
if timezone.now() > obj.due_date:
|
||||
return format_html('<span style="color: red;">Yes</span>')
|
||||
return 'No'
|
||||
is_overdue.short_description = 'Overdue'
|
||||
|
||||
|
||||
@admin.register(ComplianceReport)
|
||||
class ComplianceReportAdmin(admin.ModelAdmin):
|
||||
"""Admin interface for Compliance Report"""
|
||||
|
||||
list_display = [
|
||||
'title', 'report_type', 'framework', 'status', 'overall_compliance_score',
|
||||
'report_period_start', 'report_period_end', 'prepared_by'
|
||||
]
|
||||
list_filter = [
|
||||
'report_type', 'status', 'framework', 'report_period_start', 'report_period_end'
|
||||
]
|
||||
search_fields = ['title', 'description', 'executive_summary']
|
||||
readonly_fields = ['id', 'created_at', 'updated_at']
|
||||
filter_horizontal = ['applicable_requirements']
|
||||
|
||||
|
||||
@admin.register(LegalHold)
|
||||
class LegalHoldAdmin(admin.ModelAdmin):
|
||||
"""Admin interface for Legal Hold"""
|
||||
|
||||
list_display = [
|
||||
'case_name', 'case_number', 'status', 'legal_counsel', 'hold_date',
|
||||
'expiration_date', 'affected_data_count', 'is_active'
|
||||
]
|
||||
list_filter = [
|
||||
'status', 'hold_date', 'expiration_date', 'created_at'
|
||||
]
|
||||
search_fields = ['case_name', 'case_number', 'description', 'legal_counsel', 'law_firm']
|
||||
readonly_fields = ['id', 'created_at', 'updated_at']
|
||||
filter_horizontal = ['related_incidents', 'related_evidence']
|
||||
|
||||
def affected_data_count(self, obj):
|
||||
"""Display count of affected data items"""
|
||||
count = obj.get_affected_data_count()
|
||||
return f"{count} items"
|
||||
affected_data_count.short_description = 'Affected Data'
|
||||
|
||||
def is_active(self, obj):
|
||||
"""Check if legal hold is active"""
|
||||
if obj.is_active():
|
||||
return format_html('<span style="color: green;">Active</span>')
|
||||
return format_html('<span style="color: red;">Inactive</span>')
|
||||
is_active.short_description = 'Status'
|
||||
|
||||
|
||||
# Custom admin site configuration
|
||||
admin.site.site_header = "ETB Compliance & Governance Administration"
|
||||
admin.site.site_title = "ETB Compliance Admin"
|
||||
admin.site.index_title = "Compliance & Governance Management"
|
||||
Reference in New Issue
Block a user