474 lines
24 KiB
HTML
474 lines
24 KiB
HTML
{% extends 'base.html' %}
|
|
{% load static %}
|
|
|
|
{% block title %}Sign Operative Note - Operating Theatre{% 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>Sign Operative Note</h4>
|
|
<h6>Review and electronically sign the operative note</h6>
|
|
</div>
|
|
<div class="page-btn">
|
|
<a href="{% url 'operating_theatre:surgical_case_list' %}" class="btn btn-secondary">
|
|
<i class="fa fa-arrow-left"></i> Back to Cases
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Operative Note Content -->
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title">Operative Note - {{ surgical_case.case_id }}</h5>
|
|
<div class="card-tools">
|
|
<span class="badge bg-{{ note.status_color }}">{{ note.status|title }}</span>
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
<!-- Note Content Display -->
|
|
<div class="operative-note-content">
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<h6 class="text-primary">Patient Information</h6>
|
|
<hr>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<strong>Patient Name:</strong> {{ surgical_case.patient.get_full_name }}<br>
|
|
<strong>MRN:</strong> {{ surgical_case.patient.medical_record_number }}<br>
|
|
<strong>DOB:</strong> {{ surgical_case.patient.date_of_birth|date:"M d, Y" }}<br>
|
|
<strong>Age:</strong> {{ surgical_case.patient.age }} years
|
|
</div>
|
|
<div class="col-md-6">
|
|
<strong>Date of Surgery:</strong> {{ surgical_case.actual_start_time|date:"M d, Y" }}<br>
|
|
<strong>Operating Room:</strong> {{ surgical_case.operating_room.room_number }}<br>
|
|
<strong>Case Duration:</strong> {{ case_duration }} minutes
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<h6 class="text-primary">Procedure Information</h6>
|
|
<hr>
|
|
</div>
|
|
<div class="col-12">
|
|
<strong>Primary Procedure:</strong><br>
|
|
<p>{{ note.primary_procedure|default:surgical_case.procedure_name }}</p>
|
|
|
|
{% if note.secondary_procedures %}
|
|
<strong>Secondary Procedures:</strong><br>
|
|
<p>{{ note.secondary_procedures }}</p>
|
|
{% endif %}
|
|
|
|
<strong>Procedure Code(s):</strong><br>
|
|
<p>{{ surgical_case.procedure_code }}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<h6 class="text-primary">Surgical Team</h6>
|
|
<hr>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<strong>Primary Surgeon:</strong> {{ surgical_case.primary_surgeon.get_full_name }}<br>
|
|
{% if surgical_case.assistant_surgeon %}
|
|
<strong>Assistant Surgeon:</strong> {{ surgical_case.assistant_surgeon.get_full_name }}<br>
|
|
{% endif %}
|
|
<strong>Anesthesiologist:</strong> {{ surgical_case.anesthesiologist.get_full_name|default:"Not specified" }}
|
|
</div>
|
|
<div class="col-md-6">
|
|
{% if note.scrub_nurse %}
|
|
<strong>Scrub Nurse:</strong> {{ note.scrub_nurse }}<br>
|
|
{% endif %}
|
|
{% if note.circulating_nurse %}
|
|
<strong>Circulating Nurse:</strong> {{ note.circulating_nurse }}<br>
|
|
{% endif %}
|
|
<strong>Anesthesia Type:</strong> {{ note.anesthesia_type|title|default:"Not specified" }}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<h6 class="text-primary">Pre-operative Diagnosis</h6>
|
|
<hr>
|
|
<p>{{ note.preop_diagnosis|default:"Not specified" }}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<h6 class="text-primary">Post-operative Diagnosis</h6>
|
|
<hr>
|
|
<p>{{ note.postop_diagnosis|default:"Same as pre-operative diagnosis" }}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<h6 class="text-primary">Operative Findings</h6>
|
|
<hr>
|
|
<p>{{ note.operative_findings|default:"No significant findings documented" }}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<h6 class="text-primary">Procedure Description</h6>
|
|
<hr>
|
|
<p>{{ note.procedure_description|default:"Detailed procedure description pending" }}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<h6 class="text-primary">Complications</h6>
|
|
<hr>
|
|
<p>{{ note.complications|default:"None" }}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-4">
|
|
<div class="col-md-6">
|
|
<h6 class="text-primary">Estimated Blood Loss</h6>
|
|
<hr>
|
|
<p>{{ note.estimated_blood_loss|default:"Not documented" }} mL</p>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<h6 class="text-primary">Fluid Balance</h6>
|
|
<hr>
|
|
<p>{{ note.fluid_balance|default:"Not documented" }} mL</p>
|
|
</div>
|
|
</div>
|
|
|
|
{% if note.specimens_collected %}
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<h6 class="text-primary">Specimens Collected</h6>
|
|
<hr>
|
|
<p>{{ note.specimens_collected }}</p>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if note.implants_used %}
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<h6 class="text-primary">Implants and Devices</h6>
|
|
<hr>
|
|
<p>{{ note.implants_used }}</p>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<h6 class="text-primary">Post-operative Plan</h6>
|
|
<hr>
|
|
<p>{{ note.postop_plan|default:"Standard post-operative care" }}</p>
|
|
</div>
|
|
</div>
|
|
|
|
{% if note.additional_notes %}
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<h6 class="text-primary">Additional Notes</h6>
|
|
<hr>
|
|
<p>{{ note.additional_notes }}</p>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Signature Section -->
|
|
{% if note.status != 'signed' %}
|
|
<div class="signature-section mt-5">
|
|
<div class="card border-warning">
|
|
<div class="card-header bg-warning text-dark">
|
|
<h6 class="mb-0">Electronic Signature Required</h6>
|
|
</div>
|
|
<div class="card-body">
|
|
<form method="post" id="signatureForm">
|
|
{% csrf_token %}
|
|
<input type="hidden" name="note_id" value="{{ note.id }}">
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label class="form-label">Signing Physician *</label>
|
|
<input type="text" class="form-control" value="{{ request.user.get_full_name }}" readonly>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label class="form-label">Signature Date/Time *</label>
|
|
<input type="datetime-local" name="signature_datetime" class="form-control" required>
|
|
</div>
|
|
</div>
|
|
<div class="col-12">
|
|
<div class="mb-3">
|
|
<label class="form-label">Password Confirmation *</label>
|
|
<input type="password" name="password_confirmation" class="form-control"
|
|
placeholder="Enter your password to confirm signature" required>
|
|
<div class="form-text">Your password is required to electronically sign this document</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-12">
|
|
<div class="form-check mb-3">
|
|
<input class="form-check-input" type="checkbox" name="signature_confirmation"
|
|
id="signatureConfirmation" required>
|
|
<label class="form-check-label" for="signatureConfirmation">
|
|
I confirm that I have reviewed this operative note and that it accurately
|
|
reflects the procedure performed. I understand that this electronic signature
|
|
has the same legal effect as a handwritten signature.
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-12">
|
|
<div class="d-flex justify-content-between">
|
|
<button type="button" class="btn btn-secondary" onclick="history.back()">
|
|
<i class="fa fa-times"></i> Cancel
|
|
</button>
|
|
<button type="submit" class="btn btn-success btn-lg">
|
|
<i class="fa fa-signature"></i> Sign Operative Note
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<!-- Already Signed -->
|
|
<div class="signature-section mt-5">
|
|
<div class="card border-success">
|
|
<div class="card-header bg-success text-white">
|
|
<h6 class="mb-0">Document Signed</h6>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<strong>Signed By:</strong><br>
|
|
{{ note.signed_by.get_full_name }}<br>
|
|
<small class="text-muted">{{ note.signed_by.professional_title|default:"Physician" }}</small>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<strong>Signature Date/Time:</strong><br>
|
|
{{ note.signature_datetime|date:"M d, Y H:i" }}<br>
|
|
<small class="text-muted">{{ note.signature_datetime|timesince }} ago</small>
|
|
</div>
|
|
</div>
|
|
<div class="mt-3">
|
|
<div class="alert alert-success mb-0">
|
|
<i class="fa fa-check-circle"></i> This operative note has been electronically signed and is legally binding.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Sidebar -->
|
|
<div class="col-md-4">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title">Document Information</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="mb-3">
|
|
<strong>Document Type:</strong><br>
|
|
Operative Note
|
|
</div>
|
|
<div class="mb-3">
|
|
<strong>Case ID:</strong><br>
|
|
<span class="text-primary">{{ surgical_case.case_id }}</span>
|
|
</div>
|
|
<div class="mb-3">
|
|
<strong>Created:</strong><br>
|
|
{{ note.created_at|date:"M d, Y H:i" }}
|
|
</div>
|
|
<div class="mb-3">
|
|
<strong>Last Modified:</strong><br>
|
|
{{ note.updated_at|date:"M d, Y H:i" }}
|
|
</div>
|
|
<div class="mb-3">
|
|
<strong>Status:</strong><br>
|
|
<span class="badge bg-{{ note.status_color }}">{{ note.status|title }}</span>
|
|
</div>
|
|
{% if note.status == 'signed' %}
|
|
<div class="mb-3">
|
|
<strong>Signed By:</strong><br>
|
|
{{ note.signed_by.get_full_name }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Actions -->
|
|
<div class="card mt-3">
|
|
<div class="card-header">
|
|
<h5 class="card-title">Actions</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="d-grid gap-2">
|
|
<a href="#" class="btn btn-outline-primary btn-sm">
|
|
<i class="fa fa-print"></i> Print Note
|
|
</a>
|
|
<a href="#" class="btn btn-outline-info btn-sm">
|
|
<i class="fa fa-download"></i> Download PDF
|
|
</a>
|
|
{% if note.status != 'signed' %}
|
|
<a href="#" class="btn btn-outline-warning btn-sm">
|
|
<i class="fa fa-edit"></i> Edit Note
|
|
</a>
|
|
{% endif %}
|
|
<a href="#" class="btn btn-outline-secondary btn-sm">
|
|
<i class="fa fa-history"></i> View History
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Related Documents -->
|
|
<div class="card mt-3">
|
|
<div class="card-header">
|
|
<h5 class="card-title">Related Documents</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="list-group list-group-flush">
|
|
<a href="#" class="list-group-item list-group-item-action">
|
|
<i class="fa fa-file-text"></i> Pre-operative Assessment
|
|
</a>
|
|
<a href="#" class="list-group-item list-group-item-action">
|
|
<i class="fa fa-file-text"></i> Anesthesia Record
|
|
</a>
|
|
<a href="#" class="list-group-item list-group-item-action">
|
|
<i class="fa fa-file-text"></i> Pathology Report
|
|
</a>
|
|
<a href="#" class="list-group-item list-group-item-action">
|
|
<i class="fa fa-file-text"></i> Post-op Orders
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Signature History -->
|
|
{% if signature_history %}
|
|
<div class="card mt-3">
|
|
<div class="card-header">
|
|
<h5 class="card-title">Signature History</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
{% for signature in signature_history %}
|
|
<div class="signature-entry mb-2">
|
|
<strong>{{ signature.signer_name }}</strong><br>
|
|
<small class="text-muted">{{ signature.signature_datetime|date:"M d, Y H:i" }}</small><br>
|
|
<span class="badge bg-{{ signature.status_color }}">{{ signature.status|title }}</span>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Set current time as default signature time
|
|
const now = new Date();
|
|
const localDateTime = new Date(now.getTime() - now.getTimezoneOffset() * 60000).toISOString().slice(0, 16);
|
|
const signatureDatetime = document.querySelector('input[name="signature_datetime"]');
|
|
if (signatureDatetime) {
|
|
signatureDatetime.value = localDateTime;
|
|
}
|
|
|
|
// Form validation and submission
|
|
const signatureForm = document.getElementById('signatureForm');
|
|
if (signatureForm) {
|
|
signatureForm.addEventListener('submit', function(e) {
|
|
const confirmation = document.getElementById('signatureConfirmation');
|
|
const password = document.querySelector('input[name="password_confirmation"]');
|
|
|
|
if (!confirmation.checked) {
|
|
e.preventDefault();
|
|
alert('Please confirm that you have reviewed the operative note.');
|
|
return false;
|
|
}
|
|
|
|
if (!password.value.trim()) {
|
|
e.preventDefault();
|
|
alert('Password confirmation is required for electronic signature.');
|
|
password.focus();
|
|
return false;
|
|
}
|
|
|
|
// Final confirmation
|
|
if (!confirm('Are you sure you want to electronically sign this operative note? 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> Signing...';
|
|
});
|
|
}
|
|
|
|
// Print functionality
|
|
document.querySelector('.btn-outline-primary').addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
window.print();
|
|
});
|
|
|
|
// Auto-save draft functionality (if note is not signed)
|
|
{% if note.status != 'signed' %}
|
|
let autoSaveTimer;
|
|
const formInputs = document.querySelectorAll('input, textarea, select');
|
|
|
|
formInputs.forEach(input => {
|
|
input.addEventListener('change', function() {
|
|
clearTimeout(autoSaveTimer);
|
|
autoSaveTimer = setTimeout(autoSaveDraft, 30000); // Auto-save after 30 seconds of inactivity
|
|
});
|
|
});
|
|
|
|
function autoSaveDraft() {
|
|
console.log('Auto-saving draft...');
|
|
// Implementation for auto-saving draft
|
|
}
|
|
{% endif %}
|
|
});
|
|
|
|
// Print styles
|
|
const printStyles = `
|
|
@media print {
|
|
.page-header, .card-header, .signature-section .card-header,
|
|
.btn, .sidebar, .col-md-4 { display: none !important; }
|
|
.operative-note-content { font-size: 12px; }
|
|
.card { border: none; box-shadow: none; }
|
|
.card-body { padding: 0; }
|
|
}
|
|
`;
|
|
|
|
const styleSheet = document.createElement('style');
|
|
styleSheet.textContent = printStyles;
|
|
document.head.appendChild(styleSheet);
|
|
</script>
|
|
{% endblock %}
|
|
|