642 lines
35 KiB
HTML
642 lines
35 KiB
HTML
{% extends "base.html" %}
|
|
{% load static %}
|
|
|
|
{% block title %}{% if object %}Edit Specimen{% else %}New Specimen{% endif %}{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="d-flex align-items-center mb-3">
|
|
<div>
|
|
<ol class="breadcrumb">
|
|
<li class="breadcrumb-item"><a href="{% url 'laboratory:dashboard' %}">Laboratory</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'laboratory:specimen_list' %}">Specimens</a></li>
|
|
<li class="breadcrumb-item active">{% if object %}Edit{% else %}New{% endif %}</li>
|
|
</ol>
|
|
<h1 class="page-header mb-0">
|
|
{% if object %}Edit Specimen - {{ object.specimen_id }}{% else %}New Specimen Collection{% endif %}
|
|
</h1>
|
|
</div>
|
|
<div class="ms-auto">
|
|
<a href="{% url 'laboratory:specimen_list' %}" class="btn btn-secondary">
|
|
<i class="fas fa-arrow-left me-2"></i>Back to Specimens
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-xl-8">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h4 class="card-title">
|
|
<i class="fas fa-vial me-2"></i>
|
|
Specimen Information
|
|
</h4>
|
|
</div>
|
|
<div class="card-body">
|
|
{% if messages %}
|
|
{% for message in messages %}
|
|
<div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
|
|
{{ message }}
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
</div>
|
|
{% endfor %}
|
|
{% endif %}
|
|
|
|
<form method="post" novalidate>
|
|
{% csrf_token %}
|
|
|
|
<!-- Patient Selection -->
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="{{ form.patient.id_for_label }}" class="form-label">Patient *</label>
|
|
<select class="form-select {% if form.patient.errors %}is-invalid{% endif %}"
|
|
id="{{ form.patient.id_for_label }}"
|
|
name="{{ form.patient.name }}"
|
|
required>
|
|
<option value="">Select Patient</option>
|
|
{% for choice in form.patient.field.choices %}
|
|
{% if choice.0 %}
|
|
<option value="{{ choice.0 }}" {% if choice.0 == form.patient.value %}selected{% endif %}>
|
|
{{ choice.1 }}
|
|
</option>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</select>
|
|
{% if form.patient.errors %}
|
|
<div class="invalid-feedback">
|
|
{{ form.patient.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
<div class="form-text">
|
|
<button type="button" class="btn btn-sm btn-outline-primary" onclick="searchPatient()">
|
|
<i class="fas fa-search me-1"></i>Search Patient
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="{{ form.specimen_id.id_for_label }}" class="form-label">Specimen ID</label>
|
|
<div class="input-group">
|
|
<input type="text"
|
|
class="specimen form-control {% if form.specimen_id.errors %}is-invalid{% endif %}"
|
|
id="{{ form.specimen_id.id_for_label }}"
|
|
name="{{ form.specimen_id.name }}"
|
|
value="{{ form.specimen_id.value|default:'' }}"
|
|
placeholder="Auto-generated if empty">
|
|
<button type="button" class="btn btn-outline-secondary" onclick="generateSpecimenId()">
|
|
<i class="fas fa-sync"></i>
|
|
</button>
|
|
</div>
|
|
{% if form.specimen_id.errors %}
|
|
<div class="invalid-feedback">
|
|
{{ form.specimen_id.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Specimen Details -->
|
|
<div class="row">
|
|
<div class="col-md-4">
|
|
<div class="mb-3">
|
|
<label for="{{ form.specimen_type.id_for_label }}" class="form-label">Specimen Type *</label>
|
|
<select class="form-select {% if form.specimen_type.errors %}is-invalid{% endif %}"
|
|
id="{{ form.specimen_type.id_for_label }}"
|
|
name="{{ form.specimen_type.name }}"
|
|
required>
|
|
<option value="">Select Type</option>
|
|
{% for choice in form.specimen_type.field.choices %}
|
|
<option value="{{ choice.0 }}" {% if choice.0 == form.specimen_type.value %}selected{% endif %}>
|
|
{{ choice.1 }}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
{% if form.specimen_type.errors %}
|
|
<div class="invalid-feedback">
|
|
{{ form.specimen_type.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="mb-3">
|
|
<label for="{{ form.collection_site.id_for_label }}" class="form-label">Collection Site</label>
|
|
<input type="text"
|
|
class="form-control {% if form.collection_site.errors %}is-invalid{% endif %}"
|
|
id="{{ form.collection_site.id_for_label }}"
|
|
name="{{ form.collection_site.name }}"
|
|
value="{{ form.collection_site.value|default:'' }}"
|
|
placeholder="e.g., Left arm, Right hand">
|
|
{% if form.collection_site.errors %}
|
|
<div class="invalid-feedback">
|
|
{{ form.collection_site.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="mb-3">
|
|
<label for="{{ form.volume.id_for_label }}" class="form-label">Volume</label>
|
|
<input type="text"
|
|
class="form-control {% if form.volume.errors %}is-invalid{% endif %}"
|
|
id="{{ form.volume.id_for_label }}"
|
|
name="{{ form.volume.name }}"
|
|
value="{{ form.volume.value|default:'' }}"
|
|
placeholder="e.g., 5 mL, 10 tubes">
|
|
{% if form.volume.errors %}
|
|
<div class="invalid-feedback">
|
|
{{ form.volume.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Collection Information -->
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="{{ form.collection_date.id_for_label }}" class="form-label">Collection Date & Time *</label>
|
|
<input type="datetime-local"
|
|
class="form-control {% if form.collection_date.errors %}is-invalid{% endif %}"
|
|
id="{{ form.collection_date.id_for_label }}"
|
|
name="{{ form.collection_date.name }}"
|
|
value="{{ form.collection_date.value|default:'' }}"
|
|
required>
|
|
{% if form.collection_date.errors %}
|
|
<div class="invalid-feedback">
|
|
{{ form.collection_date.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="{{ form.collected_by.id_for_label }}" class="form-label">Collected By *</label>
|
|
<select class="form-select {% if form.collected_by.errors %}is-invalid{% endif %}"
|
|
id="{{ form.collected_by.id_for_label }}"
|
|
name="{{ form.collected_by.name }}"
|
|
required>
|
|
<option value="">Select Staff Member</option>
|
|
{% for choice in form.collected_by.field.choices %}
|
|
{% if choice.0 %}
|
|
<option value="{{ choice.0 }}" {% if choice.0 == form.collected_by.value %}selected{% endif %}>
|
|
{{ choice.1 }}
|
|
</option>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</select>
|
|
{% if form.collected_by.errors %}
|
|
<div class="invalid-feedback">
|
|
{{ form.collected_by.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Container and Storage -->
|
|
<div class="row">
|
|
<div class="col-md-4">
|
|
<div class="mb-3">
|
|
<label for="{{ form.container_type.id_for_label }}" class="form-label">Container Type</label>
|
|
<select class="form-select {% if form.container_type.errors %}is-invalid{% endif %}"
|
|
id="{{ form.container_type.id_for_label }}"
|
|
name="{{ form.container_type.name }}">
|
|
<option value="">Select Container</option>
|
|
<option value="red_top" {% if form.container_type.value == 'red_top' %}selected{% endif %}>Red Top (No Additive)</option>
|
|
<option value="lavender_top" {% if form.container_type.value == 'lavender_top' %}selected{% endif %}>Lavender Top (EDTA)</option>
|
|
<option value="green_top" {% if form.container_type.value == 'green_top' %}selected{% endif %}>Green Top (Heparin)</option>
|
|
<option value="blue_top" {% if form.container_type.value == 'blue_top' %}selected{% endif %}>Blue Top (Citrate)</option>
|
|
<option value="gray_top" {% if form.container_type.value == 'gray_top' %}selected{% endif %}>Gray Top (Fluoride)</option>
|
|
<option value="urine_cup" {% if form.container_type.value == 'urine_cup' %}selected{% endif %}>Urine Cup</option>
|
|
<option value="sterile_container" {% if form.container_type.value == 'sterile_container' %}selected{% endif %}>Sterile Container</option>
|
|
</select>
|
|
{% if form.container_type.errors %}
|
|
<div class="invalid-feedback">
|
|
{{ form.container_type.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="mb-3">
|
|
<label for="{{ form.storage_temperature.id_for_label }}" class="form-label">Storage Temperature</label>
|
|
<select class="form-select {% if form.storage_temperature.errors %}is-invalid{% endif %}"
|
|
id="{{ form.storage_temperature.id_for_label }}"
|
|
name="{{ form.storage_temperature.name }}">
|
|
<option value="">Select Temperature</option>
|
|
<option value="room_temp" {% if form.storage_temperature.value == 'room_temp' %}selected{% endif %}>Room Temperature</option>
|
|
<option value="refrigerated" {% if form.storage_temperature.value == 'refrigerated' %}selected{% endif %}>Refrigerated (2-8°C)</option>
|
|
<option value="frozen" {% if form.storage_temperature.value == 'frozen' %}selected{% endif %}>Frozen (-20°C)</option>
|
|
<option value="deep_frozen" {% if form.storage_temperature.value == 'deep_frozen' %}selected{% endif %}>Deep Frozen (-80°C)</option>
|
|
</select>
|
|
{% if form.storage_temperature.errors %}
|
|
<div class="invalid-feedback">
|
|
{{ form.storage_temperature.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="mb-3">
|
|
<label for="{{ form.priority.id_for_label }}" class="form-label">Priority</label>
|
|
<select class="form-select {% if form.priority.errors %}is-invalid{% endif %}"
|
|
id="{{ form.priority.id_for_label }}"
|
|
name="{{ form.priority.name }}">
|
|
{% for choice in form.priority.field.choices %}
|
|
<option value="{{ choice.0 }}" {% if choice.0 == form.priority.value %}selected{% endif %}>
|
|
{{ choice.1 }}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
{% if form.priority.errors %}
|
|
<div class="invalid-feedback">
|
|
{{ form.priority.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Status and Condition -->
|
|
<div class="row">
|
|
<div class="col-md-4">
|
|
<div class="mb-3">
|
|
<label for="{{ form.status.id_for_label }}" class="form-label">Status</label>
|
|
<select class="form-select {% if form.status.errors %}is-invalid{% endif %}"
|
|
id="{{ form.status.id_for_label }}"
|
|
name="{{ form.status.name }}">
|
|
{% for choice in form.status.field.choices %}
|
|
<option value="{{ choice.0 }}" {% if choice.0 == form.status.value %}selected{% endif %}>
|
|
{{ choice.1 }}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
{% if form.status.errors %}
|
|
<div class="invalid-feedback">
|
|
{{ form.status.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="mb-3">
|
|
<label for="{{ form.condition.id_for_label }}" class="form-label">Condition</label>
|
|
<select class="form-select {% if form.condition.errors %}is-invalid{% endif %}"
|
|
id="{{ form.condition.id_for_label }}"
|
|
name="{{ form.condition.name }}">
|
|
<option value="">Select Condition</option>
|
|
<option value="good" {% if form.condition.value == 'good' %}selected{% endif %}>Good</option>
|
|
<option value="acceptable" {% if form.condition.value == 'acceptable' %}selected{% endif %}>Acceptable</option>
|
|
<option value="hemolyzed" {% if form.condition.value == 'hemolyzed' %}selected{% endif %}>Hemolyzed</option>
|
|
<option value="clotted" {% if form.condition.value == 'clotted' %}selected{% endif %}>Clotted</option>
|
|
<option value="insufficient" {% if form.condition.value == 'insufficient' %}selected{% endif %}>Insufficient Volume</option>
|
|
<option value="contaminated" {% if form.condition.value == 'contaminated' %}selected{% endif %}>Contaminated</option>
|
|
<option value="rejected" {% if form.condition.value == 'rejected' %}selected{% endif %}>Rejected</option>
|
|
</select>
|
|
{% if form.condition.errors %}
|
|
<div class="invalid-feedback">
|
|
{{ form.condition.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="mb-3">
|
|
<label for="{{ form.expiry_date.id_for_label }}" class="form-label">Expiry Date</label>
|
|
<input type="date"
|
|
class="form-control {% if form.expiry_date.errors %}is-invalid{% endif %}"
|
|
id="{{ form.expiry_date.id_for_label }}"
|
|
name="{{ form.expiry_date.name }}"
|
|
value="{{ form.expiry_date.value|default:'' }}">
|
|
{% if form.expiry_date.errors %}
|
|
<div class="invalid-feedback">
|
|
{{ form.expiry_date.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Additional Information -->
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="{{ form.collection_method.id_for_label }}" class="form-label">Collection Method</label>
|
|
<input type="text"
|
|
class="form-control {% if form.collection_method.errors %}is-invalid{% endif %}"
|
|
id="{{ form.collection_method.id_for_label }}"
|
|
name="{{ form.collection_method.name }}"
|
|
value="{{ form.collection_method.value|default:'' }}"
|
|
placeholder="e.g., Venipuncture, Clean catch">
|
|
{% if form.collection_method.errors %}
|
|
<div class="invalid-feedback">
|
|
{{ form.collection_method.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="{{ form.current_location.id_for_label }}" class="form-label">Current Location</label>
|
|
<input type="text"
|
|
class="form-control {% if form.current_location.errors %}is-invalid{% endif %}"
|
|
id="{{ form.current_location.id_for_label }}"
|
|
name="{{ form.current_location.name }}"
|
|
value="{{ form.current_location.value|default:'' }}"
|
|
placeholder="e.g., Lab Refrigerator A">
|
|
{% if form.current_location.errors %}
|
|
<div class="invalid-feedback">
|
|
{{ form.current_location.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Checkboxes -->
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-check mb-3">
|
|
<input class="form-check-input {% if form.fasting_status.errors %}is-invalid{% endif %}"
|
|
type="checkbox"
|
|
id="{{ form.fasting_status.id_for_label }}"
|
|
name="{{ form.fasting_status.name }}"
|
|
{% if form.fasting_status.value %}checked{% endif %}>
|
|
<label class="form-check-label" for="{{ form.fasting_status.id_for_label }}">
|
|
Patient was fasting
|
|
</label>
|
|
{% if form.fasting_status.errors %}
|
|
<div class="invalid-feedback">
|
|
{{ form.fasting_status.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-check mb-3">
|
|
<input class="form-check-input {% if form.requires_special_handling.errors %}is-invalid{% endif %}"
|
|
type="checkbox"
|
|
id="{{ form.requires_special_handling.id_for_label }}"
|
|
name="{{ form.requires_special_handling.name }}"
|
|
{% if form.requires_special_handling.value %}checked{% endif %}>
|
|
<label class="form-check-label" for="{{ form.requires_special_handling.id_for_label }}">
|
|
Requires special handling
|
|
</label>
|
|
{% if form.requires_special_handling.errors %}
|
|
<div class="invalid-feedback">
|
|
{{ form.requires_special_handling.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Notes -->
|
|
<div class="mb-3">
|
|
<label for="{{ form.collection_notes.id_for_label }}" class="form-label">Collection Notes</label>
|
|
<textarea class="form-control {% if form.collection_notes.errors %}is-invalid{% endif %}"
|
|
id="{{ form.collection_notes.id_for_label }}"
|
|
name="{{ form.collection_notes.name }}"
|
|
rows="3"
|
|
placeholder="Enter any notes about the collection process, patient condition, or special circumstances...">{{ form.collection_notes.value|default:'' }}</textarea>
|
|
{% if form.collection_notes.errors %}
|
|
<div class="invalid-feedback">
|
|
{{ form.collection_notes.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="d-flex justify-content-between">
|
|
<div>
|
|
{% if object %}
|
|
<a href="{% url 'laboratory:specimen_detail' object.pk %}" class="btn btn-secondary">
|
|
<i class="fas fa-times me-2"></i>Cancel
|
|
</a>
|
|
{% else %}
|
|
<a href="{% url 'laboratory:specimen_list' %}" class="btn btn-secondary">
|
|
<i class="fas fa-times me-2"></i>Cancel
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
<div>
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="fas fa-save me-2"></i>
|
|
{% if object %}Update Specimen{% else %}Create Specimen{% endif %}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-xl-4">
|
|
<!-- Collection Guidelines -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="card-title">
|
|
<i class="fas fa-clipboard-check me-2"></i>
|
|
Collection Guidelines
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div id="guidelinesContent">
|
|
<p class="text-muted">Select a specimen type to view collection guidelines.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Container Guide -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="card-title">
|
|
<i class="fas fa-vials me-2"></i>
|
|
Container Guide
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="mb-3">
|
|
<div class="d-flex align-items-center mb-2">
|
|
<div class="bg-danger rounded-circle me-2" style="width: 16px; height: 16px;"></div>
|
|
<strong>Red Top</strong>
|
|
</div>
|
|
<p class="small text-muted">No additive - for serum chemistry tests</p>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<div class="d-flex align-items-center mb-2">
|
|
<div class="bg-purple rounded-circle me-2" style="width: 16px; height: 16px; background-color: #6f42c1;"></div>
|
|
<strong>Lavender Top</strong>
|
|
</div>
|
|
<p class="small text-muted">EDTA - for hematology tests</p>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<div class="d-flex align-items-center mb-2">
|
|
<div class="bg-success rounded-circle me-2" style="width: 16px; height: 16px;"></div>
|
|
<strong>Green Top</strong>
|
|
</div>
|
|
<p class="small text-muted">Heparin - for plasma chemistry</p>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<div class="d-flex align-items-center mb-2">
|
|
<div class="bg-primary rounded-circle me-2" style="width: 16px; height: 16px;"></div>
|
|
<strong>Blue Top</strong>
|
|
</div>
|
|
<p class="small text-muted">Citrate - for coagulation studies</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Quick Actions -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title">
|
|
<i class="fas fa-bolt me-2"></i>
|
|
Quick Actions
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="d-grid gap-2">
|
|
<button type="button" class="btn btn-outline-primary" onclick="setCurrentDateTime()">
|
|
<i class="fas fa-clock me-2"></i>Set Current Time
|
|
</button>
|
|
<button type="button" class="btn btn-outline-secondary" onclick="generateBarcode()">
|
|
<i class="fas fa-barcode me-2"></i>Generate Barcode
|
|
</button>
|
|
<button type="button" class="btn btn-outline-info" onclick="printLabel()">
|
|
<i class="fas fa-print me-2"></i>Print Label
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const specimenTypeSelect = document.getElementById('{{ form.specimen_type.id_for_label }}');
|
|
const containerSelect = document.getElementById('{{ form.container_type.id_for_label }}');
|
|
const patientSelect = document.getElementById('{{ form.patient.id_for_label }}');
|
|
|
|
// Update guidelines when specimen type changes
|
|
specimenTypeSelect.addEventListener('change', function() {
|
|
updateGuidelines(this.value);
|
|
updateRecommendedContainer(this.value);
|
|
});
|
|
|
|
// Set current date/time if creating new specimen
|
|
{% if not object %}
|
|
setCurrentDateTime();
|
|
{% endif %}
|
|
|
|
// Initialize guidelines if specimen type is already selected
|
|
if (specimenTypeSelect.value) {
|
|
updateGuidelines(specimenTypeSelect.value);
|
|
}
|
|
});
|
|
|
|
function updateGuidelines(specimenType) {
|
|
const guidelines = {
|
|
'blood': `
|
|
<h6><i class="fas fa-tint text-danger me-2"></i>Blood Collection</h6>
|
|
<ul class="small">
|
|
<li>Verify patient identity with two identifiers</li>
|
|
<li>Use proper venipuncture technique</li>
|
|
<li>Fill tubes in correct order of draw</li>
|
|
<li>Invert tubes gently 8-10 times</li>
|
|
<li>Label tubes immediately after collection</li>
|
|
</ul>
|
|
`,
|
|
'urine': `
|
|
<h6><i class="fas fa-flask text-warning me-2"></i>Urine Collection</h6>
|
|
<ul class="small">
|
|
<li>Use clean-catch midstream technique</li>
|
|
<li>Collect first morning specimen when possible</li>
|
|
<li>Minimum 10mL required for routine analysis</li>
|
|
<li>Refrigerate if transport delayed >2 hours</li>
|
|
<li>Avoid contamination from external sources</li>
|
|
</ul>
|
|
`,
|
|
'sputum': `
|
|
<h6><i class="fas fa-lungs text-info me-2"></i>Sputum Collection</h6>
|
|
<ul class="small">
|
|
<li>Collect early morning specimen</li>
|
|
<li>Rinse mouth with water before collection</li>
|
|
<li>Cough deeply to produce lower respiratory secretions</li>
|
|
<li>Avoid saliva contamination</li>
|
|
<li>Transport to lab within 2 hours</li>
|
|
</ul>
|
|
`,
|
|
'swab': `
|
|
<h6><i class="fas fa-hand text-secondary me-2"></i>Swab Collection</h6>
|
|
<ul class="small">
|
|
<li>Use sterile swab and transport medium</li>
|
|
<li>Collect adequate sample material</li>
|
|
<li>Avoid contamination from surrounding areas</li>
|
|
<li>Place swab in transport medium immediately</li>
|
|
<li>Label with specific collection site</li>
|
|
</ul>
|
|
`
|
|
};
|
|
|
|
let content
|
|
content = guidelines[specimenType] || '<p class="text-muted">Select a specimen type to view collection guidelines.</p>';
|
|
document.getElementById('guidelinesContent').innerHTML = content;
|
|
}
|
|
|
|
function updateRecommendedContainer(specimenType) {
|
|
const containerSelect = document.getElementById('{{ form.container_type.id_for_label }}');
|
|
const recommendations = {
|
|
'blood': 'red_top',
|
|
'urine': 'urine_cup',
|
|
'sputum': 'sterile_container',
|
|
'swab': 'sterile_container'
|
|
};
|
|
|
|
if (recommendations[specimenType] && !containerSelect.value) {
|
|
containerSelect.value = recommendations[specimenType];
|
|
}
|
|
}
|
|
|
|
function setCurrentDateTime() {
|
|
const now = new Date();
|
|
const localDateTime = new Date(now.getTime() - now.getTimezoneOffset() * 60000).toISOString().slice(0, 16);
|
|
document.getElementById('{{ form.collection_date.id_for_label }}').value = localDateTime;
|
|
}
|
|
|
|
function generateSpecimenId() {
|
|
const now = new Date();
|
|
const year = now.getFullYear().toString().slice(-2);
|
|
const month = (now.getMonth() + 1).toString().padStart(2, '0');
|
|
const day = now.getDate().toString().padStart(2, '0');
|
|
const time = now.getTime().toString().slice(-6);
|
|
|
|
let specimenId;
|
|
specimenId = `SP${year}${month}${day}${time}`;
|
|
document.querySelector('.specimen').value = specimenId;
|
|
}
|
|
|
|
function generateBarcode() {
|
|
// In a real implementation, this would generate a barcode
|
|
alert('Barcode generation functionality would be implemented here.');
|
|
}
|
|
|
|
function printLabel() {
|
|
// In a real implementation, this would print a specimen label
|
|
alert('Label printing functionality would be implemented here.');
|
|
}
|
|
|
|
function searchPatient() {
|
|
// In a real implementation, this would open a patient search modal
|
|
alert('Patient search functionality would be implemented here.');
|
|
}
|
|
</script>
|
|
{% endblock %}
|
|
|