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

494 lines
22 KiB
HTML

{% extends "base.html" %}
{% load static %}
{% block title %}Incident Report Details - 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_report_list' %}">Incident Reports</a></li>
<li class="breadcrumb-item active">{{ object.report_number }}</li>
</ol>
<!-- END breadcrumb -->
<!-- BEGIN page-header -->
<h1 class="page-header">
Incident Report Details
<small>{{ object.report_number }}</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">
<i class="fa fa-file-alt me-2"></i>
{{ object.title }}
</h4>
<div class="panel-heading-btn">
<a href="{% url 'quality:incident_report_edit' object.pk %}" class="btn btn-sm btn-primary">
<i class="fa fa-edit me-1"></i>Edit
</a>
<a href="{% url 'quality:incident_report_print' object.pk %}" class="btn btn-sm btn-secondary" target="_blank">
<i class="fa fa-print me-1"></i>Print
</a>
</div>
</div>
<div class="panel-body">
<!-- Report Status and Priority -->
<div class="row mb-4">
<div class="col-md-6">
<div class="d-flex align-items-center mb-2">
<strong class="me-2">Status:</strong>
{% if object.status == 'draft' %}
<span class="badge bg-secondary">Draft</span>
{% elif object.status == 'submitted' %}
<span class="badge bg-warning text-dark">Submitted</span>
{% elif object.status == 'under_review' %}
<span class="badge bg-info">Under Review</span>
{% elif object.status == 'approved' %}
<span class="badge bg-success">Approved</span>
{% elif object.status == 'rejected' %}
<span class="badge bg-danger">Rejected</span>
{% endif %}
</div>
<div class="d-flex align-items-center mb-2">
<strong class="me-2">Priority:</strong>
{% if object.priority == 'critical' %}
<span class="badge bg-danger">Critical</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>Report Number:</strong> {{ object.report_number }}
</div>
<div class="mb-2">
<strong>Created:</strong> {{ object.created_at|date:"M d, Y H:i" }}
</div>
</div>
</div>
<!-- Report Content -->
<div class="card border-primary mb-4">
<div class="card-header bg-primary text-white">
<h6 class="card-title mb-0">Report Content</h6>
</div>
<div class="card-body">
<div class="mb-3">
<strong>Description:</strong>
<div class="mt-2">{{ object.description|linebreaks }}</div>
</div>
{% if object.findings %}
<div class="mb-3">
<strong>Findings:</strong>
<div class="mt-2">{{ object.findings|linebreaks }}</div>
</div>
{% endif %}
{% if object.recommendations %}
<div class="mb-3">
<strong>Recommendations:</strong>
<div class="mt-2">{{ object.recommendations|linebreaks }}</div>
</div>
{% endif %}
</div>
</div>
<!-- Related Incidents -->
{% if object.related_incidents.exists %}
<div class="card border-info mb-4">
<div class="card-header bg-info text-white">
<h6 class="card-title mb-0">Related Incidents</h6>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-sm">
<thead>
<tr>
<th>Incident Number</th>
<th>Title</th>
<th>Status</th>
<th>Severity</th>
<th>Date</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for incident in object.related_incidents.all %}
<tr>
<td>{{ incident.incident_number }}</td>
<td>{{ incident.title|truncatechars:40 }}</td>
<td>
{% if incident.status == 'open' %}
<span class="badge bg-warning text-dark">Open</span>
{% elif incident.status == 'investigating' %}
<span class="badge bg-info">Investigating</span>
{% elif incident.status == 'resolved' %}
<span class="badge bg-success">Resolved</span>
{% elif incident.status == 'closed' %}
<span class="badge bg-secondary">Closed</span>
{% endif %}
</td>
<td>
{% if incident.severity == 'critical' %}
<span class="badge bg-danger">Critical</span>
{% elif incident.severity == 'high' %}
<span class="badge bg-warning text-dark">High</span>
{% elif incident.severity == 'medium' %}
<span class="badge bg-info">Medium</span>
{% elif incident.severity == 'low' %}
<span class="badge bg-success">Low</span>
{% endif %}
</td>
<td>{{ incident.occurred_at|date:"M d, Y" }}</td>
<td>
<a href="{% url 'quality:incident_detail' incident.pk %}" class="btn btn-sm 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">Attachments</h6>
</div>
<div class="card-body">
<div class="row">
{% for attachment in object.attachments.all %}
<div class="col-md-6 mb-3">
<div class="card">
<div class="card-body">
<h6 class="card-title">{{ attachment.name }}</h6>
<p class="card-text small text-muted">
Size: {{ attachment.file.size|filesizeformat }}<br>
Uploaded: {{ attachment.uploaded_at|date:"M d, Y H:i" }}
</p>
<a href="{{ attachment.file.url }}" class="btn btn-sm btn-primary" target="_blank">
<i class="fa fa-download me-1"></i>Download
</a>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
{% endif %}
<!-- Review History -->
{% if object.review_history.exists %}
<div class="card border-warning mb-4">
<div class="card-header bg-warning text-dark">
<h6 class="card-title mb-0">Review History</h6>
</div>
<div class="card-body">
<div class="timeline">
{% for review in object.review_history.all %}
<div class="timeline-item">
<div class="timeline-marker"></div>
<div class="timeline-content">
<h6 class="timeline-title">
{{ review.action }} by {{ review.reviewer.get_full_name }}
</h6>
<p class="timeline-text">{{ review.comments }}</p>
<small class="text-muted">{{ review.created_at|date:"M d, Y H:i" }}</small>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
{% endif %}
</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">Report Information</h4>
</div>
<div class="panel-body">
<div class="mb-3">
<strong>Author:</strong><br>
{{ object.author.get_full_name }}<br>
<small class="text-muted">{{ object.author.email }}</small>
</div>
<div class="mb-3">
<strong>Department:</strong><br>
{{ object.department.name|default:"Not specified" }}
</div>
<div class="mb-3">
<strong>Report Type:</strong><br>
{{ object.get_report_type_display }}
</div>
<div class="mb-3">
<strong>Reporting Period:</strong><br>
{{ object.period_start|date:"M d, Y" }} - {{ object.period_end|date:"M d, Y" }}
</div>
{% if object.reviewer %}
<div class="mb-3">
<strong>Reviewer:</strong><br>
{{ object.reviewer.get_full_name }}<br>
<small class="text-muted">{{ object.reviewer.email }}</small>
</div>
{% endif %}
{% if object.approved_at %}
<div class="mb-3">
<strong>Approved:</strong><br>
{{ object.approved_at|date:"M d, Y H:i" }}
</div>
{% endif %}
<div class="mb-3">
<strong>Last Modified:</strong><br>
{{ object.updated_at|date:"M d, Y H:i" }}
</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 == 'draft' %}
<button type="button" class="btn btn-primary" onclick="submitReport()">
<i class="fa fa-paper-plane me-2"></i>Submit for Review
</button>
{% elif object.status == 'submitted' and user.has_perm:'quality.review_incident_report' %}
<button type="button" class="btn btn-info" onclick="startReview()">
<i class="fa fa-search me-2"></i>Start Review
</button>
{% elif object.status == 'under_review' and user.has_perm:'quality.approve_incident_report' %}
<button type="button" class="btn btn-success" onclick="approveReport()">
<i class="fa fa-check me-2"></i>Approve Report
</button>
<button type="button" class="btn btn-danger" onclick="rejectReport()">
<i class="fa fa-times me-2"></i>Reject Report
</button>
{% endif %}
<a href="{% url 'quality:incident_report_edit' object.pk %}" class="btn btn-outline-primary">
<i class="fa fa-edit me-2"></i>Edit Report
</a>
<button type="button" class="btn btn-outline-secondary" onclick="duplicateReport()">
<i class="fa fa-copy me-2"></i>Duplicate Report
</button>
<a href="{% url 'quality:incident_report_export' object.pk %}" class="btn btn-outline-info">
<i class="fa fa-download me-2"></i>Export PDF
</a>
{% if user.has_perm:'quality.delete_incident_report' %}
<a href="{% url 'quality:incident_report_delete' object.pk %}" class="btn btn-outline-danger">
<i class="fa fa-trash me-2"></i>Delete Report
</a>
{% endif %}
</div>
</div>
</div>
<!-- END panel -->
<!-- BEGIN panel -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Statistics</h4>
</div>
<div class="panel-body">
<div class="row text-center">
<div class="col-6">
<div class="mb-2">
<div class="h4 mb-0">{{ object.related_incidents.count }}</div>
<div class="small text-muted">Related Incidents</div>
</div>
</div>
<div class="col-6">
<div class="mb-2">
<div class="h4 mb-0">{{ object.attachments.count }}</div>
<div class="small text-muted">Attachments</div>
</div>
</div>
</div>
<div class="row text-center mt-3">
<div class="col-6">
<div class="mb-2">
<div class="h4 mb-0">{{ object.review_history.count }}</div>
<div class="small text-muted">Reviews</div>
</div>
</div>
<div class="col-6">
<div class="mb-2">
<div class="h4 mb-0">{{ object.days_since_created }}</div>
<div class="small text-muted">Days Old</div>
</div>
</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>Report Author:</strong><br>
<i class="fa fa-user me-1"></i> {{ object.author.get_full_name }}<br>
<i class="fa fa-envelope me-1"></i> {{ object.author.email }}
</div>
</div>
</div>
</div>
<!-- END panel -->
</div>
</div>
{% endblock %}
{% block js %}
<script>
function submitReport() {
if (confirm('Submit this report for review? You will not be able to edit it after submission.')) {
$.ajax({
url: '{% url "quality:submit_incident_report" object.pk %}',
method: 'POST',
data: {
'csrfmiddlewaretoken': '{{ csrf_token }}'
},
success: function(response) {
toastr.success('Report submitted for review');
location.reload();
},
error: function() {
toastr.error('Failed to submit report');
}
});
}
}
function startReview() {
if (confirm('Start reviewing this report?')) {
$.ajax({
url: '{% url "quality:start_review_incident_report" object.pk %}',
method: 'POST',
data: {
'csrfmiddlewaretoken': '{{ csrf_token }}'
},
success: function(response) {
toastr.success('Review started');
location.reload();
},
error: function() {
toastr.error('Failed to start review');
}
});
}
}
function approveReport() {
var comments = prompt('Enter approval comments (optional):');
if (comments !== null) {
$.ajax({
url: '{% url "quality:approve_incident_report" object.pk %}',
method: 'POST',
data: {
'csrfmiddlewaretoken': '{{ csrf_token }}',
'comments': comments
},
success: function(response) {
toastr.success('Report approved');
location.reload();
},
error: function() {
toastr.error('Failed to approve report');
}
});
}
}
function rejectReport() {
var reason = prompt('Enter rejection reason:');
if (reason && reason.trim()) {
$.ajax({
url: '{% url "quality:reject_incident_report" object.pk %}',
method: 'POST',
data: {
'csrfmiddlewaretoken': '{{ csrf_token }}',
'reason': reason
},
success: function(response) {
toastr.success('Report rejected');
location.reload();
},
error: function() {
toastr.error('Failed to reject report');
}
});
} else {
toastr.warning('Rejection reason is required');
}
}
function duplicateReport() {
if (confirm('Create a duplicate of this report?')) {
$.ajax({
url: '{% url "quality:duplicate_incident_report" object.pk %}',
method: 'POST',
data: {
'csrfmiddlewaretoken': '{{ csrf_token }}'
},
success: function(response) {
toastr.success('Report duplicated');
window.location.href = response.redirect_url;
},
error: function() {
toastr.error('Failed to duplicate report');
}
});
}
}
</script>
{% endblock %}