2025-08-12 13:33:25 +03:00

640 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="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>
`
};
const 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);
const specimenId = `SP${year}${month}${day}${time}`;
document.getElementById('{{ form.specimen_id.id_for_label }}').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 %}