654 lines
28 KiB
HTML
654 lines
28 KiB
HTML
{% extends 'base.html' %}
|
|
{% load static %}
|
|
|
|
{% block title %}{% if form.instance.pk %}Edit Blood Request{% else %}New Blood Request{% endif %}{% endblock %}
|
|
|
|
{% block css %}
|
|
<link href="{% static 'plugins/select2/dist/css/select2.min.css' %}" rel="stylesheet" />
|
|
<link href="{% static 'plugins/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css' %}" rel="stylesheet" />
|
|
<style>
|
|
.form-section {
|
|
background: #f8f9fa;
|
|
border-radius: 8px;
|
|
padding: 20px;
|
|
margin-bottom: 20px;
|
|
border-left: 4px solid #007bff;
|
|
}
|
|
|
|
.form-section h5 {
|
|
color: #007bff;
|
|
margin-bottom: 15px;
|
|
}
|
|
|
|
.required-field {
|
|
color: #dc3545;
|
|
}
|
|
|
|
.patient-info {
|
|
background: #d4edda;
|
|
border-left: 4px solid #28a745;
|
|
}
|
|
|
|
.clinical-info {
|
|
background: #d1ecf1;
|
|
border-left: 4px solid #17a2b8;
|
|
}
|
|
|
|
.urgency-info {
|
|
background: #fff3cd;
|
|
border-left: 4px solid #ffc107;
|
|
}
|
|
|
|
.emergency-alert {
|
|
background: #f8d7da;
|
|
border-left: 4px solid #dc3545;
|
|
animation: pulse 2s infinite;
|
|
}
|
|
|
|
@keyframes pulse {
|
|
0% { opacity: 1; }
|
|
50% { opacity: 0.8; }
|
|
100% { opacity: 1; }
|
|
}
|
|
|
|
.compatibility-check {
|
|
background: #e2e3e5;
|
|
border-radius: 8px;
|
|
padding: 15px;
|
|
margin-top: 15px;
|
|
}
|
|
|
|
.availability-indicator {
|
|
display: inline-block;
|
|
width: 12px;
|
|
height: 12px;
|
|
border-radius: 50%;
|
|
margin-right: 5px;
|
|
}
|
|
|
|
.available { background-color: #28a745; }
|
|
.limited { background-color: #ffc107; }
|
|
.unavailable { background-color: #dc3545; }
|
|
</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' %}">Blood Requests</a></li>
|
|
{% if form.instance.pk %}
|
|
<li class="breadcrumb-item"><a href="{% url 'blood_bank:blood_request_detail' form.instance.id %}">{{ form.instance.request_number }}</a></li>
|
|
<li class="breadcrumb-item active">Edit</li>
|
|
{% else %}
|
|
<li class="breadcrumb-item active">New Request</li>
|
|
{% endif %}
|
|
</ol>
|
|
<!-- END breadcrumb -->
|
|
|
|
<!-- BEGIN page-header -->
|
|
<h1 class="page-header">
|
|
{% if form.instance.pk %}
|
|
Edit Blood Request <small>{{ form.instance.request_number }}</small>
|
|
{% else %}
|
|
New Blood Request <small>patient transfusion request</small>
|
|
{% endif %}
|
|
</h1>
|
|
<!-- END page-header -->
|
|
|
|
<!-- BEGIN panel -->
|
|
<div class="panel panel-inverse">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">
|
|
<i class="fa fa-clipboard-list"></i> Blood Request Information
|
|
</h4>
|
|
<div class="panel-heading-btn">
|
|
<span class="badge bg-info">Request ID: {{ form.instance.request_number|default:'Auto-generated' }}</span>
|
|
</div>
|
|
</div>
|
|
<div class="panel-body">
|
|
<form method="post" id="bloodRequestForm">
|
|
{% csrf_token %}
|
|
|
|
<!-- BEGIN patient information -->
|
|
<div class="form-section patient-info">
|
|
<h5><i class="fa fa-user-injured"></i> Patient Information</h5>
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<div class="form-group">
|
|
<label for="{{ form.patient.id_for_label }}" class="form-label">
|
|
Patient <span class="required-field">*</span>
|
|
</label>
|
|
<select class="form-select" name="{{ form.patient.name }}" id="{{ form.patient.id_for_label }}" required>
|
|
<option value="">Select patient...</option>
|
|
{% for patient in form.patient.field.queryset %}
|
|
<option value="{{ patient.id }}"
|
|
data-blood-group="{{ patient.blood_group.display_name|default:'Unknown' }}"
|
|
data-age="{{ patient.age }}"
|
|
data-gender="{{ patient.gender }}"
|
|
{% if form.patient.value == patient.id %}selected{% endif %}>
|
|
{{ patient.full_name }} ({{ patient.patient_id }})
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
{% if form.patient.errors %}
|
|
<div class="text-danger">{{ form.patient.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-group">
|
|
<label class="form-label">Patient Details</label>
|
|
<div id="patientDetails" class="alert alert-info">
|
|
<i class="fa fa-info-circle"></i> Select a patient to view details
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- END patient information -->
|
|
|
|
<!-- BEGIN clinical information -->
|
|
<div class="form-section clinical-info">
|
|
<h5><i class="fa fa-stethoscope"></i> Clinical Information</h5>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="{{ form.requesting_physician.id_for_label }}" class="form-label">
|
|
Requesting Physician <span class="required-field">*</span>
|
|
</label>
|
|
<select class="form-select" name="{{ form.requesting_physician.name }}" id="{{ form.requesting_physician.id_for_label }}" required>
|
|
<option value="">Select physician...</option>
|
|
{% for physician in form.requesting_physician.field.queryset %}
|
|
<option value="{{ physician.id }}" {% if form.requesting_physician.value == physician.id %}selected{% endif %}>
|
|
Dr. {{ physician.get_full_name }}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
{% if form.requesting_physician.errors %}
|
|
<div class="text-danger">{{ form.requesting_physician.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="{{ form.department.id_for_label }}" class="form-label">
|
|
Department <span class="required-field">*</span>
|
|
</label>
|
|
<select class="form-select" name="{{ form.department.name }}" id="{{ form.department.id_for_label }}" required>
|
|
<option value="">Select department...</option>
|
|
{% for dept in form.department.field.queryset %}
|
|
<option value="{{ dept.id }}" {% if form.department.value == dept.id %}selected{% endif %}>
|
|
{{ dept.name }}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
{% if form.department.errors %}
|
|
<div class="text-danger">{{ form.department.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<div class="form-group">
|
|
<label for="{{ form.clinical_indication.id_for_label }}" class="form-label">
|
|
Clinical Indication <span class="required-field">*</span>
|
|
</label>
|
|
<textarea class="form-control" name="{{ form.clinical_indication.name }}"
|
|
id="{{ form.clinical_indication.id_for_label }}" rows="3"
|
|
placeholder="Describe the clinical reason for blood transfusion..." required>{{ form.clinical_indication.value|default:'' }}</textarea>
|
|
{% if form.clinical_indication.errors %}
|
|
<div class="text-danger">{{ form.clinical_indication.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- END clinical information -->
|
|
|
|
<!-- BEGIN blood component request -->
|
|
<div class="form-section">
|
|
<h5><i class="fa fa-tint"></i> Blood Component Request</h5>
|
|
<div class="row">
|
|
<div class="col-md-4">
|
|
<div class="form-group">
|
|
<label for="{{ form.component_requested.id_for_label }}" class="form-label">
|
|
Component Requested <span class="required-field">*</span>
|
|
</label>
|
|
<select class="form-select" name="{{ form.component_requested.name }}" id="{{ form.component_requested.id_for_label }}" required>
|
|
<option value="">Select component...</option>
|
|
{% for component in form.component_requested.field.queryset %}
|
|
<option value="{{ component.id }}" {% if form.component_requested.value == component.id %}selected{% endif %}>
|
|
{{ component.get_name_display }}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
{% if form.component_requested.errors %}
|
|
<div class="text-danger">{{ form.component_requested.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-group">
|
|
<label for="{{ form.units_requested.id_for_label }}" class="form-label">
|
|
Units Requested <span class="required-field">*</span>
|
|
</label>
|
|
<input type="number" class="form-control" name="{{ form.units_requested.name }}"
|
|
id="{{ form.units_requested.id_for_label }}"
|
|
value="{{ form.units_requested.value }}" min="1" max="10" required>
|
|
{% if form.units_requested.errors %}
|
|
<div class="text-danger">{{ form.units_requested.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-group">
|
|
<label class="form-label">Availability Check</label>
|
|
<div id="availabilityCheck" class="alert alert-info">
|
|
<i class="fa fa-info-circle"></i> Select patient and component to check availability
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- END blood component request -->
|
|
|
|
<!-- BEGIN urgency and timing -->
|
|
<div class="form-section urgency-info" id="urgencySection">
|
|
<h5><i class="fa fa-clock"></i> Urgency & Timing</h5>
|
|
<div class="row">
|
|
<div class="col-md-4">
|
|
<div class="form-group">
|
|
<label for="{{ form.urgency.id_for_label }}" class="form-label">
|
|
Urgency Level <span class="required-field">*</span>
|
|
</label>
|
|
<select class="form-select" name="{{ form.urgency.name }}" id="{{ form.urgency.id_for_label }}" required>
|
|
<option value="">Select urgency...</option>
|
|
{% for value, label in form.urgency.field.choices %}
|
|
<option value="{{ value }}" {% if form.urgency.value == value %}selected{% endif %}>
|
|
{{ label }}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
{% if form.urgency.errors %}
|
|
<div class="text-danger">{{ form.urgency.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-group">
|
|
<label for="{{ form.required_by.id_for_label }}" class="form-label">
|
|
Required By <span class="required-field">*</span>
|
|
</label>
|
|
<input type="datetime-local" class="form-control" name="{{ form.required_by.name }}"
|
|
id="{{ form.required_by.id_for_label }}"
|
|
value="{{ form.required_by.value|date:'Y-m-d\TH:i' }}" required>
|
|
{% if form.required_by.errors %}
|
|
<div class="text-danger">{{ form.required_by.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-group">
|
|
<label class="form-label">Time to Required</label>
|
|
<div id="timeToRequired" class="alert alert-info">
|
|
<i class="fa fa-clock"></i> Set required by time
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- END urgency and timing -->
|
|
|
|
<!-- BEGIN special requirements -->
|
|
<div class="form-section">
|
|
<h5><i class="fa fa-exclamation-circle"></i> Special Requirements</h5>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label class="form-label">Special Requirements</label>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" name="irradiated" id="irradiated"
|
|
{% if form.instance.special_requirements.irradiated %}checked{% endif %}>
|
|
<label class="form-check-label" for="irradiated">
|
|
Irradiated Blood Products
|
|
</label>
|
|
</div>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" name="cmv_negative" id="cmvNegative"
|
|
{% if form.instance.special_requirements.cmv_negative %}checked{% endif %}>
|
|
<label class="form-check-label" for="cmvNegative">
|
|
CMV Negative
|
|
</label>
|
|
</div>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" name="leukoreduced" id="leukoreduced"
|
|
{% if form.instance.special_requirements.leukoreduced %}checked{% endif %}>
|
|
<label class="form-check-label" for="leukoreduced">
|
|
Leukoreduced
|
|
</label>
|
|
</div>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" name="washed" id="washed"
|
|
{% if form.instance.special_requirements.washed %}checked{% endif %}>
|
|
<label class="form-check-label" for="washed">
|
|
Washed Red Cells
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="{{ form.special_instructions.id_for_label }}" class="form-label">
|
|
Special Instructions
|
|
</label>
|
|
<textarea class="form-control" name="{{ form.special_instructions.name }}"
|
|
id="{{ form.special_instructions.id_for_label }}" rows="4"
|
|
placeholder="Any special handling or administration instructions...">{{ form.special_instructions.value|default:'' }}</textarea>
|
|
{% if form.special_instructions.errors %}
|
|
<div class="text-danger">{{ form.special_instructions.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- END special requirements -->
|
|
|
|
<!-- BEGIN compatibility check -->
|
|
<div class="compatibility-check">
|
|
<h5><i class="fa fa-shield-alt"></i> Compatibility Check</h5>
|
|
<div id="compatibilityResults">
|
|
<p class="text-muted">Select patient and component to perform compatibility check</p>
|
|
</div>
|
|
</div>
|
|
<!-- END compatibility check -->
|
|
|
|
<!-- BEGIN form actions -->
|
|
<div class="d-flex justify-content-between mt-4">
|
|
<a href="{% if form.instance.pk %}{% url 'blood_bank:blood_request_detail' form.instance.id %}{% else %}{% url 'blood_bank:blood_request_list' %}{% endif %}"
|
|
class="btn btn-secondary">
|
|
<i class="fa fa-arrow-left"></i> Cancel
|
|
</a>
|
|
<div>
|
|
<button type="button" class="btn btn-info" onclick="validateRequest()">
|
|
<i class="fa fa-check"></i> Validate Request
|
|
</button>
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="fa fa-save"></i>
|
|
{% if form.instance.pk %}Update Request{% else %}Submit Request{% endif %}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<!-- END form actions -->
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<!-- END panel -->
|
|
{% endblock %}
|
|
|
|
{% block js %}
|
|
<script src="{% static 'plugins/select2/dist/js/select2.min.js' %}"></script>
|
|
|
|
<script>
|
|
$(document).ready(function() {
|
|
// Initialize Select2
|
|
$('#{{ form.patient.id_for_label }}, #{{ form.requesting_physician.id_for_label }}, #{{ form.department.id_for_label }}, #{{ form.component_requested.id_for_label }}').select2({
|
|
theme: 'bootstrap-5'
|
|
});
|
|
|
|
// Set default required by time (2 hours from now)
|
|
if (!$('#{{ form.required_by.id_for_label }}').val()) {
|
|
var defaultTime = new Date();
|
|
defaultTime.setHours(defaultTime.getHours() + 2);
|
|
$('#{{ form.required_by.id_for_label }}').val(defaultTime.toISOString().slice(0, 16));
|
|
}
|
|
|
|
// Update displays when form changes
|
|
updatePatientDetails();
|
|
updateTimeToRequired();
|
|
updateUrgencySection();
|
|
checkAvailability();
|
|
|
|
// Event listeners
|
|
$('#{{ form.patient.id_for_label }}').on('change', function() {
|
|
updatePatientDetails();
|
|
checkAvailability();
|
|
performCompatibilityCheck();
|
|
});
|
|
|
|
$('#{{ form.component_requested.id_for_label }}, #{{ form.units_requested.id_for_label }}').on('change', function() {
|
|
checkAvailability();
|
|
performCompatibilityCheck();
|
|
});
|
|
|
|
$('#{{ form.urgency.id_for_label }}').on('change', function() {
|
|
updateUrgencySection();
|
|
updateRequiredByTime();
|
|
});
|
|
|
|
$('#{{ form.required_by.id_for_label }}').on('change', function() {
|
|
updateTimeToRequired();
|
|
});
|
|
|
|
// Form validation
|
|
$('#bloodRequestForm').on('submit', function(e) {
|
|
if (!validateRequest()) {
|
|
e.preventDefault();
|
|
}
|
|
});
|
|
});
|
|
|
|
function updatePatientDetails() {
|
|
var patientId = $('#{{ form.patient.id_for_label }}').val();
|
|
if (!patientId) {
|
|
$('#patientDetails').html('<i class="fa fa-info-circle"></i> Select a patient to view details').removeClass().addClass('alert alert-info');
|
|
return;
|
|
}
|
|
|
|
var selectedOption = $('#{{ form.patient.id_for_label }} option:selected');
|
|
var bloodGroup = selectedOption.data('blood-group');
|
|
var age = selectedOption.data('age');
|
|
var gender = selectedOption.data('gender');
|
|
|
|
var detailsHtml = '<strong>Blood Group:</strong> ' + (bloodGroup || 'Unknown') + '<br>';
|
|
detailsHtml += '<strong>Age:</strong> ' + (age || 'Unknown') + '<br>';
|
|
detailsHtml += '<strong>Gender:</strong> ' + (gender || 'Unknown');
|
|
|
|
$('#patientDetails').html(detailsHtml).removeClass().addClass('alert alert-success');
|
|
}
|
|
|
|
function updateUrgencySection() {
|
|
var urgency = $('#{{ form.urgency.id_for_label }}').val();
|
|
var section = $('#urgencySection');
|
|
|
|
section.removeClass('urgency-info emergency-alert');
|
|
|
|
if (urgency === 'emergency') {
|
|
section.addClass('emergency-alert');
|
|
} else {
|
|
section.addClass('urgency-info');
|
|
}
|
|
}
|
|
|
|
function updateRequiredByTime() {
|
|
var urgency = $('#{{ form.urgency.id_for_label }}').val();
|
|
var now = new Date();
|
|
var requiredBy;
|
|
|
|
switch(urgency) {
|
|
case 'emergency':
|
|
requiredBy = new Date(now.getTime() + 30 * 60000); // 30 minutes
|
|
break;
|
|
case 'urgent':
|
|
requiredBy = new Date(now.getTime() + 2 * 60 * 60000); // 2 hours
|
|
break;
|
|
case 'routine':
|
|
requiredBy = new Date(now.getTime() + 24 * 60 * 60000); // 24 hours
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
|
|
$('#{{ form.required_by.id_for_label }}').val(requiredBy.toISOString().slice(0, 16));
|
|
updateTimeToRequired();
|
|
}
|
|
|
|
function updateTimeToRequired() {
|
|
var requiredBy = $('#{{ form.required_by.id_for_label }}').val();
|
|
if (!requiredBy) {
|
|
$('#timeToRequired').html('<i class="fa fa-clock"></i> Set required by time').removeClass().addClass('alert alert-info');
|
|
return;
|
|
}
|
|
|
|
var now = new Date();
|
|
var required = new Date(requiredBy);
|
|
var diffMs = required - now;
|
|
var diffHours = Math.floor(diffMs / (1000 * 60 * 60));
|
|
var diffMinutes = Math.floor((diffMs % (1000 * 60 * 60)) / (1000 * 60));
|
|
|
|
var alertClass = 'alert-info';
|
|
var icon = 'fa-clock';
|
|
|
|
if (diffMs < 0) {
|
|
$('#timeToRequired').html('<i class="fa fa-exclamation-triangle"></i> Overdue!').removeClass().addClass('alert alert-danger');
|
|
} else if (diffHours < 1) {
|
|
alertClass = 'alert-danger';
|
|
icon = 'fa-exclamation-triangle';
|
|
$('#timeToRequired').html('<i class="fa ' + icon + '"></i> ' + diffMinutes + ' minutes remaining').removeClass().addClass('alert ' + alertClass);
|
|
} else if (diffHours < 4) {
|
|
alertClass = 'alert-warning';
|
|
$('#timeToRequired').html('<i class="fa ' + icon + '"></i> ' + diffHours + ' hours, ' + diffMinutes + ' minutes').removeClass().addClass('alert ' + alertClass);
|
|
} else {
|
|
$('#timeToRequired').html('<i class="fa ' + icon + '"></i> ' + diffHours + ' hours, ' + diffMinutes + ' minutes').removeClass().addClass('alert ' + alertClass);
|
|
}
|
|
}
|
|
|
|
function checkAvailability() {
|
|
var patientId = $('#{{ form.patient.id_for_label }}').val();
|
|
var componentId = $('#{{ form.component_requested.id_for_label }}').val();
|
|
var unitsRequested = $('#{{ form.units_requested.id_for_label }}').val();
|
|
|
|
if (!patientId || !componentId) {
|
|
$('#availabilityCheck').html('<i class="fa fa-info-circle"></i> Select patient and component to check availability').removeClass().addClass('alert alert-info');
|
|
return;
|
|
}
|
|
|
|
// Simulate availability check (in real implementation, this would be an AJAX call)
|
|
var availableUnits = Math.floor(Math.random() * 10) + 1;
|
|
var requested = parseInt(unitsRequested) || 1;
|
|
|
|
var indicator, message, alertClass;
|
|
|
|
if (availableUnits >= requested) {
|
|
indicator = '<span class="availability-indicator available"></span>';
|
|
message = availableUnits + ' units available';
|
|
alertClass = 'alert-success';
|
|
} else if (availableUnits > 0) {
|
|
indicator = '<span class="availability-indicator limited"></span>';
|
|
message = 'Only ' + availableUnits + ' units available (need ' + requested + ')';
|
|
alertClass = 'alert-warning';
|
|
} else {
|
|
indicator = '<span class="availability-indicator unavailable"></span>';
|
|
message = 'No units available';
|
|
alertClass = 'alert-danger';
|
|
}
|
|
|
|
$('#availabilityCheck').html(indicator + message).removeClass().addClass('alert ' + alertClass);
|
|
}
|
|
|
|
function performCompatibilityCheck() {
|
|
var patientId = $('#{{ form.patient.id_for_label }}').val();
|
|
var componentId = $('#{{ form.component_requested.id_for_label }}').val();
|
|
|
|
if (!patientId || !componentId) {
|
|
$('#compatibilityResults').html('<p class="text-muted">Select patient and component to perform compatibility check</p>');
|
|
return;
|
|
}
|
|
|
|
var selectedPatient = $('#{{ form.patient.id_for_label }} option:selected');
|
|
var patientBloodGroup = selectedPatient.data('blood-group');
|
|
|
|
if (!patientBloodGroup || patientBloodGroup === 'Unknown') {
|
|
$('#compatibilityResults').html('<div class="alert alert-warning"><i class="fa fa-exclamation-triangle"></i> Patient blood group unknown - type and screen required</div>');
|
|
return;
|
|
}
|
|
|
|
// Simulate compatibility check
|
|
var compatible = Math.random() > 0.1; // 90% compatibility rate
|
|
|
|
if (compatible) {
|
|
$('#compatibilityResults').html('<div class="alert alert-success"><i class="fa fa-check-circle"></i> Compatible blood group (' + patientBloodGroup + ') - crossmatch required before transfusion</div>');
|
|
} else {
|
|
$('#compatibilityResults').html('<div class="alert alert-danger"><i class="fa fa-times-circle"></i> Potential compatibility issues detected - additional testing required</div>');
|
|
}
|
|
}
|
|
|
|
function validateRequest() {
|
|
var errors = [];
|
|
|
|
// Check required fields
|
|
if (!$('#{{ form.patient.id_for_label }}').val()) {
|
|
errors.push('Please select a patient');
|
|
}
|
|
|
|
if (!$('#{{ form.requesting_physician.id_for_label }}').val()) {
|
|
errors.push('Please select requesting physician');
|
|
}
|
|
|
|
if (!$('#{{ form.component_requested.id_for_label }}').val()) {
|
|
errors.push('Please select blood component');
|
|
}
|
|
|
|
if (!$('#{{ form.units_requested.id_for_label }}').val()) {
|
|
errors.push('Please specify number of units');
|
|
}
|
|
|
|
if (!$('#{{ form.urgency.id_for_label }}').val()) {
|
|
errors.push('Please select urgency level');
|
|
}
|
|
|
|
if (!$('#{{ form.clinical_indication.id_for_label }}').val().trim()) {
|
|
errors.push('Please provide clinical indication');
|
|
}
|
|
|
|
// Check timing
|
|
var requiredBy = $('#{{ form.required_by.id_for_label }}').val();
|
|
if (requiredBy) {
|
|
var required = new Date(requiredBy);
|
|
var now = new Date();
|
|
|
|
if (required <= now) {
|
|
errors.push('Required by time must be in the future');
|
|
}
|
|
}
|
|
|
|
if (errors.length > 0) {
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: 'Validation Errors',
|
|
html: '<ul class="text-start"><li>' + errors.join('</li><li>') + '</li></ul>',
|
|
confirmButtonText: 'OK'
|
|
});
|
|
return false;
|
|
}
|
|
|
|
Swal.fire({
|
|
icon: 'success',
|
|
title: 'Validation Passed',
|
|
text: 'Blood request is ready for submission.',
|
|
timer: 1500,
|
|
showConfirmButton: false
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
// Update time display every minute
|
|
setInterval(updateTimeToRequired, 60000);
|
|
</script>
|
|
{% endblock %}
|
|
|