hospital-management/templates/pharmacy/dispensing/medication_dispensing.html
2025-08-12 13:33:25 +03:00

580 lines
31 KiB
HTML

{% extends 'base.html' %}
{% load static %}
{% block title %}Medication Dispensing - Pharmacy{% endblock %}
{% block content %}
<div class="content">
<div class="container-fluid">
<!-- Page Header -->
<div class="row">
<div class="col-12">
<div class="page-header">
<div class="page-title">
<h4>Medication Dispensing</h4>
<h6>Process and dispense prescription medications with safety checks</h6>
</div>
<div class="page-btn">
<div class="btn-group">
<a href="{% url 'pharmacy:prescription_queue' %}" class="btn btn-primary">
<i class="fa fa-list"></i> Prescription Queue
</a>
<button type="button" class="btn btn-info" data-bs-toggle="modal" data-bs-target="#scanPrescriptionModal">
<i class="fa fa-qrcode"></i> Scan Prescription
</button>
</div>
</div>
</div>
</div>
</div>
<!-- Prescription Information -->
{% if prescription %}
<div class="row">
<div class="col-md-8">
<div class="card">
<div class="card-header">
<h5 class="card-title">Prescription Details - {{ prescription.prescription_number }}</h5>
<div class="card-tools">
<span class="badge bg-{{ prescription.priority_color }}">{{ prescription.priority|title }}</span>
<span class="badge bg-{{ prescription.status_color }}">{{ prescription.status|title }}</span>
</div>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<h6 class="text-primary">Patient Information</h6>
<strong>Name:</strong> {{ prescription.patient.get_full_name }}<br>
<strong>MRN:</strong> {{ prescription.patient.medical_record_number }}<br>
<strong>DOB:</strong> {{ prescription.patient.date_of_birth|date:"M d, Y" }}<br>
<strong>Age:</strong> {{ prescription.patient.age }} years<br>
<strong>Phone:</strong> {{ prescription.patient.phone_number|default:"Not provided" }}
</div>
<div class="col-md-6">
<h6 class="text-primary">Prescriber Information</h6>
<strong>Prescriber:</strong> {{ prescription.prescriber.get_full_name }}<br>
<strong>Specialty:</strong> {{ prescription.prescriber.specialty|default:"Physician" }}<br>
<strong>DEA:</strong> {{ prescription.prescriber.dea_number|default:"Not on file" }}<br>
<strong>Date Prescribed:</strong> {{ prescription.date_prescribed|date:"M d, Y H:i" }}
</div>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-header">
<h5 class="card-title">Insurance Information</h5>
</div>
<div class="card-body">
{% if prescription.insurance_plan %}
<strong>Plan:</strong> {{ prescription.insurance_plan.name }}<br>
<strong>Member ID:</strong> {{ prescription.insurance_member_id }}<br>
<strong>Group:</strong> {{ prescription.insurance_group|default:"N/A" }}<br>
<strong>Copay:</strong> ${{ prescription.copay_amount|default:0|floatformat:2 }}
{% else %}
<p class="text-muted">No insurance information on file</p>
<span class="badge bg-warning">Cash Pay</span>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Medication Details -->
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h5 class="card-title">Medication Information</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div class="medication-info">
<h6 class="text-primary">{{ prescription.medication.name }}</h6>
<p class="text-muted">{{ prescription.medication.generic_name }}</p>
<div class="row">
<div class="col-6">
<strong>Strength:</strong> {{ prescription.strength }}<br>
<strong>Dosage Form:</strong> {{ prescription.dosage_form|title }}<br>
<strong>NDC:</strong> {{ prescription.medication.ndc_number }}
</div>
<div class="col-6">
<strong>Quantity:</strong> {{ prescription.quantity }} {{ prescription.unit }}<br>
<strong>Days Supply:</strong> {{ prescription.days_supply }} days<br>
<strong>Refills:</strong> {{ prescription.refills_remaining }}/{{ prescription.total_refills }}
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="dosing-info">
<h6 class="text-primary">Dosing Instructions</h6>
<div class="alert alert-info">
<strong>Sig:</strong> {{ prescription.sig_instructions }}
</div>
<strong>Route:</strong> {{ prescription.route|title }}<br>
<strong>Frequency:</strong> {{ prescription.frequency }}<br>
{% if prescription.special_instructions %}
<strong>Special Instructions:</strong><br>
<em>{{ prescription.special_instructions }}</em>
{% endif %}
</div>
</div>
</div>
{% if prescription.medication.controlled_substance %}
<div class="alert alert-warning mt-3">
<h6><i class="fa fa-exclamation-triangle"></i> Controlled Substance</h6>
<strong>Schedule:</strong> {{ prescription.medication.controlled_schedule }}<br>
<strong>DEA Required:</strong> Yes<br>
<strong>Special Handling:</strong> Secure storage and documentation required
</div>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Safety Checks -->
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h5 class="card-title">Safety Verification Checklist</h5>
</div>
<div class="card-body">
<form method="post" id="dispensingForm">
{% csrf_token %}
<input type="hidden" name="prescription_id" value="{{ prescription.id }}">
<div class="row">
<div class="col-md-6">
<h6 class="text-primary">Clinical Checks</h6>
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" name="allergy_check" id="allergyCheck" required>
<label class="form-check-label" for="allergyCheck">
<strong>Allergy Check</strong> - No known allergies to this medication
</label>
</div>
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" name="interaction_check" id="interactionCheck" required>
<label class="form-check-label" for="interactionCheck">
<strong>Drug Interaction Check</strong> - No significant interactions detected
</label>
</div>
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" name="duplicate_therapy" id="duplicateCheck" required>
<label class="form-check-label" for="duplicateCheck">
<strong>Duplicate Therapy Check</strong> - No duplicate medications
</label>
</div>
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" name="dosage_check" id="dosageCheck" required>
<label class="form-check-label" for="dosageCheck">
<strong>Dosage Verification</strong> - Dose appropriate for patient
</label>
</div>
</div>
<div class="col-md-6">
<h6 class="text-primary">Physical Checks</h6>
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" name="medication_verification" id="medicationVerification" required>
<label class="form-check-label" for="medicationVerification">
<strong>Medication Verification</strong> - Correct drug, strength, and form
</label>
</div>
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" name="quantity_verification" id="quantityVerification" required>
<label class="form-check-label" for="quantityVerification">
<strong>Quantity Verification</strong> - Correct quantity counted
</label>
</div>
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" name="expiration_check" id="expirationCheck" required>
<label class="form-check-label" for="expirationCheck">
<strong>Expiration Check</strong> - Medication not expired
</label>
</div>
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" name="label_verification" id="labelVerification" required>
<label class="form-check-label" for="labelVerification">
<strong>Label Verification</strong> - Label information accurate
</label>
</div>
</div>
</div>
<hr>
<!-- Dispensing Information -->
<div class="row">
<div class="col-md-6">
<h6 class="text-primary">Dispensing Details</h6>
<div class="mb-3">
<label class="form-label">Lot Number *</label>
<select name="lot_number" class="form-select" required>
<option value="">Select Lot Number</option>
{% for lot in available_lots %}
<option value="{{ lot.lot_number }}" data-expiry="{{ lot.expiration_date|date:'Y-m-d' }}">
{{ lot.lot_number }} (Exp: {{ lot.expiration_date|date:"M d, Y" }}) - {{ lot.quantity_available }} available
</option>
{% endfor %}
</select>
</div>
<div class="mb-3">
<label class="form-label">Quantity Dispensed *</label>
<input type="number" name="quantity_dispensed" class="form-control"
value="{{ prescription.quantity }}" min="1" max="{{ prescription.quantity }}" required>
</div>
<div class="mb-3">
<label class="form-label">Days Supply</label>
<input type="number" name="days_supply" class="form-control"
value="{{ prescription.days_supply }}" readonly>
</div>
</div>
<div class="col-md-6">
<h6 class="text-primary">Pharmacist Information</h6>
<div class="mb-3">
<label class="form-label">Dispensing Pharmacist *</label>
<input type="text" class="form-control" value="{{ request.user.get_full_name }}" readonly>
<input type="hidden" name="dispensing_pharmacist" value="{{ request.user.id }}">
</div>
<div class="mb-3">
<label class="form-label">Dispensing Date/Time *</label>
<input type="datetime-local" name="dispensing_datetime" class="form-control" required>
</div>
<div class="mb-3">
<label class="form-label">Counseling Provided</label>
<select name="counseling_provided" class="form-select">
<option value="yes">Yes - Patient counseled</option>
<option value="no">No - Patient declined</option>
<option value="pickup_by_other">Picked up by authorized person</option>
</select>
</div>
</div>
</div>
<!-- Additional Notes -->
<div class="row">
<div class="col-12">
<div class="mb-3">
<label class="form-label">Dispensing Notes</label>
<textarea name="dispensing_notes" class="form-control" rows="3"
placeholder="Any additional notes about this dispensing..."></textarea>
</div>
</div>
</div>
<!-- Final Verification -->
<div class="row">
<div class="col-12">
<div class="alert alert-warning">
<h6><i class="fa fa-exclamation-triangle"></i> Final Verification</h6>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="final_verification" id="finalVerification" required>
<label class="form-check-label" for="finalVerification">
I certify that I have performed all required safety checks and that this
medication is being dispensed correctly according to the prescription and
applicable regulations.
</label>
</div>
</div>
</div>
</div>
<!-- Action Buttons -->
<div class="row">
<div class="col-12">
<div class="d-flex justify-content-between">
<div>
<a href="{% url 'pharmacy:prescription_queue' %}" class="btn btn-secondary">
<i class="fa fa-arrow-left"></i> Back to Queue
</a>
<button type="button" class="btn btn-warning" onclick="holdPrescription()">
<i class="fa fa-pause"></i> Hold
</button>
</div>
<div>
<button type="button" class="btn btn-info me-2" onclick="printLabel()">
<i class="fa fa-print"></i> Print Label
</button>
<button type="submit" class="btn btn-success btn-lg">
<i class="fa fa-check"></i> Dispense Medication
</button>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<!-- Patient Counseling Information -->
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h5 class="card-title">Patient Counseling Points</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<h6 class="text-primary">Key Counseling Points</h6>
<ul class="list-unstyled">
<li><i class="fa fa-check text-success"></i> How to take the medication</li>
<li><i class="fa fa-check text-success"></i> When to take the medication</li>
<li><i class="fa fa-check text-success"></i> What to do if a dose is missed</li>
<li><i class="fa fa-check text-success"></i> Common side effects to watch for</li>
<li><i class="fa fa-check text-success"></i> Drug and food interactions</li>
<li><i class="fa fa-check text-success"></i> Storage requirements</li>
</ul>
</div>
<div class="col-md-6">
<h6 class="text-primary">Medication-Specific Information</h6>
{% if prescription.medication.counseling_points %}
<div class="alert alert-info">
{{ prescription.medication.counseling_points }}
</div>
{% else %}
<p class="text-muted">No specific counseling points on file for this medication.</p>
{% endif %}
{% if prescription.medication.black_box_warning %}
<div class="alert alert-danger">
<h6><i class="fa fa-exclamation-triangle"></i> Black Box Warning</h6>
{{ prescription.medication.black_box_warning }}
</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>
{% else %}
<!-- No Prescription Selected -->
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body text-center">
<i class="fa fa-prescription fa-5x text-muted mb-4"></i>
<h4>No Prescription Selected</h4>
<p class="text-muted">Please select a prescription from the queue or scan a prescription to begin dispensing.</p>
<div class="mt-4">
<a href="{% url 'pharmacy:prescription_queue' %}" class="btn btn-primary me-2">
<i class="fa fa-list"></i> View Prescription Queue
</a>
<button type="button" class="btn btn-outline-primary" data-bs-toggle="modal" data-bs-target="#scanPrescriptionModal">
<i class="fa fa-qrcode"></i> Scan Prescription
</button>
</div>
</div>
</div>
</div>
</div>
{% endif %}
</div>
</div>
<!-- Scan Prescription Modal -->
<div class="modal fade" id="scanPrescriptionModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Scan Prescription</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="text-center">
<div id="scannerContainer" style="width: 100%; height: 300px; background: #f8f9fa; border: 2px dashed #dee2e6; display: flex; align-items: center; justify-content: center;">
<div>
<i class="fa fa-qrcode fa-3x text-muted mb-3"></i>
<p class="text-muted">Position prescription barcode in the scanner area</p>
<button type="button" class="btn btn-primary" onclick="startScanner()">
<i class="fa fa-camera"></i> Start Scanner
</button>
</div>
</div>
</div>
<div class="mt-3">
<label class="form-label">Or enter prescription number manually:</label>
<div class="input-group">
<input type="text" id="manualPrescriptionNumber" class="form-control" placeholder="Prescription number">
<button type="button" class="btn btn-outline-primary" onclick="lookupPrescription()">
<i class="fa fa-search"></i> Lookup
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Set current time as default dispensing time
const now = new Date();
const localDateTime = new Date(now.getTime() - now.getTimezoneOffset() * 60000).toISOString().slice(0, 16);
const dispensingDatetime = document.querySelector('input[name="dispensing_datetime"]');
if (dispensingDatetime) {
dispensingDatetime.value = localDateTime;
}
// Form validation and submission
const dispensingForm = document.getElementById('dispensingForm');
if (dispensingForm) {
dispensingForm.addEventListener('submit', function(e) {
// Validate all safety checks are completed
const requiredChecks = document.querySelectorAll('input[type="checkbox"][required]');
let allChecked = true;
requiredChecks.forEach(checkbox => {
if (!checkbox.checked) {
allChecked = false;
}
});
if (!allChecked) {
e.preventDefault();
alert('Please complete all required safety checks before dispensing.');
return false;
}
// Final confirmation
if (!confirm('Are you sure you want to dispense this medication? This action cannot be undone.')) {
e.preventDefault();
return false;
}
// Show loading state
const submitBtn = this.querySelector('button[type="submit"]');
submitBtn.disabled = true;
submitBtn.innerHTML = '<i class="fa fa-spinner fa-spin"></i> Dispensing...';
});
}
// Quantity dispensed validation
const quantityInput = document.querySelector('input[name="quantity_dispensed"]');
if (quantityInput) {
quantityInput.addEventListener('change', function() {
const maxQuantity = parseInt(this.getAttribute('max'));
const currentQuantity = parseInt(this.value);
if (currentQuantity > maxQuantity) {
alert(`Quantity cannot exceed prescribed amount of ${maxQuantity}`);
this.value = maxQuantity;
}
});
}
// Lot number selection handler
const lotSelect = document.querySelector('select[name="lot_number"]');
if (lotSelect) {
lotSelect.addEventListener('change', function() {
const selectedOption = this.options[this.selectedIndex];
const expiryDate = selectedOption.getAttribute('data-expiry');
if (expiryDate) {
const expiry = new Date(expiryDate);
const today = new Date();
const daysUntilExpiry = Math.ceil((expiry - today) / (1000 * 60 * 60 * 24));
if (daysUntilExpiry <= 30) {
alert(`Warning: This lot expires in ${daysUntilExpiry} days. Consider using a different lot if available.`);
}
}
});
}
});
function holdPrescription() {
const reason = prompt('Enter reason for holding this prescription:');
if (reason !== null && reason.trim() !== '') {
// Handle prescription hold
console.log('Holding prescription with reason:', reason);
alert('Prescription has been placed on hold.');
window.location.href = '{% url "pharmacy:prescription_queue" %}';
}
}
function printLabel() {
// Handle label printing
console.log('Printing prescription label...');
alert('Label sent to printer.');
}
function startScanner() {
// Simulate barcode scanner
document.getElementById('scannerContainer').innerHTML = `
<div class="text-center">
<div class="spinner-border text-primary mb-3" role="status">
<span class="visually-hidden">Scanning...</span>
</div>
<p class="text-muted">Scanner active - position barcode in view</p>
<button type="button" class="btn btn-secondary" onclick="stopScanner()">Stop Scanner</button>
</div>
`;
// Simulate successful scan after 3 seconds
setTimeout(() => {
const mockPrescriptionNumber = 'RX' + Math.floor(Math.random() * 1000000);
alert(`Prescription scanned: ${mockPrescriptionNumber}`);
lookupPrescription(mockPrescriptionNumber);
}, 3000);
}
function stopScanner() {
document.getElementById('scannerContainer').innerHTML = `
<div>
<i class="fa fa-qrcode fa-3x text-muted mb-3"></i>
<p class="text-muted">Position prescription barcode in the scanner area</p>
<button type="button" class="btn btn-primary" onclick="startScanner()">
<i class="fa fa-camera"></i> Start Scanner
</button>
</div>
`;
}
function lookupPrescription(prescriptionNumber = null) {
const rxNumber = prescriptionNumber || document.getElementById('manualPrescriptionNumber').value;
if (!rxNumber.trim()) {
alert('Please enter a prescription number');
return;
}
// Simulate prescription lookup
console.log('Looking up prescription:', rxNumber);
// Close modal
bootstrap.Modal.getInstance(document.getElementById('scanPrescriptionModal')).hide();
// Redirect to dispensing page with prescription
window.location.href = `{% url 'pharmacy:medication_dispensing' %}?rx=${rxNumber}`;
}
// Auto-save functionality for form data
let autoSaveTimer;
const formInputs = document.querySelectorAll('#dispensingForm input, #dispensingForm select, #dispensingForm textarea');
formInputs.forEach(input => {
input.addEventListener('change', function() {
clearTimeout(autoSaveTimer);
autoSaveTimer = setTimeout(autoSaveForm, 30000); // Auto-save after 30 seconds of inactivity
});
});
function autoSaveForm() {
console.log('Auto-saving dispensing form data...');
// Implementation for auto-saving form data
}
</script>
{% endblock %}