hospital-management/templates/blood_bank/requests/blood_request_detail.html
Marwan Alwali 35be20ae4c update
2025-09-06 19:07:14 +03:00

640 lines
26 KiB
HTML

{% extends 'base.html' %}
{% load static %}
{% block title %}Blood Request Details - {{ blood_request.request_number }}{% endblock %}
{% block css %}
<link href="{% static 'plugins/datatables.net-bs5/css/dataTables.bootstrap5.min.css' %}" rel="stylesheet" />
<style>
.request-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-radius: 10px;
padding: 20px;
margin-bottom: 20px;
}
.urgency-emergency {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { opacity: 1; }
50% { opacity: 0.7; }
100% { opacity: 1; }
}
.compatibility-check {
border: 2px solid #e9ecef;
border-radius: 8px;
padding: 15px;
margin-bottom: 15px;
}
.compatibility-check.compatible {
border-color: #28a745;
background-color: #f8fff9;
}
.compatibility-check.incompatible {
border-color: #dc3545;
background-color: #fff8f8;
}
.timeline {
position: relative;
padding-left: 30px;
}
.timeline::before {
content: '';
position: absolute;
left: 15px;
top: 0;
bottom: 0;
width: 2px;
background: #e9ecef;
}
.timeline-item {
position: relative;
margin-bottom: 20px;
}
.timeline-item::before {
content: '';
position: absolute;
left: -23px;
top: 5px;
width: 12px;
height: 12px;
border-radius: 50%;
background: #007bff;
border: 2px solid #fff;
box-shadow: 0 0 0 2px #e9ecef;
}
.timeline-item.current::before {
background: #28a745;
box-shadow: 0 0 0 2px #28a745;
}
</style>
{% endblock %}
{% block content %}
<!-- BEGIN breadcrumb -->
<ol class="breadcrumb float-xl-end">
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Home</a></li>
<li class="breadcrumb-item"><a href="{% url 'blood_bank:dashboard' %}">Blood Bank</a></li>
<li class="breadcrumb-item"><a href="{% url 'blood_bank:blood_request_list' %}">Requests</a></li>
<li class="breadcrumb-item active">{{ blood_request.request_number }}</li>
</ol>
<!-- END breadcrumb -->
<!-- BEGIN page-header -->
<h1 class="page-header">
Blood Request Details
<small>{{ blood_request.request_number }}</small>
</h1>
<!-- END page-header -->
<!-- BEGIN request header -->
<div class="request-header">
<div class="row align-items-center">
<div class="col-md-8">
<h3 class="mb-1">{{ blood_request.request_number }}</h3>
<p class="mb-0">
<i class="fa fa-user"></i> {{ blood_request.patient.full_name }}
({{ blood_request.patient.patient_id }})
</p>
</div>
<div class="col-md-4 text-end">
<div class="mb-2">
{% if blood_request.urgency == 'emergency' %}
<span class="badge bg-danger fs-6 urgency-emergency">
<i class="fa fa-exclamation-triangle"></i> {{ blood_request.get_urgency_display }}
</span>
{% elif blood_request.urgency == 'urgent' %}
<span class="badge bg-warning fs-6">
<i class="fa fa-clock"></i> {{ blood_request.get_urgency_display }}
</span>
{% else %}
<span class="badge bg-secondary fs-6">{{ blood_request.get_urgency_display }}</span>
{% endif %}
</div>
<div>
{% if blood_request.status == 'pending' %}
<span class="badge bg-warning fs-6">{{ blood_request.get_status_display }}</span>
{% elif blood_request.status == 'processing' %}
<span class="badge bg-info fs-6">{{ blood_request.get_status_display }}</span>
{% elif blood_request.status == 'ready' %}
<span class="badge bg-primary fs-6">{{ blood_request.get_status_display }}</span>
{% elif blood_request.status == 'issued' %}
<span class="badge bg-success fs-6">{{ blood_request.get_status_display }}</span>
{% elif blood_request.status == 'completed' %}
<span class="badge bg-success fs-6">{{ blood_request.get_status_display }}</span>
{% elif blood_request.status == 'cancelled' %}
<span class="badge bg-danger fs-6">{{ blood_request.get_status_display }}</span>
{% endif %}
</div>
</div>
</div>
</div>
<!-- END request header -->
<!-- BEGIN row -->
<div class="row">
<!-- BEGIN col-4 -->
<div class="col-xl-4">
<!-- BEGIN request info panel -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Request Information</h4>
</div>
<div class="panel-body">
<table class="table table-borderless">
<tr>
<td class="fw-bold">Request Number:</td>
<td>{{ blood_request.request_number }}</td>
</tr>
<tr>
<td class="fw-bold">Request Date:</td>
<td>{{ blood_request.request_date|date:"M d, Y H:i" }}</td>
</tr>
<tr>
<td class="fw-bold">Required By:</td>
<td>
{{ blood_request.required_by|date:"M d, Y H:i" }}
{% if blood_request.is_overdue %}
<br><span class="badge bg-danger">Overdue</span>
{% endif %}
</td>
</tr>
<tr>
<td class="fw-bold">Department:</td>
<td>{{ blood_request.requesting_department.name }}</td>
</tr>
<tr>
<td class="fw-bold">Requesting Physician:</td>
<td>{{ blood_request.requesting_physician.get_full_name }}</td>
</tr>
<tr>
<td class="fw-bold">Component:</td>
<td>{{ blood_request.component_requested.get_name_display }}</td>
</tr>
<tr>
<td class="fw-bold">Units Requested:</td>
<td>
<span class="badge bg-info fs-6">{{ blood_request.units_requested }}</span>
</td>
</tr>
<tr>
<td class="fw-bold">Patient Blood Group:</td>
<td>
<span class="badge bg-primary">{{ blood_request.patient_blood_group.display_name }}</span>
</td>
</tr>
</table>
{% if blood_request.processed_by %}
<hr>
<h6 class="fw-bold">Processing Information</h6>
<table class="table table-borderless">
<tr>
<td class="fw-bold">Processed By:</td>
<td>{{ blood_request.processed_by.get_full_name }}</td>
</tr>
<tr>
<td class="fw-bold">Processed At:</td>
<td>{{ blood_request.processed_at|date:"M d, Y H:i" }}</td>
</tr>
</table>
{% endif %}
</div>
</div>
<!-- END request info panel -->
<!-- BEGIN patient info panel -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Patient Information</h4>
</div>
<div class="panel-body">
<table class="table table-borderless">
<tr>
<td class="fw-bold">Patient ID:</td>
<td>{{ blood_request.patient.patient_id }}</td>
</tr>
<tr>
<td class="fw-bold">Name:</td>
<td>{{ blood_request.patient.get_full_name }}</td>
</tr>
<tr>
<td class="fw-bold">Age:</td>
<td>{{ blood_request.patient.age }} years</td>
</tr>
<tr>
<td class="fw-bold">Gender:</td>
<td>{{ blood_request.patient.get_gender_display }}</td>
</tr>
<tr>
<td class="fw-bold">Blood Group:</td>
<td>
<span class="badge bg-primary">{{ blood_request.patient_blood_group.display_name }}</span>
</td>
</tr>
{% if blood_request.hemoglobin_level %}
<tr>
<td class="fw-bold">Hemoglobin:</td>
<td>{{ blood_request.hemoglobin_level|floatformat:2 }} g/dL</td>
</tr>
{% endif %}
{% if blood_request.platelet_count %}
<tr>
<td class="fw-bold">Platelet Count:</td>
<td>{{ blood_request.platelet_count }}/μL</td>
</tr>
{% endif %}
</table>
</div>
</div>
<!-- END patient info panel -->
<!-- BEGIN clinical info panel -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Clinical Information</h4>
</div>
<div class="panel-body">
<h6 class="fw-bold">Indication for Transfusion</h6>
<p class="text-muted">{{ blood_request.indication }}</p>
{% if blood_request.special_requirements %}
<h6 class="fw-bold">Special Requirements</h6>
<p class="text-muted">{{ blood_request.special_requirements }}</p>
{% endif %}
{% if blood_request.notes %}
<h6 class="fw-bold">Additional Notes</h6>
<p class="text-muted">{{ blood_request.notes }}</p>
{% endif %}
</div>
</div>
<!-- END clinical info panel -->
</div>
<!-- END col-4 -->
<!-- BEGIN col-8 -->
<div class="col-xl-8">
<!-- BEGIN blood compatibility check -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Blood Compatibility Check</h4>
<div class="panel-heading-btn">
<button type="button" class="btn btn-info btn-sm" onclick="checkAvailability()">
<i class="fa fa-search"></i> Check Availability
</button>
</div>
</div>
<div class="panel-body">
<div class="compatibility-check compatible">
<div class="row">
<div class="col-md-6">
<h6><i class="fa fa-check-circle text-success"></i> ABO Compatibility</h6>
<p class="mb-0">Patient: {{ blood_request.patient_blood_group.display_name }}</p>
<p class="mb-0">Compatible with:
{% if blood_request.patient_blood_group.abo_type == 'AB' %}
A, B, AB, O
{% elif blood_request.patient_blood_group.abo_type == 'A' %}
A, O
{% elif blood_request.patient_blood_group.abo_type == 'B' %}
B, O
{% else %}
O only
{% endif %}
</p>
</div>
<div class="col-md-6">
<h6><i class="fa fa-info-circle text-info"></i> Rh Compatibility</h6>
<p class="mb-0">Patient: {{ blood_request.patient_blood_group.rh_factor|title }}</p>
<p class="mb-0">Compatible with:
{% if blood_request.patient_blood_group.rh_factor == 'positive' %}
Positive, Negative
{% else %}
Negative only
{% endif %}
</p>
</div>
</div>
</div>
<div id="availabilityResults" class="mt-3" style="display: none;">
<!-- Availability results will be loaded here -->
</div>
</div>
</div>
<!-- END blood compatibility check -->
<!-- BEGIN issued units -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Issued Blood Units</h4>
<div class="panel-heading-btn">
{% if blood_request.status in 'pending,processing,ready' %}
<a href="{% url 'blood_bank:blood_issue_create' blood_request.id %}" class="btn btn-success btn-sm">
<i class="fa fa-share"></i> Issue Blood Unit
</a>
{% endif %}
</div>
</div>
<div class="panel-body">
{% if issues %}
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Unit Number</th>
<th>Blood Group</th>
<th>Component</th>
<th>Issue Date</th>
<th>Issued To</th>
<th>Expiry Time</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for issue in issues %}
<tr>
<td>
<a href="{% url 'blood_bank:blood_unit_detail' issue.blood_unit.id %}">
{{ issue.blood_unit.unit_number }}
</a>
</td>
<td>
<span class="badge bg-primary">{{ issue.blood_unit.blood_group.display_name }}</span>
</td>
<td>{{ issue.blood_unit.component.get_name_display }}</td>
<td>{{ issue.issue_date|date:"M d, Y H:i" }}</td>
<td>{{ issue.issued_to.get_full_name }}</td>
<td>
{{ issue.expiry_time|date:"M d, Y H:i" }}
{% if issue.is_expired %}
<br><span class="badge bg-danger">Expired</span>
{% endif %}
</td>
<td>
{% if issue.returned %}
<span class="badge bg-warning">Returned</span>
{% elif issue.is_expired %}
<span class="badge bg-danger">Expired</span>
{% else %}
<span class="badge bg-success">Active</span>
{% endif %}
</td>
<td>
{% if not issue.returned and not issue.is_expired %}
<a href="{% url 'blood_bank:transfusion_create' issue.id %}"
class="btn btn-outline-primary btn-sm" title="Start Transfusion">
<i class="fa fa-heartbeat"></i>
</a>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="text-center py-4">
<i class="fa fa-share fa-3x text-muted mb-3"></i>
<h5 class="text-muted">No Units Issued</h5>
<p class="text-muted">No blood units have been issued for this request yet.</p>
{% if blood_request.status in 'pending,processing,ready' %}
<a href="{% url 'blood_bank:blood_issue_create' blood_request.id %}" class="btn btn-primary">
<i class="fa fa-share"></i> Issue First Unit
</a>
{% endif %}
</div>
{% endif %}
</div>
</div>
<!-- END issued units -->
<!-- BEGIN request timeline -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Request Timeline</h4>
</div>
<div class="panel-body">
<div class="timeline">
<div class="timeline-item {% if blood_request.status == 'pending' %}current{% endif %}">
<div class="card">
<div class="card-body">
<h6 class="card-title">
<i class="fa fa-plus text-primary"></i> Request Created
</h6>
<p class="card-text">
<small class="text-muted">{{ blood_request.request_date|date:"M d, Y H:i" }}</small><br>
Request submitted by {{ blood_request.requesting_physician.get_full_name }}
</p>
</div>
</div>
</div>
{% if blood_request.status != 'pending' %}
<div class="timeline-item {% if blood_request.status == 'processing' %}current{% endif %}">
<div class="card">
<div class="card-body">
<h6 class="card-title">
<i class="fa fa-cog text-info"></i> Processing Started
</h6>
<p class="card-text">
{% if blood_request.processed_at %}
<small class="text-muted">{{ blood_request.processed_at|date:"M d, Y H:i" }}</small><br>
{% endif %}
Blood bank staff began processing the request
</p>
</div>
</div>
</div>
{% endif %}
{% if blood_request.status == 'ready' %}
<div class="timeline-item current">
<div class="card">
<div class="card-body">
<h6 class="card-title">
<i class="fa fa-check text-success"></i> Units Ready
</h6>
<p class="card-text">
Compatible blood units identified and ready for issue
</p>
</div>
</div>
</div>
{% endif %}
{% if blood_request.status == 'issued' %}
<div class="timeline-item current">
<div class="card">
<div class="card-body">
<h6 class="card-title">
<i class="fa fa-share text-primary"></i> Units Issued
</h6>
<p class="card-text">
Blood units issued to clinical staff
</p>
</div>
</div>
</div>
{% endif %}
{% if blood_request.status == 'completed' %}
<div class="timeline-item current">
<div class="card">
<div class="card-body">
<h6 class="card-title">
<i class="fa fa-check-circle text-success"></i> Request Completed
</h6>
<p class="card-text">
All requested units have been successfully transfused
</p>
</div>
</div>
</div>
{% endif %}
{% if blood_request.status == 'cancelled' %}
<div class="timeline-item current">
<div class="card">
<div class="card-body">
<h6 class="card-title">
<i class="fa fa-times text-danger"></i> Request Cancelled
</h6>
<p class="card-text">
Request was cancelled and no units were issued
</p>
</div>
</div>
</div>
{% endif %}
</div>
</div>
</div>
<!-- END request timeline -->
</div>
<!-- END col-8 -->
</div>
<!-- END row -->
<!-- BEGIN action buttons -->
<div class="row">
<div class="col-12">
<div class="d-flex justify-content-between">
<a href="{% url 'blood_bank:blood_request_list' %}" class="btn btn-default">
<i class="fa fa-arrow-left"></i> Back to Requests
</a>
<div>
{% if blood_request.status in 'pending,processing,ready' %}
<a href="{% url 'blood_bank:blood_issue_create' blood_request.id %}" class="btn btn-success">
<i class="fa fa-share"></i> Issue Blood Unit
</a>
{% endif %}
{% if blood_request.status == 'pending' %}
<button type="button" class="btn btn-danger" onclick="cancelRequest()">
<i class="fa fa-times"></i> Cancel Request
</button>
{% endif %}
<button type="button" class="btn btn-info" onclick="window.print()">
<i class="fa fa-print"></i> Print Request
</button>
</div>
</div>
</div>
</div>
<!-- END action buttons -->
{% endblock %}
{% block js %}
<script>
function checkAvailability() {
var bloodGroupId = {{ blood_request.patient_blood_group.id }};
var componentId = {{ blood_request.component_requested.id }};
// Show loading
$('#availabilityResults').html(`
<div class="text-center">
<i class="fa fa-spinner fa-spin fa-2x"></i>
<p>Checking availability...</p>
</div>
`).show();
// Make AJAX call to check availability
$.get('/blood-bank/api/blood-availability/', {
blood_group: bloodGroupId,
component: componentId
})
.done(function(data) {
var resultHtml = `
<div class="alert alert-info">
<h6><i class="fa fa-info-circle"></i> Availability Results</h6>
<p><strong>Available Units:</strong> ${data.available_units}</p>
<p><strong>Requested Units:</strong> {{ blood_request.units_requested }}</p>
`;
if (data.available_units >= {{ blood_request.units_requested }}) {
resultHtml += '<p class="text-success"><i class="fa fa-check"></i> Sufficient units available</p>';
} else {
resultHtml += '<p class="text-warning"><i class="fa fa-exclamation-triangle"></i> Insufficient units available</p>';
}
resultHtml += '</div>';
$('#availabilityResults').html(resultHtml);
})
.fail(function() {
$('#availabilityResults').html(`
<div class="alert alert-danger">
<i class="fa fa-exclamation-triangle"></i> Error checking availability
</div>
`);
});
}
function cancelRequest() {
Swal.fire({
title: 'Cancel Blood Request?',
text: 'This action cannot be undone. The request will be marked as cancelled.',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#d33',
cancelButtonColor: '#3085d6',
confirmButtonText: 'Yes, Cancel Request',
cancelButtonText: 'Keep Request'
}).then((result) => {
if (result.isConfirmed) {
// Here you would make an AJAX call to cancel the request
Swal.fire({
icon: 'success',
title: 'Request Cancelled',
text: 'The blood request has been cancelled.',
confirmButtonText: 'OK'
}).then(() => {
location.reload();
});
}
});
}
// Auto-refresh for emergency requests
{% if blood_request.urgency == 'emergency' %}
setInterval(function() {
if (document.visibilityState === 'visible') {
location.reload();
}
}, 60000); // Refresh every minute for emergency requests
{% endif %}
</script>
{% endblock %}