314 lines
20 KiB
HTML
314 lines
20 KiB
HTML
{% extends 'base.html' %}
|
|
{% load static %}
|
|
|
|
{% block title %}Mark No Show{% endblock %}
|
|
|
|
{% block content %}
|
|
<div id="content" class="app-content">
|
|
<div class="container">
|
|
<div class="row justify-content-center">
|
|
<div class="col-xl-8">
|
|
<ul class="breadcrumb">
|
|
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'appointments:appointment_list' %}">Appointments</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'appointments:appointment_detail' appointment.id %}">{{ appointment.patient.first_name }} {{ appointment.patient.last_name }}</a></li>
|
|
<li class="breadcrumb-item active">No Show</li>
|
|
</ul>
|
|
|
|
<h1 class="page-header">Mark Appointment as No Show</h1>
|
|
|
|
<!-- Appointment Info -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h4 class="card-title">Appointment Details</h4>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="row mb-2">
|
|
<div class="col-4"><strong>Patient:</strong></div>
|
|
<div class="col-8">{{ appointment.patient.first_name }} {{ appointment.patient.last_name }}</div>
|
|
</div>
|
|
<div class="row mb-2">
|
|
<div class="col-4"><strong>Patient ID:</strong></div>
|
|
<div class="col-8">{{ appointment.patient.patient_id }}</div>
|
|
</div>
|
|
<div class="row mb-2">
|
|
<div class="col-4"><strong>Phone:</strong></div>
|
|
<div class="col-8">{{ appointment.patient.phone_number|default:"Not provided" }}</div>
|
|
</div>
|
|
<div class="row mb-2">
|
|
<div class="col-4"><strong>Provider:</strong></div>
|
|
<div class="col-8">{{ appointment.provider.first_name }} {{ appointment.provider.last_name }}</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="row mb-2">
|
|
<div class="col-4"><strong>Date:</strong></div>
|
|
<div class="col-8">{{ appointment.appointment_date|date:"M d, Y" }}</div>
|
|
</div>
|
|
<div class="row mb-2">
|
|
<div class="col-4"><strong>Time:</strong></div>
|
|
<div class="col-8">{{ appointment.appointment_time|time:"g:i A" }}</div>
|
|
</div>
|
|
<div class="row mb-2">
|
|
<div class="col-4"><strong>Department:</strong></div>
|
|
<div class="col-8">{{ appointment.department.name }}</div>
|
|
</div>
|
|
<div class="row mb-2">
|
|
<div class="col-4"><strong>Type:</strong></div>
|
|
<div class="col-8">{{ appointment.appointment_type.name }}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- No Show Form -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h4 class="card-title">No Show Documentation</h4>
|
|
</div>
|
|
<div class="card-body">
|
|
{% if messages %}
|
|
{% for message in messages %}
|
|
<div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
|
|
{{ message }}
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
</div>
|
|
{% endfor %}
|
|
{% endif %}
|
|
|
|
<div class="alert alert-warning">
|
|
<i class="fa fa-exclamation-triangle me-2"></i>
|
|
<strong>Important:</strong> Please ensure you have attempted to contact the patient before marking as no show.
|
|
</div>
|
|
|
|
<form method="post" class="form-horizontal">
|
|
{% csrf_token %}
|
|
|
|
<div class="row mb-3">
|
|
<label class="col-form-label col-md-3">Wait Time</label>
|
|
<div class="col-md-9">
|
|
<div class="input-group">
|
|
<input type="number" name="wait_time" class="form-control"
|
|
value="{{ form.wait_time.value|default:'15' }}" min="0" max="120">
|
|
<span class="input-group-text">minutes</span>
|
|
</div>
|
|
<small class="form-text text-muted">How long did you wait for the patient?</small>
|
|
{% if form.wait_time.errors %}
|
|
<div class="text-danger">{{ form.wait_time.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-3">
|
|
<label class="col-form-label col-md-3">Contact Attempts</label>
|
|
<div class="col-md-9">
|
|
<div class="form-check mb-2">
|
|
<input class="form-check-input" type="checkbox" name="phone_attempted" id="phone_attempted"
|
|
{% if form.phone_attempted.value %}checked{% endif %}>
|
|
<label class="form-check-label" for="phone_attempted">
|
|
Phone call attempted
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-2">
|
|
<input class="form-check-input" type="checkbox" name="text_attempted" id="text_attempted"
|
|
{% if form.text_attempted.value %}checked{% endif %}>
|
|
<label class="form-check-label" for="text_attempted">
|
|
Text message sent
|
|
</label>
|
|
</div>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" name="email_attempted" id="email_attempted"
|
|
{% if form.email_attempted.value %}checked{% endif %}>
|
|
<label class="form-check-label" for="email_attempted">
|
|
Email sent
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-3">
|
|
<label class="col-form-label col-md-3">Number of Contact Attempts</label>
|
|
<div class="col-md-9">
|
|
<select name="contact_attempts" class="form-select">
|
|
<option value="1" {% if form.contact_attempts.value == '1' %}selected{% endif %}>1 attempt</option>
|
|
<option value="2" {% if form.contact_attempts.value == '2' %}selected{% endif %}>2 attempts</option>
|
|
<option value="3" {% if form.contact_attempts.value == '3' %}selected{% endif %}>3 attempts</option>
|
|
<option value="4" {% if form.contact_attempts.value == '4' %}selected{% endif %}>4+ attempts</option>
|
|
</select>
|
|
{% if form.contact_attempts.errors %}
|
|
<div class="text-danger">{{ form.contact_attempts.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-3">
|
|
<label class="col-form-label col-md-3">No Show Reason</label>
|
|
<div class="col-md-9">
|
|
<select name="no_show_reason" class="form-select">
|
|
<option value="">Select Reason (if known)</option>
|
|
<option value="forgot" {% if form.no_show_reason.value == 'forgot' %}selected{% endif %}>Patient forgot appointment</option>
|
|
<option value="illness" {% if form.no_show_reason.value == 'illness' %}selected{% endif %}>Patient became ill</option>
|
|
<option value="emergency" {% if form.no_show_reason.value == 'emergency' %}selected{% endif %}>Emergency situation</option>
|
|
<option value="transportation" {% if form.no_show_reason.value == 'transportation' %}selected{% endif %}>Transportation issues</option>
|
|
<option value="work_conflict" {% if form.no_show_reason.value == 'work_conflict' %}selected{% endif %}>Work conflict</option>
|
|
<option value="weather" {% if form.no_show_reason.value == 'weather' %}selected{% endif %}>Weather conditions</option>
|
|
<option value="financial" {% if form.no_show_reason.value == 'financial' %}selected{% endif %}>Financial concerns</option>
|
|
<option value="no_response" {% if form.no_show_reason.value == 'no_response' %}selected{% endif %}>No response to contact attempts</option>
|
|
<option value="other" {% if form.no_show_reason.value == 'other' %}selected{% endif %}>Other</option>
|
|
</select>
|
|
{% if form.no_show_reason.errors %}
|
|
<div class="text-danger">{{ form.no_show_reason.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-3">
|
|
<label class="col-form-label col-md-3">No Show Fee</label>
|
|
<div class="col-md-9">
|
|
<div class="input-group">
|
|
<span class="input-group-text">$</span>
|
|
<input type="number" name="no_show_fee" class="form-control"
|
|
step="0.01" min="0" value="{{ form.no_show_fee.value|default:'25.00' }}">
|
|
</div>
|
|
<small class="form-text text-muted">Standard no-show fee as per policy</small>
|
|
{% if form.no_show_fee.errors %}
|
|
<div class="text-danger">{{ form.no_show_fee.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-3">
|
|
<label class="col-form-label col-md-3">Documented By</label>
|
|
<div class="col-md-9">
|
|
<input type="text" name="documented_by" class="form-control"
|
|
value="{{ form.documented_by.value|default:request.user.get_full_name }}" readonly>
|
|
{% if form.documented_by.errors %}
|
|
<div class="text-danger">{{ form.documented_by.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-3">
|
|
<label class="col-form-label col-md-3">Notes</label>
|
|
<div class="col-md-9">
|
|
<textarea name="no_show_notes" class="form-control" rows="4"
|
|
placeholder="Additional details about the no-show incident, contact attempts, or patient communication">{{ form.no_show_notes.value|default:'' }}</textarea>
|
|
{% if form.no_show_notes.errors %}
|
|
<div class="text-danger">{{ form.no_show_notes.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-3">
|
|
<div class="col-md-9 offset-md-3">
|
|
<div class="form-check mb-2">
|
|
<input class="form-check-input" type="checkbox" name="reschedule_offered" id="reschedule_offered"
|
|
{% if form.reschedule_offered.value %}checked{% endif %}>
|
|
<label class="form-check-label" for="reschedule_offered">
|
|
Rescheduling was offered to patient
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-2">
|
|
<input class="form-check-input" type="checkbox" name="add_to_waitlist" id="add_to_waitlist"
|
|
{% if form.add_to_waitlist.value %}checked{% endif %}>
|
|
<label class="form-check-label" for="add_to_waitlist">
|
|
Add patient to waitlist for future appointments
|
|
</label>
|
|
</div>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" name="send_follow_up" id="send_follow_up"
|
|
{% if form.send_follow_up.value %}checked{% endif %}>
|
|
<label class="form-check-label" for="send_follow_up">
|
|
Send follow-up communication to patient
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-9 offset-md-3">
|
|
<button type="submit" class="btn btn-warning" onclick="return confirm('Are you sure you want to mark this appointment as no show? This will apply the no-show fee and update the patient record.')">
|
|
<i class="fa fa-exclamation-triangle me-2"></i>Mark as No Show
|
|
</button>
|
|
<a href="{% url 'appointments:appointment_detail' appointment.id %}" class="btn btn-secondary ms-2">
|
|
<i class="fa fa-arrow-left me-2"></i>Go Back
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- No Show Policy -->
|
|
<div class="card mt-4">
|
|
<div class="card-header">
|
|
<h4 class="card-title">No Show Policy</h4>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<h6>Policy Guidelines:</h6>
|
|
<ul>
|
|
<li>Wait minimum 15 minutes past appointment time</li>
|
|
<li>Make at least 2 contact attempts</li>
|
|
<li>Document all contact attempts</li>
|
|
<li>Apply standard no-show fee ($25.00)</li>
|
|
<li>Offer rescheduling when possible</li>
|
|
</ul>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<h6>Patient Impact:</h6>
|
|
<ul>
|
|
<li>No-show fee will be added to patient account</li>
|
|
<li>Appointment slot becomes available for other patients</li>
|
|
<li>Patient's no-show history is tracked</li>
|
|
<li>Multiple no-shows may affect future scheduling</li>
|
|
<li>Follow-up communication will be sent</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block js %}
|
|
<script>
|
|
$(document).ready(function() {
|
|
// Auto-check contact attempts based on patient contact info
|
|
var hasPhone = '{{ appointment.patient.phone_number }}' !== '';
|
|
var hasEmail = '{{ appointment.patient.email }}' !== '';
|
|
|
|
if (hasPhone) {
|
|
$('#phone_attempted').prop('checked', true);
|
|
}
|
|
if (hasEmail) {
|
|
$('#email_attempted').prop('checked', true);
|
|
}
|
|
|
|
// Adjust no-show fee based on appointment type
|
|
var appointmentType = '{{ appointment.appointment_type.name }}';
|
|
if (appointmentType.toLowerCase().includes('consultation') || appointmentType.toLowerCase().includes('follow-up')) {
|
|
$('input[name="no_show_fee"]').val('15.00');
|
|
} else if (appointmentType.toLowerCase().includes('procedure') || appointmentType.toLowerCase().includes('surgery')) {
|
|
$('input[name="no_show_fee"]').val('50.00');
|
|
}
|
|
|
|
// Update contact attempts count based on checkboxes
|
|
$('input[type="checkbox"][name$="_attempted"]').change(function() {
|
|
var checkedCount = $('input[type="checkbox"][name$="_attempted"]:checked').length;
|
|
if (checkedCount > 0) {
|
|
$('select[name="contact_attempts"]').val(Math.min(checkedCount, 4));
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
{% endblock %}
|
|
|