582 lines
27 KiB
HTML
582 lines
27 KiB
HTML
{% extends "base.html" %}
|
|
{% load static %}
|
|
|
|
{% block title %}Surgical Case Details - Operating Theatre{% endblock %}
|
|
|
|
{% block css %}
|
|
<link href="{% static 'assets/plugins/fullcalendar/dist/main.min.css' %}" rel="stylesheet" />
|
|
{% 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 'operating_theatre:dashboard' %}">Operating Theatre</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'operating_theatre:surgical_case_list' %}">Surgical Cases</a></li>
|
|
<li class="breadcrumb-item active">Case Details</li>
|
|
</ol>
|
|
<!-- END breadcrumb -->
|
|
|
|
<!-- BEGIN page-header -->
|
|
<h1 class="page-header">
|
|
Surgical Case Details
|
|
<small>{{ object.case_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">Case Information</h4>
|
|
<div class="panel-heading-btn">
|
|
<a href="{% url 'operating_theatre:surgical_case_update' object.pk %}" class="btn btn-xs btn-warning me-2">
|
|
<i class="fa fa-edit"></i> Edit Case
|
|
</a>
|
|
<button class="btn btn-xs btn-info me-2" onclick="printCase()">
|
|
<i class="fa fa-print"></i> Print
|
|
</button>
|
|
<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">
|
|
<!-- Case Status Alert -->
|
|
{% if object.status == 'SCHEDULED' %}
|
|
<div class="alert alert-info">
|
|
<i class="fa fa-calendar me-2"></i>
|
|
<strong>Scheduled:</strong> This case is scheduled for {{ object.scheduled_start_time|date:"M d, Y" }} at {{ object.scheduled_start_time|time:"H:i" }}
|
|
</div>
|
|
{% elif object.status == 'IN_PROGRESS' %}
|
|
<div class="alert alert-warning">
|
|
<i class="fa fa-clock me-2"></i>
|
|
<strong>In Progress:</strong> Surgery started at {{ object.actual_start_time|time:"H:i" }}
|
|
</div>
|
|
{% elif object.status == 'COMPLETED' %}
|
|
<div class="alert alert-success">
|
|
<i class="fa fa-check me-2"></i>
|
|
<strong>Completed:</strong> Surgery completed on {{ object.actual_end_time|date:"M d, Y" }} at {{ object.actual_end_time|time:"H:i" }}
|
|
</div>
|
|
{% elif object.status == 'CANCELLED' %}
|
|
<div class="alert alert-danger">
|
|
<i class="fa fa-times me-2"></i>
|
|
<strong>Cancelled:</strong> {{ object.cancellation_reason }}
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Patient Information -->
|
|
<h6 class="border-bottom pb-2 mb-3">Patient Information</h6>
|
|
<div class="row mb-4">
|
|
<div class="col-md-6">
|
|
<table class="table table-borderless">
|
|
<tr>
|
|
<td class="fw-bold" width="150">Patient Name:</td>
|
|
<td>{{ object.patient.get_full_name }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Patient ID:</td>
|
|
<td>{{ object.patient.patient_id }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Date of Birth:</td>
|
|
<td>{{ object.patient.date_of_birth|date:"M d, Y" }} ({{ object.patient.age }} years)</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Gender:</td>
|
|
<td>{{ object.patient.get_gender_display }}</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<table class="table table-borderless">
|
|
<tr>
|
|
<td class="fw-bold" width="150">Blood Type:</td>
|
|
<td>{{ object.patient.blood_type|default:"Not specified" }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Allergies:</td>
|
|
<td>{{ object.patient.allergies|default:"None known" }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Emergency Contact:</td>
|
|
<td>{{ object.patient.emergency_contact_name|default:"Not specified" }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Contact Phone:</td>
|
|
<td>{{ object.patient.emergency_contact_phone|default:"Not specified" }}</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Surgery Information -->
|
|
<h6 class="border-bottom pb-2 mb-3">Surgery Information</h6>
|
|
<div class="row mb-4">
|
|
<div class="col-md-6">
|
|
<table class="table table-borderless">
|
|
<tr>
|
|
<td class="fw-bold" width="150">Case Number:</td>
|
|
<td><code>{{ object.case_number }}</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Procedure:</td>
|
|
<td>{{ object.procedure_name }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Procedure Code:</td>
|
|
<td><code>{{ object.procedure_code }}</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Surgery Type:</td>
|
|
<td>{{ object.get_surgery_type_display }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Priority:</td>
|
|
<td>
|
|
<span class="badge bg-{% if object.priority == 'EMERGENCY' %}danger{% elif object.priority == 'URGENT' %}warning{% else %}primary{% endif %}">
|
|
{{ object.get_priority_display }}
|
|
</span>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<table class="table table-borderless">
|
|
<tr>
|
|
<td class="fw-bold" width="150">Operating Room:</td>
|
|
<td>{{ object.operating_room.name }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Primary Surgeon:</td>
|
|
<td>{{ object.primary_surgeon.get_full_name }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Anesthesiologist:</td>
|
|
<td>{{ object.anesthesiologist.get_full_name|default:"Not assigned" }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Estimated Duration:</td>
|
|
<td>{{ object.estimated_duration }} minutes</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Status:</td>
|
|
<td>
|
|
<span class="badge bg-{% if object.status == 'SCHEDULED' %}info{% elif object.status == 'IN_PROGRESS' %}warning{% elif object.status == 'COMPLETED' %}success{% elif object.status == 'CANCELLED' %}danger{% else %}secondary{% endif %}">
|
|
{{ object.get_status_display }}
|
|
</span>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Scheduling Information -->
|
|
<h6 class="border-bottom pb-2 mb-3">Scheduling Information</h6>
|
|
<div class="row mb-4">
|
|
<div class="col-md-6">
|
|
<table class="table table-borderless">
|
|
<tr>
|
|
<td class="fw-bold" width="150">Scheduled Date:</td>
|
|
<td>{{ object.scheduled_start_time|date:"M d, Y" }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Scheduled Start:</td>
|
|
<td>{{ object.scheduled_start_time|time:"H:i" }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Scheduled End:</td>
|
|
<td>{{ object.scheduled_end_time|time:"H:i" }}</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="col-md-6">
|
|
{% if object.actual_start_time %}
|
|
<table class="table table-borderless">
|
|
<tr>
|
|
<td class="fw-bold" width="150">Actual Start:</td>
|
|
<td>{{ object.actual_start_time|time:"H:i" }}</td>
|
|
</tr>
|
|
{% if object.actual_end_time %}
|
|
<tr>
|
|
<td class="fw-bold">Actual End:</td>
|
|
<td>{{ object.actual_end_time|time:"H:i" }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Actual Duration:</td>
|
|
<td>{{ object.actual_duration }} minutes</td>
|
|
</tr>
|
|
{% endif %}
|
|
</table>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Surgical Team -->
|
|
<h6 class="border-bottom pb-2 mb-3">Surgical Team</h6>
|
|
<div class="row mb-4">
|
|
<div class="col-md-12">
|
|
<div class="table-responsive">
|
|
<table class="table table-striped">
|
|
<thead>
|
|
<tr>
|
|
<th>Role</th>
|
|
<th>Name</th>
|
|
<th>Department</th>
|
|
<th>Contact</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><span class="badge bg-primary">Primary Surgeon</span></td>
|
|
<td>{{ object.primary_surgeon.get_full_name }}</td>
|
|
<td>{{ object.primary_surgeon.department.name }}</td>
|
|
<td>{{ object.primary_surgeon.phone|default:"--" }}</td>
|
|
</tr>
|
|
{% if object.anesthesiologist %}
|
|
<tr>
|
|
<td><span class="badge bg-info">Anesthesiologist</span></td>
|
|
<td>{{ object.anesthesiologist.get_full_name }}</td>
|
|
<td>{{ object.anesthesiologist.department.name }}</td>
|
|
<td>{{ object.anesthesiologist.phone|default:"--" }}</td>
|
|
</tr>
|
|
{% endif %}
|
|
{% for team_member in object.surgical_team.all %}
|
|
<tr>
|
|
<td><span class="badge bg-secondary">{{ team_member.role }}</span></td>
|
|
<td>{{ team_member.staff_member.get_full_name }}</td>
|
|
<td>{{ team_member.staff_member.department.name }}</td>
|
|
<td>{{ team_member.staff_member.phone|default:"--" }}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Clinical Notes -->
|
|
{% if object.pre_operative_notes or object.operative_notes or object.post_operative_notes %}
|
|
<h6 class="border-bottom pb-2 mb-3">Clinical Notes</h6>
|
|
<div class="row mb-4">
|
|
{% if object.pre_operative_notes %}
|
|
<div class="col-md-4">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h6 class="card-title mb-0">Pre-operative Notes</h6>
|
|
</div>
|
|
<div class="card-body">
|
|
<p class="card-text">{{ object.pre_operative_notes|linebreaks }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
{% if object.operative_notes %}
|
|
<div class="col-md-4">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h6 class="card-title mb-0">Operative Notes</h6>
|
|
</div>
|
|
<div class="card-body">
|
|
<p class="card-text">{{ object.operative_notes|linebreaks }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
{% if object.post_operative_notes %}
|
|
<div class="col-md-4">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h6 class="card-title mb-0">Post-operative Notes</h6>
|
|
</div>
|
|
<div class="card-body">
|
|
<p class="card-text">{{ object.post_operative_notes|linebreaks }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Equipment and Supplies -->
|
|
{% if object.equipment_used.all or object.supplies_used.all %}
|
|
<h6 class="border-bottom pb-2 mb-3">Equipment & Supplies</h6>
|
|
<div class="row mb-4">
|
|
{% if object.equipment_used.all %}
|
|
<div class="col-md-6">
|
|
<h6>Equipment Used</h6>
|
|
<div class="list-group">
|
|
{% for equipment in object.equipment_used.all %}
|
|
<div class="list-group-item">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<div class="fw-bold">{{ equipment.name }}</div>
|
|
<div class="small text-muted">{{ equipment.model }} - {{ equipment.serial_number }}</div>
|
|
</div>
|
|
<span class="badge bg-{% if equipment.status == 'AVAILABLE' %}success{% elif equipment.status == 'IN_USE' %}warning{% else %}danger{% endif %}">
|
|
{{ equipment.get_status_display }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
{% if object.supplies_used.all %}
|
|
<div class="col-md-6">
|
|
<h6>Supplies Used</h6>
|
|
<div class="list-group">
|
|
{% for supply in object.supplies_used.all %}
|
|
<div class="list-group-item">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<div class="fw-bold">{{ supply.item.name }}</div>
|
|
<div class="small text-muted">Quantity: {{ supply.quantity_used }}</div>
|
|
</div>
|
|
<div class="text-end">
|
|
<div class="small">Lot: {{ supply.lot_number|default:"--" }}</div>
|
|
<div class="small">Exp: {{ supply.expiry_date|date:"M Y"|default:"--" }}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</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">Quick Actions</h4>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div class="d-grid gap-2">
|
|
{% if object.status == 'SCHEDULED' %}
|
|
<button class="btn btn-success" onclick="startSurgery()">
|
|
<i class="fa fa-play me-2"></i>Start Surgery
|
|
</button>
|
|
<button class="btn btn-warning" onclick="delaySurgery()">
|
|
<i class="fa fa-clock me-2"></i>Delay Surgery
|
|
</button>
|
|
<button class="btn btn-danger" onclick="cancelSurgery()">
|
|
<i class="fa fa-times me-2"></i>Cancel Surgery
|
|
</button>
|
|
{% elif object.status == 'IN_PROGRESS' %}
|
|
<button class="btn btn-success" onclick="completeSurgery()">
|
|
<i class="fa fa-check me-2"></i>Complete Surgery
|
|
</button>
|
|
<button class="btn btn-info" onclick="addOperativeNotes()">
|
|
<i class="fa fa-notes-medical me-2"></i>Add Operative Notes
|
|
</button>
|
|
{% elif object.status == 'COMPLETED' %}
|
|
<button class="btn btn-primary" onclick="generateReport()">
|
|
<i class="fa fa-file-medical me-2"></i>Generate Report
|
|
</button>
|
|
{% endif %}
|
|
|
|
<hr>
|
|
|
|
<a href="{% url 'operating_theatre:surgical_case_update' object.pk %}" class="btn btn-outline-warning">
|
|
<i class="fa fa-edit me-2"></i>Edit Case
|
|
</a>
|
|
<button class="btn btn-outline-info" onclick="printCase()">
|
|
<i class="fa fa-print me-2"></i>Print Case Details
|
|
</button>
|
|
<button class="btn btn-outline-secondary" onclick="exportCase()">
|
|
<i class="fa fa-download me-2"></i>Export Case Data
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- END panel -->
|
|
|
|
<!-- BEGIN panel -->
|
|
<div class="panel panel-inverse">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">Case 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">Case Created</h6>
|
|
<p class="timeline-text">{{ object.created_at|date:"M d, Y H:i" }}</p>
|
|
</div>
|
|
</div>
|
|
|
|
{% if object.scheduled_start_time %}
|
|
<div class="timeline-item">
|
|
<div class="timeline-marker bg-info"></div>
|
|
<div class="timeline-content">
|
|
<h6 class="timeline-title">Scheduled</h6>
|
|
<p class="timeline-text">{{ object.scheduled_start_time|date:"M d, Y H:i" }}</p>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if object.actual_start_time %}
|
|
<div class="timeline-item">
|
|
<div class="timeline-marker bg-warning"></div>
|
|
<div class="timeline-content">
|
|
<h6 class="timeline-title">Surgery Started</h6>
|
|
<p class="timeline-text">{{ object.actual_start_time|date:"M d, Y H:i" }}</p>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if object.actual_end_time %}
|
|
<div class="timeline-item">
|
|
<div class="timeline-marker bg-success"></div>
|
|
<div class="timeline-content">
|
|
<h6 class="timeline-title">Surgery Completed</h6>
|
|
<p class="timeline-text">{{ object.actual_end_time|date:"M d, Y H:i" }}</p>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if object.status == 'CANCELLED' %}
|
|
<div class="timeline-item">
|
|
<div class="timeline-marker bg-danger"></div>
|
|
<div class="timeline-content">
|
|
<h6 class="timeline-title">Surgery Cancelled</h6>
|
|
<p class="timeline-text">{{ object.updated_at|date:"M d, Y H:i" }}</p>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- END panel -->
|
|
|
|
<!-- BEGIN panel -->
|
|
<div class="panel panel-inverse">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">Case Statistics</h4>
|
|
</div>
|
|
<div class="panel-body">
|
|
<table class="table table-borderless table-sm">
|
|
<tr>
|
|
<td class="fw-bold">Created:</td>
|
|
<td>{{ object.created_at|date:"M d, Y H:i" }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Last Updated:</td>
|
|
<td>{{ object.updated_at|date:"M d, Y H:i" }}</td>
|
|
</tr>
|
|
{% if object.actual_duration %}
|
|
<tr>
|
|
<td class="fw-bold">Duration:</td>
|
|
<td>{{ object.actual_duration }} minutes</td>
|
|
</tr>
|
|
{% endif %}
|
|
<tr>
|
|
<td class="fw-bold">Team Size:</td>
|
|
<td>{{ object.surgical_team.count|add:"1" }} members</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Equipment Used:</td>
|
|
<td>{{ object.equipment_used.count }} items</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<!-- END panel -->
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block js %}
|
|
<script>
|
|
function startSurgery() {
|
|
if (confirm('Are you sure you want to start this surgery?')) {
|
|
$.ajax({
|
|
url: '{% url "operating_theatre:surgical_case_start" object.pk %}',
|
|
method: 'POST',
|
|
data: {
|
|
'csrfmiddlewaretoken': '{{ csrf_token }}'
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
toastr.success('Surgery started successfully');
|
|
location.reload();
|
|
} else {
|
|
toastr.error('Failed to start surgery: ' + response.error);
|
|
}
|
|
},
|
|
error: function() {
|
|
toastr.error('An error occurred while starting the surgery');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function completeSurgery() {
|
|
if (confirm('Are you sure you want to complete this surgery?')) {
|
|
$.ajax({
|
|
url: '{% url "operating_theatre:surgical_case_complete" object.pk %}',
|
|
method: 'POST',
|
|
data: {
|
|
'csrfmiddlewaretoken': '{{ csrf_token }}'
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
toastr.success('Surgery completed successfully');
|
|
location.reload();
|
|
} else {
|
|
toastr.error('Failed to complete surgery: ' + response.error);
|
|
}
|
|
},
|
|
error: function() {
|
|
toastr.error('An error occurred while completing the surgery');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function cancelSurgery() {
|
|
var reason = prompt('Please provide a reason for cancellation:');
|
|
if (reason) {
|
|
$.ajax({
|
|
url: '{% url "operating_theatre:surgical_case_cancel" object.pk %}',
|
|
method: 'POST',
|
|
data: {
|
|
'csrfmiddlewaretoken': '{{ csrf_token }}',
|
|
'cancellation_reason': reason
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
toastr.success('Surgery cancelled successfully');
|
|
location.reload();
|
|
} else {
|
|
toastr.error('Failed to cancel surgery: ' + response.error);
|
|
}
|
|
},
|
|
error: function() {
|
|
toastr.error('An error occurred while cancelling the surgery');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function printCase() {
|
|
window.print();
|
|
}
|
|
|
|
function exportCase() {
|
|
window.open('{% url "operating_theatre:surgical_case_export" object.pk %}');
|
|
}
|
|
|
|
function generateReport() {
|
|
window.open('{% url "operating_theatre:surgical_case_report" object.pk %}');
|
|
}
|
|
</script>
|
|
{% endblock %}
|
|
|