760 lines
34 KiB
HTML
760 lines
34 KiB
HTML
{% extends "base.html" %}
|
|
{% load static %}
|
|
|
|
{% block title %}{% if object %}Edit{% else %}New{% endif %} Prescription - Pharmacy{% endblock %}
|
|
|
|
{% block content %}
|
|
<!-- BEGIN breadcrumb -->
|
|
<ol class="breadcrumb float-xl-end">
|
|
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'pharmacy:dashboard' %}">Pharmacy</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'pharmacy:prescription_list' %}">Prescriptions</a></li>
|
|
{% if object %}
|
|
<li class="breadcrumb-item"><a href="{% url 'pharmacy:prescription_detail' object.pk %}">{{ object.prescription_number }}</a></li>
|
|
<li class="breadcrumb-item active">Edit</li>
|
|
{% else %}
|
|
<li class="breadcrumb-item active">New</li>
|
|
{% endif %}
|
|
</ol>
|
|
<!-- END breadcrumb -->
|
|
|
|
<!-- BEGIN page-header -->
|
|
<h1 class="page-header">
|
|
{% if object %}Edit Prescription{% else %}New Prescription{% endif %}
|
|
<small>{% if object %}{{ object.prescription_number }}{% else %}Create new prescription order{% endif %}</small>
|
|
</h1>
|
|
<!-- END page-header -->
|
|
|
|
<div class="row">
|
|
<div class="col-xl-8">
|
|
<!-- BEGIN panel -->
|
|
<div class="panel panel-inverse">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">Prescription Details</h4>
|
|
<div class="panel-heading-btn">
|
|
<button type="button" class="btn btn-xs btn-info me-2" onclick="checkInteractions()">
|
|
<i class="fa fa-exclamation-triangle"></i> Check Interactions
|
|
</button>
|
|
<button type="button" class="btn btn-xs btn-secondary me-2" onclick="saveDraft()">
|
|
<i class="fa fa-save"></i> Save Draft
|
|
</button>
|
|
<a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-expand"><i class="fa fa-expand"></i></a>
|
|
</div>
|
|
</div>
|
|
<div class="panel-body">
|
|
<form method="post" id="prescription-form" novalidate>
|
|
{% csrf_token %}
|
|
|
|
<!-- Patient Selection -->
|
|
<div class="row mb-3">
|
|
<div class="col-md-6">
|
|
<div class="form-floating">
|
|
{{ form.patient }}
|
|
<label for="{{ form.patient.id_for_label }}">Patient <span class="text-danger">*</span></label>
|
|
{% if form.patient.errors %}
|
|
<div class="invalid-feedback d-block">{{ form.patient.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
<div class="form-text">Select the patient for this prescription.</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-floating">
|
|
{{ form.prescriber }}
|
|
<label for="{{ form.prescriber.id_for_label }}">Prescriber <span class="text-danger">*</span></label>
|
|
{% if form.prescriber.errors %}
|
|
<div class="invalid-feedback d-block">{{ form.prescriber.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
<div class="form-text">Prescribing physician or provider.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Patient Information Display -->
|
|
<div id="patient-info" class="card border-info mb-3" style="display: none;">
|
|
<div class="card-header bg-info text-white">
|
|
<h6 class="card-title mb-0">
|
|
<i class="fa fa-user me-2"></i>Patient Information
|
|
</h6>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div id="patient-details"></div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div id="patient-allergies"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Medication Selection -->
|
|
<div class="row mb-3">
|
|
<div class="col-md-8">
|
|
<div class="form-floating">
|
|
{{ form.medication }}
|
|
<label for="{{ form.medication.id_for_label }}">Medication <span class="text-danger">*</span></label>
|
|
{% if form.medication.errors %}
|
|
<div class="invalid-feedback d-block">{{ form.medication.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
<div class="form-text">Search and select medication.</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-floating">
|
|
{{ form.strength }}
|
|
<label for="{{ form.strength.id_for_label }}">Strength</label>
|
|
{% if form.strength.errors %}
|
|
<div class="invalid-feedback d-block">{{ form.strength.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
<div class="form-text">Medication strength.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Medication Information Display -->
|
|
<div id="medication-info" class="card border-warning mb-3" style="display: none;">
|
|
<div class="card-header bg-warning text-dark">
|
|
<h6 class="card-title mb-0">
|
|
<i class="fa fa-pills me-2"></i>Medication Information
|
|
</h6>
|
|
</div>
|
|
<div class="card-body">
|
|
<div id="medication-details"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Dosage and Quantity -->
|
|
<div class="row mb-3">
|
|
<div class="col-md-3">
|
|
<div class="form-floating">
|
|
{{ form.dosage }}
|
|
<label for="{{ form.dosage.id_for_label }}">Dosage <span class="text-danger">*</span></label>
|
|
{% if form.dosage.errors %}
|
|
<div class="invalid-feedback d-block">{{ form.dosage.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
<div class="form-text">Dose amount.</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="form-floating">
|
|
{{ form.dosage_unit }}
|
|
<label for="{{ form.dosage_unit.id_for_label }}">Unit</label>
|
|
{% if form.dosage_unit.errors %}
|
|
<div class="invalid-feedback d-block">{{ form.dosage_unit.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
<div class="form-text">Dosage unit.</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="form-floating">
|
|
{{ form.quantity }}
|
|
<label for="{{ form.quantity.id_for_label }}">Quantity <span class="text-danger">*</span></label>
|
|
{% if form.quantity.errors %}
|
|
<div class="invalid-feedback d-block">{{ form.quantity.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
<div class="form-text">Total quantity.</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="form-floating">
|
|
{{ form.days_supply }}
|
|
<label for="{{ form.days_supply.id_for_label }}">Days Supply</label>
|
|
{% if form.days_supply.errors %}
|
|
<div class="invalid-feedback d-block">{{ form.days_supply.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
<div class="form-text">Number of days.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Frequency and Route -->
|
|
<div class="row mb-3">
|
|
<div class="col-md-6">
|
|
<div class="form-floating">
|
|
{{ form.frequency }}
|
|
<label for="{{ form.frequency.id_for_label }}">Frequency <span class="text-danger">*</span></label>
|
|
{% if form.frequency.errors %}
|
|
<div class="invalid-feedback d-block">{{ form.frequency.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
<div class="form-text">How often to take medication.</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-floating">
|
|
{{ form.route }}
|
|
<label for="{{ form.route.id_for_label }}">Route</label>
|
|
{% if form.route.errors %}
|
|
<div class="invalid-feedback d-block">{{ form.route.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
<div class="form-text">Route of administration.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Instructions -->
|
|
<div class="mb-3">
|
|
<label for="{{ form.instructions.id_for_label }}" class="form-label">Instructions <span class="text-danger">*</span></label>
|
|
{{ form.instructions }}
|
|
{% if form.instructions.errors %}
|
|
<div class="invalid-feedback d-block">{{ form.instructions.errors.0 }}</div>
|
|
{% endif %}
|
|
<div class="form-text">Detailed instructions for patient.</div>
|
|
</div>
|
|
|
|
<!-- Priority and Refills -->
|
|
<div class="row mb-3">
|
|
<div class="col-md-4">
|
|
<div class="form-floating">
|
|
{{ form.priority }}
|
|
<label for="{{ form.priority.id_for_label }}">Priority</label>
|
|
{% if form.priority.errors %}
|
|
<div class="invalid-feedback d-block">{{ form.priority.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
<div class="form-text">Prescription priority.</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-floating">
|
|
{{ form.refills }}
|
|
<label for="{{ form.refills.id_for_label }}">Refills</label>
|
|
{% if form.refills.errors %}
|
|
<div class="invalid-feedback d-block">{{ form.refills.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
<div class="form-text">Number of refills allowed.</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-floating">
|
|
{{ form.due_date }}
|
|
<label for="{{ form.due_date.id_for_label }}">Due Date</label>
|
|
{% if form.due_date.errors %}
|
|
<div class="invalid-feedback d-block">{{ form.due_date.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
<div class="form-text">When prescription is needed.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Special Instructions -->
|
|
<div class="row mb-3">
|
|
<div class="col-md-4">
|
|
<div class="form-check">
|
|
{{ form.is_controlled }}
|
|
<label class="form-check-label" for="{{ form.is_controlled.id_for_label }}">
|
|
<i class="fa fa-shield text-warning me-1"></i>Controlled substance
|
|
</label>
|
|
{% if form.is_controlled.errors %}
|
|
<div class="invalid-feedback d-block">{{ form.is_controlled.errors.0 }}</div>
|
|
{% endif %}
|
|
<div class="form-text">Requires special handling.</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-check">
|
|
{{ form.generic_substitution }}
|
|
<label class="form-check-label" for="{{ form.generic_substitution.id_for_label }}">
|
|
<i class="fa fa-exchange text-info me-1"></i>Allow generic substitution
|
|
</label>
|
|
{% if form.generic_substitution.errors %}
|
|
<div class="invalid-feedback d-block">{{ form.generic_substitution.errors.0 }}</div>
|
|
{% endif %}
|
|
<div class="form-text">Allow generic equivalent.</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-check">
|
|
{{ form.urgent }}
|
|
<label class="form-check-label" for="{{ form.urgent.id_for_label }}">
|
|
<i class="fa fa-exclamation-triangle text-danger me-1"></i>Mark as urgent
|
|
</label>
|
|
{% if form.urgent.errors %}
|
|
<div class="invalid-feedback d-block">{{ form.urgent.errors.0 }}</div>
|
|
{% endif %}
|
|
<div class="form-text">Requires immediate attention.</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Controlled Substance Information -->
|
|
<div id="controlled-info" class="card border-warning mb-3" style="display: none;">
|
|
<div class="card-header bg-warning text-dark">
|
|
<h6 class="card-title mb-0">
|
|
<i class="fa fa-shield me-2"></i>Controlled Substance Information
|
|
</h6>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
{{ form.dea_number }}
|
|
<label for="{{ form.dea_number.id_for_label }}">DEA Number</label>
|
|
{% if form.dea_number.errors %}
|
|
<div class="invalid-feedback d-block">{{ form.dea_number.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
{{ form.schedule }}
|
|
<label for="{{ form.schedule.id_for_label }}">Schedule</label>
|
|
{% if form.schedule.errors %}
|
|
<div class="invalid-feedback d-block">{{ form.schedule.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="alert alert-warning">
|
|
<i class="fa fa-exclamation-triangle me-2"></i>
|
|
This prescription contains controlled substances and requires additional verification.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Notes -->
|
|
<div class="mb-3">
|
|
<label for="{{ form.notes.id_for_label }}" class="form-label">Notes</label>
|
|
{{ form.notes }}
|
|
{% if form.notes.errors %}
|
|
<div class="invalid-feedback d-block">{{ form.notes.errors.0 }}</div>
|
|
{% endif %}
|
|
<div class="form-text">Additional notes or comments.</div>
|
|
</div>
|
|
|
|
<!-- Form Actions -->
|
|
<div class="d-flex justify-content-between">
|
|
<div>
|
|
<a href="{% if object %}{% url 'pharmacy:prescription_detail' object.pk %}{% else %}{% url 'pharmacy:prescription_list' %}{% endif %}" class="btn btn-secondary">
|
|
<i class="fa fa-arrow-left me-2"></i>Cancel
|
|
</a>
|
|
</div>
|
|
<div>
|
|
<button type="button" class="btn btn-info me-2" onclick="saveDraft()">
|
|
<i class="fa fa-save me-2"></i>Save Draft
|
|
</button>
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="fa fa-check me-2"></i>{% if object %}Update{% else %}Create{% endif %} Prescription
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<!-- END panel -->
|
|
</div>
|
|
|
|
<div class="col-xl-4">
|
|
<!-- BEGIN panel -->
|
|
<div class="panel panel-inverse">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">Prescription Guidelines</h4>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div class="alert alert-info">
|
|
<h6 class="alert-heading">Best Practices</h6>
|
|
<ul class="mb-0 small">
|
|
<li>Verify patient allergies before prescribing</li>
|
|
<li>Check for drug interactions</li>
|
|
<li>Use clear, specific instructions</li>
|
|
<li>Include indication when appropriate</li>
|
|
<li>Verify dosage calculations</li>
|
|
<li>Consider patient's medical history</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="card border-danger mb-3">
|
|
<div class="card-header bg-danger text-white">
|
|
<h6 class="card-title mb-0">Safety Checks</h6>
|
|
</div>
|
|
<div class="card-body">
|
|
<ul class="list-unstyled mb-0 small">
|
|
<li id="allergy-check"><i class="fa fa-times text-danger me-2"></i>Allergy check pending</li>
|
|
<li id="interaction-check"><i class="fa fa-times text-danger me-2"></i>Interaction check pending</li>
|
|
<li id="dosage-check"><i class="fa fa-times text-danger me-2"></i>Dosage verification pending</li>
|
|
<li id="duplicate-check"><i class="fa fa-times text-danger me-2"></i>Duplicate therapy check pending</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- END panel -->
|
|
|
|
<!-- BEGIN panel -->
|
|
<div class="panel panel-inverse">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">Quick Actions</h4>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div class="d-grid gap-2">
|
|
<button type="button" class="btn btn-outline-warning" onclick="checkInteractions()">
|
|
<i class="fa fa-exclamation-triangle me-2"></i>Check Interactions
|
|
</button>
|
|
<button type="button" class="btn btn-outline-info" onclick="checkAllergies()">
|
|
<i class="fa fa-user-md me-2"></i>Check Allergies
|
|
</button>
|
|
<button type="button" class="btn btn-outline-primary" onclick="verifyDosage()">
|
|
<i class="fa fa-calculator me-2"></i>Verify Dosage
|
|
</button>
|
|
<button type="button" class="btn btn-outline-secondary" onclick="loadTemplate()">
|
|
<i class="fa fa-copy me-2"></i>Load Template
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- END panel -->
|
|
|
|
<!-- BEGIN panel -->
|
|
<div class="panel panel-inverse">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">Prescription Status</h4>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div id="prescription-status">
|
|
<div class="alert alert-secondary">
|
|
<i class="fa fa-info-circle me-2"></i>
|
|
<span id="status-text">Draft prescription</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="small text-muted">
|
|
<div>Last saved: <span id="last-saved">Never</span></div>
|
|
<div>Auto-save: <span class="text-success">Enabled</span></div>
|
|
<div>Validation: <span id="validation-status" class="text-warning">Pending</span></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- END panel -->
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block js %}
|
|
<script>
|
|
var autoSaveTimer;
|
|
|
|
$(document).ready(function() {
|
|
// Initialize form behavior
|
|
initializeFormBehavior();
|
|
|
|
// Auto-save functionality
|
|
$('#prescription-form input, #prescription-form select, #prescription-form textarea').on('change input', function() {
|
|
clearTimeout(autoSaveTimer);
|
|
autoSaveTimer = setTimeout(function() {
|
|
saveDraft();
|
|
}, 5000);
|
|
});
|
|
|
|
// Form validation
|
|
$('#prescription-form').on('submit', function(e) {
|
|
if (!validateForm()) {
|
|
e.preventDefault();
|
|
}
|
|
});
|
|
});
|
|
|
|
function initializeFormBehavior() {
|
|
// Patient selection change
|
|
$('#{{ form.patient.id_for_label }}').on('change', function() {
|
|
var patientId = $(this).val();
|
|
if (patientId) {
|
|
loadPatientInfo(patientId);
|
|
checkAllergies();
|
|
} else {
|
|
$('#patient-info').hide();
|
|
}
|
|
});
|
|
|
|
// Medication selection change
|
|
$('#{{ form.medication.id_for_label }}').on('change', function() {
|
|
var medicationId = $(this).val();
|
|
if (medicationId) {
|
|
loadMedicationInfo(medicationId);
|
|
checkInteractions();
|
|
} else {
|
|
$('#medication-info').hide();
|
|
}
|
|
});
|
|
|
|
// Controlled substance checkbox
|
|
$('#{{ form.is_controlled.id_for_label }}').on('change', function() {
|
|
if ($(this).is(':checked')) {
|
|
$('#controlled-info').show();
|
|
} else {
|
|
$('#controlled-info').hide();
|
|
}
|
|
});
|
|
|
|
// Initial state
|
|
if ($('#{{ form.is_controlled.id_for_label }}').is(':checked')) {
|
|
$('#controlled-info').show();
|
|
}
|
|
}
|
|
|
|
function loadPatientInfo(patientId) {
|
|
$.ajax({
|
|
url: '{% url "pharmacy:get_patient_info" 0 %}'.replace('0', patientId),
|
|
method: 'GET',
|
|
success: function(response) {
|
|
var patient = response.patient;
|
|
|
|
$('#patient-details').html(`
|
|
<div><strong>Name:</strong> ${patient.full_name}</div>
|
|
<div><strong>Patient ID:</strong> ${patient.patient_id}</div>
|
|
<div><strong>Date of Birth:</strong> ${patient.date_of_birth}</div>
|
|
<div><strong>Age:</strong> ${patient.age} years</div>
|
|
<div><strong>Weight:</strong> ${patient.weight || 'Not recorded'}</div>
|
|
`);
|
|
|
|
var allergiesHtml = '<div><strong>Allergies:</strong></div>';
|
|
if (patient.allergies && patient.allergies.length > 0) {
|
|
allergiesHtml += '<ul class="mb-0">';
|
|
patient.allergies.forEach(function(allergy) {
|
|
allergiesHtml += '<li class="text-danger">' + allergy.allergen + ' (' + allergy.reaction + ')</li>';
|
|
});
|
|
allergiesHtml += '</ul>';
|
|
} else {
|
|
allergiesHtml += '<div class="text-muted">No known allergies</div>';
|
|
}
|
|
|
|
$('#patient-allergies').html(allergiesHtml);
|
|
$('#patient-info').show();
|
|
},
|
|
error: function() {
|
|
toastr.error('Failed to load patient information');
|
|
}
|
|
});
|
|
}
|
|
|
|
function loadMedicationInfo(medicationId) {
|
|
$.ajax({
|
|
url: '{% url "pharmacy:get_medication_info" 0 %}'.replace('0', medicationId),
|
|
method: 'GET',
|
|
success: function(response) {
|
|
var medication = response.medication;
|
|
|
|
$('#medication-details').html(`
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div><strong>Generic Name:</strong> ${medication.generic_name}</div>
|
|
<div><strong>Brand Name:</strong> ${medication.brand_name || 'N/A'}</div>
|
|
<div><strong>Category:</strong> ${medication.category}</div>
|
|
<div><strong>Form:</strong> ${medication.dosage_form}</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div><strong>Strength:</strong> ${medication.strength}</div>
|
|
<div><strong>Route:</strong> ${medication.route}</div>
|
|
<div><strong>Controlled:</strong> ${medication.is_controlled ? 'Yes' : 'No'}</div>
|
|
<div><strong>Stock:</strong> ${medication.stock_quantity} units</div>
|
|
</div>
|
|
</div>
|
|
<div class="mt-2">
|
|
<strong>Indications:</strong>
|
|
<div class="small text-muted">${medication.indications || 'Not specified'}</div>
|
|
</div>
|
|
`);
|
|
|
|
$('#medication-info').show();
|
|
},
|
|
error: function() {
|
|
toastr.error('Failed to load medication information');
|
|
}
|
|
});
|
|
}
|
|
|
|
function validateForm() {
|
|
var isValid = true;
|
|
var errors = [];
|
|
|
|
// Required field validation
|
|
var requiredFields = [
|
|
'{{ form.patient.id_for_label }}',
|
|
'{{ form.medication.id_for_label }}',
|
|
'{{ form.dosage.id_for_label }}',
|
|
'{{ form.quantity.id_for_label }}',
|
|
'{{ form.frequency.id_for_label }}',
|
|
'{{ form.instructions.id_for_label }}'
|
|
];
|
|
|
|
requiredFields.forEach(function(fieldId) {
|
|
var field = $('#' + fieldId);
|
|
if (!field.val()) {
|
|
field.addClass('is-invalid');
|
|
errors.push(field.closest('.form-floating, .mb-3').find('label').text().replace(' *', '') + ' is required');
|
|
isValid = false;
|
|
} else {
|
|
field.removeClass('is-invalid');
|
|
}
|
|
});
|
|
|
|
// Quantity validation
|
|
var quantity = parseInt($('#{{ form.quantity.id_for_label }}').val());
|
|
if (quantity && quantity <= 0) {
|
|
$('#{{ form.quantity.id_for_label }}').addClass('is-invalid');
|
|
errors.push('Quantity must be greater than 0');
|
|
isValid = false;
|
|
}
|
|
|
|
// Refills validation
|
|
var refills = parseInt($('#{{ form.refills.id_for_label }}').val());
|
|
if (refills && refills < 0) {
|
|
$('#{{ form.refills.id_for_label }}').addClass('is-invalid');
|
|
errors.push('Refills cannot be negative');
|
|
isValid = false;
|
|
}
|
|
|
|
// Due date validation
|
|
var dueDate = $('#{{ form.due_date.id_for_label }}').val();
|
|
if (dueDate) {
|
|
var today = new Date();
|
|
var due = new Date(dueDate);
|
|
if (due < today) {
|
|
$('#{{ form.due_date.id_for_label }}').addClass('is-invalid');
|
|
errors.push('Due date cannot be in the past');
|
|
isValid = false;
|
|
}
|
|
}
|
|
|
|
if (!isValid) {
|
|
toastr.error('Please fix the following errors:\n' + errors.join('\n'));
|
|
$('#validation-status').text('Failed').removeClass('text-success text-warning').addClass('text-danger');
|
|
} else {
|
|
$('#validation-status').text('Passed').removeClass('text-danger text-warning').addClass('text-success');
|
|
}
|
|
|
|
return isValid;
|
|
}
|
|
|
|
function saveDraft() {
|
|
var formData = $('#prescription-form').serialize();
|
|
|
|
$.ajax({
|
|
url: '{% url "pharmacy:save_prescription_draft" %}',
|
|
method: 'POST',
|
|
data: formData,
|
|
success: function(response) {
|
|
updatePrescriptionStatus('Draft saved', 'success');
|
|
$('#last-saved').text(new Date().toLocaleTimeString());
|
|
},
|
|
error: function() {
|
|
updatePrescriptionStatus('Failed to save draft', 'danger');
|
|
}
|
|
});
|
|
}
|
|
|
|
function updatePrescriptionStatus(message, type) {
|
|
var alertClass = 'alert-' + type;
|
|
$('#prescription-status').html('<div class="alert ' + alertClass + '"><i class="fa fa-info-circle me-2"></i>' + message + '</div>');
|
|
}
|
|
|
|
function checkInteractions() {
|
|
var patientId = $('#{{ form.patient.id_for_label }}').val();
|
|
var medicationId = $('#{{ form.medication.id_for_label }}').val();
|
|
|
|
if (!patientId || !medicationId) {
|
|
toastr.warning('Please select both patient and medication first');
|
|
return;
|
|
}
|
|
|
|
$.ajax({
|
|
url: '{% url "pharmacy:check_drug_interactions" %}',
|
|
method: 'POST',
|
|
data: {
|
|
'patient_id': patientId,
|
|
'medication_id': medicationId,
|
|
'csrfmiddlewaretoken': '{{ csrf_token }}'
|
|
},
|
|
success: function(response) {
|
|
if (response.interactions.length > 0) {
|
|
var message = 'Drug interactions found:\n';
|
|
response.interactions.forEach(function(interaction) {
|
|
message += '- ' + interaction.description + '\n';
|
|
});
|
|
toastr.warning(message);
|
|
$('#interaction-check').html('<i class="fa fa-exclamation-triangle text-warning me-2"></i>Interactions found');
|
|
} else {
|
|
toastr.success('No drug interactions found');
|
|
$('#interaction-check').html('<i class="fa fa-check text-success me-2"></i>No interactions found');
|
|
}
|
|
},
|
|
error: function() {
|
|
toastr.error('Failed to check drug interactions');
|
|
}
|
|
});
|
|
}
|
|
|
|
function checkAllergies() {
|
|
var patientId = $('#{{ form.patient.id_for_label }}').val();
|
|
var medicationId = $('#{{ form.medication.id_for_label }}').val();
|
|
|
|
if (!patientId || !medicationId) {
|
|
return;
|
|
}
|
|
|
|
$.ajax({
|
|
url: '{% url "pharmacy:check_allergies" %}',
|
|
method: 'POST',
|
|
data: {
|
|
'patient_id': patientId,
|
|
'medication_id': medicationId,
|
|
'csrfmiddlewaretoken': '{{ csrf_token }}'
|
|
},
|
|
success: function(response) {
|
|
if (response.allergies.length > 0) {
|
|
var message = 'Allergy alert:\n';
|
|
response.allergies.forEach(function(allergy) {
|
|
message += '- ' + allergy.allergen + ' (' + allergy.reaction + ')\n';
|
|
});
|
|
toastr.error(message);
|
|
$('#allergy-check').html('<i class="fa fa-exclamation-triangle text-danger me-2"></i>Allergy alert');
|
|
} else {
|
|
$('#allergy-check').html('<i class="fa fa-check text-success me-2"></i>No allergies found');
|
|
}
|
|
},
|
|
error: function() {
|
|
toastr.error('Failed to check allergies');
|
|
}
|
|
});
|
|
}
|
|
|
|
function verifyDosage() {
|
|
var dosage = $('#{{ form.dosage.id_for_label }}').val();
|
|
var medicationId = $('#{{ form.medication.id_for_label }}').val();
|
|
var patientId = $('#{{ form.patient.id_for_label }}').val();
|
|
|
|
if (!dosage || !medicationId || !patientId) {
|
|
toastr.warning('Please fill in dosage, medication, and patient first');
|
|
return;
|
|
}
|
|
|
|
$.ajax({
|
|
url: '{% url "pharmacy:verify_dosage" %}',
|
|
method: 'POST',
|
|
data: {
|
|
'dosage': dosage,
|
|
'medication_id': medicationId,
|
|
'patient_id': patientId,
|
|
'csrfmiddlewaretoken': '{{ csrf_token }}'
|
|
},
|
|
success: function(response) {
|
|
if (response.is_valid) {
|
|
toastr.success('Dosage is within normal range');
|
|
$('#dosage-check').html('<i class="fa fa-check text-success me-2"></i>Dosage verified');
|
|
} else {
|
|
toastr.warning('Dosage may be outside normal range: ' + response.message);
|
|
$('#dosage-check').html('<i class="fa fa-exclamation-triangle text-warning me-2"></i>Dosage warning');
|
|
}
|
|
},
|
|
error: function() {
|
|
toastr.error('Failed to verify dosage');
|
|
}
|
|
});
|
|
}
|
|
|
|
function loadTemplate() {
|
|
// Implementation for loading prescription templates
|
|
toastr.info('Template loading feature coming soon');
|
|
}
|
|
</script>
|
|
{% endblock %}
|
|
|