282 lines
13 KiB
HTML
282 lines
13 KiB
HTML
{% extends "base.html" %}
|
|
{% load static %}
|
|
|
|
{% block title %}Cancel Appointment{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="d-flex align-items-center mb-3">
|
|
<div>
|
|
<ol class="breadcrumb">
|
|
<li class="breadcrumb-item"><a href="{% url 'appointments:dashboard' %}">Appointments</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' object.pk %}">{{ object.patient.get_full_name }}</a></li>
|
|
<li class="breadcrumb-item active">Cancel</li>
|
|
</ol>
|
|
<h1 class="page-header mb-0">Cancel Appointment</h1>
|
|
</div>
|
|
<div class="ms-auto">
|
|
<a href="{% url 'appointments:appointment_detail' object.pk %}" class="btn btn-secondary">
|
|
<i class="fas fa-arrow-left me-2"></i>Back to Appointment
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row justify-content-center">
|
|
<div class="col-xl-8">
|
|
<div class="card">
|
|
<div class="card-header bg-danger text-white">
|
|
<h4 class="card-title mb-0">
|
|
<i class="fas fa-exclamation-triangle me-2"></i>
|
|
Confirm Appointment Cancellation
|
|
</h4>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="alert alert-warning">
|
|
<h5 class="alert-heading">
|
|
<i class="fas fa-exclamation-triangle me-2"></i>
|
|
Are you sure you want to cancel this appointment?
|
|
</h5>
|
|
<p class="mb-0">
|
|
This action cannot be undone. The appointment will be permanently cancelled
|
|
and the patient will be notified.
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Appointment Details -->
|
|
<div class="row mb-4">
|
|
<div class="col-md-6">
|
|
<div class="card bg-light">
|
|
<div class="card-body">
|
|
<h6 class="card-title">
|
|
<i class="fas fa-user me-2"></i>Patient Information
|
|
</h6>
|
|
<div class="mb-2">
|
|
<strong>Name:</strong> {{ object.patient.get_full_name }}
|
|
</div>
|
|
<div class="mb-2">
|
|
<strong>Phone:</strong> {{ object.patient.phone|default:"Not provided" }}
|
|
</div>
|
|
<div class="mb-2">
|
|
<strong>Email:</strong> {{ object.patient.email|default:"Not provided" }}
|
|
</div>
|
|
<div>
|
|
<strong>Patient ID:</strong> {{ object.patient.patient_id }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="card bg-light">
|
|
<div class="card-body">
|
|
<h6 class="card-title">
|
|
<i class="fas fa-calendar-alt me-2"></i>Appointment Details
|
|
</h6>
|
|
<div class="mb-2">
|
|
<strong>Date:</strong> {{ object.appointment_date|date:"F d, Y" }}
|
|
</div>
|
|
<div class="mb-2">
|
|
<strong>Time:</strong> {{ object.appointment_time|time:"g:i A" }}
|
|
</div>
|
|
<div class="mb-2">
|
|
<strong>Doctor:</strong> {{ object.doctor.get_full_name }}
|
|
</div>
|
|
<div class="mb-2">
|
|
<strong>Type:</strong> {{ object.get_appointment_type_display }}
|
|
</div>
|
|
<div>
|
|
<strong>Duration:</strong> {{ object.duration|default:"30" }} minutes
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<div class="card bg-light">
|
|
<div class="card-body">
|
|
<h6 class="card-title">
|
|
<i class="fas fa-notes-medical me-2"></i>Appointment Details
|
|
</h6>
|
|
<div class="mb-2">
|
|
<strong>Reason:</strong> {{ object.reason|default:"Not specified" }}
|
|
</div>
|
|
{% if object.notes %}
|
|
<div>
|
|
<strong>Notes:</strong> {{ object.notes }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Cancellation Form -->
|
|
<form method="post">
|
|
{% csrf_token %}
|
|
|
|
<div class="mb-3">
|
|
<label for="cancellation_reason" class="form-label">
|
|
<strong>Reason for Cancellation *</strong>
|
|
</label>
|
|
<select class="form-select" id="cancellation_reason" name="cancellation_reason" required>
|
|
<option value="">Select a reason</option>
|
|
<option value="patient_request">Patient Request</option>
|
|
<option value="doctor_unavailable">Doctor Unavailable</option>
|
|
<option value="emergency">Emergency</option>
|
|
<option value="rescheduled">Rescheduled</option>
|
|
<option value="no_show">Patient No-Show</option>
|
|
<option value="medical_reasons">Medical Reasons</option>
|
|
<option value="administrative">Administrative</option>
|
|
<option value="other">Other</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label for="cancellation_notes" class="form-label">
|
|
<strong>Additional Notes</strong>
|
|
</label>
|
|
<textarea class="form-control"
|
|
id="cancellation_notes"
|
|
name="cancellation_notes"
|
|
rows="3"
|
|
placeholder="Provide additional details about the cancellation..."></textarea>
|
|
<div class="form-text">
|
|
These notes will be included in the cancellation record and patient notification.
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-3">
|
|
<div class="col-md-6">
|
|
<div class="form-check">
|
|
<input class="form-check-input"
|
|
type="checkbox"
|
|
id="notify_patient"
|
|
name="notify_patient"
|
|
checked>
|
|
<label class="form-check-label" for="notify_patient">
|
|
Notify patient via email/SMS
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-check">
|
|
<input class="form-check-input"
|
|
type="checkbox"
|
|
id="offer_reschedule"
|
|
name="offer_reschedule"
|
|
checked>
|
|
<label class="form-check-label" for="offer_reschedule">
|
|
Offer to reschedule appointment
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="alert alert-info">
|
|
<h6 class="alert-heading">
|
|
<i class="fas fa-info-circle me-2"></i>What happens next?
|
|
</h6>
|
|
<ul class="mb-0">
|
|
<li>The appointment will be marked as cancelled</li>
|
|
<li>The time slot will become available for other patients</li>
|
|
<li>Patient will receive a cancellation notification (if selected)</li>
|
|
<li>A cancellation record will be created for audit purposes</li>
|
|
{% if object.is_follow_up %}
|
|
<li>Follow-up scheduling may need to be rearranged</li>
|
|
{% endif %}
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="d-flex justify-content-between">
|
|
<a href="{% url 'appointments:appointment_detail' object.pk %}" class="btn btn-secondary">
|
|
<i class="fas fa-times me-2"></i>Keep Appointment
|
|
</a>
|
|
<div>
|
|
<button type="button" class="btn btn-warning me-2" onclick="rescheduleAppointment()">
|
|
<i class="fas fa-calendar-alt me-2"></i>Reschedule Instead
|
|
</button>
|
|
<button type="submit" class="btn btn-danger" onclick="return confirmCancellation()">
|
|
<i class="fas fa-ban me-2"></i>Cancel Appointment
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Impact Warning -->
|
|
{% if object.is_follow_up or object.priority == 'high' %}
|
|
<div class="card mt-4">
|
|
<div class="card-header bg-warning text-dark">
|
|
<h5 class="card-title mb-0">
|
|
<i class="fas fa-exclamation-triangle me-2"></i>
|
|
Special Considerations
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
{% if object.is_follow_up %}
|
|
<div class="alert alert-warning">
|
|
<strong>Follow-up Appointment:</strong> This is a follow-up appointment.
|
|
Cancelling may affect the patient's treatment plan. Consider rescheduling instead.
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if object.priority == 'high' %}
|
|
<div class="alert alert-danger">
|
|
<strong>High Priority:</strong> This appointment is marked as high priority.
|
|
Please ensure the patient receives appropriate alternative care if cancelled.
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function confirmCancellation() {
|
|
const reason = document.getElementById('cancellation_reason').value;
|
|
|
|
if (!reason) {
|
|
alert('Please select a reason for cancellation.');
|
|
return false;
|
|
}
|
|
|
|
const patientName = "{{ object.patient.get_full_name }}";
|
|
const appointmentDate = "{{ object.appointment_date|date:'F d, Y' }}";
|
|
const appointmentTime = "{{ object.appointment_time|time:'g:i A' }}";
|
|
|
|
const message = `Are you absolutely sure you want to cancel the appointment for ${patientName} on ${appointmentDate} at ${appointmentTime}?\n\nThis action cannot be undone.`;
|
|
|
|
return confirm(message);
|
|
}
|
|
|
|
function rescheduleAppointment() {
|
|
if (confirm('Would you like to reschedule this appointment instead of cancelling it?')) {
|
|
window.location.href = "{% url 'appointments:appointment_form' %}?reschedule={{ object.pk }}";
|
|
}
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Auto-focus on cancellation reason
|
|
document.getElementById('cancellation_reason').focus();
|
|
|
|
// Show/hide additional options based on reason
|
|
const reasonSelect = document.getElementById('cancellation_reason');
|
|
const notesTextarea = document.getElementById('cancellation_notes');
|
|
|
|
reasonSelect.addEventListener('change', function() {
|
|
if (this.value === 'other') {
|
|
notesTextarea.required = true;
|
|
notesTextarea.placeholder = 'Please specify the reason for cancellation...';
|
|
} else {
|
|
notesTextarea.required = false;
|
|
notesTextarea.placeholder = 'Provide additional details about the cancellation...';
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
{% endblock %}
|
|
|