Marwan Alwali 35be20ae4c update
2025-09-06 19:07:14 +03:00

645 lines
28 KiB
HTML

{% extends 'base.html' %}
{% load static %}
{% block title %}Blood Test - {{ blood_unit.unit_number }}{% endblock %}
{% block css %}
<link href="{% static 'plugins/select2/dist/css/select2.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;
}
.unit-info {
background: #d1ecf1;
border-left: 4px solid #17a2b8;
}
.test-panel {
background: #d4edda;
border-left: 4px solid #28a745;
}
.safety-panel {
background: #fff3cd;
border-left: 4px solid #ffc107;
}
.test-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
margin-top: 15px;
}
.test-category {
background: white;
border: 1px solid #dee2e6;
border-radius: 8px;
padding: 15px;
}
.test-category h6 {
color: #495057;
border-bottom: 1px solid #dee2e6;
padding-bottom: 10px;
margin-bottom: 15px;
}
.test-item {
margin-bottom: 15px;
}
.test-result {
display: flex;
align-items: center;
gap: 10px;
}
.result-indicator {
width: 20px;
height: 20px;
border-radius: 50%;
display: inline-block;
}
.positive { background-color: #dc3545; }
.negative { background-color: #28a745; }
.pending { background-color: #6c757d; }
.invalid { background-color: #ffc107; }
.test-notes {
background: #f8f9fa;
border-radius: 4px;
padding: 10px;
margin-top: 10px;
}
.compliance-check {
background: #e2e3e5;
border-radius: 8px;
padding: 15px;
margin-top: 15px;
}
</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_unit_list' %}">Blood Units</a></li>
<li class="breadcrumb-item"><a href="{% url 'blood_bank:blood_unit_detail' blood_unit.id %}">{{ blood_unit.unit_number }}</a></li>
<li class="breadcrumb-item active">Blood Test</li>
</ol>
<!-- END breadcrumb -->
<!-- BEGIN page-header -->
<h1 class="page-header">Blood Test <small>{{ blood_unit.unit_number }}</small></h1>
<!-- END page-header -->
<!-- BEGIN panel -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">
<i class="fa fa-vial"></i> Blood Testing Panel
</h4>
<div class="panel-heading-btn">
<span class="badge bg-info">Unit: {{ blood_unit.unit_number }}</span>
</div>
</div>
<div class="panel-body">
<form method="post" id="bloodTestForm">
{% csrf_token %}
<!-- BEGIN unit information -->
<div class="form-section unit-info">
<h5><i class="fa fa-tint"></i> Blood Unit Information</h5>
<div class="row">
<div class="col-md-6">
<table class="table table-borderless mb-0">
<tr>
<td class="fw-bold">Unit Number:</td>
<td>{{ blood_unit.unit_number }}</td>
</tr>
<tr>
<td class="fw-bold">Blood Group:</td>
<td><span class="badge bg-primary">{{ blood_unit.blood_group.display_name }}</span></td>
</tr>
<tr>
<td class="fw-bold">Component:</td>
<td>{{ blood_unit.component.get_name_display }}</td>
</tr>
<tr>
<td class="fw-bold">Volume:</td>
<td>{{ blood_unit.volume_ml }} ml</td>
</tr>
</table>
</div>
<div class="col-md-6">
<table class="table table-borderless mb-0">
<tr>
<td class="fw-bold">Donor:</td>
<td>{{ blood_unit.donor.full_name }}</td>
</tr>
<tr>
<td class="fw-bold">Collection Date:</td>
<td>{{ blood_unit.collection_date|date:"M d, Y" }}</td>
</tr>
<tr>
<td class="fw-bold">Expiry Date:</td>
<td>{{ blood_unit.expiry_date|date:"M d, Y" }}</td>
</tr>
<tr>
<td class="fw-bold">Status:</td>
<td>
<span class="badge bg-{% if blood_unit.status == 'available' %}success{% else %}warning{% endif %}">
{{ blood_unit.get_status_display }}
</span>
</td>
</tr>
</table>
</div>
</div>
</div>
<!-- END unit information -->
<!-- BEGIN test information -->
<div class="form-section test-panel">
<h5><i class="fa fa-flask"></i> Test Information</h5>
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label for="testDate" class="form-label">
Test Date <span class="required-field">*</span>
</label>
<input type="datetime-local" class="form-control" id="testDate" name="test_date" required>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label for="testedBy" class="form-label">
Tested By <span class="required-field">*</span>
</label>
<select class="form-select" id="testedBy" name="tested_by" required>
<option value="">Select technician...</option>
{% for staff in lab_staff %}
<option value="{{ staff.id }}">{{ staff.get_full_name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label for="testMethod" class="form-label">
Test Method <span class="required-field">*</span>
</label>
<select class="form-select" id="testMethod" name="test_method" required>
<option value="">Select method...</option>
<option value="elisa">ELISA</option>
<option value="chemiluminescence">Chemiluminescence</option>
<option value="nat">NAT (Nucleic Acid Testing)</option>
<option value="rapid_test">Rapid Test</option>
<option value="pcr">PCR</option>
</select>
</div>
</div>
</div>
</div>
<!-- END test information -->
<!-- BEGIN infectious disease testing -->
<div class="form-section">
<h5><i class="fa fa-virus"></i> Infectious Disease Testing</h5>
<div class="test-grid">
<!-- HIV Testing -->
<div class="test-category">
<h6><i class="fa fa-shield-virus"></i> HIV Testing</h6>
<div class="test-item">
<label class="form-label">HIV 1/2 Antibody</label>
<div class="test-result">
<select class="form-select" name="hiv_antibody" required>
<option value="">Select result...</option>
<option value="negative">Negative</option>
<option value="positive">Positive</option>
<option value="indeterminate">Indeterminate</option>
<option value="invalid">Invalid</option>
</select>
<span class="result-indicator pending" id="hiv_antibody_indicator"></span>
</div>
</div>
<div class="test-item">
<label class="form-label">HIV NAT</label>
<div class="test-result">
<select class="form-select" name="hiv_nat" required>
<option value="">Select result...</option>
<option value="negative">Negative</option>
<option value="positive">Positive</option>
<option value="indeterminate">Indeterminate</option>
<option value="invalid">Invalid</option>
</select>
<span class="result-indicator pending" id="hiv_nat_indicator"></span>
</div>
</div>
</div>
<!-- Hepatitis Testing -->
<div class="test-category">
<h6><i class="fa fa-liver"></i> Hepatitis Testing</h6>
<div class="test-item">
<label class="form-label">Hepatitis B Surface Antigen</label>
<div class="test-result">
<select class="form-select" name="hbsag" required>
<option value="">Select result...</option>
<option value="negative">Negative</option>
<option value="positive">Positive</option>
<option value="indeterminate">Indeterminate</option>
<option value="invalid">Invalid</option>
</select>
<span class="result-indicator pending" id="hbsag_indicator"></span>
</div>
</div>
<div class="test-item">
<label class="form-label">Hepatitis C Antibody</label>
<div class="test-result">
<select class="form-select" name="hcv_antibody" required>
<option value="">Select result...</option>
<option value="negative">Negative</option>
<option value="positive">Positive</option>
<option value="indeterminate">Indeterminate</option>
<option value="invalid">Invalid</option>
</select>
<span class="result-indicator pending" id="hcv_antibody_indicator"></span>
</div>
</div>
<div class="test-item">
<label class="form-label">Hepatitis C NAT</label>
<div class="test-result">
<select class="form-select" name="hcv_nat" required>
<option value="">Select result...</option>
<option value="negative">Negative</option>
<option value="positive">Positive</option>
<option value="indeterminate">Indeterminate</option>
<option value="invalid">Invalid</option>
</select>
<span class="result-indicator pending" id="hcv_nat_indicator"></span>
</div>
</div>
</div>
<!-- Syphilis Testing -->
<div class="test-category">
<h6><i class="fa fa-bacteria"></i> Syphilis Testing</h6>
<div class="test-item">
<label class="form-label">Syphilis Antibody</label>
<div class="test-result">
<select class="form-select" name="syphilis" required>
<option value="">Select result...</option>
<option value="negative">Negative</option>
<option value="positive">Positive</option>
<option value="indeterminate">Indeterminate</option>
<option value="invalid">Invalid</option>
</select>
<span class="result-indicator pending" id="syphilis_indicator"></span>
</div>
</div>
</div>
<!-- Additional Testing -->
<div class="test-category">
<h6><i class="fa fa-microscope"></i> Additional Tests</h6>
<div class="test-item">
<label class="form-label">HTLV I/II</label>
<div class="test-result">
<select class="form-select" name="htlv" required>
<option value="">Select result...</option>
<option value="negative">Negative</option>
<option value="positive">Positive</option>
<option value="indeterminate">Indeterminate</option>
<option value="invalid">Invalid</option>
</select>
<span class="result-indicator pending" id="htlv_indicator"></span>
</div>
</div>
<div class="test-item">
<label class="form-label">West Nile Virus NAT</label>
<div class="test-result">
<select class="form-select" name="wnv_nat">
<option value="">Select result...</option>
<option value="negative">Negative</option>
<option value="positive">Positive</option>
<option value="indeterminate">Indeterminate</option>
<option value="invalid">Invalid</option>
</select>
<span class="result-indicator pending" id="wnv_nat_indicator"></span>
</div>
</div>
<div class="test-item">
<label class="form-label">Chagas Disease</label>
<div class="test-result">
<select class="form-select" name="chagas">
<option value="">Select result...</option>
<option value="negative">Negative</option>
<option value="positive">Positive</option>
<option value="indeterminate">Indeterminate</option>
<option value="invalid">Invalid</option>
</select>
<span class="result-indicator pending" id="chagas_indicator"></span>
</div>
</div>
</div>
</div>
</div>
<!-- END infectious disease testing -->
<!-- BEGIN test notes and observations -->
<div class="form-section">
<h5><i class="fa fa-clipboard"></i> Test Notes & Observations</h5>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label for="testNotes" class="form-label">Test Notes</label>
<textarea class="form-control" id="testNotes" name="test_notes" rows="4"
placeholder="Record any observations, deviations, or additional notes..."></textarea>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="equipmentUsed" class="form-label">Equipment Used</label>
<input type="text" class="form-control" id="equipmentUsed" name="equipment_used"
placeholder="Analyzer model/serial number">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="lotNumbers" class="form-label">Reagent Lot Numbers</label>
<input type="text" class="form-control" id="lotNumbers" name="lot_numbers"
placeholder="Reagent lot numbers used">
</div>
</div>
</div>
</div>
<!-- END test notes and observations -->
<!-- BEGIN compliance verification -->
<div class="form-section safety-panel">
<h5><i class="fa fa-shield-alt"></i> Compliance Verification</h5>
<div class="compliance-check">
<div class="row">
<div class="col-md-6">
<h6>Quality Control</h6>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="controlsPassed" name="controls_passed" required>
<label class="form-check-label" for="controlsPassed">
Quality controls passed within acceptable limits
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="equipmentCalibrated" name="equipment_calibrated" required>
<label class="form-check-label" for="equipmentCalibrated">
Equipment calibrated and functioning properly
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="procedureFollowed" name="procedure_followed" required>
<label class="form-check-label" for="procedureFollowed">
Standard operating procedure followed
</label>
</div>
</div>
<div class="col-md-6">
<h6>Regulatory Compliance</h6>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="fdaCompliant" checked disabled>
<label class="form-check-label" for="fdaCompliant">
FDA 21 CFR Part 606 compliant
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="aabbCompliant" checked disabled>
<label class="form-check-label" for="aabbCompliant">
AABB standards compliant
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="cliaCompliant" checked disabled>
<label class="form-check-label" for="cliaCompliant">
CLIA requirements met
</label>
</div>
</div>
</div>
</div>
</div>
<!-- END compliance verification -->
<!-- BEGIN test summary -->
<div class="test-notes">
<h6><i class="fa fa-chart-bar"></i> Test Summary</h6>
<div id="testSummary">
<p class="text-muted">Complete test results to view summary</p>
</div>
</div>
<!-- END test summary -->
<!-- BEGIN form actions -->
<div class="d-flex justify-content-between mt-4">
<a href="{% url 'blood_bank:blood_unit_detail' blood_unit.id %}" class="btn btn-secondary">
<i class="fa fa-arrow-left"></i> Cancel
</a>
<div>
<button type="button" class="btn btn-info" onclick="validateTests()">
<i class="fa fa-check"></i> Validate Results
</button>
<button type="submit" class="btn btn-primary" id="submitBtn" disabled>
<i class="fa fa-save"></i> Save Test Results
</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
$('#testedBy, #testMethod').select2({
theme: 'bootstrap-5'
});
// Set default test date to now
var now = new Date();
$('#testDate').val(now.toISOString().slice(0, 16));
// Update result indicators when test results change
$('select[name$="_antibody"], select[name$="_nat"], select[name="hbsag"], select[name="syphilis"], select[name="htlv"], select[name="chagas"]').on('change', function() {
updateResultIndicator(this);
updateTestSummary();
validateTests();
});
// Form validation
$('#bloodTestForm').on('submit', function(e) {
if (!validateTests()) {
e.preventDefault();
}
});
});
function updateResultIndicator(selectElement) {
var result = $(selectElement).val();
var indicatorId = $(selectElement).attr('name') + '_indicator';
var indicator = $('#' + indicatorId);
indicator.removeClass('positive negative pending invalid');
switch(result) {
case 'positive':
indicator.addClass('positive');
break;
case 'negative':
indicator.addClass('negative');
break;
case 'indeterminate':
case 'invalid':
indicator.addClass('invalid');
break;
default:
indicator.addClass('pending');
}
}
function updateTestSummary() {
var allTests = $('select[name$="_antibody"], select[name$="_nat"], select[name="hbsag"], select[name="syphilis"], select[name="htlv"], select[name="chagas"]');
var completedTests = allTests.filter(function() { return $(this).val() !== ''; });
var positiveTests = allTests.filter(function() { return $(this).val() === 'positive'; });
var negativeTests = allTests.filter(function() { return $(this).val() === 'negative'; });
var indeterminateTests = allTests.filter(function() { return $(this).val() === 'indeterminate' || $(this).val() === 'invalid'; });
var summaryHtml = '<div class="row">';
summaryHtml += '<div class="col-md-3"><strong>Total Tests:</strong> ' + allTests.length + '</div>';
summaryHtml += '<div class="col-md-3"><strong>Completed:</strong> ' + completedTests.length + '</div>';
summaryHtml += '<div class="col-md-3"><strong>Negative:</strong> <span class="text-success">' + negativeTests.length + '</span></div>';
summaryHtml += '<div class="col-md-3"><strong>Positive/Issues:</strong> <span class="text-danger">' + (positiveTests.length + indeterminateTests.length) + '</span></div>';
summaryHtml += '</div>';
if (positiveTests.length > 0) {
summaryHtml += '<div class="alert alert-danger mt-2">';
summaryHtml += '<strong>⚠️ POSITIVE RESULTS DETECTED:</strong> This unit must be quarantined immediately.';
summaryHtml += '</div>';
} else if (indeterminateTests.length > 0) {
summaryHtml += '<div class="alert alert-warning mt-2">';
summaryHtml += '<strong>⚠️ INDETERMINATE RESULTS:</strong> Repeat testing required.';
summaryHtml += '</div>';
} else if (completedTests.length === allTests.length && negativeTests.length === allTests.length) {
summaryHtml += '<div class="alert alert-success mt-2">';
summaryHtml += '<strong>✅ ALL TESTS NEGATIVE:</strong> Unit cleared for use.';
summaryHtml += '</div>';
}
$('#testSummary').html(summaryHtml);
}
function validateTests() {
var errors = [];
// Check required fields
if (!$('#testDate').val()) {
errors.push('Please enter test date');
}
if (!$('#testedBy').val()) {
errors.push('Please select who performed the tests');
}
if (!$('#testMethod').val()) {
errors.push('Please select test method');
}
// Check required tests
var requiredTests = ['hiv_antibody', 'hiv_nat', 'hbsag', 'hcv_antibody', 'hcv_nat', 'syphilis', 'htlv'];
var missingTests = [];
requiredTests.forEach(function(testName) {
if (!$('select[name="' + testName + '"]').val()) {
missingTests.push(testName.replace('_', ' ').toUpperCase());
}
});
if (missingTests.length > 0) {
errors.push('Missing required test results: ' + missingTests.join(', '));
}
// Check compliance checkboxes
var complianceChecks = ['controlsPassed', 'equipmentCalibrated', 'procedureFollowed'];
var uncheckedCompliance = complianceChecks.filter(function(id) {
return !document.getElementById(id).checked;
});
if (uncheckedCompliance.length > 0) {
errors.push('Please confirm all compliance requirements');
}
// Enable/disable submit button
$('#submitBtn').prop('disabled', errors.length > 0);
if (errors.length > 0) {
if (errors.length < 5) { // Only show errors if validation was explicitly requested
Swal.fire({
icon: 'error',
title: 'Validation Errors',
html: '<ul class="text-start"><li>' + errors.join('</li><li>') + '</li></ul>',
confirmButtonText: 'OK'
});
}
return false;
}
// Check for positive results
var positiveTests = $('select').filter(function() { return $(this).val() === 'positive'; });
if (positiveTests.length > 0) {
Swal.fire({
icon: 'warning',
title: 'Positive Test Results Detected',
html: '<strong>This blood unit has positive test results and will be automatically quarantined.</strong><br><br>Please ensure proper disposal procedures are followed.',
confirmButtonText: 'I Understand'
});
} else {
Swal.fire({
icon: 'success',
title: 'Validation Passed',
text: 'All test results are complete and valid.',
timer: 1500,
showConfirmButton: false
});
}
return true;
}
</script>
{% endblock %}