1079 lines
60 KiB
HTML
1079 lines
60 KiB
HTML
{% extends 'base.html' %}
|
|
{% load static %}
|
|
|
|
{% block title %}Patient Admission{% endblock %}
|
|
|
|
{% block content %}
|
|
<div id="content" class="app-content">
|
|
<div class="container">
|
|
<ul class="breadcrumb">
|
|
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'inpatients:dashboard' %}">Inpatients</a></li>
|
|
<li class="breadcrumb-item active">Patient Admission</li>
|
|
</ul>
|
|
|
|
<div class="row align-items-center mb-3">
|
|
<div class="col">
|
|
<h1 class="page-header">Patient Admission</h1>
|
|
<p class="text-muted">Admit new patients and manage admission process</p>
|
|
</div>
|
|
<div class="col-auto">
|
|
<div class="btn-group">
|
|
<button class="btn btn-primary" onclick="startAdmission()">
|
|
<i class="fa fa-plus me-2"></i>New Admission
|
|
</button>
|
|
<button class="btn btn-outline-secondary" onclick="bulkAdmission()">
|
|
<i class="fa fa-users me-2"></i>Bulk Admission
|
|
</button>
|
|
<button class="btn btn-outline-info" onclick="viewQueue()">
|
|
<i class="fa fa-list me-2"></i>Admission Queue
|
|
</button>
|
|
<button class="btn btn-outline-success" onclick="generateReport()">
|
|
<i class="fa fa-chart-bar me-2"></i>Reports
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Admission Statistics -->
|
|
<div class="row mb-4">
|
|
<div class="col-md-3">
|
|
<div class="card bg-primary text-white">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-center">
|
|
<div class="flex-grow-1">
|
|
<h4 class="mb-0">{{ today_admissions }}</h4>
|
|
<p class="mb-0">Today's Admissions</p>
|
|
</div>
|
|
<div class="ms-3">
|
|
<i class="fa fa-user-plus fa-2x"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="card bg-warning text-white">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-center">
|
|
<div class="flex-grow-1">
|
|
<h4 class="mb-0">{{ pending_admissions }}</h4>
|
|
<p class="mb-0">Pending</p>
|
|
</div>
|
|
<div class="ms-3">
|
|
<i class="fa fa-clock fa-2x"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="card bg-success text-white">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-center">
|
|
<div class="flex-grow-1">
|
|
<h4 class="mb-0">{{ emergency_admissions }}</h4>
|
|
<p class="mb-0">Emergency</p>
|
|
</div>
|
|
<div class="ms-3">
|
|
<i class="fa fa-ambulance fa-2x"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="card bg-info text-white">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-center">
|
|
<div class="flex-grow-1">
|
|
<h4 class="mb-0">{{ available_beds }}</h4>
|
|
<p class="mb-0">Available Beds</p>
|
|
</div>
|
|
<div class="ms-3">
|
|
<i class="fa fa-bed fa-2x"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Admission Process Tabs -->
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<ul class="nav nav-tabs card-header-tabs" id="admissionTabs" role="tablist">
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link active" id="new-admission-tab" data-bs-toggle="tab" data-bs-target="#new-admission" type="button" role="tab">
|
|
<i class="fa fa-user-plus me-2"></i>New Admission
|
|
</button>
|
|
</li>
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link" id="pending-tab" data-bs-toggle="tab" data-bs-target="#pending" type="button" role="tab">
|
|
<i class="fa fa-clock me-2"></i>Pending Admissions
|
|
</button>
|
|
</li>
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link" id="recent-tab" data-bs-toggle="tab" data-bs-target="#recent" type="button" role="tab">
|
|
<i class="fa fa-history me-2"></i>Recent Admissions
|
|
</button>
|
|
</li>
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link" id="emergency-tab" data-bs-toggle="tab" data-bs-target="#emergency" type="button" role="tab">
|
|
<i class="fa fa-ambulance me-2"></i>Emergency Admissions
|
|
</button>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="tab-content" id="admissionTabContent">
|
|
<!-- New Admission Tab -->
|
|
<div class="tab-pane fade show active" id="new-admission" role="tabpanel">
|
|
<form id="admissionForm" class="needs-validation" novalidate>
|
|
{% csrf_token %}
|
|
|
|
<!-- Patient Information -->
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<h5 class="text-primary mb-3">
|
|
<i class="fa fa-user me-2"></i>Patient Information
|
|
</h5>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label class="form-label">Patient <span class="text-danger">*</span></label>
|
|
<div class="input-group">
|
|
<select class="form-select" name="patient_id" id="patientSelect" required>
|
|
<option value="">Select existing patient...</option>
|
|
{% for patient in patients %}
|
|
<option value="{{ patient.id }}" data-details="{{ patient.details_json }}">
|
|
{{ patient.get_full_name }} ({{ patient.patient_id }})
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
<button class="btn btn-outline-secondary" type="button" onclick="createNewPatient()">
|
|
<i class="fa fa-plus"></i> New
|
|
</button>
|
|
</div>
|
|
<div class="invalid-feedback">Please select a patient.</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label class="form-label">Emergency Contact</label>
|
|
<input type="text" class="form-control" name="emergency_contact" id="emergencyContact" readonly>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Patient Details Display -->
|
|
<div id="patientDetails" class="row mb-4" style="display: none;">
|
|
<div class="col-12">
|
|
<div class="alert alert-info">
|
|
<div class="row">
|
|
<div class="col-md-3">
|
|
<strong>Patient ID:</strong> <span id="displayPatientId"></span>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<strong>Age:</strong> <span id="displayAge"></span>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<strong>Gender:</strong> <span id="displayGender"></span>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<strong>Insurance:</strong> <span id="displayInsurance"></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Admission Details -->
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<h5 class="text-primary mb-3">
|
|
<i class="fa fa-hospital me-2"></i>Admission Details
|
|
</h5>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="mb-3">
|
|
<label class="form-label">Admission Type <span class="text-danger">*</span></label>
|
|
<select class="form-select" name="admission_type" id="admissionType" required>
|
|
<option value="">Select type...</option>
|
|
<option value="emergency">Emergency</option>
|
|
<option value="elective">Elective</option>
|
|
<option value="transfer">Transfer</option>
|
|
<option value="observation">Observation</option>
|
|
<option value="day_surgery">Day Surgery</option>
|
|
</select>
|
|
<div class="invalid-feedback">Please select admission type.</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="mb-3">
|
|
<label class="form-label">Admission Date & Time <span class="text-danger">*</span></label>
|
|
<input type="datetime-local" class="form-control" name="admission_datetime" id="admissionDateTime" required>
|
|
<div class="invalid-feedback">Please select admission date and time.</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="mb-3">
|
|
<label class="form-label">Priority</label>
|
|
<select class="form-select" name="priority" id="priority">
|
|
<option value="routine">Routine</option>
|
|
<option value="urgent">Urgent</option>
|
|
<option value="emergency">Emergency</option>
|
|
<option value="critical">Critical</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Medical Information -->
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<h5 class="text-primary mb-3">
|
|
<i class="fa fa-stethoscope me-2"></i>Medical Information
|
|
</h5>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label class="form-label">Admitting Physician <span class="text-danger">*</span></label>
|
|
<select class="form-select" name="admitting_physician" id="admittingPhysician" required>
|
|
<option value="">Select physician...</option>
|
|
{% for physician in physicians %}
|
|
<option value="{{ physician.id }}">{{ physician.get_full_name }} - {{ physician.specialization }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
<div class="invalid-feedback">Please select admitting physician.</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label class="form-label">Department <span class="text-danger">*</span></label>
|
|
<select class="form-select" name="department" id="department" required>
|
|
<option value="">Select department...</option>
|
|
{% for dept in departments %}
|
|
<option value="{{ dept.id }}">{{ dept.name }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
<div class="invalid-feedback">Please select department.</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label class="form-label">Primary Diagnosis</label>
|
|
<input type="text" class="form-control" name="primary_diagnosis" id="primaryDiagnosis" placeholder="Enter primary diagnosis">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label class="form-label">ICD-10 Code</label>
|
|
<input type="text" class="form-control" name="icd10_code" id="icd10Code" placeholder="Enter ICD-10 code">
|
|
</div>
|
|
</div>
|
|
<div class="col-12">
|
|
<div class="mb-3">
|
|
<label class="form-label">Chief Complaint</label>
|
|
<textarea class="form-control" name="chief_complaint" id="chiefComplaint" rows="3" placeholder="Enter chief complaint"></textarea>
|
|
</div>
|
|
</div>
|
|
<div class="col-12">
|
|
<div class="mb-3">
|
|
<label class="form-label">Medical History</label>
|
|
<textarea class="form-control" name="medical_history" id="medicalHistory" rows="3" placeholder="Enter relevant medical history"></textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Bed Assignment -->
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<h5 class="text-primary mb-3">
|
|
<i class="fa fa-bed me-2"></i>Bed Assignment
|
|
</h5>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="mb-3">
|
|
<label class="form-label">Ward <span class="text-danger">*</span></label>
|
|
<select class="form-select" name="ward" id="ward" required>
|
|
<option value="">Select ward...</option>
|
|
{% for ward in wards %}
|
|
<option value="{{ ward.id }}">{{ ward.name }} ({{ ward.available_beds }} available)</option>
|
|
{% endfor %}
|
|
</select>
|
|
<div class="invalid-feedback">Please select ward.</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="mb-3">
|
|
<label class="form-label">Bed <span class="text-danger">*</span></label>
|
|
<select class="form-select" name="bed" id="bed" required disabled>
|
|
<option value="">Select bed...</option>
|
|
</select>
|
|
<div class="invalid-feedback">Please select bed.</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="mb-3">
|
|
<label class="form-label">Room Type</label>
|
|
<select class="form-select" name="room_type" id="roomType">
|
|
<option value="general">General</option>
|
|
<option value="private">Private</option>
|
|
<option value="semi_private">Semi-Private</option>
|
|
<option value="icu">ICU</option>
|
|
<option value="isolation">Isolation</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Insurance & Billing -->
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<h5 class="text-primary mb-3">
|
|
<i class="fa fa-credit-card me-2"></i>Insurance & Billing
|
|
</h5>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label class="form-label">Insurance Provider</label>
|
|
<select class="form-select" name="insurance_provider" id="insuranceProvider">
|
|
<option value="">Select insurance...</option>
|
|
{% for insurance in insurance_providers %}
|
|
<option value="{{ insurance.id }}">{{ insurance.name }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label class="form-label">Policy Number</label>
|
|
<input type="text" class="form-control" name="policy_number" id="policyNumber" placeholder="Enter policy number">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label class="form-label">Authorization Number</label>
|
|
<input type="text" class="form-control" name="authorization_number" id="authorizationNumber" placeholder="Enter authorization number">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label class="form-label">Estimated Length of Stay (days)</label>
|
|
<input type="number" class="form-control" name="estimated_los" id="estimatedLOS" min="1" placeholder="Enter estimated days">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Additional Information -->
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<h5 class="text-primary mb-3">
|
|
<i class="fa fa-info-circle me-2"></i>Additional Information
|
|
</h5>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-check mb-3">
|
|
<input class="form-check-input" type="checkbox" name="isolation_required" id="isolationRequired">
|
|
<label class="form-check-label" for="isolationRequired">
|
|
Isolation Required
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-check mb-3">
|
|
<input class="form-check-input" type="checkbox" name="special_diet" id="specialDiet">
|
|
<label class="form-check-label" for="specialDiet">
|
|
Special Diet Required
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-12">
|
|
<div class="mb-3">
|
|
<label class="form-label">Special Instructions</label>
|
|
<textarea class="form-control" name="special_instructions" id="specialInstructions" rows="3" placeholder="Enter any special instructions or notes"></textarea>
|
|
</div>
|
|
</div>
|
|
<div class="col-12">
|
|
<div class="mb-3">
|
|
<label class="form-label">Allergies</label>
|
|
<textarea class="form-control" name="allergies" id="allergies" rows="2" placeholder="Enter known allergies"></textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Form Actions -->
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="d-flex justify-content-end gap-2">
|
|
<button type="button" class="btn btn-secondary" onclick="resetForm()">
|
|
<i class="fa fa-undo me-2"></i>Reset
|
|
</button>
|
|
<button type="button" class="btn btn-outline-primary" onclick="saveAsDraft()">
|
|
<i class="fa fa-save me-2"></i>Save as Draft
|
|
</button>
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="fa fa-user-plus me-2"></i>Admit Patient
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Pending Admissions Tab -->
|
|
<div class="tab-pane fade" id="pending" role="tabpanel">
|
|
<div class="row mb-3">
|
|
<div class="col-md-6">
|
|
<div class="input-group">
|
|
<input type="text" class="form-control" placeholder="Search pending admissions..." id="pendingSearch">
|
|
<button class="btn btn-outline-secondary" type="button">
|
|
<i class="fa fa-search"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<select class="form-select" id="pendingDepartment">
|
|
<option value="">All Departments</option>
|
|
{% for dept in departments %}
|
|
<option value="{{ dept.id }}">{{ dept.name }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<select class="form-select" id="pendingPriority">
|
|
<option value="">All Priorities</option>
|
|
<option value="critical">Critical</option>
|
|
<option value="emergency">Emergency</option>
|
|
<option value="urgent">Urgent</option>
|
|
<option value="routine">Routine</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="table-responsive">
|
|
<table class="table table-hover">
|
|
<thead>
|
|
<tr>
|
|
<th>Patient</th>
|
|
<th>Type</th>
|
|
<th>Priority</th>
|
|
<th>Department</th>
|
|
<th>Physician</th>
|
|
<th>Requested Date</th>
|
|
<th>Status</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for admission in pending_admissions %}
|
|
<tr>
|
|
<td>
|
|
<div>
|
|
<strong>{{ admission.patient.get_full_name }}</strong>
|
|
<br><small class="text-muted">{{ admission.patient.patient_id }}</small>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<span class="badge bg-secondary">{{ admission.get_admission_type_display }}</span>
|
|
</td>
|
|
<td>
|
|
<span class="badge bg-{{ admission.priority_color }}">
|
|
{{ admission.get_priority_display }}
|
|
</span>
|
|
</td>
|
|
<td>{{ admission.department.name }}</td>
|
|
<td>{{ admission.admitting_physician.get_full_name }}</td>
|
|
<td>{{ admission.requested_date|date:"M d, Y H:i" }}</td>
|
|
<td>
|
|
<span class="badge bg-warning">Pending</span>
|
|
</td>
|
|
<td>
|
|
<div class="btn-group btn-group-sm">
|
|
<button class="btn btn-outline-primary" onclick="viewPendingAdmission('{{ admission.id }}')" title="View">
|
|
<i class="fa fa-eye"></i>
|
|
</button>
|
|
<button class="btn btn-outline-success" onclick="approvePendingAdmission('{{ admission.id }}')" title="Approve">
|
|
<i class="fa fa-check"></i>
|
|
</button>
|
|
<button class="btn btn-outline-secondary" onclick="editPendingAdmission('{{ admission.id }}')" title="Edit">
|
|
<i class="fa fa-edit"></i>
|
|
</button>
|
|
<button class="btn btn-outline-danger" onclick="rejectPendingAdmission('{{ admission.id }}')" title="Reject">
|
|
<i class="fa fa-times"></i>
|
|
</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% empty %}
|
|
<tr>
|
|
<td colspan="8" class="text-center py-4">
|
|
<i class="fa fa-clock fa-3x text-muted mb-3"></i>
|
|
<h5 class="text-muted">No pending admissions</h5>
|
|
<p class="text-muted">All admission requests have been processed.</p>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Recent Admissions Tab -->
|
|
<div class="tab-pane fade" id="recent" role="tabpanel">
|
|
<div class="row mb-3">
|
|
<div class="col-md-4">
|
|
<div class="input-group">
|
|
<input type="text" class="form-control" placeholder="Search recent admissions..." id="recentSearch">
|
|
<button class="btn btn-outline-secondary" type="button">
|
|
<i class="fa fa-search"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<select class="form-select" id="recentDays">
|
|
<option value="1">Today</option>
|
|
<option value="7" selected>Last 7 days</option>
|
|
<option value="30">Last 30 days</option>
|
|
<option value="90">Last 90 days</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<select class="form-select" id="recentDepartment">
|
|
<option value="">All Departments</option>
|
|
{% for dept in departments %}
|
|
<option value="{{ dept.id }}">{{ dept.name }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<select class="form-select" id="recentType">
|
|
<option value="">All Types</option>
|
|
<option value="emergency">Emergency</option>
|
|
<option value="elective">Elective</option>
|
|
<option value="transfer">Transfer</option>
|
|
<option value="observation">Observation</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="table-responsive">
|
|
<table class="table table-hover">
|
|
<thead>
|
|
<tr>
|
|
<th>Patient</th>
|
|
<th>Admission Date</th>
|
|
<th>Type</th>
|
|
<th>Department</th>
|
|
<th>Bed</th>
|
|
<th>Physician</th>
|
|
<th>Status</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for admission in recent_admissions %}
|
|
<tr>
|
|
<td>
|
|
<div>
|
|
<strong>{{ admission.patient.get_full_name }}</strong>
|
|
<br><small class="text-muted">{{ admission.patient.patient_id }}</small>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<div>
|
|
<strong>{{ admission.admission_date|date:"M d, Y" }}</strong>
|
|
<br><small class="text-muted">{{ admission.admission_date|time:"H:i" }}</small>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<span class="badge bg-secondary">{{ admission.get_admission_type_display }}</span>
|
|
</td>
|
|
<td>{{ admission.department.name }}</td>
|
|
<td>
|
|
{% if admission.bed %}
|
|
<div>
|
|
<strong>{{ admission.bed.bed_number }}</strong>
|
|
<br><small class="text-muted">{{ admission.bed.ward.name }}</small>
|
|
</div>
|
|
{% else %}
|
|
<span class="text-muted">Not assigned</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>{{ admission.admitting_physician.get_full_name }}</td>
|
|
<td>
|
|
<span class="badge bg-{{ admission.status_color }}">
|
|
{{ admission.get_status_display }}
|
|
</span>
|
|
</td>
|
|
<td>
|
|
<div class="btn-group btn-group-sm">
|
|
<button class="btn btn-outline-primary" onclick="viewAdmission('{{ admission.id }}')" title="View">
|
|
<i class="fa fa-eye"></i>
|
|
</button>
|
|
<button class="btn btn-outline-secondary" onclick="editAdmission('{{ admission.id }}')" title="Edit">
|
|
<i class="fa fa-edit"></i>
|
|
</button>
|
|
<button class="btn btn-outline-info" onclick="printAdmission('{{ admission.id }}')" title="Print">
|
|
<i class="fa fa-print"></i>
|
|
</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% empty %}
|
|
<tr>
|
|
<td colspan="8" class="text-center py-4">
|
|
<i class="fa fa-history fa-3x text-muted mb-3"></i>
|
|
<h5 class="text-muted">No recent admissions</h5>
|
|
<p class="text-muted">No admissions found for the selected period.</p>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Emergency Admissions Tab -->
|
|
<div class="tab-pane fade" id="emergency" role="tabpanel">
|
|
<div class="alert alert-danger">
|
|
<i class="fa fa-ambulance me-2"></i>
|
|
<strong>Emergency Admission Protocol</strong> - Fast-track admission process for emergency cases
|
|
</div>
|
|
|
|
<div class="row mb-3">
|
|
<div class="col-md-6">
|
|
<div class="input-group">
|
|
<input type="text" class="form-control" placeholder="Search emergency admissions..." id="emergencySearch">
|
|
<button class="btn btn-outline-secondary" type="button">
|
|
<i class="fa fa-search"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<select class="form-select" id="emergencyStatus">
|
|
<option value="">All Status</option>
|
|
<option value="active">Active</option>
|
|
<option value="stable">Stable</option>
|
|
<option value="critical">Critical</option>
|
|
<option value="discharged">Discharged</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<button class="btn btn-danger w-100" onclick="emergencyAdmission()">
|
|
<i class="fa fa-plus me-2"></i>Emergency Admission
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="table-responsive">
|
|
<table class="table table-hover">
|
|
<thead>
|
|
<tr>
|
|
<th>Patient</th>
|
|
<th>Arrival Time</th>
|
|
<th>Chief Complaint</th>
|
|
<th>Triage Level</th>
|
|
<th>Bed</th>
|
|
<th>Physician</th>
|
|
<th>Status</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for admission in emergency_admissions_list %}
|
|
<tr class="{% if admission.triage_level == 'critical' %}table-danger{% elif admission.triage_level == 'urgent' %}table-warning{% endif %}">
|
|
<td>
|
|
<div>
|
|
<strong>{{ admission.patient.get_full_name }}</strong>
|
|
<br><small class="text-muted">{{ admission.patient.patient_id }}</small>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<div>
|
|
<strong>{{ admission.admission_date|date:"M d, Y" }}</strong>
|
|
<br><small class="text-muted">{{ admission.admission_date|time:"H:i" }}</small>
|
|
</div>
|
|
</td>
|
|
<td>{{ admission.chief_complaint|truncatewords:5 }}</td>
|
|
<td>
|
|
<span class="badge bg-{{ admission.triage_color }}">
|
|
{{ admission.get_triage_level_display }}
|
|
</span>
|
|
</td>
|
|
<td>
|
|
{% if admission.bed %}
|
|
<div>
|
|
<strong>{{ admission.bed.bed_number }}</strong>
|
|
<br><small class="text-muted">{{ admission.bed.ward.name }}</small>
|
|
</div>
|
|
{% else %}
|
|
<span class="text-warning">Pending</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>{{ admission.admitting_physician.get_full_name }}</td>
|
|
<td>
|
|
<span class="badge bg-{{ admission.status_color }}">
|
|
{{ admission.get_status_display }}
|
|
</span>
|
|
</td>
|
|
<td>
|
|
<div class="btn-group btn-group-sm">
|
|
<button class="btn btn-outline-primary" onclick="viewEmergencyAdmission('{{ admission.id }}')" title="View">
|
|
<i class="fa fa-eye"></i>
|
|
</button>
|
|
<button class="btn btn-outline-warning" onclick="updateTriage('{{ admission.id }}')" title="Update Triage">
|
|
<i class="fa fa-exclamation-triangle"></i>
|
|
</button>
|
|
{% if not admission.bed %}
|
|
<button class="btn btn-outline-success" onclick="assignEmergencyBed('{{ admission.id }}')" title="Assign Bed">
|
|
<i class="fa fa-bed"></i>
|
|
</button>
|
|
{% endif %}
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% empty %}
|
|
<tr>
|
|
<td colspan="8" class="text-center py-4">
|
|
<i class="fa fa-ambulance fa-3x text-muted mb-3"></i>
|
|
<h5 class="text-muted">No emergency admissions</h5>
|
|
<p class="text-muted">No emergency admissions at this time.</p>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block js %}
|
|
<script>
|
|
$(document).ready(function() {
|
|
setupEventHandlers();
|
|
setDefaultDateTime();
|
|
setupValidation();
|
|
});
|
|
|
|
function setupEventHandlers() {
|
|
// Patient selection
|
|
$('#patientSelect').on('change', function() {
|
|
var selectedOption = $(this).find('option:selected');
|
|
if (selectedOption.val()) {
|
|
var details = selectedOption.data('details');
|
|
displayPatientDetails(details);
|
|
} else {
|
|
hidePatientDetails();
|
|
}
|
|
});
|
|
|
|
// Ward selection
|
|
$('#ward').on('change', function() {
|
|
loadAvailableBeds($(this).val());
|
|
});
|
|
|
|
// Admission type change
|
|
$('#admissionType').on('change', function() {
|
|
var type = $(this).val();
|
|
if (type === 'emergency') {
|
|
$('#priority').val('emergency');
|
|
}
|
|
});
|
|
|
|
// Form submission
|
|
$('#admissionForm').on('submit', function(e) {
|
|
e.preventDefault();
|
|
if (this.checkValidity()) {
|
|
submitAdmission();
|
|
}
|
|
$(this).addClass('was-validated');
|
|
});
|
|
}
|
|
|
|
function setDefaultDateTime() {
|
|
var now = new Date();
|
|
var datetime = now.toISOString().slice(0, 16);
|
|
$('#admissionDateTime').val(datetime);
|
|
}
|
|
|
|
function setupValidation() {
|
|
// Custom validation for bed selection
|
|
$('#bed').on('change', function() {
|
|
if ($(this).val()) {
|
|
$(this).removeClass('is-invalid').addClass('is-valid');
|
|
}
|
|
});
|
|
}
|
|
|
|
function displayPatientDetails(details) {
|
|
if (details) {
|
|
$('#displayPatientId').text(details.patient_id || 'N/A');
|
|
$('#displayAge').text(details.age || 'N/A');
|
|
$('#displayGender').text(details.gender || 'N/A');
|
|
$('#displayInsurance').text(details.insurance || 'None');
|
|
$('#emergencyContact').val(details.emergency_contact || '');
|
|
$('#patientDetails').show();
|
|
}
|
|
}
|
|
|
|
function hidePatientDetails() {
|
|
$('#patientDetails').hide();
|
|
$('#emergencyContact').val('');
|
|
}
|
|
|
|
function loadAvailableBeds(wardId) {
|
|
if (!wardId) {
|
|
$('#bed').prop('disabled', true).html('<option value="">Select bed...</option>');
|
|
return;
|
|
}
|
|
|
|
$.get('{% url "inpatients:get_available_beds" %}', {ward_id: wardId}, function(data) {
|
|
var bedSelect = $('#bed');
|
|
bedSelect.html('<option value="">Select bed...</option>');
|
|
|
|
if (data.success && data.beds.length > 0) {
|
|
data.beds.forEach(function(bed) {
|
|
bedSelect.append(`<option value="${bed.id}">${bed.bed_number} - ${bed.room_number} (${bed.bed_type})</option>`);
|
|
});
|
|
bedSelect.prop('disabled', false);
|
|
} else {
|
|
bedSelect.append('<option value="">No beds available</option>');
|
|
bedSelect.prop('disabled', true);
|
|
}
|
|
});
|
|
}
|
|
|
|
function createNewPatient() {
|
|
window.open('{% url "patients:patient_create" %}', '_blank');
|
|
}
|
|
|
|
function submitAdmission() {
|
|
var formData = $('#admissionForm').serialize();
|
|
|
|
$.post('{% url "inpatients:submit_admission" %}', formData, function(data) {
|
|
if (data.success) {
|
|
toastr.success('Patient admitted successfully');
|
|
if (data.admission_id) {
|
|
window.location.href = '{% url "inpatients:admission_detail" 0 %}'.replace('0', data.admission_id);
|
|
} else {
|
|
resetForm();
|
|
}
|
|
} else {
|
|
toastr.error('Failed to admit patient: ' + data.error);
|
|
}
|
|
});
|
|
}
|
|
|
|
function saveAsDraft() {
|
|
var formData = $('#admissionForm').serialize() + '&save_as_draft=true';
|
|
|
|
$.post('{% url "inpatients:save_admission_draft" %}', formData, function(data) {
|
|
if (data.success) {
|
|
toastr.success('Admission saved as draft');
|
|
} else {
|
|
toastr.error('Failed to save draft: ' + data.error);
|
|
}
|
|
});
|
|
}
|
|
|
|
function resetForm() {
|
|
$('#admissionForm')[0].reset();
|
|
$('#admissionForm').removeClass('was-validated');
|
|
hidePatientDetails();
|
|
$('#bed').prop('disabled', true).html('<option value="">Select bed...</option>');
|
|
setDefaultDateTime();
|
|
}
|
|
|
|
function startAdmission() {
|
|
$('#new-admission-tab').click();
|
|
resetForm();
|
|
}
|
|
|
|
function bulkAdmission() {
|
|
window.location.href = '{% url "inpatients:bulk_admission" %}';
|
|
}
|
|
|
|
function viewQueue() {
|
|
$('#pending-tab').click();
|
|
}
|
|
|
|
function generateReport() {
|
|
window.location.href = '{% url "inpatients:admission_reports" %}';
|
|
}
|
|
|
|
function emergencyAdmission() {
|
|
$('#new-admission-tab').click();
|
|
resetForm();
|
|
$('#admissionType').val('emergency');
|
|
$('#priority').val('emergency');
|
|
}
|
|
|
|
// Pending admissions functions
|
|
function viewPendingAdmission(admissionId) {
|
|
window.location.href = '{% url "inpatients:pending_admission_detail" 0 %}'.replace('0', admissionId);
|
|
}
|
|
|
|
function approvePendingAdmission(admissionId) {
|
|
if (confirm('Are you sure you want to approve this admission?')) {
|
|
$.post('{% url "inpatients:approve_pending_admission" %}', {
|
|
admission_id: admissionId,
|
|
csrfmiddlewaretoken: '{{ csrf_token }}'
|
|
}, function(data) {
|
|
if (data.success) {
|
|
toastr.success('Admission approved');
|
|
location.reload();
|
|
} else {
|
|
toastr.error('Failed to approve admission: ' + data.error);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function editPendingAdmission(admissionId) {
|
|
window.location.href = '{% url "inpatients:edit_pending_admission" 0 %}'.replace('0', admissionId);
|
|
}
|
|
|
|
function rejectPendingAdmission(admissionId) {
|
|
var reason = prompt('Reason for rejection:');
|
|
if (reason) {
|
|
$.post('{% url "inpatients:reject_pending_admission" %}', {
|
|
admission_id: admissionId,
|
|
reason: reason,
|
|
csrfmiddlewaretoken: '{{ csrf_token }}'
|
|
}, function(data) {
|
|
if (data.success) {
|
|
toastr.success('Admission rejected');
|
|
location.reload();
|
|
} else {
|
|
toastr.error('Failed to reject admission: ' + data.error);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
// Recent admissions functions
|
|
function viewAdmission(admissionId) {
|
|
window.location.href = '{% url "inpatients:admission_detail" 0 %}'.replace('0', admissionId);
|
|
}
|
|
|
|
function editAdmission(admissionId) {
|
|
window.location.href = '{% url "inpatients:admission_edit" 0 %}'.replace('0', admissionId);
|
|
}
|
|
|
|
function printAdmission(admissionId) {
|
|
window.open('{% url "inpatients:print_admission" 0 %}'.replace('0', admissionId), '_blank');
|
|
}
|
|
|
|
// Emergency admissions functions
|
|
function viewEmergencyAdmission(admissionId) {
|
|
window.location.href = '{% url "inpatients:emergency_admission_detail" 0 %}'.replace('0', admissionId);
|
|
}
|
|
|
|
function updateTriage(admissionId) {
|
|
window.location.href = '{% url "inpatients:update_triage" 0 %}'.replace('0', admissionId);
|
|
}
|
|
|
|
function assignEmergencyBed(admissionId) {
|
|
window.location.href = '{% url "inpatients:assign_emergency_bed" 0 %}'.replace('0', admissionId);
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
.nav-tabs .nav-link {
|
|
border: none;
|
|
color: #6c757d;
|
|
}
|
|
|
|
.nav-tabs .nav-link.active {
|
|
background-color: transparent;
|
|
border-bottom: 2px solid #0d6efd;
|
|
color: #0d6efd;
|
|
}
|
|
|
|
.form-control:focus, .form-select:focus {
|
|
border-color: #86b7fe;
|
|
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
|
|
}
|
|
|
|
.was-validated .form-control:valid, .was-validated .form-select:valid {
|
|
border-color: #198754;
|
|
}
|
|
|
|
.was-validated .form-control:invalid, .was-validated .form-select:invalid {
|
|
border-color: #dc3545;
|
|
}
|
|
|
|
.table-danger {
|
|
background-color: rgba(220, 53, 69, 0.1);
|
|
}
|
|
|
|
.table-warning {
|
|
background-color: rgba(255, 193, 7, 0.1);
|
|
}
|
|
|
|
.badge {
|
|
font-size: 0.75em;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.btn-group-sm .btn {
|
|
padding: 0.25rem 0.5rem;
|
|
font-size: 0.875rem;
|
|
}
|
|
|
|
.alert {
|
|
border: none;
|
|
border-radius: 0.5rem;
|
|
}
|
|
|
|
.card-header-tabs {
|
|
margin-bottom: -1px;
|
|
}
|
|
|
|
.card-header-tabs .nav-link {
|
|
border: none;
|
|
border-bottom: 2px solid transparent;
|
|
}
|
|
|
|
.card-header-tabs .nav-link.active {
|
|
border-bottom-color: #0d6efd;
|
|
background-color: transparent;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.btn-group {
|
|
flex-direction: column;
|
|
}
|
|
|
|
.btn-group .btn {
|
|
margin-bottom: 0.25rem;
|
|
}
|
|
|
|
.table-responsive {
|
|
font-size: 0.875rem;
|
|
}
|
|
|
|
.nav-tabs {
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.nav-tabs .nav-link {
|
|
font-size: 0.875rem;
|
|
padding: 0.5rem 0.75rem;
|
|
}
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|