Marwan Alwali 73c9e2e921 update
2025-09-02 15:14:36 +03:00

583 lines
31 KiB
HTML

{% extends "base.html" %}
{% load static %}
{% block title %}{% if object %}Edit Lab Test{% else %}New Lab Test{% 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:lab_test_list' %}">Tests</a></li>
<li class="breadcrumb-item active">{% if object %}Edit{% else %}New{% endif %}</li>
</ol>
<h1 class="page-header mb-0">
{% if object %}Edit Lab Test{% else %}Create Lab Test{% endif %}
</h1>
</div>
<div class="ms-auto">
<a href="{% url 'laboratory:lab_test_list' %}" class="btn btn-secondary">
<i class="fas fa-arrow-left me-2"></i>Back to Tests
</a>
</div>
</div>
<div class="row">
<div class="col-xl-8">
<div class="panel panel-inverse" data-sortable-id="index-1">
<div class="panel-heading">
<h4 class="panel-title"><i class="fas fa-vial me-2"></i> {{ _("Lab Test Information")}}</h4>
{# <div class="panel-heading-btn">#}
{# <a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-expand"><i class="fa fa-expand"></i></a>#}
{# <a href="javascript:;" class="btn btn-xs btn-icon btn-success" data-toggle="panel-reload"><i class="fa fa-redo"></i></a>#}
{# <a href="javascript:;" class="btn btn-xs btn-icon btn-warning" data-toggle="panel-collapse"><i class="fa fa-minus"></i></a>#}
{# <a href="javascript:;" class="btn btn-xs btn-icon btn-danger" data-toggle="panel-remove"><i class="fa fa-times"></i></a>#}
{##}
{# </div>#}
</div>
<div class="panel-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 %}
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.name.id_for_label }}" class="form-label">Test Name *</label>
<input type="text"
class="form-control {% if form.name.errors %}is-invalid{% endif %}"
id="{{ form.name.id_for_label }}"
name="{{ form.name.name }}"
value="{{ form.name.value|default:'' }}"
placeholder="Enter test name"
required>
{% if form.name.errors %}
<div class="invalid-feedback">
{{ form.name.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.code.id_for_label }}" class="form-label">Test Code *</label>
<input type="text"
class="form-control {% if form.code.errors %}is-invalid{% endif %}"
id="{{ form.code.id_for_label }}"
name="{{ form.code.name }}"
value="{{ form.code.value|default:'' }}"
placeholder="Enter test code"
required>
{% if form.code.errors %}
<div class="invalid-feedback">
{{ form.code.errors.0 }}
</div>
{% endif %}
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.test_category.id_for_label }}" class="form-label">Category *</label>
<select class="form-select {% if form.test_category.errors %}is-invalid{% endif %}"
id="{{ form.test_category.id_for_label }}"
name="{{ form.test_category.name }}"
required>
<option value="">Select Category</option>
{% for choice in form.test_category.field.choices %}
<option value="{{ choice.0 }}" {% if choice.0 == form.test_category.value %}selected{% endif %}>
{{ choice.1 }}
</option>
{% endfor %}
</select>
{% if form.test_category.errors %}
<div class="invalid-feedback">
{{ form.test_category.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.department.id_for_label }}" class="form-label">Department *</label>
<select class="form-select {% if form.department.errors %}is-invalid{% endif %}"
id="{{ form.department.id_for_label }}"
name="{{ form.department.name }}"
required>
<option value="">Select Department</option>
{% for choice in form.department.field.choices %}
{% if choice.0 %}
<option value="{{ choice.0 }}" {% if choice.0 == form.department.value %}selected{% endif %}>
{{ choice.1 }}
</option>
{% endif %}
{% endfor %}
</select>
{% if form.department.errors %}
<div class="invalid-feedback">
{{ form.department.errors.0 }}
</div>
{% endif %}
</div>
</div>
</div>
<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 Specimen 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.turnaround_time.id_for_label }}" class="form-label">Turnaround Time (hours)</label>
<input type="number"
class="form-control {% if form.turnaround_time.errors %}is-invalid{% endif %}"
id="{{ form.turnaround_time.id_for_label }}"
name="{{ form.turnaround_time.name }}"
value="{{ form.turnaround_time.value|default:'' }}"
min="0"
step="0.5"
placeholder="Enter hours">
{% if form.turnaround_time.errors %}
<div class="invalid-feedback">
{{ form.turnaround_time.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="col-md-4">
<div class="mb-3">
<label for="{{ form.cost.id_for_label }}" class="form-label">Cost</label>
<div class="input-group">
<span class="input-group-text">$</span>
<input type="number"
class="form-control {% if form.cost.errors %}is-invalid{% endif %}"
id="{{ form.cost.id_for_label }}"
name="{{ form.cost.name }}"
value="{{ form.cost.value|default:'' }}"
min="0"
step="0.01"
placeholder="0.00">
</div>
{% if form.cost.errors %}
<div class="invalid-feedback">
{{ form.cost.errors.0 }}
</div>
{% endif %}
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.loinc_code.id_for_label }}" class="form-label">LOINC Code</label>
<input type="text"
class="form-control {% if form.loinc_code.errors %}is-invalid{% endif %}"
id="{{ form.loinc_code.id_for_label }}"
name="{{ form.loinc_code.name }}"
value="{{ form.loinc_code.value|default:'' }}"
placeholder="Enter LOINC code">
{% if form.loinc_code.errors %}
<div class="invalid-feedback">
{{ form.loinc_code.errors.0 }}
</div>
{% endif %}
<div class="form-text">
Logical Observation Identifiers Names and Codes
</div>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.cpt_code.id_for_label }}" class="form-label">CPT Code</label>
<input type="text"
class="form-control {% if form.cpt_code.errors %}is-invalid{% endif %}"
id="{{ form.cpt_code.id_for_label }}"
name="{{ form.cpt_code.name }}"
value="{{ form.cpt_code.value|default:'' }}"
placeholder="Enter CPT code">
{% if form.cpt_code.errors %}
<div class="invalid-feedback">
{{ form.cpt_code.errors.0 }}
</div>
{% endif %}
<div class="form-text">
Current Procedural Terminology code for billing
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.reference_range.id_for_label }}" class="form-label">Reference Range</label>
<input type="text"
class="form-control {% if form.reference_range.errors %}is-invalid{% endif %}"
id="{{ form.reference_range.id_for_label }}"
name="{{ form.reference_range.name }}"
value="{{ form.reference_range.value|default:'' }}"
placeholder="e.g., 70-100 mg/dL">
{% if form.reference_range.errors %}
<div class="invalid-feedback">
{{ form.reference_range.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.unit.id_for_label }}" class="form-label">Unit of Measure</label>
<input type="text"
class="form-control {% if form.unit.errors %}is-invalid{% endif %}"
id="{{ form.unit.id_for_label }}"
name="{{ form.unit.name }}"
value="{{ form.unit.value|default:'' }}"
placeholder="e.g., mg/dL, mmol/L, %">
{% if form.unit.errors %}
<div class="invalid-feedback">
{{ form.unit.errors.0 }}
</div>
{% endif %}
</div>
</div>
</div>
<div class="mb-3">
<label for="{{ form.description.id_for_label }}" class="form-label">Description</label>
<textarea class="form-control {% if form.description.errors %}is-invalid{% endif %}"
id="{{ form.description.id_for_label }}"
name="{{ form.description.name }}"
rows="3"
placeholder="Enter test description and clinical significance...">{{ form.description.value|default:'' }}</textarea>
{% if form.description.errors %}
<div class="invalid-feedback">
{{ form.description.errors.0 }}
</div>
{% endif %}
</div>
<div class="mb-3">
<label for="{{ form.preparation_instructions.id_for_label }}" class="form-label">Preparation Instructions</label>
<textarea class="form-control {% if form.preparation_instructions.errors %}is-invalid{% endif %}"
id="{{ form.preparation_instructions.id_for_label }}"
name="{{ form.preparation_instructions.name }}"
rows="3"
placeholder="Enter patient preparation instructions (fasting, medications, etc.)...">{{ form.preparation_instructions.value|default:'' }}</textarea>
{% if form.preparation_instructions.errors %}
<div class="invalid-feedback">
{{ form.preparation_instructions.errors.0 }}
</div>
{% endif %}
</div>
<div class="row">
<div class="col-md-4">
<div class="form-check mb-3">
<input class="form-check-input {% if form.is_active.errors %}is-invalid{% endif %}"
type="checkbox"
id="{{ form.is_active.id_for_label }}"
name="{{ form.is_active.name }}"
{% if form.is_active.value %}checked{% endif %}>
<label class="form-check-label" for="{{ form.is_active.id_for_label }}">
Active
</label>
{% if form.is_active.errors %}
<div class="invalid-feedback">
{{ form.is_active.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="col-md-4">
<div class="form-check mb-3">
<input class="form-check-input {% if form.requires_fasting.errors %}is-invalid{% endif %}"
type="checkbox"
id="{{ form.requires_fasting.id_for_label }}"
name="{{ form.requires_fasting.name }}"
{% if form.requires_fasting.value %}checked{% endif %}>
<label class="form-check-label" for="{{ form.requires_fasting.id_for_label }}">
Requires Fasting
</label>
{% if form.requires_fasting.errors %}
<div class="invalid-feedback">
{{ form.requires_fasting.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="col-md-4">
<div class="form-check mb-3">
<input class="form-check-input {% if form.is_urgent_available.errors %}is-invalid{% endif %}"
type="checkbox"
id="{{ form.is_urgent_available.id_for_label }}"
name="{{ form.is_urgent_available.name }}"
{% if form.is_urgent_available.value %}checked{% endif %}>
<label class="form-check-label" for="{{ form.is_urgent_available.id_for_label }}">
Urgent Available
</label>
{% if form.is_urgent_available.errors %}
<div class="invalid-feedback">
{{ form.is_urgent_available.errors.0 }}
</div>
{% endif %}
</div>
</div>
</div>
<div class="d-flex justify-content-between">
<div>
{% if object %}
<a href="{% url 'laboratory:lab_test_detail' object.pk %}" class="btn btn-secondary">
<i class="fas fa-times me-2"></i>Cancel
</a>
{% else %}
<a href="{% url 'laboratory:lab_test_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 Test{% else %}Create Test{% endif %}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="col-xl-4">
<!-- Test Categories -->
<div class="panel panel-inverse" data-sortable-id="index-2">
<div class="panel-heading">
<h4 class="panel-title"><i class="fas fa-tags me-2"></i> {{ _("Test Categories")}}</h4>
{# <div class="panel-heading-btn">#}
{# <a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-expand"><i class="fa fa-expand"></i></a>#}
{# <a href="javascript:;" class="btn btn-xs btn-icon btn-success" data-toggle="panel-reload"><i class="fa fa-redo"></i></a>#}
{# <a href="javascript:;" class="btn btn-xs btn-icon btn-warning" data-toggle="panel-collapse"><i class="fa fa-minus"></i></a>#}
{# <a href="javascript:;" class="btn btn-xs btn-icon btn-danger" data-toggle="panel-remove"><i class="fa fa-times"></i></a>#}
{##}
{# </div>#}
</div>
<div class="panel-body">
<div class="mb-3">
<h6><i class="fas fa-heart text-danger me-2"></i>Hematology</h6>
<p class="small text-muted">Blood cell counts, coagulation studies</p>
</div>
<div class="mb-3">
<h6><i class="fas fa-flask text-primary me-2"></i>Chemistry</h6>
<p class="small text-muted">Metabolic panels, enzymes, proteins</p>
</div>
<div class="mb-3">
<h6><i class="fas fa-bug text-warning me-2"></i>Microbiology</h6>
<p class="small text-muted">Cultures, sensitivity testing</p>
</div>
<div class="mb-3">
<h6><i class="fas fa-dna text-success me-2"></i>Molecular</h6>
<p class="small text-muted">PCR, genetic testing</p>
</div>
</div>
</div>
<!-- Specimen Types -->
<div class="panel panel-inverse" data-sortable-id="index-3">
<div class="panel-heading">
<h4 class="panel-title"><i class="fas fa-bolt me-2"></i> {{ _("Common Specimen Types")}}</h4>
{# <div class="panel-heading-btn">#}
{# <a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-expand"><i class="fa fa-expand"></i></a>#}
{# <a href="javascript:;" class="btn btn-xs btn-icon btn-success" data-toggle="panel-reload"><i class="fa fa-redo"></i></a>#}
{# <a href="javascript:;" class="btn btn-xs btn-icon btn-warning" data-toggle="panel-collapse"><i class="fa fa-minus"></i></a>#}
{# <a href="javascript:;" class="btn btn-xs btn-icon btn-danger" data-toggle="panel-remove"><i class="fa fa-times"></i></a>#}
{##}
{# </div>#}
</div>
<div class="panel-body">
<div class="row">
<div class="col-6">
<ul class="list-unstyled small">
<li><i class="fas fa-tint text-danger me-2"></i>Blood</li>
<li><i class="fas fa-flask text-warning me-2"></i>Urine</li>
<li><i class="fas fa-lungs text-info me-2"></i>Sputum</li>
<li><i class="fas fa-eye text-primary me-2"></i>CSF</li>
</ul>
</div>
<div class="col-6">
<ul class="list-unstyled small">
<li><i class="fas fa-hand text-secondary me-2"></i>Swab</li>
<li><i class="fas fa-microscope text-success me-2"></i>Tissue</li>
<li><i class="fas fa-droplet text-info me-2"></i>Fluid</li>
<li><i class="fas fa-circle text-muted me-2"></i>Other</li>
</ul>
</div>
</div>
</div>
</div>
<!-- Quick Actions -->
<div class="panel panel-inverse" data-sortable-id="index-4">
<div class="panel-heading">
<h4 class="panel-title"><i class="fas fa-bolt me-2"></i> {{ _("Quick Actions")}}</h4>
{# <div class="panel-heading-btn">#}
{# <a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-expand"><i class="fa fa-expand"></i></a>#}
{# <a href="javascript:;" class="btn btn-xs btn-icon btn-success" data-toggle="panel-reload"><i class="fa fa-redo"></i></a>#}
{# <a href="javascript:;" class="btn btn-xs btn-icon btn-warning" data-toggle="panel-collapse"><i class="fa fa-minus"></i></a>#}
{# <a href="javascript:;" class="btn btn-xs btn-icon btn-danger" data-toggle="panel-remove"><i class="fa fa-times"></i></a>#}
{##}
{# </div>#}
</div>
<div class="panel-body">
<div class="d-grid gap-2">
<button type="button" class="btn btn-outline-primary" onclick="generateCode()">
<i class="fas fa-barcode me-2"></i>Generate Test Code
</button>
<button type="button" class="btn btn-outline-secondary" onclick="lookupLOINC()">
<i class="fas fa-search me-2"></i>Lookup LOINC Code
</button>
<button type="button" class="btn btn-outline-info" onclick="copyFromExisting()">
<i class="fas fa-copy me-2"></i>Copy from Existing
</button>
</div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const nameInput = document.getElementById('{{ form.name.id_for_label }}');
const codeInput = document.getElementById('{{ form.code.id_for_label }}');
const categorySelect = document.getElementById('{{ form.category.id_for_label }}');
const specimenSelect = document.getElementById('{{ form.specimen_type.id_for_label }}');
// Auto-generate code from name
nameInput.addEventListener('blur', function() {
if (!codeInput.value && this.value) {
generateCode();
}
});
// Update turnaround time based on category
categorySelect.addEventListener('change', function() {
updateTurnaroundTime();
});
// Update preparation instructions based on specimen type
specimenSelect.addEventListener('change', function() {
updatePreparationInstructions();
});
});
function generateCode() {
const nameInput = document.getElementById('{{ form.name.id_for_label }}');
const codeInput = document.getElementById('{{ form.code.id_for_label }}');
const categorySelect = document.getElementById('{{ form.category.id_for_label }}');
if (!nameInput.value) {
alert('Please enter a test name first.');
return;
}
// Generate code from name and category
const name = nameInput.value.toUpperCase();
const category = categorySelect.value || 'GEN';
// Take first 3 letters of each word
const words = name.split(' ');
let code = category.substring(0, 3);
words.forEach(word => {
if (word.length > 0) {
code += word.substring(0, 3);
}
});
// Limit to 10 characters
code = code.substring(0, 10);
codeInput.value = code;
}
function updateTurnaroundTime() {
const categorySelect = document.getElementById('{{ form.category.id_for_label }}');
const turnaroundInput = document.getElementById('{{ form.turnaround_time.id_for_label }}');
// Default turnaround times by category
const defaults = {
'hematology': 2,
'chemistry': 4,
'microbiology': 24,
'molecular': 48,
'pathology': 72
};
const category = categorySelect.value;
if (category && defaults[category] && !turnaroundInput.value) {
turnaroundInput.value = defaults[category];
}
}
function updatePreparationInstructions() {
const specimenSelect = document.getElementById('{{ form.specimen_type.id_for_label }}');
const preparationTextarea = document.getElementById('{{ form.preparation_instructions.id_for_label }}');
// Default preparation instructions by specimen type
const instructions = {
'blood': 'Patient should fast for 8-12 hours if required. Avoid strenuous exercise before collection.',
'urine': 'Collect clean-catch midstream urine sample. Avoid contamination.',
'sputum': 'Collect early morning specimen. Rinse mouth with water before collection.',
'swab': 'Collect specimen before antibiotic treatment if possible.'
};
const specimen = specimenSelect.value;
if (specimen && instructions[specimen] && !preparationTextarea.value) {
preparationTextarea.value = instructions[specimen];
}
}
function lookupLOINC() {
// In a real implementation, this would open a LOINC lookup modal
alert('LOINC code lookup functionality would be implemented here.');
}
function copyFromExisting() {
// In a real implementation, this would open a modal to select existing test
alert('Copy from existing test functionality would be implemented here.');
}
</script>
{% endblock %}