2025-08-12 13:33:25 +03:00

748 lines
37 KiB
HTML

{% extends "base.html" %}
{% load static %}
{% block title %}Incident Detail - Quality Management{% endblock %}
{% block content %}
<!-- BEGIN breadcrumb -->
<ol class="breadcrumb float-xl-end">
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
<li class="breadcrumb-item"><a href="{% url 'quality:dashboard' %}">Quality</a></li>
<li class="breadcrumb-item"><a href="{% url 'quality:incident_list' %}">Incidents</a></li>
<li class="breadcrumb-item active">{{ object.incident_number }}</li>
</ol>
<!-- END breadcrumb -->
<!-- BEGIN page-header -->
<h1 class="page-header">
Incident Detail
<small>{{ object.incident_number }} - {{ object.title }}</small>
</h1>
<!-- END page-header -->
<div class="row">
<div class="col-xl-8">
<!-- BEGIN panel -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">
{% if object.severity == 'critical' %}
<i class="fa fa-exclamation-triangle text-danger me-2"></i>
<span class="badge bg-danger me-2">Critical</span>
{% elif object.severity == 'high' %}
<i class="fa fa-exclamation-circle text-warning me-2"></i>
<span class="badge bg-warning text-dark me-2">High</span>
{% elif object.severity == 'medium' %}
<i class="fa fa-info-circle text-info me-2"></i>
<span class="badge bg-info me-2">Medium</span>
{% elif object.severity == 'low' %}
<i class="fa fa-check-circle text-success me-2"></i>
<span class="badge bg-success me-2">Low</span>
{% endif %}
{{ object.title }}
</h4>
<div class="panel-heading-btn">
<button type="button" class="btn btn-xs btn-success me-2" onclick="createCorrectiveAction()">
<i class="fa fa-plus"></i> Corrective Action
</button>
<button type="button" class="btn btn-xs btn-info me-2" onclick="printIncident()">
<i class="fa fa-print"></i> Print
</button>
<button type="button" class="btn btn-xs btn-warning me-2" onclick="escalateIncident()">
<i class="fa fa-arrow-up"></i> Escalate
</button>
<a href="{% url 'quality:incident_edit' object.pk %}" class="btn btn-xs btn-primary me-2">
<i class="fa fa-edit"></i> Edit
</a>
<a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-expand"><i class="fa fa-expand"></i></a>
</div>
</div>
<div class="panel-body">
<!-- Status Alert -->
{% if object.status == 'open' %}
<div class="alert alert-warning">
<h5 class="alert-heading">
<i class="fa fa-clock me-2"></i>
Incident Open - Investigation Required
</h5>
<p class="mb-0">
This incident is currently open and requires investigation. Please review the details and take appropriate action.
</p>
</div>
{% elif object.status == 'investigating' %}
<div class="alert alert-info">
<h5 class="alert-heading">
<i class="fa fa-search me-2"></i>
Investigation in Progress
</h5>
<p class="mb-0">
This incident is currently under investigation. Investigation started on {{ object.investigation_started_at|date:"M d, Y H:i" }}.
</p>
</div>
{% elif object.status == 'resolved' %}
<div class="alert alert-success">
<h5 class="alert-heading">
<i class="fa fa-check-circle me-2"></i>
Incident Resolved
</h5>
<p class="mb-0">
This incident has been resolved on {{ object.resolved_at|date:"M d, Y H:i" }}. Resolution: {{ object.resolution_summary|truncatechars:100 }}
</p>
</div>
{% elif object.status == 'closed' %}
<div class="alert alert-secondary">
<h5 class="alert-heading">
<i class="fa fa-archive me-2"></i>
Incident Closed
</h5>
<p class="mb-0">
This incident has been closed on {{ object.closed_at|date:"M d, Y H:i" }}. All corrective actions have been completed.
</p>
</div>
{% endif %}
<!-- Incident Information -->
<div class="card border-primary mb-4">
<div class="card-header bg-primary text-white">
<h6 class="card-title mb-0">
<i class="fa fa-info-circle me-2"></i>Incident Information
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div class="mb-2">
<strong>Incident Number:</strong> {{ object.incident_number }}
</div>
<div class="mb-2">
<strong>Title:</strong> {{ object.title }}
</div>
<div class="mb-2">
<strong>Category:</strong> {{ object.get_category_display }}
</div>
<div class="mb-2">
<strong>Type:</strong> {{ object.get_incident_type_display }}
</div>
<div class="mb-2">
<strong>Severity:</strong>
{% if object.severity == 'critical' %}
<span class="badge bg-danger">Critical</span>
{% elif object.severity == 'high' %}
<span class="badge bg-warning text-dark">High</span>
{% elif object.severity == 'medium' %}
<span class="badge bg-info">Medium</span>
{% elif object.severity == 'low' %}
<span class="badge bg-success">Low</span>
{% endif %}
</div>
<div class="mb-2">
<strong>Priority:</strong>
{% if object.priority == 'urgent' %}
<span class="badge bg-danger">Urgent</span>
{% elif object.priority == 'high' %}
<span class="badge bg-warning text-dark">High</span>
{% elif object.priority == 'medium' %}
<span class="badge bg-info">Medium</span>
{% elif object.priority == 'low' %}
<span class="badge bg-success">Low</span>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-2">
<strong>Status:</strong>
{% if object.status == 'open' %}
<span class="badge bg-warning text-dark">Open</span>
{% elif object.status == 'investigating' %}
<span class="badge bg-info">Investigating</span>
{% elif object.status == 'resolved' %}
<span class="badge bg-success">Resolved</span>
{% elif object.status == 'closed' %}
<span class="badge bg-secondary">Closed</span>
{% endif %}
</div>
<div class="mb-2">
<strong>Reported By:</strong> {{ object.reported_by.get_full_name }}
</div>
<div class="mb-2">
<strong>Assigned To:</strong> {{ object.assigned_to.get_full_name|default:"Not assigned" }}
</div>
<div class="mb-2">
<strong>Department:</strong> {{ object.department.name|default:"Not specified" }}
</div>
<div class="mb-2">
<strong>Location:</strong> {{ object.location|default:"Not specified" }}
</div>
<div class="mb-2">
<strong>Occurred At:</strong> {{ object.occurred_at|date:"M d, Y H:i" }}
</div>
</div>
</div>
</div>
</div>
<!-- Description -->
<div class="card border-info mb-4">
<div class="card-header bg-info text-white">
<h6 class="card-title mb-0">
<i class="fa fa-file-text me-2"></i>Description
</h6>
</div>
<div class="card-body">
<p>{{ object.description|linebreaks }}</p>
{% if object.immediate_action_taken %}
<div class="mt-3">
<h6 class="text-info">Immediate Action Taken:</h6>
<p>{{ object.immediate_action_taken|linebreaks }}</p>
</div>
{% endif %}
</div>
</div>
<!-- Patient Impact -->
{% if object.patient_involved %}
<div class="card border-warning mb-4">
<div class="card-header bg-warning text-dark">
<h6 class="card-title mb-0">
<i class="fa fa-user-injured me-2"></i>Patient Impact
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div class="mb-2">
<strong>Patient Involved:</strong>
<span class="badge bg-warning text-dark">Yes</span>
</div>
{% if object.patient %}
<div class="mb-2">
<strong>Patient:</strong> {{ object.patient.get_full_name }}
</div>
<div class="mb-2">
<strong>MRN:</strong> {{ object.patient.medical_record_number }}
</div>
{% endif %}
<div class="mb-2">
<strong>Patient Harm:</strong>
{% if object.patient_harm %}
<span class="badge bg-danger">Yes</span>
{% else %}
<span class="badge bg-success">No</span>
{% endif %}
</div>
</div>
<div class="col-md-6">
{% if object.harm_level %}
<div class="mb-2">
<strong>Harm Level:</strong> {{ object.get_harm_level_display }}
</div>
{% endif %}
{% if object.patient_notified %}
<div class="mb-2">
<strong>Patient Notified:</strong>
<span class="badge bg-success">Yes</span>
</div>
{% endif %}
</div>
</div>
{% if object.patient_impact_description %}
<div class="mt-3">
<h6 class="text-warning">Impact Description:</h6>
<p>{{ object.patient_impact_description|linebreaks }}</p>
</div>
{% endif %}
</div>
</div>
{% endif %}
<!-- Investigation Details -->
{% if object.status == 'investigating' or object.status == 'resolved' or object.status == 'closed' %}
<div class="card border-success mb-4">
<div class="card-header bg-success text-white">
<h6 class="card-title mb-0">
<i class="fa fa-search me-2"></i>Investigation Details
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
{% if object.investigation_started_at %}
<div class="mb-2">
<strong>Investigation Started:</strong> {{ object.investigation_started_at|date:"M d, Y H:i" }}
</div>
{% endif %}
{% if object.investigator %}
<div class="mb-2">
<strong>Investigator:</strong> {{ object.investigator.get_full_name }}
</div>
{% endif %}
{% if object.root_cause_analysis %}
<div class="mb-2">
<strong>RCA Performed:</strong>
<span class="badge bg-success">Yes</span>
</div>
{% endif %}
</div>
<div class="col-md-6">
{% if object.investigation_completed_at %}
<div class="mb-2">
<strong>Investigation Completed:</strong> {{ object.investigation_completed_at|date:"M d, Y H:i" }}
</div>
{% endif %}
{% if object.external_reporting_required %}
<div class="mb-2">
<strong>External Reporting:</strong>
<span class="badge bg-warning text-dark">Required</span>
</div>
{% endif %}
</div>
</div>
{% if object.investigation_findings %}
<div class="mt-3">
<h6 class="text-success">Investigation Findings:</h6>
<p>{{ object.investigation_findings|linebreaks }}</p>
</div>
{% endif %}
{% if object.root_cause %}
<div class="mt-3">
<h6 class="text-success">Root Cause:</h6>
<p>{{ object.root_cause|linebreaks }}</p>
</div>
{% endif %}
{% if object.contributing_factors %}
<div class="mt-3">
<h6 class="text-success">Contributing Factors:</h6>
<p>{{ object.contributing_factors|linebreaks }}</p>
</div>
{% endif %}
</div>
</div>
{% endif %}
<!-- Resolution -->
{% if object.status == 'resolved' or object.status == 'closed' %}
<div class="card border-primary mb-4">
<div class="card-header bg-primary text-white">
<h6 class="card-title mb-0">
<i class="fa fa-check-circle me-2"></i>Resolution
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
{% if object.resolved_at %}
<div class="mb-2">
<strong>Resolved At:</strong> {{ object.resolved_at|date:"M d, Y H:i" }}
</div>
{% endif %}
{% if object.resolved_by %}
<div class="mb-2">
<strong>Resolved By:</strong> {{ object.resolved_by.get_full_name }}
</div>
{% endif %}
</div>
<div class="col-md-6">
{% if object.closed_at %}
<div class="mb-2">
<strong>Closed At:</strong> {{ object.closed_at|date:"M d, Y H:i" }}
</div>
{% endif %}
{% if object.closed_by %}
<div class="mb-2">
<strong>Closed By:</strong> {{ object.closed_by.get_full_name }}
</div>
{% endif %}
</div>
</div>
{% if object.resolution_summary %}
<div class="mt-3">
<h6 class="text-primary">Resolution Summary:</h6>
<p>{{ object.resolution_summary|linebreaks }}</p>
</div>
{% endif %}
{% if object.lessons_learned %}
<div class="mt-3">
<h6 class="text-primary">Lessons Learned:</h6>
<p>{{ object.lessons_learned|linebreaks }}</p>
</div>
{% endif %}
</div>
</div>
{% endif %}
<!-- Corrective Actions -->
{% if object.corrective_actions.exists %}
<div class="card border-warning mb-4">
<div class="card-header bg-warning text-dark">
<h6 class="card-title mb-0">
<i class="fa fa-tasks me-2"></i>Corrective Actions
</h6>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-sm">
<thead>
<tr>
<th>Action</th>
<th>Assigned To</th>
<th>Due Date</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for action in object.corrective_actions.all %}
<tr>
<td>
<div class="fw-bold">{{ action.title }}</div>
<div class="small text-muted">{{ action.description|truncatechars:50 }}</div>
</td>
<td>{{ action.assigned_to.get_full_name|default:"Not assigned" }}</td>
<td>
{% if action.due_date %}
{{ action.due_date|date:"M d, Y" }}
{% if action.due_date < today %}
<span class="badge bg-danger ms-1">Overdue</span>
{% endif %}
{% else %}
<span class="text-muted">Not set</span>
{% endif %}
</td>
<td>
{% if action.status == 'pending' %}
<span class="badge bg-warning text-dark">Pending</span>
{% elif action.status == 'in_progress' %}
<span class="badge bg-info">In Progress</span>
{% elif action.status == 'completed' %}
<span class="badge bg-success">Completed</span>
{% elif action.status == 'cancelled' %}
<span class="badge bg-secondary">Cancelled</span>
{% endif %}
</td>
<td>
<a href="{% url 'quality:corrective_action_detail' action.pk %}"
class="btn btn-xs btn-outline-primary">
<i class="fa fa-eye"></i>
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endif %}
<!-- Attachments -->
{% if object.attachments.exists %}
<div class="card border-secondary mb-4">
<div class="card-header bg-secondary text-white">
<h6 class="card-title mb-0">
<i class="fa fa-paperclip me-2"></i>Attachments
</h6>
</div>
<div class="card-body">
<div class="row">
{% for attachment in object.attachments.all %}
<div class="col-md-6 mb-2">
<div class="d-flex align-items-center">
<i class="fa fa-file me-2"></i>
<a href="{{ attachment.file.url }}" target="_blank" class="text-decoration-none">
{{ attachment.filename }}
</a>
<span class="badge bg-light text-dark ms-2">{{ attachment.file_size|filesizeformat }}</span>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
{% endif %}
<!-- Action Buttons -->
<div class="d-flex justify-content-between">
<div>
<a href="{% url 'quality:incident_list' %}" class="btn btn-secondary">
<i class="fa fa-arrow-left me-2"></i>Back to List
</a>
</div>
<div>
{% if object.status == 'open' %}
<button type="button" class="btn btn-info me-2" onclick="startInvestigation()">
<i class="fa fa-search me-2"></i>Start Investigation
</button>
{% endif %}
{% if object.status == 'investigating' %}
<button type="button" class="btn btn-success me-2" onclick="resolveIncident()">
<i class="fa fa-check me-2"></i>Resolve Incident
</button>
{% endif %}
{% if object.status == 'resolved' %}
<button type="button" class="btn btn-secondary me-2" onclick="closeIncident()">
<i class="fa fa-archive me-2"></i>Close Incident
</button>
{% endif %}
<button type="button" class="btn btn-warning me-2" onclick="createCorrectiveAction()">
<i class="fa fa-plus me-2"></i>Add Corrective Action
</button>
<a href="{% url 'quality:incident_edit' object.pk %}" class="btn btn-primary">
<i class="fa fa-edit me-2"></i>Edit
</a>
</div>
</div>
</div>
</div>
<!-- END panel -->
</div>
<div class="col-xl-4">
<!-- BEGIN panel -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Incident Timeline</h4>
</div>
<div class="panel-body">
<div class="timeline">
<div class="timeline-item">
<div class="timeline-marker bg-primary"></div>
<div class="timeline-content">
<h6 class="timeline-title">Incident Reported</h6>
<p class="timeline-text">{{ object.created_at|date:"M d, Y H:i" }}</p>
<p class="timeline-text small text-muted">By {{ object.reported_by.get_full_name }}</p>
</div>
</div>
{% if object.investigation_started_at %}
<div class="timeline-item">
<div class="timeline-marker bg-info"></div>
<div class="timeline-content">
<h6 class="timeline-title">Investigation Started</h6>
<p class="timeline-text">{{ object.investigation_started_at|date:"M d, Y H:i" }}</p>
{% if object.investigator %}
<p class="timeline-text small text-muted">By {{ object.investigator.get_full_name }}</p>
{% endif %}
</div>
</div>
{% endif %}
{% if object.investigation_completed_at %}
<div class="timeline-item">
<div class="timeline-marker bg-warning"></div>
<div class="timeline-content">
<h6 class="timeline-title">Investigation Completed</h6>
<p class="timeline-text">{{ object.investigation_completed_at|date:"M d, Y H:i" }}</p>
</div>
</div>
{% endif %}
{% if object.resolved_at %}
<div class="timeline-item">
<div class="timeline-marker bg-success"></div>
<div class="timeline-content">
<h6 class="timeline-title">Incident Resolved</h6>
<p class="timeline-text">{{ object.resolved_at|date:"M d, Y H:i" }}</p>
{% if object.resolved_by %}
<p class="timeline-text small text-muted">By {{ object.resolved_by.get_full_name }}</p>
{% endif %}
</div>
</div>
{% endif %}
{% if object.closed_at %}
<div class="timeline-item">
<div class="timeline-marker bg-secondary"></div>
<div class="timeline-content">
<h6 class="timeline-title">Incident Closed</h6>
<p class="timeline-text">{{ object.closed_at|date:"M d, Y H:i" }}</p>
{% if object.closed_by %}
<p class="timeline-text small text-muted">By {{ object.closed_by.get_full_name }}</p>
{% endif %}
</div>
</div>
{% endif %}
</div>
</div>
</div>
<!-- END panel -->
<!-- BEGIN panel -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Quick Actions</h4>
</div>
<div class="panel-body">
<div class="d-grid gap-2">
{% if object.status == 'open' %}
<button type="button" class="btn btn-outline-info" onclick="startInvestigation()">
<i class="fa fa-search me-2"></i>Start Investigation
</button>
{% endif %}
{% if object.status == 'investigating' %}
<button type="button" class="btn btn-outline-success" onclick="resolveIncident()">
<i class="fa fa-check me-2"></i>Resolve Incident
</button>
{% endif %}
{% if object.status == 'resolved' %}
<button type="button" class="btn btn-outline-secondary" onclick="closeIncident()">
<i class="fa fa-archive me-2"></i>Close Incident
</button>
{% endif %}
<button type="button" class="btn btn-outline-warning" onclick="createCorrectiveAction()">
<i class="fa fa-plus me-2"></i>Add Corrective Action
</button>
<button type="button" class="btn btn-outline-primary" onclick="escalateIncident()">
<i class="fa fa-arrow-up me-2"></i>Escalate
</button>
<button type="button" class="btn btn-outline-info" onclick="printIncident()">
<i class="fa fa-print me-2"></i>Print Report
</button>
<button type="button" class="btn btn-outline-secondary" onclick="shareIncident()">
<i class="fa fa-share me-2"></i>Share
</button>
</div>
</div>
</div>
<!-- END panel -->
<!-- BEGIN panel -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Incident Statistics</h4>
</div>
<div class="panel-body">
<div class="list-group list-group-flush">
<div class="list-group-item d-flex justify-content-between align-items-center">
<span>Days Open</span>
<span class="badge bg-primary">{{ object.days_open }}</span>
</div>
{% if object.corrective_actions.exists %}
<div class="list-group-item d-flex justify-content-between align-items-center">
<span>Corrective Actions</span>
<span class="badge bg-warning text-dark">{{ object.corrective_actions.count }}</span>
</div>
{% endif %}
{% if object.attachments.exists %}
<div class="list-group-item d-flex justify-content-between align-items-center">
<span>Attachments</span>
<span class="badge bg-info">{{ object.attachments.count }}</span>
</div>
{% endif %}
<div class="list-group-item d-flex justify-content-between align-items-center">
<span>Last Updated</span>
<span class="small text-muted">{{ object.updated_at|date:"M d, Y" }}</span>
</div>
</div>
</div>
</div>
<!-- END panel -->
<!-- BEGIN panel -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Contact Information</h4>
</div>
<div class="panel-body">
<div class="small">
<div class="mb-2">
<strong>Quality Manager:</strong><br>
<i class="fa fa-phone me-1"></i> (555) 123-4567<br>
<i class="fa fa-envelope me-1"></i> quality@hospital.com
</div>
<div class="mb-2">
<strong>Risk Management:</strong><br>
<i class="fa fa-phone me-1"></i> (555) 123-4568<br>
<i class="fa fa-envelope me-1"></i> risk@hospital.com
</div>
<div class="mb-2">
<strong>Patient Safety:</strong><br>
<i class="fa fa-phone me-1"></i> (555) 123-4569<br>
<i class="fa fa-envelope me-1"></i> safety@hospital.com
</div>
</div>
</div>
</div>
<!-- END panel -->
</div>
</div>
{% endblock %}
{% block js %}
<script>
$(document).ready(function() {
// Initialize tooltips
$('[data-bs-toggle="tooltip"]').tooltip();
});
function startInvestigation() {
if (confirm('Are you sure you want to start the investigation for this incident?')) {
$.ajax({
url: '{% url "quality:start_investigation" object.pk %}',
method: 'POST',
data: {
'csrfmiddlewaretoken': '{{ csrf_token }}'
},
success: function(response) {
toastr.success('Investigation started successfully');
location.reload();
},
error: function() {
toastr.error('Failed to start investigation');
}
});
}
}
function resolveIncident() {
// Implementation for resolving incident
window.location.href = '{% url "quality:resolve_incident" object.pk %}';
}
function closeIncident() {
if (confirm('Are you sure you want to close this incident? This action cannot be undone.')) {
$.ajax({
url: '{% url "quality:close_incident" object.pk %}',
method: 'POST',
data: {
'csrfmiddlewaretoken': '{{ csrf_token }}'
},
success: function(response) {
toastr.success('Incident closed successfully');
location.reload();
},
error: function() {
toastr.error('Failed to close incident');
}
});
}
}
function createCorrectiveAction() {
window.location.href = '{% url "quality:corrective_action_create" %}?incident={{ object.pk }}';
}
function escalateIncident() {
// Implementation for escalating incident
toastr.info('Incident escalation feature coming soon');
}
function printIncident() {
var printUrl = '{% url "quality:print_incident" object.pk %}';
window.open(printUrl, '_blank');
}
function shareIncident() {
// Implementation for sharing incident
toastr.info('Incident sharing feature coming soon');
}
</script>
{% endblock %}