update
This commit is contained in:
parent
2780a2dc7c
commit
2b4c58aa34
Binary file not shown.
@ -27,6 +27,19 @@ def add_class(field, css_class):
|
|||||||
return field.as_widget(attrs={"class": css_class})
|
return field.as_widget(attrs={"class": css_class})
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter(name="attr")
|
||||||
|
def attr(field, args):
|
||||||
|
attrs = {}
|
||||||
|
definitions = args.split(",")
|
||||||
|
for definition in definitions:
|
||||||
|
if ":" in definition:
|
||||||
|
key, val = definition.split(":")
|
||||||
|
attrs[key.strip()] = val.strip()
|
||||||
|
else:
|
||||||
|
attrs[definition.strip()] = True
|
||||||
|
return field.as_widget(attrs=attrs)
|
||||||
|
|
||||||
|
|
||||||
@register.filter
|
@register.filter
|
||||||
def sum_values(queryset, field_names):
|
def sum_values(queryset, field_names):
|
||||||
"""
|
"""
|
||||||
|
|||||||
BIN
db.sqlite3
BIN
db.sqlite3
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
38
emr/forms.py
38
emr/forms.py
@ -210,25 +210,25 @@ class CarePlanForm(forms.ModelForm):
|
|||||||
'approved', 'approved_by'
|
'approved', 'approved_by'
|
||||||
]
|
]
|
||||||
widgets = {
|
widgets = {
|
||||||
'start_date': forms.DateInput(attrs={'type': 'date'}),
|
'start_date': forms.DateInput(attrs={'type': 'date', 'class':'form-control form control-sm'}),
|
||||||
'end_date': forms.DateInput(attrs={'type': 'date'}),
|
'end_date': forms.DateInput(attrs={'type': 'date', 'class':'form-control form control-sm'}),
|
||||||
'target_completion_date': forms.DateInput(attrs={'type': 'date'}),
|
'target_completion_date': forms.DateInput(attrs={'type': 'date', 'class':'form-control form control-sm'}),
|
||||||
'last_reviewed': forms.DateInput(attrs={'type': 'date'}),
|
'last_reviewed': forms.DateInput(attrs={'type': 'date', 'class':'form-control form control-sm'}),
|
||||||
'next_review_date': forms.DateInput(attrs={'type': 'date'}),
|
'next_review_date': forms.DateInput(attrs={'type': 'date', 'class':'form-control form control-sm'}),
|
||||||
'description': forms.Textarea(attrs={'rows': 3}),
|
'description': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
|
||||||
'patient_goals': forms.Textarea(attrs={'rows': 3}),
|
'patient_goals': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
|
||||||
'patient_preferences': forms.Textarea(attrs={'rows': 3}),
|
'patient_preferences': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
|
||||||
'patient_barriers': forms.Textarea(attrs={'rows': 3}),
|
'patient_barriers': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
|
||||||
'progress_notes': forms.Textarea(attrs={'rows': 3}),
|
'progress_notes': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
|
||||||
'goals': forms.Textarea(attrs={'rows': 3}),
|
'goals': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
|
||||||
'objectives': forms.Textarea(attrs={'rows': 3}),
|
'objectives': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
|
||||||
'interventions': forms.Textarea(attrs={'rows': 3}),
|
'interventions': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
|
||||||
'activities': forms.Textarea(attrs={'rows': 3}),
|
'activities': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
|
||||||
'monitoring_parameters': forms.Textarea(attrs={'rows': 3}),
|
'monitoring_parameters': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
|
||||||
'evaluation_criteria': forms.Textarea(attrs={'rows': 3}),
|
'evaluation_criteria': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
|
||||||
'resources_needed': forms.Textarea(attrs={'rows': 3}),
|
'resources_needed': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
|
||||||
'support_systems': forms.Textarea(attrs={'rows': 3}),
|
'support_systems': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
|
||||||
'outcomes_achieved': forms.Textarea(attrs={'rows': 3}),
|
'outcomes_achieved': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
|||||||
@ -1,799 +0,0 @@
|
|||||||
{% extends "base.html" %}
|
|
||||||
{% load static %}
|
|
||||||
|
|
||||||
{% block title %}{{ care_plan.title }} | Care Plan Detail{% endblock %}
|
|
||||||
|
|
||||||
{% block css %}
|
|
||||||
<link href="{% static 'plugins/timeline/timeline.css' %}" rel="stylesheet" />
|
|
||||||
<link href="{% static 'plugins/bootstrap-icons/font/bootstrap-icons.css' %}" rel="stylesheet" />
|
|
||||||
<link href="{% static 'plugins/chart.js/dist/Chart.min.css' %}" rel="stylesheet" />
|
|
||||||
<style>
|
|
||||||
.care-plan-badge {
|
|
||||||
font-size: 0.85rem;
|
|
||||||
padding: 0.35em 0.65em;
|
|
||||||
}
|
|
||||||
.care-plan-header {
|
|
||||||
background: linear-gradient(45deg, var(--bs-blue), var(--bs-indigo));
|
|
||||||
color: white;
|
|
||||||
padding: 1.5rem;
|
|
||||||
border-radius: 0.5rem;
|
|
||||||
margin-bottom: 1.5rem;
|
|
||||||
}
|
|
||||||
.care-plan-status-active {
|
|
||||||
background-color: var(--bs-success);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.care-plan-status-completed {
|
|
||||||
background-color: var(--bs-secondary);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.care-plan-status-draft {
|
|
||||||
background-color: var(--bs-warning);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.care-plan-status-on-hold {
|
|
||||||
background-color: var(--bs-info);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.care-plan-priority-high {
|
|
||||||
background-color: var(--bs-danger);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.care-plan-priority-medium {
|
|
||||||
background-color: var(--bs-warning);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.care-plan-priority-low {
|
|
||||||
background-color: var(--bs-info);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.timeline-item {
|
|
||||||
padding: 1rem;
|
|
||||||
border-left: 3px solid var(--bs-primary);
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
background-color: rgba(var(--bs-light-rgb), 0.5);
|
|
||||||
}
|
|
||||||
.related-item {
|
|
||||||
transition: all 0.2s;
|
|
||||||
}
|
|
||||||
.related-item:hover {
|
|
||||||
transform: translateY(-3px);
|
|
||||||
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
|
||||||
}
|
|
||||||
.goal-item {
|
|
||||||
padding: 1rem;
|
|
||||||
border-left: 4px solid var(--bs-success);
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
background-color: rgba(var(--bs-light-rgb), 0.5);
|
|
||||||
}
|
|
||||||
.objective-item {
|
|
||||||
padding: 1rem;
|
|
||||||
border-left: 4px solid var(--bs-info);
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
background-color: rgba(var(--bs-light-rgb), 0.5);
|
|
||||||
}
|
|
||||||
.intervention-item {
|
|
||||||
padding: 1rem;
|
|
||||||
border-left: 4px solid var(--bs-warning);
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
background-color: rgba(var(--bs-light-rgb), 0.5);
|
|
||||||
}
|
|
||||||
.activity-item {
|
|
||||||
padding: 1rem;
|
|
||||||
border-left: 4px solid var(--bs-purple);
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
background-color: rgba(var(--bs-light-rgb), 0.5);
|
|
||||||
}
|
|
||||||
.outcome-item {
|
|
||||||
padding: 1rem;
|
|
||||||
border-left: 4px solid var(--bs-teal);
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
background-color: rgba(var(--bs-light-rgb), 0.5);
|
|
||||||
}
|
|
||||||
.monitoring-item {
|
|
||||||
padding: 1rem;
|
|
||||||
border-left: 4px solid var(--bs-cyan);
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
background-color: rgba(var(--bs-light-rgb), 0.5);
|
|
||||||
}
|
|
||||||
.nav-tabs .nav-link.active {
|
|
||||||
font-weight: bold;
|
|
||||||
border-bottom: 3px solid var(--bs-primary);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<!-- begin breadcrumb -->
|
|
||||||
<ol class="breadcrumb float-xl-end">
|
|
||||||
<li class="breadcrumb-item"><a href="{% url 'dashboard' %}">Home</a></li>
|
|
||||||
<li class="breadcrumb-item"><a href="{% url 'emr:dashboard' %}">EMR</a></li>
|
|
||||||
<li class="breadcrumb-item"><a href="{% url 'emr:care_plan_list' %}">Care Plans</a></li>
|
|
||||||
<li class="breadcrumb-item active">{{ care_plan.title }}</li>
|
|
||||||
</ol>
|
|
||||||
<!-- end breadcrumb -->
|
|
||||||
|
|
||||||
<!-- begin page-header -->
|
|
||||||
<h1 class="page-header">Care Plan Detail <small>Comprehensive care plan information</small></h1>
|
|
||||||
<!-- end page-header -->
|
|
||||||
|
|
||||||
<!-- begin row -->
|
|
||||||
<div class="row">
|
|
||||||
<!-- begin col-12 -->
|
|
||||||
<div class="col-xl-12">
|
|
||||||
<!-- begin care plan header -->
|
|
||||||
<div class="care-plan-header d-flex justify-content-between align-items-center">
|
|
||||||
<div>
|
|
||||||
<h2 class="mb-1">{{ care_plan.title }}</h2>
|
|
||||||
<div class="d-flex align-items-center">
|
|
||||||
<span class="me-3">
|
|
||||||
<i class="bi bi-person-fill me-1"></i> {{ care_plan.patient.get_full_name }}
|
|
||||||
</span>
|
|
||||||
<span class="me-3">
|
|
||||||
<i class="bi bi-calendar-event me-1"></i> Start: {{ care_plan.start_date }}
|
|
||||||
{% if care_plan.end_date %}
|
|
||||||
- End: {{ care_plan.end_date }}
|
|
||||||
{% endif %}
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
<i class="bi bi-person-badge me-1"></i> {{ care_plan.primary_provider.get_full_name }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="d-flex">
|
|
||||||
<span class="badge care-plan-status-{{ care_plan.status|lower }} me-2">{{ care_plan.get_status_display }}</span>
|
|
||||||
<span class="badge care-plan-priority-{{ care_plan.priority|lower }}">{{ care_plan.get_priority_display }} Priority</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- end care plan header -->
|
|
||||||
|
|
||||||
<!-- begin progress panel -->
|
|
||||||
<div class="panel panel-inverse">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<h4 class="panel-title">Progress</h4>
|
|
||||||
<div class="panel-heading-btn">
|
|
||||||
<a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-expand"><i class="fa fa-expand"></i></a>
|
|
||||||
<a href="javascript:;" class="btn btn-xs btn-icon btn-success" data-toggle="panel-reload"><i class="fa fa-redo"></i></a>
|
|
||||||
<a href="javascript:;" class="btn btn-xs btn-icon btn-warning" data-toggle="panel-collapse"><i class="fa fa-minus"></i></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6">
|
|
||||||
<h5 class="mb-3">Completion Progress</h5>
|
|
||||||
<div class="progress" style="height: 25px;">
|
|
||||||
<div class="progress-bar progress-bar-striped progress-bar-animated bg-success"
|
|
||||||
role="progressbar"
|
|
||||||
style="width: {{ care_plan.completion_percentage }}%;"
|
|
||||||
aria-valuenow="{{ care_plan.completion_percentage }}"
|
|
||||||
aria-valuemin="0"
|
|
||||||
aria-valuemax="100">
|
|
||||||
{{ care_plan.completion_percentage }}% Complete
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-4">
|
|
||||||
<h5 class="mb-3">Plan Timeline</h5>
|
|
||||||
<div class="table-responsive">
|
|
||||||
<table class="table table-bordered">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<th width="30%">Start Date</th>
|
|
||||||
<td>{{ care_plan.start_date }}</td>
|
|
||||||
</tr>
|
|
||||||
{% if care_plan.target_completion_date %}
|
|
||||||
<tr>
|
|
||||||
<th>Target Completion</th>
|
|
||||||
<td>{{ care_plan.target_completion_date }}</td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
{% if care_plan.end_date %}
|
|
||||||
<tr>
|
|
||||||
<th>End Date</th>
|
|
||||||
<td>{{ care_plan.end_date }}</td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
{% if care_plan.last_reviewed %}
|
|
||||||
<tr>
|
|
||||||
<th>Last Reviewed</th>
|
|
||||||
<td>{{ care_plan.last_reviewed }}</td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
{% if care_plan.next_review_date %}
|
|
||||||
<tr>
|
|
||||||
<th>Next Review</th>
|
|
||||||
<td>
|
|
||||||
{{ care_plan.next_review_date }}
|
|
||||||
{% if care_plan.is_overdue %}
|
|
||||||
<span class="badge bg-danger ms-2">Overdue</span>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-6">
|
|
||||||
<h5 class="mb-3">Activity Chart</h5>
|
|
||||||
<canvas id="activityChart" height="200"></canvas>
|
|
||||||
|
|
||||||
<div class="mt-4">
|
|
||||||
<h5 class="mb-3">Approval Status</h5>
|
|
||||||
<div class="table-responsive">
|
|
||||||
<table class="table table-bordered">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<th width="30%">Status</th>
|
|
||||||
<td>
|
|
||||||
{% if care_plan.approved %}
|
|
||||||
<span class="badge bg-success">Approved</span>
|
|
||||||
{% else %}
|
|
||||||
<span class="badge bg-warning">Pending Approval</span>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% if care_plan.approved %}
|
|
||||||
<tr>
|
|
||||||
<th>Approved By</th>
|
|
||||||
<td>{{ care_plan.approved_by.get_full_name }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Approved Date</th>
|
|
||||||
<td>{{ care_plan.approved_date }}</td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- end progress panel -->
|
|
||||||
|
|
||||||
<!-- begin care plan details panel -->
|
|
||||||
<div class="panel panel-inverse">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<h4 class="panel-title">Care Plan Details</h4>
|
|
||||||
<div class="panel-heading-btn">
|
|
||||||
<a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-expand"><i class="fa fa-expand"></i></a>
|
|
||||||
<a href="javascript:;" class="btn btn-xs btn-icon btn-success" data-toggle="panel-reload"><i class="fa fa-redo"></i></a>
|
|
||||||
<a href="javascript:;" class="btn btn-xs btn-icon btn-warning" data-toggle="panel-collapse"><i class="fa fa-minus"></i></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<!-- begin nav tabs -->
|
|
||||||
<ul class="nav nav-tabs" id="carePlanTabs" role="tablist">
|
|
||||||
<li class="nav-item" role="presentation">
|
|
||||||
<button class="nav-link active" id="overview-tab" data-bs-toggle="tab" data-bs-target="#overview" type="button" role="tab" aria-controls="overview" aria-selected="true">Overview</button>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item" role="presentation">
|
|
||||||
<button class="nav-link" id="goals-tab" data-bs-toggle="tab" data-bs-target="#goals" type="button" role="tab" aria-controls="goals" aria-selected="false">Goals & Objectives</button>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item" role="presentation">
|
|
||||||
<button class="nav-link" id="interventions-tab" data-bs-toggle="tab" data-bs-target="#interventions" type="button" role="tab" aria-controls="interventions" aria-selected="false">Interventions</button>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item" role="presentation">
|
|
||||||
<button class="nav-link" id="monitoring-tab" data-bs-toggle="tab" data-bs-target="#monitoring" type="button" role="tab" aria-controls="monitoring" aria-selected="false">Monitoring</button>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item" role="presentation">
|
|
||||||
<button class="nav-link" id="patient-tab" data-bs-toggle="tab" data-bs-target="#patient" type="button" role="tab" aria-controls="patient" aria-selected="false">Patient Involvement</button>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item" role="presentation">
|
|
||||||
<button class="nav-link" id="outcomes-tab" data-bs-toggle="tab" data-bs-target="#outcomes" type="button" role="tab" aria-controls="outcomes" aria-selected="false">Outcomes</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<!-- end nav tabs -->
|
|
||||||
|
|
||||||
<!-- begin tab content -->
|
|
||||||
<div class="tab-content" id="carePlanTabsContent">
|
|
||||||
<!-- Overview Tab -->
|
|
||||||
<div class="tab-pane fade show active" id="overview" role="tabpanel" aria-labelledby="overview-tab">
|
|
||||||
<div class="p-3">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6">
|
|
||||||
<h5 class="mb-3">Basic Information</h5>
|
|
||||||
<div class="table-responsive">
|
|
||||||
<table class="table table-bordered">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<th width="30%">Care Plan ID</th>
|
|
||||||
<td>{{ care_plan.care_plan_id }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Plan Type</th>
|
|
||||||
<td>{{ care_plan.get_plan_type_display }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Category</th>
|
|
||||||
<td>{{ care_plan.get_category_display }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Status</th>
|
|
||||||
<td>{{ care_plan.get_status_display }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Priority</th>
|
|
||||||
<td>{{ care_plan.get_priority_display }}</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h5 class="mb-3 mt-4">Description</h5>
|
|
||||||
<div class="p-3 bg-light rounded">
|
|
||||||
{{ care_plan.description|linebreaks }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-6">
|
|
||||||
<h5 class="mb-3">Provider Information</h5>
|
|
||||||
<div class="table-responsive">
|
|
||||||
<table class="table table-bordered">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<th width="30%">Primary Provider</th>
|
|
||||||
<td>{{ care_plan.primary_provider.get_full_name }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Care Team</th>
|
|
||||||
<td>
|
|
||||||
{% if care_plan.care_team.all %}
|
|
||||||
<ul class="mb-0 ps-3">
|
|
||||||
{% for provider in care_plan.care_team.all %}
|
|
||||||
<li>{{ provider.get_full_name }}</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
{% else %}
|
|
||||||
No additional care team members
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h5 class="mb-3 mt-4">Related Problems</h5>
|
|
||||||
{% if care_plan.related_problems.all %}
|
|
||||||
<div class="list-group">
|
|
||||||
{% for problem in care_plan.related_problems.all %}
|
|
||||||
<a href="{% url 'emr:problem_detail' problem.id %}" class="list-group-item list-group-item-action d-flex justify-content-between align-items-center">
|
|
||||||
{{ problem.problem_name }}
|
|
||||||
<span class="badge bg-{{ problem.status|lower }} rounded-pill">{{ problem.get_status_display }}</span>
|
|
||||||
</a>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="alert alert-info">
|
|
||||||
<i class="fa fa-info-circle me-2"></i> No problems are associated with this care plan.
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Goals & Objectives Tab -->
|
|
||||||
<div class="tab-pane fade" id="goals" role="tabpanel" aria-labelledby="goals-tab">
|
|
||||||
<div class="p-3">
|
|
||||||
<h5 class="mb-3">Goals</h5>
|
|
||||||
{% if care_plan.goals %}
|
|
||||||
<div class="goals-list">
|
|
||||||
{% for goal in care_plan.goals %}
|
|
||||||
<div class="goal-item">
|
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
|
||||||
<h6 class="mb-1">{{ goal.title }}</h6>
|
|
||||||
<span class="badge bg-{{ goal.status|default:'secondary'|lower }}">{{ goal.status|default:'Not Started' }}</span>
|
|
||||||
</div>
|
|
||||||
<p class="mb-1">{{ goal.description }}</p>
|
|
||||||
{% if goal.target_date %}
|
|
||||||
<small class="text-muted">Target Date: {{ goal.target_date }}</small>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="alert alert-info">
|
|
||||||
<i class="fa fa-info-circle me-2"></i> No goals have been defined for this care plan.
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<h5 class="mb-3 mt-4">Objectives</h5>
|
|
||||||
{% if care_plan.objectives %}
|
|
||||||
<div class="objectives-list">
|
|
||||||
{% for objective in care_plan.objectives %}
|
|
||||||
<div class="objective-item">
|
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
|
||||||
<h6 class="mb-1">{{ objective.title }}</h6>
|
|
||||||
<span class="badge bg-{{ objective.status|default:'secondary'|lower }}">{{ objective.status|default:'Not Started' }}</span>
|
|
||||||
</div>
|
|
||||||
<p class="mb-1">{{ objective.description }}</p>
|
|
||||||
{% if objective.measure %}
|
|
||||||
<small class="text-muted">Measure: {{ objective.measure }}</small>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="alert alert-info">
|
|
||||||
<i class="fa fa-info-circle me-2"></i> No objectives have been defined for this care plan.
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Interventions Tab -->
|
|
||||||
<div class="tab-pane fade" id="interventions" role="tabpanel" aria-labelledby="interventions-tab">
|
|
||||||
<div class="p-3">
|
|
||||||
<h5 class="mb-3">Interventions</h5>
|
|
||||||
{% if care_plan.interventions %}
|
|
||||||
<div class="interventions-list">
|
|
||||||
{% for intervention in care_plan.interventions %}
|
|
||||||
<div class="intervention-item">
|
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
|
||||||
<h6 class="mb-1">{{ intervention.title }}</h6>
|
|
||||||
<span class="badge bg-{{ intervention.status|default:'secondary'|lower }}">{{ intervention.status|default:'Not Started' }}</span>
|
|
||||||
</div>
|
|
||||||
<p class="mb-1">{{ intervention.description }}</p>
|
|
||||||
{% if intervention.frequency %}
|
|
||||||
<small class="text-muted">Frequency: {{ intervention.frequency }}</small>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="alert alert-info">
|
|
||||||
<i class="fa fa-info-circle me-2"></i> No interventions have been defined for this care plan.
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<h5 class="mb-3 mt-4">Activities</h5>
|
|
||||||
{% if care_plan.activities %}
|
|
||||||
<div class="activities-list">
|
|
||||||
{% for activity in care_plan.activities %}
|
|
||||||
<div class="activity-item">
|
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
|
||||||
<h6 class="mb-1">{{ activity.title }}</h6>
|
|
||||||
<span class="badge bg-{{ activity.status|default:'secondary'|lower }}">{{ activity.status|default:'Not Started' }}</span>
|
|
||||||
</div>
|
|
||||||
<p class="mb-1">{{ activity.description }}</p>
|
|
||||||
{% if activity.assigned_to %}
|
|
||||||
<small class="text-muted">Assigned to: {{ activity.assigned_to }}</small>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="alert alert-info">
|
|
||||||
<i class="fa fa-info-circle me-2"></i> No activities have been defined for this care plan.
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Monitoring Tab -->
|
|
||||||
<div class="tab-pane fade" id="monitoring" role="tabpanel" aria-labelledby="monitoring-tab">
|
|
||||||
<div class="p-3">
|
|
||||||
<h5 class="mb-3">Monitoring Parameters</h5>
|
|
||||||
{% if care_plan.monitoring_parameters %}
|
|
||||||
<div class="monitoring-list">
|
|
||||||
{% for parameter in care_plan.monitoring_parameters %}
|
|
||||||
<div class="monitoring-item">
|
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
|
||||||
<h6 class="mb-1">{{ parameter.title }}</h6>
|
|
||||||
<span class="badge bg-{{ parameter.status|default:'secondary'|lower }}">{{ parameter.status|default:'Not Started' }}</span>
|
|
||||||
</div>
|
|
||||||
<p class="mb-1">{{ parameter.description }}</p>
|
|
||||||
{% if parameter.frequency %}
|
|
||||||
<small class="text-muted">Frequency: {{ parameter.frequency }}</small>
|
|
||||||
{% endif %}
|
|
||||||
{% if parameter.target_range %}
|
|
||||||
<small class="text-muted d-block">Target Range: {{ parameter.target_range }}</small>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="alert alert-info">
|
|
||||||
<i class="fa fa-info-circle me-2"></i> No monitoring parameters have been defined for this care plan.
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<h5 class="mb-3 mt-4">Evaluation Criteria</h5>
|
|
||||||
{% if care_plan.evaluation_criteria %}
|
|
||||||
<div class="evaluation-list">
|
|
||||||
{% for criteria in care_plan.evaluation_criteria %}
|
|
||||||
<div class="monitoring-item">
|
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
|
||||||
<h6 class="mb-1">{{ criteria.title }}</h6>
|
|
||||||
<span class="badge bg-{{ criteria.status|default:'secondary'|lower }}">{{ criteria.status|default:'Not Evaluated' }}</span>
|
|
||||||
</div>
|
|
||||||
<p class="mb-1">{{ criteria.description }}</p>
|
|
||||||
{% if criteria.measure %}
|
|
||||||
<small class="text-muted">Measure: {{ criteria.measure }}</small>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="alert alert-info">
|
|
||||||
<i class="fa fa-info-circle me-2"></i> No evaluation criteria have been defined for this care plan.
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if care_plan.progress_notes %}
|
|
||||||
<h5 class="mb-3 mt-4">Progress Notes</h5>
|
|
||||||
<div class="p-3 bg-light rounded">
|
|
||||||
{{ care_plan.progress_notes|linebreaks }}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Patient Involvement Tab -->
|
|
||||||
<div class="tab-pane fade" id="patient" role="tabpanel" aria-labelledby="patient-tab">
|
|
||||||
<div class="p-3">
|
|
||||||
{% if care_plan.patient_goals %}
|
|
||||||
<h5 class="mb-3">Patient Goals</h5>
|
|
||||||
<div class="p-3 bg-light rounded mb-4">
|
|
||||||
{{ care_plan.patient_goals|linebreaks }}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if care_plan.patient_preferences %}
|
|
||||||
<h5 class="mb-3">Patient Preferences</h5>
|
|
||||||
<div class="p-3 bg-light rounded mb-4">
|
|
||||||
{{ care_plan.patient_preferences|linebreaks }}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if care_plan.patient_barriers %}
|
|
||||||
<h5 class="mb-3">Identified Barriers</h5>
|
|
||||||
<div class="p-3 bg-light rounded mb-4">
|
|
||||||
{{ care_plan.patient_barriers|linebreaks }}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<h5 class="mb-3">Resources Needed</h5>
|
|
||||||
{% if care_plan.resources_needed %}
|
|
||||||
<div class="list-group mb-4">
|
|
||||||
{% for resource in care_plan.resources_needed %}
|
|
||||||
<div class="list-group-item">
|
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
|
||||||
<h6 class="mb-1">{{ resource.name }}</h6>
|
|
||||||
<span class="badge bg-{{ resource.status|default:'secondary'|lower }}">{{ resource.status|default:'Pending' }}</span>
|
|
||||||
</div>
|
|
||||||
{% if resource.description %}
|
|
||||||
<p class="mb-1">{{ resource.description }}</p>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="alert alert-info mb-4">
|
|
||||||
<i class="fa fa-info-circle me-2"></i> No resources have been identified for this care plan.
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<h5 class="mb-3">Support Systems</h5>
|
|
||||||
{% if care_plan.support_systems %}
|
|
||||||
<div class="list-group">
|
|
||||||
{% for support in care_plan.support_systems %}
|
|
||||||
<div class="list-group-item">
|
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
|
||||||
<h6 class="mb-1">{{ support.name }}</h6>
|
|
||||||
<span class="badge bg-{{ support.type|default:'secondary'|lower }}">{{ support.type|default:'Other' }}</span>
|
|
||||||
</div>
|
|
||||||
{% if support.description %}
|
|
||||||
<p class="mb-1">{{ support.description }}</p>
|
|
||||||
{% endif %}
|
|
||||||
{% if support.contact %}
|
|
||||||
<small class="text-muted">Contact: {{ support.contact }}</small>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="alert alert-info">
|
|
||||||
<i class="fa fa-info-circle me-2"></i> No support systems have been identified for this care plan.
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Outcomes Tab -->
|
|
||||||
<div class="tab-pane fade" id="outcomes" role="tabpanel" aria-labelledby="outcomes-tab">
|
|
||||||
<div class="p-3">
|
|
||||||
<h5 class="mb-3">Outcomes Achieved</h5>
|
|
||||||
{% if care_plan.outcomes_achieved %}
|
|
||||||
<div class="outcomes-list">
|
|
||||||
{% for outcome in care_plan.outcomes_achieved %}
|
|
||||||
<div class="outcome-item">
|
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
|
||||||
<h6 class="mb-1">{{ outcome.title }}</h6>
|
|
||||||
<span class="badge bg-{{ outcome.status|default:'success'|lower }}">{{ outcome.status|default:'Achieved' }}</span>
|
|
||||||
</div>
|
|
||||||
<p class="mb-1">{{ outcome.description }}</p>
|
|
||||||
{% if outcome.date_achieved %}
|
|
||||||
<small class="text-muted">Date Achieved: {{ outcome.date_achieved }}</small>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="alert alert-info">
|
|
||||||
<i class="fa fa-info-circle me-2"></i> No outcomes have been recorded for this care plan.
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- end tab content -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- end care plan details panel -->
|
|
||||||
|
|
||||||
<!-- begin clinical notes panel -->
|
|
||||||
<div class="panel panel-inverse">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<h4 class="panel-title">Related Clinical Notes</h4>
|
|
||||||
<div class="panel-heading-btn">
|
|
||||||
<a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-expand"><i class="fa fa-expand"></i></a>
|
|
||||||
<a href="javascript:;" class="btn btn-xs btn-icon btn-success" data-toggle="panel-reload"><i class="fa fa-redo"></i></a>
|
|
||||||
<a href="javascript:;" class="btn btn-xs btn-icon btn-warning" data-toggle="panel-collapse"><i class="fa fa-minus"></i></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
{% if care_plan.clinical_notes.all %}
|
|
||||||
<div class="timeline">
|
|
||||||
{% for note in care_plan.clinical_notes.all %}
|
|
||||||
<div class="timeline-item">
|
|
||||||
<div class="timeline-time">
|
|
||||||
{{ note.note_datetime|date:"M d, Y" }} <small>{{ note.note_datetime|time:"h:i A" }}</small>
|
|
||||||
</div>
|
|
||||||
<div class="timeline-icon">
|
|
||||||
<a href="javascript:;"> </a>
|
|
||||||
</div>
|
|
||||||
<div class="timeline-content">
|
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
|
||||||
<h5>{{ note.title }}</h5>
|
|
||||||
<span class="badge bg-{{ note.status|lower }}">{{ note.get_status_display }}</span>
|
|
||||||
</div>
|
|
||||||
<p class="mb-2">{{ note.content|truncatechars:200 }}</p>
|
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
|
||||||
<small class="text-muted">{{ note.get_note_type_display }} by {{ note.author.get_full_name }}</small>
|
|
||||||
<a href="{% url 'emr:clinical_note_detail' note.id %}" class="btn btn-sm btn-primary">View Note</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="alert alert-info">
|
|
||||||
<i class="fa fa-info-circle me-2"></i> No clinical notes are associated with this care plan.
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- end clinical notes panel -->
|
|
||||||
|
|
||||||
<!-- begin action buttons -->
|
|
||||||
<div class="d-flex justify-content-between mt-3">
|
|
||||||
<div>
|
|
||||||
<a href="{% url 'emr:care_plan_list' %}" class="btn btn-secondary me-2">
|
|
||||||
<i class="fa fa-arrow-left me-1"></i> Back to Care Plans
|
|
||||||
</a>
|
|
||||||
<a href="{% url 'emr:patient_detail' care_plan.patient.id %}" class="btn btn-info">
|
|
||||||
<i class="fa fa-user me-1"></i> Patient Profile
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
{% if not care_plan.approved %}
|
|
||||||
<a href="#" class="btn btn-success me-2" data-bs-toggle="modal" data-bs-target="#approveModal">
|
|
||||||
<i class="fa fa-check-circle me-1"></i> Approve Plan
|
|
||||||
</a>
|
|
||||||
{% endif %}
|
|
||||||
<a href="{% url 'emr:care_plan_update' care_plan.id %}" class="btn btn-primary me-2">
|
|
||||||
<i class="fa fa-edit me-1"></i> Edit Care Plan
|
|
||||||
</a>
|
|
||||||
<a href="{% url 'emr:care_plan_delete' care_plan.id %}" class="btn btn-danger">
|
|
||||||
<i class="fa fa-trash me-1"></i> Delete
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- end action buttons -->
|
|
||||||
</div>
|
|
||||||
<!-- end col-12 -->
|
|
||||||
</div>
|
|
||||||
<!-- end row -->
|
|
||||||
|
|
||||||
<!-- begin approve modal -->
|
|
||||||
<div class="modal fade" id="approveModal" tabindex="-1" aria-labelledby="approveModalLabel" aria-hidden="true">
|
|
||||||
<div class="modal-dialog">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h5 class="modal-title" id="approveModalLabel">Approve Care Plan</h5>
|
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
||||||
</div>
|
|
||||||
<form action="{% url 'emr:care_plan_approve' care_plan.id %}" method="post">
|
|
||||||
{% csrf_token %}
|
|
||||||
<div class="modal-body">
|
|
||||||
<p>You are about to approve this care plan. This action will mark the plan as officially approved and ready for implementation.</p>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="approval_notes" class="form-label">Approval Notes (Optional)</label>
|
|
||||||
<textarea class="form-control" id="approval_notes" name="approval_notes" rows="3"></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
|
||||||
<button type="submit" class="btn btn-success">Approve Care Plan</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- end approve modal -->
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block js %}
|
|
||||||
<script src="{% static 'plugins/moment/min/moment.min.js' %}"></script>
|
|
||||||
<script src="{% static 'plugins/chart.js/dist/Chart.min.js' %}"></script>
|
|
||||||
<script>
|
|
||||||
$(document).ready(function() {
|
|
||||||
// Initialize tooltips
|
|
||||||
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
||||||
|
|
||||||
// Initialize activity chart
|
|
||||||
var ctx = document.getElementById('activityChart').getContext('2d');
|
|
||||||
var activityChart = new Chart(ctx, {
|
|
||||||
type: 'line',
|
|
||||||
data: {
|
|
||||||
labels: ['Initial', 'Week 1', 'Week 2', 'Week 3', 'Week 4', 'Current'],
|
|
||||||
datasets: [{
|
|
||||||
label: 'Completion Progress',
|
|
||||||
data: [0, 15, 30, 45, 60, {{ care_plan.completion_percentage }}],
|
|
||||||
backgroundColor: 'rgba(40, 167, 69, 0.2)',
|
|
||||||
borderColor: 'rgba(40, 167, 69, 1)',
|
|
||||||
borderWidth: 2,
|
|
||||||
tension: 0.4
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
responsive: true,
|
|
||||||
scales: {
|
|
||||||
y: {
|
|
||||||
beginAtZero: true,
|
|
||||||
max: 100,
|
|
||||||
ticks: {
|
|
||||||
callback: function(value) {
|
|
||||||
return value + '%';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
plugins: {
|
|
||||||
tooltip: {
|
|
||||||
callbacks: {
|
|
||||||
label: function(context) {
|
|
||||||
return context.dataset.label + ': ' + context.raw + '%';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Handle HTMX events
|
|
||||||
document.body.addEventListener('htmx:afterSwap', function(evt) {
|
|
||||||
if (evt.detail.target.id === 'clinical-notes-container') {
|
|
||||||
// Reinitialize any components in the clinical notes container
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
804
emr/templates/emr/care_plans/care_plan_detail.html
Normal file
804
emr/templates/emr/care_plans/care_plan_detail.html
Normal file
@ -0,0 +1,804 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% block title %}{{ care_plan.title }} | Care Plan Detail{% endblock %}
|
||||||
|
|
||||||
|
{% block css %}
|
||||||
|
{#<link href="{% static 'plugins/timeline/timeline.css' %}" rel="stylesheet" />#}
|
||||||
|
<link href="{% static 'plugins/bootstrap-icons/font/bootstrap-icons.css' %}" rel="stylesheet" />
|
||||||
|
{#<link href="{% static 'plugins/chart.js/dist/' %}" rel="stylesheet" />#}
|
||||||
|
<style>
|
||||||
|
.care-plan-badge {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
padding: 0.35em 0.65em;
|
||||||
|
}
|
||||||
|
.care-plan-header {
|
||||||
|
background: linear-gradient(90deg, var(--bs-black), var(--bs-gray));
|
||||||
|
color: white;
|
||||||
|
padding: 1.5rem;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
.care-plan-status-active {
|
||||||
|
background-color: var(--bs-success);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.care-plan-status-completed {
|
||||||
|
background-color: var(--bs-secondary);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.care-plan-status-draft {
|
||||||
|
background-color: var(--bs-warning);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.care-plan-status-on-hold {
|
||||||
|
background-color: var(--bs-info);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.care-plan-priority-high {
|
||||||
|
background-color: var(--bs-danger);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.care-plan-priority-medium {
|
||||||
|
background-color: var(--bs-warning);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.care-plan-priority-low {
|
||||||
|
background-color: var(--bs-info);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.timeline-item {
|
||||||
|
padding: 1rem;
|
||||||
|
border-left: 3px solid var(--bs-primary);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
background-color: rgba(var(--bs-light-rgb), 0.5);
|
||||||
|
}
|
||||||
|
.related-item {
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
.related-item:hover {
|
||||||
|
transform: translateY(-3px);
|
||||||
|
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
.goal-item {
|
||||||
|
padding: 1rem;
|
||||||
|
border-left: 4px solid var(--bs-success);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
background-color: rgba(var(--bs-light-rgb), 0.5);
|
||||||
|
}
|
||||||
|
.objective-item {
|
||||||
|
padding: 1rem;
|
||||||
|
border-left: 4px solid var(--bs-info);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
background-color: rgba(var(--bs-light-rgb), 0.5);
|
||||||
|
}
|
||||||
|
.intervention-item {
|
||||||
|
padding: 1rem;
|
||||||
|
border-left: 4px solid var(--bs-warning);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
background-color: rgba(var(--bs-light-rgb), 0.5);
|
||||||
|
}
|
||||||
|
.activity-item {
|
||||||
|
padding: 1rem;
|
||||||
|
border-left: 4px solid var(--bs-purple);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
background-color: rgba(var(--bs-light-rgb), 0.5);
|
||||||
|
}
|
||||||
|
.outcome-item {
|
||||||
|
padding: 1rem;
|
||||||
|
border-left: 4px solid var(--bs-teal);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
background-color: rgba(var(--bs-light-rgb), 0.5);
|
||||||
|
}
|
||||||
|
.monitoring-item {
|
||||||
|
padding: 1rem;
|
||||||
|
border-left: 4px solid var(--bs-cyan);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
background-color: rgba(var(--bs-light-rgb), 0.5);
|
||||||
|
}
|
||||||
|
.nav-tabs .nav-link.active {
|
||||||
|
font-weight: bold;
|
||||||
|
border-bottom: 3px solid var(--bs-primary);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<!-- begin page-header -->
|
||||||
|
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||||
|
<div>
|
||||||
|
<h1 class="h2">
|
||||||
|
<i class="fas fa-tachometer-alt"></i>Care Plan<span class="fw-light">Detail</span>
|
||||||
|
</h1>
|
||||||
|
<p class="text-muted">Comprehensive care plan information</p>
|
||||||
|
</div>
|
||||||
|
<div class="btn-toolbar mb-2 mb-md-0">
|
||||||
|
<div class="btn-group me-2">
|
||||||
|
<a href="{% url 'emr:care_plan_list' %}" class="btn btn-secondary me-2">
|
||||||
|
<i class="fa fa-arrow-left me-1"></i> Back to the list
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- end page-header -->
|
||||||
|
|
||||||
|
<!-- begin row -->
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<!-- begin col-12 -->
|
||||||
|
<div class="col-xl-12">
|
||||||
|
<!-- begin care plan header -->
|
||||||
|
<div class="care-plan-header d-flex justify-content-between align-items-center">
|
||||||
|
<div>
|
||||||
|
<h2 class="mb-1">{{ care_plan.title }}</h2>
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="me-3">
|
||||||
|
<i class="bi bi-person-fill me-1"></i> {{ care_plan.patient.get_full_name }}
|
||||||
|
</span>
|
||||||
|
<span class="me-3">
|
||||||
|
<i class="bi bi-calendar-event me-1"></i> Start: {{ care_plan.start_date }}
|
||||||
|
{% if care_plan.end_date %}
|
||||||
|
- End: {{ care_plan.end_date }}
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<i class="bi bi-person-badge me-1"></i> {{ care_plan.primary_provider.get_full_name }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex">
|
||||||
|
<span class="badge care-plan-status-{{ care_plan.status|lower }} me-2">{{ care_plan.get_status_display }}</span>
|
||||||
|
<span class="badge care-plan-priority-{{ care_plan.priority|lower }}">{{ care_plan.get_priority_display }} Priority</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- end care plan header -->
|
||||||
|
|
||||||
|
<!-- begin progress panel -->
|
||||||
|
<div class="panel panel-inverse">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h4 class="panel-title">Progress</h4>
|
||||||
|
|
||||||
|
<div class="panel-heading-btn">
|
||||||
|
<a href="{% url 'patients:patient_detail' care_plan.patient.id %}" class="btn btn-xs btn-outline-secondary me-2">
|
||||||
|
<i class="fa fa-user me-1"></i> Patient Profile
|
||||||
|
</a>
|
||||||
|
{% if not care_plan.approved %}
|
||||||
|
<a href="#" class="btn btn-xs btn-outline-success me-2" data-bs-toggle="modal" data-bs-target="#approveModal">
|
||||||
|
<i class="fa fa-check-circle me-1"></i> Approve Plan
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
<a href="{% url 'emr:care_plan_update' care_plan.id %}" class="btn btn-xs btn-outline-warning me-2">
|
||||||
|
<i class="fa fa-edit me-1"></i> Edit
|
||||||
|
</a>
|
||||||
|
<a href="{% url 'emr:care_plan_delete' care_plan.id %}" class="btn btn-xs btn-outline-danger me-2">
|
||||||
|
<i class="fa fa-trash me-1"></i> Delete
|
||||||
|
</a>
|
||||||
|
<a href="javascript:" class="btn btn-xs btn-icon btn-default" data-toggle="panel-expand"><i class="fa fa-expand"></i></a>
|
||||||
|
<a href="javascript:" class="btn btn-xs btn-icon btn-success" data-toggle="panel-reload"><i class="fa fa-redo"></i></a>
|
||||||
|
<a href="javascript:" class="btn btn-xs btn-icon btn-warning" data-toggle="panel-collapse"><i class="fa fa-minus"></i></a>
|
||||||
|
<a href="javascript:" class="btn btn-xs btn-icon btn-danger" data-toggle="panel-remove"><i class="fa fa-times"></i></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h5 class="mb-3">Completion Progress</h5>
|
||||||
|
<div class="progress" style="height: 25px;">
|
||||||
|
<div class="progress-bar progress-bar-striped progress-bar-animated bg-success"
|
||||||
|
role="progressbar"
|
||||||
|
style="width: {{ care_plan.completion_percentage }}%;"
|
||||||
|
aria-valuenow="{{ care_plan.completion_percentage }}"
|
||||||
|
aria-valuemin="0"
|
||||||
|
aria-valuemax="100">
|
||||||
|
{{ care_plan.completion_percentage }}% Complete
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-4">
|
||||||
|
<h5 class="mb-3">Plan Timeline</h5>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th width="30%">Start Date</th>
|
||||||
|
<td>{{ care_plan.start_date }}</td>
|
||||||
|
</tr>
|
||||||
|
{% if care_plan.target_completion_date %}
|
||||||
|
<tr>
|
||||||
|
<th>Target Completion</th>
|
||||||
|
<td>{{ care_plan.target_completion_date }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
{% if care_plan.end_date %}
|
||||||
|
<tr>
|
||||||
|
<th>End Date</th>
|
||||||
|
<td>{{ care_plan.end_date }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
{% if care_plan.last_reviewed %}
|
||||||
|
<tr>
|
||||||
|
<th>Last Reviewed</th>
|
||||||
|
<td>{{ care_plan.last_reviewed }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
{% if care_plan.next_review_date %}
|
||||||
|
<tr>
|
||||||
|
<th>Next Review</th>
|
||||||
|
<td>
|
||||||
|
{{ care_plan.next_review_date }}
|
||||||
|
{% if care_plan.is_overdue %}
|
||||||
|
<span class="badge bg-danger ms-2">Overdue</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h5 class="mb-3">Activity Chart</h5>
|
||||||
|
<canvas id="activityChart" height="200"></canvas>
|
||||||
|
|
||||||
|
<div class="mt-4">
|
||||||
|
<h5 class="mb-3">Approval Status</h5>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th width="30%">Status</th>
|
||||||
|
<td>
|
||||||
|
{% if care_plan.approved %}
|
||||||
|
<span class="badge bg-success">Approved</span>
|
||||||
|
{% else %}
|
||||||
|
<span class="badge bg-warning">Pending Approval</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% if care_plan.approved %}
|
||||||
|
<tr>
|
||||||
|
<th>Approved By</th>
|
||||||
|
<td>{{ care_plan.approved_by.get_full_name }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Approved Date</th>
|
||||||
|
<td>{{ care_plan.approved_date }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- end progress panel -->
|
||||||
|
|
||||||
|
<!-- begin care plan details panel -->
|
||||||
|
<div class="panel panel-inverse">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h4 class="panel-title">Care Plan Details</h4>
|
||||||
|
<div class="panel-heading-btn">
|
||||||
|
<a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-expand"><i class="fa fa-expand"></i></a>
|
||||||
|
<a href="javascript:;" class="btn btn-xs btn-icon btn-success" data-toggle="panel-reload"><i class="fa fa-redo"></i></a>
|
||||||
|
<a href="javascript:;" class="btn btn-xs btn-icon btn-warning" data-toggle="panel-collapse"><i class="fa fa-minus"></i></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<!-- begin nav tabs -->
|
||||||
|
<ul class="nav nav-tabs" id="carePlanTabs" role="tablist">
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link active" id="overview-tab" data-bs-toggle="tab" data-bs-target="#overview" type="button" role="tab" aria-controls="overview" aria-selected="true">Overview</button>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link" id="goals-tab" data-bs-toggle="tab" data-bs-target="#goals" type="button" role="tab" aria-controls="goals" aria-selected="false">Goals & Objectives</button>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link" id="interventions-tab" data-bs-toggle="tab" data-bs-target="#interventions" type="button" role="tab" aria-controls="interventions" aria-selected="false">Interventions</button>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link" id="monitoring-tab" data-bs-toggle="tab" data-bs-target="#monitoring" type="button" role="tab" aria-controls="monitoring" aria-selected="false">Monitoring</button>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link" id="patient-tab" data-bs-toggle="tab" data-bs-target="#patient" type="button" role="tab" aria-controls="patient" aria-selected="false">Patient Involvement</button>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link" id="outcomes-tab" data-bs-toggle="tab" data-bs-target="#outcomes" type="button" role="tab" aria-controls="outcomes" aria-selected="false">Outcomes</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<!-- end nav tabs -->
|
||||||
|
|
||||||
|
<!-- begin tab content -->
|
||||||
|
<div class="tab-content" id="carePlanTabsContent">
|
||||||
|
<!-- Overview Tab -->
|
||||||
|
<div class="tab-pane fade show active" id="overview" role="tabpanel" aria-labelledby="overview-tab">
|
||||||
|
<div class="p-3">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h5 class="mb-3">Basic Information</h5>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th width="30%">Care Plan ID</th>
|
||||||
|
<td>{{ care_plan.care_plan_id }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Plan Type</th>
|
||||||
|
<td>{{ care_plan.get_plan_type_display }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Category</th>
|
||||||
|
<td>{{ care_plan.get_category_display }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Status</th>
|
||||||
|
<td>{{ care_plan.get_status_display }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Priority</th>
|
||||||
|
<td>{{ care_plan.get_priority_display }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h5 class="mb-3 mt-4">Description</h5>
|
||||||
|
<div class="p-3 bg-light rounded">
|
||||||
|
{{ care_plan.description|linebreaks }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h5 class="mb-3">Provider Information</h5>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th width="30%">Primary Provider</th>
|
||||||
|
<td>{{ care_plan.primary_provider.get_full_name }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Care Team</th>
|
||||||
|
<td>
|
||||||
|
{% if care_plan.care_team.all %}
|
||||||
|
<ul class="mb-0 ps-3">
|
||||||
|
{% for provider in care_plan.care_team.all %}
|
||||||
|
<li>{{ provider.get_full_name }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
No additional care team members
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h5 class="mb-3 mt-4">Related Problems</h5>
|
||||||
|
{% if care_plan.related_problems.all %}
|
||||||
|
<div class="list-group">
|
||||||
|
{% for problem in care_plan.related_problems.all %}
|
||||||
|
<a href="{% url 'emr:problem_detail' problem.id %}" class="list-group-item list-group-item-action d-flex justify-content-between align-items-center">
|
||||||
|
{{ problem.problem_name }}
|
||||||
|
<span class="badge bg-{{ problem.status|lower }} rounded-pill">{{ problem.get_status_display }}</span>
|
||||||
|
</a>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<i class="fa fa-info-circle me-2"></i> No problems are associated with this care plan.
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Goals & Objectives Tab -->
|
||||||
|
<div class="tab-pane fade" id="goals" role="tabpanel" aria-labelledby="goals-tab">
|
||||||
|
<div class="p-3">
|
||||||
|
<h5 class="mb-3">Goals</h5>
|
||||||
|
{% if care_plan.goals %}
|
||||||
|
<div class="goals-list">
|
||||||
|
{% for goal in care_plan.goals %}
|
||||||
|
<div class="goal-item">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<h6 class="mb-1">{{ goal.title }}</h6>
|
||||||
|
<span class="badge bg-{{ goal.status|default:'secondary'|lower }}">{{ goal.status|default:'Not Started' }}</span>
|
||||||
|
</div>
|
||||||
|
<p class="mb-1">{{ goal.description }}</p>
|
||||||
|
{% if goal.target_date %}
|
||||||
|
<small class="text-muted">Target Date: {{ goal.target_date }}</small>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<i class="fa fa-info-circle me-2"></i> No goals have been defined for this care plan.
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<h5 class="mb-3 mt-4">Objectives</h5>
|
||||||
|
{% if care_plan.objectives %}
|
||||||
|
<div class="objectives-list">
|
||||||
|
{% for objective in care_plan.objectives %}
|
||||||
|
<div class="objective-item">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<h6 class="mb-1">{{ objective.title }}</h6>
|
||||||
|
<span class="badge bg-{{ objective.status|default:'secondary'|lower }}">{{ objective.status|default:'Not Started' }}</span>
|
||||||
|
</div>
|
||||||
|
<p class="mb-1">{{ objective.description }}</p>
|
||||||
|
{% if objective.measure %}
|
||||||
|
<small class="text-muted">Measure: {{ objective.measure }}</small>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<i class="fa fa-info-circle me-2"></i> No objectives have been defined for this care plan.
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Interventions Tab -->
|
||||||
|
<div class="tab-pane fade" id="interventions" role="tabpanel" aria-labelledby="interventions-tab">
|
||||||
|
<div class="p-3">
|
||||||
|
<h5 class="mb-3">Interventions</h5>
|
||||||
|
{% if care_plan.interventions %}
|
||||||
|
<div class="interventions-list">
|
||||||
|
{% for intervention in care_plan.interventions %}
|
||||||
|
<div class="intervention-item">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<h6 class="mb-1">{{ intervention.title }}</h6>
|
||||||
|
<span class="badge bg-{{ intervention.status|default:'secondary'|lower }}">{{ intervention.status|default:'Not Started' }}</span>
|
||||||
|
</div>
|
||||||
|
<p class="mb-1">{{ intervention.description }}</p>
|
||||||
|
{% if intervention.frequency %}
|
||||||
|
<small class="text-muted">Frequency: {{ intervention.frequency }}</small>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<i class="fa fa-info-circle me-2"></i> No interventions have been defined for this care plan.
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<h5 class="mb-3 mt-4">Activities</h5>
|
||||||
|
{% if care_plan.activities %}
|
||||||
|
<div class="activities-list">
|
||||||
|
{% for activity in care_plan.activities %}
|
||||||
|
<div class="activity-item">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<h6 class="mb-1">{{ activity.title }}</h6>
|
||||||
|
<span class="badge bg-{{ activity.status|default:'secondary'|lower }}">{{ activity.status|default:'Not Started' }}</span>
|
||||||
|
</div>
|
||||||
|
<p class="mb-1">{{ activity.description }}</p>
|
||||||
|
{% if activity.assigned_to %}
|
||||||
|
<small class="text-muted">Assigned to: {{ activity.assigned_to }}</small>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<i class="fa fa-info-circle me-2"></i> No activities have been defined for this care plan.
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Monitoring Tab -->
|
||||||
|
<div class="tab-pane fade" id="monitoring" role="tabpanel" aria-labelledby="monitoring-tab">
|
||||||
|
<div class="p-3">
|
||||||
|
<h5 class="mb-3">Monitoring Parameters</h5>
|
||||||
|
{% if care_plan.monitoring_parameters %}
|
||||||
|
<div class="monitoring-list">
|
||||||
|
{% for parameter in care_plan.monitoring_parameters %}
|
||||||
|
<div class="monitoring-item">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<h6 class="mb-1">{{ parameter.title }}</h6>
|
||||||
|
<span class="badge bg-{{ parameter.status|default:'secondary'|lower }}">{{ parameter.status|default:'Not Started' }}</span>
|
||||||
|
</div>
|
||||||
|
<p class="mb-1">{{ parameter.description }}</p>
|
||||||
|
{% if parameter.frequency %}
|
||||||
|
<small class="text-muted">Frequency: {{ parameter.frequency }}</small>
|
||||||
|
{% endif %}
|
||||||
|
{% if parameter.target_range %}
|
||||||
|
<small class="text-muted d-block">Target Range: {{ parameter.target_range }}</small>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<i class="fa fa-info-circle me-2"></i> No monitoring parameters have been defined for this care plan.
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<h5 class="mb-3 mt-4">Evaluation Criteria</h5>
|
||||||
|
{% if care_plan.evaluation_criteria %}
|
||||||
|
<div class="evaluation-list">
|
||||||
|
{% for criteria in care_plan.evaluation_criteria %}
|
||||||
|
<div class="monitoring-item">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<h6 class="mb-1">{{ criteria.title }}</h6>
|
||||||
|
<span class="badge bg-{{ criteria.status|default:'secondary'|lower }}">{{ criteria.status|default:'Not Evaluated' }}</span>
|
||||||
|
</div>
|
||||||
|
<p class="mb-1">{{ criteria.description }}</p>
|
||||||
|
{% if criteria.measure %}
|
||||||
|
<small class="text-muted">Measure: {{ criteria.measure }}</small>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<i class="fa fa-info-circle me-2"></i> No evaluation criteria have been defined for this care plan.
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if care_plan.progress_notes %}
|
||||||
|
<h5 class="mb-3 mt-4">Progress Notes</h5>
|
||||||
|
<div class="p-3 bg-light rounded">
|
||||||
|
{{ care_plan.progress_notes|linebreaks }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Patient Involvement Tab -->
|
||||||
|
<div class="tab-pane fade" id="patient" role="tabpanel" aria-labelledby="patient-tab">
|
||||||
|
<div class="p-3">
|
||||||
|
{% if care_plan.patient_goals %}
|
||||||
|
<h5 class="mb-3">Patient Goals</h5>
|
||||||
|
<div class="p-3 bg-light rounded mb-4">
|
||||||
|
{{ care_plan.patient_goals|linebreaks }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if care_plan.patient_preferences %}
|
||||||
|
<h5 class="mb-3">Patient Preferences</h5>
|
||||||
|
<div class="p-3 bg-light rounded mb-4">
|
||||||
|
{{ care_plan.patient_preferences|linebreaks }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if care_plan.patient_barriers %}
|
||||||
|
<h5 class="mb-3">Identified Barriers</h5>
|
||||||
|
<div class="p-3 bg-light rounded mb-4">
|
||||||
|
{{ care_plan.patient_barriers|linebreaks }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<h5 class="mb-3">Resources Needed</h5>
|
||||||
|
{% if care_plan.resources_needed %}
|
||||||
|
<div class="list-group mb-4">
|
||||||
|
{% for resource in care_plan.resources_needed %}
|
||||||
|
<div class="list-group-item">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<h6 class="mb-1">{{ resource.name }}</h6>
|
||||||
|
<span class="badge bg-{{ resource.status|default:'secondary'|lower }}">{{ resource.status|default:'Pending' }}</span>
|
||||||
|
</div>
|
||||||
|
{% if resource.description %}
|
||||||
|
<p class="mb-1">{{ resource.description }}</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="alert alert-info mb-4">
|
||||||
|
<i class="fa fa-info-circle me-2"></i> No resources have been identified for this care plan.
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<h5 class="mb-3">Support Systems</h5>
|
||||||
|
{% if care_plan.support_systems %}
|
||||||
|
<div class="list-group">
|
||||||
|
{% for support in care_plan.support_systems %}
|
||||||
|
<div class="list-group-item">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<h6 class="mb-1">{{ support.name }}</h6>
|
||||||
|
<span class="badge bg-{{ support.type|default:'secondary'|lower }}">{{ support.type|default:'Other' }}</span>
|
||||||
|
</div>
|
||||||
|
{% if support.description %}
|
||||||
|
<p class="mb-1">{{ support.description }}</p>
|
||||||
|
{% endif %}
|
||||||
|
{% if support.contact %}
|
||||||
|
<small class="text-muted">Contact: {{ support.contact }}</small>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<i class="fa fa-info-circle me-2"></i> No support systems have been identified for this care plan.
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Outcomes Tab -->
|
||||||
|
<div class="tab-pane fade" id="outcomes" role="tabpanel" aria-labelledby="outcomes-tab">
|
||||||
|
<div class="p-3">
|
||||||
|
<h5 class="mb-3">Outcomes Achieved</h5>
|
||||||
|
{% if care_plan.outcomes_achieved %}
|
||||||
|
<div class="outcomes-list">
|
||||||
|
{% for outcome in care_plan.outcomes_achieved %}
|
||||||
|
<div class="outcome-item">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<h6 class="mb-1">{{ outcome.title }}</h6>
|
||||||
|
<span class="badge bg-{{ outcome.status|default:'success'|lower }}">{{ outcome.status|default:'Achieved' }}</span>
|
||||||
|
</div>
|
||||||
|
<p class="mb-1">{{ outcome.description }}</p>
|
||||||
|
{% if outcome.date_achieved %}
|
||||||
|
<small class="text-muted">Date Achieved: {{ outcome.date_achieved }}</small>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<i class="fa fa-info-circle me-2"></i> No outcomes have been recorded for this care plan.
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- end tab content -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- end care plan details panel -->
|
||||||
|
|
||||||
|
<!-- begin clinical notes panel -->
|
||||||
|
<div class="panel panel-inverse">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h4 class="panel-title">Related Clinical Notes</h4>
|
||||||
|
<div class="panel-heading-btn">
|
||||||
|
<a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-expand"><i class="fa fa-expand"></i></a>
|
||||||
|
<a href="javascript:;" class="btn btn-xs btn-icon btn-success" data-toggle="panel-reload"><i class="fa fa-redo"></i></a>
|
||||||
|
<a href="javascript:;" class="btn btn-xs btn-icon btn-warning" data-toggle="panel-collapse"><i class="fa fa-minus"></i></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
{% if care_plan.clinical_notes.all %}
|
||||||
|
<div class="timeline">
|
||||||
|
{% for note in care_plan.clinical_notes.all %}
|
||||||
|
<div class="timeline-item">
|
||||||
|
<div class="timeline-time">
|
||||||
|
{{ note.note_datetime|date:"M d, Y" }} <small>{{ note.note_datetime|time:"h:i A" }}</small>
|
||||||
|
</div>
|
||||||
|
<div class="timeline-icon">
|
||||||
|
<a href="javascript:;"> </a>
|
||||||
|
</div>
|
||||||
|
<div class="timeline-content">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<h5>{{ note.title }}</h5>
|
||||||
|
<span class="badge bg-{{ note.status|lower }}">{{ note.get_status_display }}</span>
|
||||||
|
</div>
|
||||||
|
<p class="mb-2">{{ note.content|truncatechars:200 }}</p>
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<small class="text-muted">{{ note.get_note_type_display }} by {{ note.author.get_full_name }}</small>
|
||||||
|
<a href="{% url 'emr:clinical_note_detail' note.id %}" class="btn btn-sm btn-primary">View Note</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<i class="fa fa-info-circle me-2"></i> No clinical notes are associated with this care plan.
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- end clinical notes panel -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- end col-12 -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- end row -->
|
||||||
|
|
||||||
|
<!-- begin approve modal -->
|
||||||
|
<div class="modal fade" id="approveModal" tabindex="-1" aria-labelledby="approveModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="approveModalLabel">Approve Care Plan</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<form action="" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="modal-body">
|
||||||
|
<p>You are about to approve this care plan. This action will mark the plan as officially approved and ready for implementation.</p>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="approval_notes" class="form-label">Approval Notes (Optional)</label>
|
||||||
|
<textarea class="form-control" id="approval_notes" name="approval_notes" rows="3"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||||
|
<button type="submit" class="btn btn-success">Approve Care Plan</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- end approve modal -->
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block js %}
|
||||||
|
<script src="{% static 'plugins/moment/min/moment.min.js' %}"></script>
|
||||||
|
<script src="{% static 'plugins/chart.js/dist/chart.umd.js' %}"></script>
|
||||||
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
// Initialize tooltips
|
||||||
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
||||||
|
|
||||||
|
// Initialize activity chart
|
||||||
|
var ctx = document.getElementById('activityChart').getContext('2d');
|
||||||
|
var activityChart = new Chart(ctx, {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: ['Initial', 'Week 1', 'Week 2', 'Week 3', 'Week 4', 'Current'],
|
||||||
|
datasets: [{
|
||||||
|
label: 'Completion Progress',
|
||||||
|
data: [0, 15, 30, 45, 60, {{ care_plan.completion_percentage }}],
|
||||||
|
backgroundColor: 'rgba(40, 167, 69, 0.2)',
|
||||||
|
borderColor: 'rgba(40, 167, 69, 1)',
|
||||||
|
borderWidth: 2,
|
||||||
|
tension: 0.4
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
scales: {
|
||||||
|
y: {
|
||||||
|
beginAtZero: true,
|
||||||
|
max: 100,
|
||||||
|
ticks: {
|
||||||
|
callback: function(value) {
|
||||||
|
return value + '%';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
tooltip: {
|
||||||
|
callbacks: {
|
||||||
|
label: function(context) {
|
||||||
|
return context.dataset.label + ': ' + context.raw + '%';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle HTMX events
|
||||||
|
document.body.addEventListener('htmx:afterSwap', function(evt) {
|
||||||
|
if (evt.detail.target.id === 'clinical-notes-container') {
|
||||||
|
// Reinitialize any components in the clinical notes container
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
@ -88,16 +88,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<!-- begin breadcrumb -->
|
|
||||||
<ol class="breadcrumb float-xl-end">
|
|
||||||
<li class="breadcrumb-item"><a href="{% url 'dashboard' %}">Home</a></li>
|
|
||||||
<li class="breadcrumb-item"><a href="{% url 'emr:dashboard' %}">EMR</a></li>
|
|
||||||
<li class="breadcrumb-item"><a href="{% url 'emr:care_plan_list' %}">Care Plans</a></li>
|
|
||||||
<li class="breadcrumb-item active">
|
|
||||||
{% if form.instance.id %}Edit Care Plan{% else %}New Care Plan{% endif %}
|
|
||||||
</li>
|
|
||||||
</ol>
|
|
||||||
<!-- end breadcrumb -->
|
|
||||||
|
|
||||||
<!-- begin page-header -->
|
<!-- begin page-header -->
|
||||||
<h1 class="page-header">
|
<h1 class="page-header">
|
||||||
|
|||||||
@ -4,17 +4,30 @@
|
|||||||
{% block title %}Care Plans - {{ block.super }}{% endblock %}
|
{% block title %}Care Plans - {{ block.super }}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||||
|
<div>
|
||||||
|
<h1 class="h2">
|
||||||
|
<i class="fas fa-clipboard-list me-2"></i>Care Plan<span class="fw-light">Management</span>
|
||||||
|
</h1>
|
||||||
|
<p class="text-muted">Manage all healthcare plans</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="card">
|
<div class="panel panel-inverse" data-sortable-id="index-1">
|
||||||
<div class="card-header">
|
<div class="panel-heading">
|
||||||
<h4 class="card-title mb-0">
|
<h4 class="panel-title"><i class="fas fa-clipboard-list me-2"></i>All Care Plans</h4>
|
||||||
<i class="fas fa-clipboard-list me-2"></i>Care Plan Management
|
<div class="panel-heading-btn">
|
||||||
</h4>
|
<a href="javascript:" class="btn btn-xs btn-icon btn-default" data-toggle="panel-expand"><i class="fa fa-expand"></i></a>
|
||||||
</div>
|
<a href="javascript:" class="btn btn-xs btn-icon btn-success" data-toggle="panel-reload"><i class="fa fa-redo"></i></a>
|
||||||
|
<a href="javascript:" class="btn btn-xs btn-icon btn-warning" data-toggle="panel-collapse"><i class="fa fa-minus"></i></a>
|
||||||
|
<a href="javascript:" class="btn btn-xs btn-icon btn-danger" data-toggle="panel-remove"><i class="fa fa-times"></i></a>
|
||||||
|
|
||||||
<div class="card-body">
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
<!-- Filters -->
|
<!-- Filters -->
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<div class="col-md-2">
|
<div class="col-md-2">
|
||||||
@ -128,20 +141,20 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="btn-group btn-group-sm">
|
<div class="btn-group btn-group-sm">
|
||||||
<button class="btn btn-outline-primary" title="View Details">
|
<a href="{% url 'emr:care_plan_detail' plan.id%}" class="btn btn-outline-primary" title="View Details">
|
||||||
<i class="fas fa-eye"></i>
|
<i class="fas fa-eye"></i>
|
||||||
</button>
|
</a>
|
||||||
{% if plan.status == 'ACTIVE' %}
|
{% if plan.status == 'ACTIVE' %}
|
||||||
<button class="btn btn-outline-info" title="Update Progress">
|
<button class="btn btn-outline-info" title="Update Progress">
|
||||||
<i class="fas fa-chart-line"></i>
|
<i class="fas fa-chart-line"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-outline-success"
|
{# <button class="btn btn-outline-success" #}
|
||||||
title="Mark Complete"
|
{# title="Mark Complete"#}
|
||||||
hx-post="{% url 'emr:complete_care_plan' plan.id %}"
|
{# hx-post="{% url 'emr:complete_care_plan' plan.id %}"#}
|
||||||
hx-confirm="Mark this care plan as complete?"
|
{# hx-confirm="Mark this care plan as complete?"#}
|
||||||
hx-swap="none">
|
{# hx-swap="none">#}
|
||||||
<i class="fas fa-check"></i>
|
{# <i class="fas fa-check"></i>#}
|
||||||
</button>
|
{# </button>#}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<button class="btn btn-outline-secondary" title="Notes">
|
<button class="btn btn-outline-secondary" title="Notes">
|
||||||
<i class="fas fa-sticky-note"></i>
|
<i class="fas fa-sticky-note"></i>
|
||||||
@ -164,33 +177,7 @@
|
|||||||
|
|
||||||
<!-- Pagination -->
|
<!-- Pagination -->
|
||||||
{% if is_paginated %}
|
{% if is_paginated %}
|
||||||
<nav aria-label="Care plan pagination">
|
{% include 'partial/pagination.html' %}
|
||||||
<ul class="pagination justify-content-center">
|
|
||||||
{% if page_obj.has_previous %}
|
|
||||||
<li class="page-item">
|
|
||||||
<a class="page-link" href="?page=1">First</a>
|
|
||||||
</li>
|
|
||||||
<li class="page-item">
|
|
||||||
<a class="page-link" href="?page={{ page_obj.previous_page_number }}">Previous</a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<li class="page-item active">
|
|
||||||
<span class="page-link">
|
|
||||||
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
{% if page_obj.has_next %}
|
|
||||||
<li class="page-item">
|
|
||||||
<a class="page-link" href="?page={{ page_obj.next_page_number }}">Next</a>
|
|
||||||
</li>
|
|
||||||
<li class="page-item">
|
|
||||||
<a class="page-link" href="?page={{ page_obj.paginator.num_pages }}">Last</a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -71,14 +71,6 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<!-- begin breadcrumb -->
|
|
||||||
<ol class="breadcrumb float-xl-end">
|
|
||||||
<li class="breadcrumb-item"><a href="{% url 'dashboard' %}">Home</a></li>
|
|
||||||
<li class="breadcrumb-item"><a href="{% url 'emr:dashboard' %}">EMR</a></li>
|
|
||||||
<li class="breadcrumb-item"><a href="{% url 'emr:problem_list' %}">Problems</a></li>
|
|
||||||
<li class="breadcrumb-item active">{{ problem.problem_name }}</li>
|
|
||||||
</ol>
|
|
||||||
<!-- end breadcrumb -->
|
|
||||||
|
|
||||||
<!-- begin page-header -->
|
<!-- begin page-header -->
|
||||||
<h1 class="page-header">Problem Detail <small>Comprehensive problem information</small></h1>
|
<h1 class="page-header">Problem Detail <small>Comprehensive problem information</small></h1>
|
||||||
@ -360,7 +352,7 @@
|
|||||||
<a href="{% url 'emr:problem_list' %}" class="btn btn-secondary me-2">
|
<a href="{% url 'emr:problem_list' %}" class="btn btn-secondary me-2">
|
||||||
<i class="fa fa-arrow-left me-1"></i> Back to Problem List
|
<i class="fa fa-arrow-left me-1"></i> Back to Problem List
|
||||||
</a>
|
</a>
|
||||||
<a href="{% url 'emr:patient_detail' problem.patient.id %}" class="btn btn-info">
|
<a href="{% url 'patients:patient_detail' problem.patient.id %}" class="btn btn-info">
|
||||||
<i class="fa fa-user me-1"></i> Patient Profile
|
<i class="fa fa-user me-1"></i> Patient Profile
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@ -392,7 +384,7 @@
|
|||||||
<h5 class="modal-title" id="resolveModalLabel">Resolve Problem</h5>
|
<h5 class="modal-title" id="resolveModalLabel">Resolve Problem</h5>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
<form action="{% url 'emr:problem_resolve' problem.id %}" method="post">
|
<form action="" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
@ -19,8 +19,17 @@ urlpatterns = [
|
|||||||
path('vital-signs/', views.VitalSignsListView.as_view(), name='vital_signs_list'),
|
path('vital-signs/', views.VitalSignsListView.as_view(), name='vital_signs_list'),
|
||||||
path('add-vital-signs/<int:pk>/', views.VitalSignsCreateView.as_view(), name='add_vital_signs'),
|
path('add-vital-signs/<int:pk>/', views.VitalSignsCreateView.as_view(), name='add_vital_signs'),
|
||||||
path('vital-signs/<int:pk>/', views.VitalSignsDetailView.as_view(), name='vital_signs_detail'),
|
path('vital-signs/<int:pk>/', views.VitalSignsDetailView.as_view(), name='vital_signs_detail'),
|
||||||
|
|
||||||
path('problems/', views.ProblemListView.as_view(), name='problem_list'),
|
path('problems/', views.ProblemListView.as_view(), name='problem_list'),
|
||||||
|
path('problems/<int:pk>/', views.ProblemListDetailView.as_view(), name='problem_detail'),
|
||||||
|
path('problems/<int:pk>/update/', views.ProblemListUpdateView.as_view(), name='problem_update'),
|
||||||
|
path('problems/<int:pk>/delete/', views.ProblemListDeleteView.as_view(), name='problem_delete'),
|
||||||
|
|
||||||
path('care-plans/', views.CarePlanListView.as_view(), name='care_plan_list'),
|
path('care-plans/', views.CarePlanListView.as_view(), name='care_plan_list'),
|
||||||
|
path('care-plans/<int:pk>/', views.CarePlanDetailView.as_view(), name='care_plan_detail'),
|
||||||
|
path('care-plans/<int:pk>/update/', views.CarePlanUpdateView.as_view(), name='care_plan_update'),
|
||||||
|
path('care-plans/<int:pk>/delete/', views.CarePlanDeleteView.as_view(), name='care_plan_delete'),
|
||||||
|
|
||||||
path('notes/', views.ClinicalNoteListView.as_view(), name='clinical_note_list'),
|
path('notes/', views.ClinicalNoteListView.as_view(), name='clinical_note_list'),
|
||||||
path('notes/<int:pk>/', views.ClinicalNoteDetailView.as_view(), name='clinical_note_detail'),
|
path('notes/<int:pk>/', views.ClinicalNoteDetailView.as_view(), name='clinical_note_detail'),
|
||||||
path('notes/<int:pk>/update/', views.ClinicalNoteUpdateView.as_view(), name='clinical_note_update'),
|
path('notes/<int:pk>/update/', views.ClinicalNoteUpdateView.as_view(), name='clinical_note_update'),
|
||||||
|
|||||||
992
emr/views.py
992
emr/views.py
File diff suppressed because it is too large
Load Diff
Binary file not shown.
68
hr/migrations/0003_alter_employee_role.py
Normal file
68
hr/migrations/0003_alter_employee_role.py
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
# Generated by Django 5.2.6 on 2025-09-16 15:05
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("hr", "0002_alter_employee_id_number"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="employee",
|
||||||
|
name="role",
|
||||||
|
field=models.CharField(
|
||||||
|
choices=[
|
||||||
|
("SUPER_ADMIN", "Super Administrator"),
|
||||||
|
("ADMIN", "Administrator"),
|
||||||
|
("PHYSICIAN", "Physician"),
|
||||||
|
("SURGEON", "Surgeon"),
|
||||||
|
("NURSE", "Nurse"),
|
||||||
|
("NURSE_PRACTITIONER", "Nurse Practitioner"),
|
||||||
|
("PHYSICIAN_ASSISTANT", "Physician Assistant"),
|
||||||
|
("SURGICAL_TECHNICIAN", "Surgical Technician"),
|
||||||
|
("ANESTHESIOLOGIST", "Anesthesiologist"),
|
||||||
|
("ANESTHESIOLOGIST_ASSOCIATE", "Anesthesiologist Associate"),
|
||||||
|
("CLINICAL_NURSE_ASSOCIATE", "Clinical Nurse Associate"),
|
||||||
|
("CLINICAL_NURSE_SPECIALIST", "Clinical Nurse Specialist"),
|
||||||
|
("CLINICAL_NURSE_MANAGER", "Clinical Nurse Manager"),
|
||||||
|
("CLINICAL_NURSE_TECHNICIAN", "Clinical Nurse Technician"),
|
||||||
|
("CLINICAL_NURSE_COORDINATOR", "Clinical Nurse Coordinator"),
|
||||||
|
("FELLOW", "Fellow"),
|
||||||
|
("INTERN", "Intern"),
|
||||||
|
("INTERNSHIP", "Internship"),
|
||||||
|
("RESIDENT", "Resident"),
|
||||||
|
("WORK_FROM_HOME", "Work from Home"),
|
||||||
|
("WORK_FROM_HOME_PART_TIME", "Work from Home Part-time"),
|
||||||
|
("PHARMACIST", "Pharmacist"),
|
||||||
|
("PHARMACY_TECH", "Pharmacy Technician"),
|
||||||
|
("LAB_TECH", "Laboratory Technician"),
|
||||||
|
("RADIOLOGIST", "Radiologist"),
|
||||||
|
("RAD_TECH", "Radiology Technician"),
|
||||||
|
("THERAPIST", "Therapist"),
|
||||||
|
("SOCIAL_WORKER", "Social Worker"),
|
||||||
|
("CASE_MANAGER", "Case Manager"),
|
||||||
|
("BILLING_SPECIALIST", "Billing Specialist"),
|
||||||
|
("REGISTRATION", "Registration Staff"),
|
||||||
|
("SCHEDULER", "Scheduler"),
|
||||||
|
("MEDICAL_ASSISTANT", "Medical Assistant"),
|
||||||
|
("CLERICAL", "Clerical Staff"),
|
||||||
|
("IT_SUPPORT", "IT Support"),
|
||||||
|
("QUALITY_ASSURANCE", "Quality Assurance"),
|
||||||
|
("COMPLIANCE", "Compliance Officer"),
|
||||||
|
("SECURITY", "Security"),
|
||||||
|
("MAINTENANCE", "Maintenance"),
|
||||||
|
("VOLUNTEER", "Volunteer"),
|
||||||
|
("STUDENT", "Student"),
|
||||||
|
("RESEARCHER", "Researcher"),
|
||||||
|
("CONSULTANT", "Consultant"),
|
||||||
|
("VENDOR", "Vendor"),
|
||||||
|
("GUEST", "Guest"),
|
||||||
|
],
|
||||||
|
default="GUEST",
|
||||||
|
max_length=50,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
Binary file not shown.
15
hr/models.py
15
hr/models.py
@ -56,9 +56,24 @@ class Employee(models.Model):
|
|||||||
SUPER_ADMIN = 'SUPER_ADMIN', 'Super Administrator'
|
SUPER_ADMIN = 'SUPER_ADMIN', 'Super Administrator'
|
||||||
ADMIN = 'ADMIN', 'Administrator'
|
ADMIN = 'ADMIN', 'Administrator'
|
||||||
PHYSICIAN = 'PHYSICIAN', 'Physician'
|
PHYSICIAN = 'PHYSICIAN', 'Physician'
|
||||||
|
SURGEON = 'SURGEON', 'Surgeon'
|
||||||
NURSE = 'NURSE', 'Nurse'
|
NURSE = 'NURSE', 'Nurse'
|
||||||
NURSE_PRACTITIONER = 'NURSE_PRACTITIONER', 'Nurse Practitioner'
|
NURSE_PRACTITIONER = 'NURSE_PRACTITIONER', 'Nurse Practitioner'
|
||||||
PHYSICIAN_ASSISTANT = 'PHYSICIAN_ASSISTANT', 'Physician Assistant'
|
PHYSICIAN_ASSISTANT = 'PHYSICIAN_ASSISTANT', 'Physician Assistant'
|
||||||
|
SURGICAL_TECHNICIAN = 'SURGICAL_TECHNICIAN', 'Surgical Technician'
|
||||||
|
ANESTHESIOLOGIST = 'ANESTHESIOLOGIST', 'Anesthesiologist'
|
||||||
|
ANESTHESIOLOGIST_ASSOCIATE = 'ANESTHESIOLOGIST_ASSOCIATE', 'Anesthesiologist Associate'
|
||||||
|
CLINICAL_NURSE_ASSOCIATE = 'CLINICAL_NURSE_ASSOCIATE', 'Clinical Nurse Associate'
|
||||||
|
CLINICAL_NURSE_SPECIALIST = 'CLINICAL_NURSE_SPECIALIST', 'Clinical Nurse Specialist'
|
||||||
|
CLINICAL_NURSE_MANAGER = 'CLINICAL_NURSE_MANAGER', 'Clinical Nurse Manager'
|
||||||
|
CLINICAL_NURSE_TECHNICIAN = 'CLINICAL_NURSE_TECHNICIAN', 'Clinical Nurse Technician'
|
||||||
|
CLINICAL_NURSE_COORDINATOR = 'CLINICAL_NURSE_COORDINATOR', 'Clinical Nurse Coordinator'
|
||||||
|
FELLOW = 'FELLOW', 'Fellow'
|
||||||
|
INTERN = 'INTERN', 'Intern'
|
||||||
|
INTERNSHIP = 'INTERNSHIP', 'Internship'
|
||||||
|
RESIDENT = 'RESIDENT', 'Resident'
|
||||||
|
WORK_FROM_HOME = 'WORK_FROM_HOME', 'Work from Home'
|
||||||
|
WORK_FROM_HOME_PART_TIME = 'WORK_FROM_HOME_PART_TIME', 'Work from Home Part-time'
|
||||||
PHARMACIST = 'PHARMACIST', 'Pharmacist'
|
PHARMACIST = 'PHARMACIST', 'Pharmacist'
|
||||||
PHARMACY_TECH = 'PHARMACY_TECH', 'Pharmacy Technician'
|
PHARMACY_TECH = 'PHARMACY_TECH', 'Pharmacy Technician'
|
||||||
LAB_TECH = 'LAB_TECH', 'Laboratory Technician'
|
LAB_TECH = 'LAB_TECH', 'Laboratory Technician'
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -153,7 +153,6 @@ class AdmissionForm(forms.ModelForm):
|
|||||||
is_accepting_admissions=True
|
is_accepting_admissions=True
|
||||||
).order_by('name')
|
).order_by('name')
|
||||||
|
|
||||||
# Initialize empty bed queryset - will be populated via AJAX
|
|
||||||
self.fields['current_bed'].queryset = Bed.objects.filter(
|
self.fields['current_bed'].queryset = Bed.objects.filter(
|
||||||
ward__tenant=user.tenant,
|
ward__tenant=user.tenant,
|
||||||
status='AVAILABLE'
|
status='AVAILABLE'
|
||||||
@ -162,13 +161,13 @@ class AdmissionForm(forms.ModelForm):
|
|||||||
self.fields['admitting_physician'].queryset = User.objects.filter(
|
self.fields['admitting_physician'].queryset = User.objects.filter(
|
||||||
tenant=user.tenant,
|
tenant=user.tenant,
|
||||||
is_active=True,
|
is_active=True,
|
||||||
role__in=['DOCTOR', 'SPECIALIST']
|
employee_profile__role__in=['PHYSICIAN', 'PHYSICIAN_ASSISTANT']
|
||||||
).order_by('last_name', 'first_name')
|
).order_by('last_name', 'first_name')
|
||||||
|
|
||||||
self.fields['attending_physician'].queryset = User.objects.filter(
|
self.fields['attending_physician'].queryset = User.objects.filter(
|
||||||
tenant=user.tenant,
|
tenant=user.tenant,
|
||||||
is_active=True,
|
is_active=True,
|
||||||
role__in=['DOCTOR', 'SPECIALIST']
|
employee_profile__role__in=['PHYSICIAN', 'PHYSICIAN_ASSISTANT']
|
||||||
).order_by('last_name', 'first_name')
|
).order_by('last_name', 'first_name')
|
||||||
|
|
||||||
def clean_admission_datetime(self):
|
def clean_admission_datetime(self):
|
||||||
@ -402,13 +401,13 @@ class SurgeryScheduleForm(forms.ModelForm):
|
|||||||
self.fields['primary_surgeon'].queryset = User.objects.filter(
|
self.fields['primary_surgeon'].queryset = User.objects.filter(
|
||||||
tenant=user.tenant,
|
tenant=user.tenant,
|
||||||
is_active=True,
|
is_active=True,
|
||||||
role__in=['DOCTOR', 'SURGEON', 'SPECIALIST']
|
employee_profile__role__in=['PHYSICIAN', 'SURGEON', 'SPECIALIST']
|
||||||
).order_by('last_name', 'first_name')
|
).order_by('last_name', 'first_name')
|
||||||
|
|
||||||
self.fields['anesthesiologist'].queryset = User.objects.filter(
|
self.fields['anesthesiologist'].queryset = User.objects.filter(
|
||||||
tenant=user.tenant,
|
tenant=user.tenant,
|
||||||
is_active=True,
|
is_active=True,
|
||||||
role__in=['DOCTOR', 'ANESTHESIOLOGIST']
|
employee_profile__role__in=['PHYSICIAN', 'ANESTHESIOLOGIST']
|
||||||
).order_by('last_name', 'first_name')
|
).order_by('last_name', 'first_name')
|
||||||
|
|
||||||
def clean_scheduled_date(self):
|
def clean_scheduled_date(self):
|
||||||
|
|||||||
@ -0,0 +1,31 @@
|
|||||||
|
# Generated by Django 5.2.6 on 2025-09-16 15:05
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("inpatients", "0001_initial"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="dischargesummary",
|
||||||
|
name="discharge_disposition",
|
||||||
|
field=models.CharField(
|
||||||
|
choices=[
|
||||||
|
("HOME", "Home"),
|
||||||
|
("HOME_HEALTH", "Home with Health Services"),
|
||||||
|
("NURSING_HOME", "Nursing Home"),
|
||||||
|
("REHAB_FACILITY", "Rehabilitation Facility"),
|
||||||
|
("HOSPICE", "Hospice"),
|
||||||
|
("TRANSFER", "Transfer to Another Hospital"),
|
||||||
|
("MORGUE", "Morgue"),
|
||||||
|
("OTHER", "Other"),
|
||||||
|
],
|
||||||
|
help_text="Discharge disposition",
|
||||||
|
max_length=30,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
Binary file not shown.
@ -849,8 +849,6 @@ class Admission(models.Model):
|
|||||||
return self.status in ['PENDING', 'ADMITTED', 'TRANSFERRED']
|
return self.status in ['PENDING', 'ADMITTED', 'TRANSFERRED']
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Transfer(models.Model):
|
class Transfer(models.Model):
|
||||||
"""
|
"""
|
||||||
Patient transfer model for tracking ward/bed changes.
|
Patient transfer model for tracking ward/bed changes.
|
||||||
@ -1124,6 +1122,7 @@ class DischargeSummary(models.Model):
|
|||||||
('REHAB_FACILITY', 'Rehabilitation Facility'),
|
('REHAB_FACILITY', 'Rehabilitation Facility'),
|
||||||
('HOSPICE', 'Hospice'),
|
('HOSPICE', 'Hospice'),
|
||||||
('TRANSFER', 'Transfer to Another Hospital'),
|
('TRANSFER', 'Transfer to Another Hospital'),
|
||||||
|
('MORGUE', 'Morgue'),
|
||||||
('OTHER', 'Other'),
|
('OTHER', 'Other'),
|
||||||
]
|
]
|
||||||
TRANSPORTATION_METHOD_CHOICES = [
|
TRANSPORTATION_METHOD_CHOICES = [
|
||||||
|
|||||||
@ -27,7 +27,7 @@
|
|||||||
<i class="fas fa-cog me-2"></i>Quick Actions
|
<i class="fas fa-cog me-2"></i>Quick Actions
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a class="dropdown-item" href="{% url 'inpatients:admission_list' %}?action=new">
|
<li><a class="dropdown-item" href="{% url 'inpatients:admission_create' %}">
|
||||||
<i class="fas fa-user-plus me-2"></i>New Admission
|
<i class="fas fa-user-plus me-2"></i>New Admission
|
||||||
</a></li>
|
</a></li>
|
||||||
<li><a class="dropdown-item" href="{% url 'inpatients:bed_management' %}">
|
<li><a class="dropdown-item" href="{% url 'inpatients:bed_management' %}">
|
||||||
@ -154,10 +154,10 @@
|
|||||||
<span class="visually-hidden">Toggle Dropdown</span>
|
<span class="visually-hidden">Toggle Dropdown</span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a class="dropdown-item" href="#">
|
<li><a class="dropdown-item" href="{% url 'inpatients:transfer_patient' admission.id %}">
|
||||||
<i class="fas fa-exchange-alt me-2"></i>Transfer
|
<i class="fas fa-exchange-alt me-2"></i>Transfer
|
||||||
</a></li>
|
</a></li>
|
||||||
<li><a class="dropdown-item" href="#">
|
<li><a class="dropdown-item" href="{% url 'inpatients:discharge_patient' admission.patient.id %}">
|
||||||
<i class="fas fa-sign-out-alt me-2"></i>Discharge
|
<i class="fas fa-sign-out-alt me-2"></i>Discharge
|
||||||
</a></li>
|
</a></li>
|
||||||
<li><a class="dropdown-item" href="#">
|
<li><a class="dropdown-item" href="#">
|
||||||
@ -297,7 +297,7 @@
|
|||||||
<small class="text-muted">{{ ward.get_ward_type_display }}</small>
|
<small class="text-muted">{{ ward.get_ward_type_display }}</small>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-end">
|
<div class="text-end">
|
||||||
<span class="badge bg-primary">{{ ward.o }}/{{ ward.total_beds }}</span>
|
<span class="badge bg-primary">{{ ward.occupied_beds }}/{{ ward.total_beds }}</span>
|
||||||
<br><small class="text-muted">{{ ward.occupancy_rate|floatformat:0 }}%</small>
|
<br><small class="text-muted">{{ ward.occupancy_rate|floatformat:0 }}%</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
|
{% block content %}
|
||||||
<!-- Surgery Calendar Partial -->
|
<!-- Surgery Calendar Partial -->
|
||||||
<div id="surgery-calendar-container">
|
<div id="surgery-calendar-container">
|
||||||
<!-- Calendar Controls -->
|
<!-- Calendar Controls -->
|
||||||
@ -164,7 +165,7 @@ $(document).ready(function() {
|
|||||||
// Event sources
|
// Event sources
|
||||||
events: function(start, end, timezone, callback) {
|
events: function(start, end, timezone, callback) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: '{% url "inpatients:surgery_calendar_data" %}',
|
url: '',
|
||||||
data: {
|
data: {
|
||||||
start: start.format(),
|
start: start.format(),
|
||||||
end: end.format()
|
end: end.format()
|
||||||
@ -242,7 +243,7 @@ $(document).ready(function() {
|
|||||||
// Load surgery quick view
|
// Load surgery quick view
|
||||||
function loadSurgeryQuickView(surgeryId) {
|
function loadSurgeryQuickView(surgeryId) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: '{% url "inpatients:surgery_quick_view" 0 %}'.replace('0', surgeryId),
|
url: ''.replace('0', surgeryId),
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
$('#surgery-quick-view-content').html(data.html);
|
$('#surgery-quick-view-content').html(data.html);
|
||||||
$('#view-full-surgery').attr('href', data.detail_url);
|
$('#view-full-surgery').attr('href', data.detail_url);
|
||||||
@ -269,7 +270,7 @@ $(document).ready(function() {
|
|||||||
function loadSelectOptions() {
|
function loadSelectOptions() {
|
||||||
// Load patients
|
// Load patients
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: '{% url "patients:patient_list_api" %}',
|
url: '',
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
var patientSelect = $('select[name="patient"]');
|
var patientSelect = $('select[name="patient"]');
|
||||||
patientSelect.empty().append('<option value="">Select Patient</option>');
|
patientSelect.empty().append('<option value="">Select Patient</option>');
|
||||||
@ -282,7 +283,7 @@ $(document).ready(function() {
|
|||||||
|
|
||||||
// Load surgeons
|
// Load surgeons
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: '{% url "users:surgeon_list_api" %}',
|
url: '',
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
var surgeonSelect = $('select[name="surgeon"]');
|
var surgeonSelect = $('select[name="surgeon"]');
|
||||||
surgeonSelect.empty().append('<option value="">Select Surgeon</option>');
|
surgeonSelect.empty().append('<option value="">Select Surgeon</option>');
|
||||||
@ -295,7 +296,7 @@ $(document).ready(function() {
|
|||||||
|
|
||||||
// Load operating rooms
|
// Load operating rooms
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: '{% url "inpatients:operating_room_list_api" %}',
|
url: '',
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
var roomSelect = $('select[name="operating_room"]');
|
var roomSelect = $('select[name="operating_room"]');
|
||||||
roomSelect.empty().append('<option value="">Select OR</option>');
|
roomSelect.empty().append('<option value="">Select OR</option>');
|
||||||
@ -311,7 +312,7 @@ $(document).ready(function() {
|
|||||||
var formData = $('#quick-surgery-form').serialize();
|
var formData = $('#quick-surgery-form').serialize();
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: '{% url "inpatients:surgery_create_quick" %}',
|
url: '',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: formData,
|
data: formData,
|
||||||
success: function(response) {
|
success: function(response) {
|
||||||
@ -419,3 +420,4 @@ $(document).ready(function() {
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Title</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -4,19 +4,13 @@
|
|||||||
{% block title %}Surgery Details - {{ object.procedure_name }}{% endblock %}
|
{% block title %}Surgery Details - {{ object.procedure_name }}{% endblock %}
|
||||||
|
|
||||||
{% block css %}
|
{% block css %}
|
||||||
<link href="{% static 'assets/plugins/datatables.net-bs5/css/dataTables.bootstrap5.min.css' %}" rel="stylesheet" />
|
<link href="{% static 'plugins/datatables.net-bs5/css/dataTables.bootstrap5.min.css' %}" rel="stylesheet" />
|
||||||
<link href="{% static 'assets/plugins/datatables.net-responsive-bs5/css/responsive.bootstrap5.min.css' %}" rel="stylesheet" />
|
<link href="{% static 'plugins/datatables.net-responsive-bs5/css/responsive.bootstrap5.min.css' %}" rel="stylesheet" />
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<!-- BEGIN breadcrumb -->
|
<!-- 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 'inpatients:dashboard' %}">Inpatients</a></li>
|
|
||||||
<li class="breadcrumb-item"><a href="{% url 'inpatients:surgery_list' %}">Surgeries</a></li>
|
|
||||||
<li class="breadcrumb-item active">{{ object.procedure_name }}</li>
|
|
||||||
</ol>
|
|
||||||
<!-- END breadcrumb -->
|
|
||||||
|
|
||||||
<!-- BEGIN page-header -->
|
<!-- BEGIN page-header -->
|
||||||
<h1 class="page-header">
|
<h1 class="page-header">
|
||||||
@ -32,7 +26,7 @@
|
|||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h4 class="panel-title">Surgery Information</h4>
|
<h4 class="panel-title">Surgery Information</h4>
|
||||||
<div class="panel-heading-btn">
|
<div class="panel-heading-btn">
|
||||||
<a href="{% url 'inpatients:surgery_update' object.pk %}" class="btn btn-xs btn-primary me-2">
|
<a href="{% url 'inpatients:surgery_update' object.pk %}" class="btn btn-xs btn-outline-theme me-2">
|
||||||
<i class="fa fa-edit"></i> Edit
|
<i class="fa fa-edit"></i> Edit
|
||||||
</a>
|
</a>
|
||||||
<a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-expand"><i class="fa fa-expand"></i></a>
|
<a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-expand"><i class="fa fa-expand"></i></a>
|
||||||
@ -63,8 +57,8 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td class="fw-bold">Primary Surgeon:</td>
|
<td class="fw-bold">Primary Surgeon:</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{% url 'users:user_detail' object.surgeon.pk %}" class="text-decoration-none">
|
<a href="{% url 'hr:employee_detail' object.primary_surgeon.pk %}" class="text-decoration-none">
|
||||||
Dr. {{ object.surgeon.get_full_name }}
|
Dr. {{ object.primary_surgeon.get_full_name }}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -148,8 +142,8 @@
|
|||||||
<h6 class="mb-3">Medical Team</h6>
|
<h6 class="mb-3">Medical Team</h6>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<strong>Primary Surgeon:</strong><br>
|
<strong>Primary Surgeon:</strong><br>
|
||||||
<a href="{% url 'users:user_detail' object.surgeon.pk %}" class="text-decoration-none">
|
<a href="{% url 'hr:employee_detail' object.primary_surgeon.pk %}" class="text-decoration-none">
|
||||||
Dr. {{ object.surgeon.get_full_name }}
|
Dr. {{ object.primary_surgeon.get_full_name }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -157,7 +151,7 @@
|
|||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<strong>Assistant Surgeons:</strong><br>
|
<strong>Assistant Surgeons:</strong><br>
|
||||||
{% for surgeon in object.assistant_surgeons.all %}
|
{% for surgeon in object.assistant_surgeons.all %}
|
||||||
<a href="{% url 'users:user_detail' surgeon.pk %}" class="text-decoration-none">
|
<a href="{% url 'hr:employee_detail' surgeon.pk %}" class="text-decoration-none">
|
||||||
Dr. {{ surgeon.get_full_name }}
|
Dr. {{ surgeon.get_full_name }}
|
||||||
</a>{% if not forloop.last %}, {% endif %}
|
</a>{% if not forloop.last %}, {% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@ -167,7 +161,7 @@
|
|||||||
{% if object.anesthesiologist %}
|
{% if object.anesthesiologist %}
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<strong>Anesthesiologist:</strong><br>
|
<strong>Anesthesiologist:</strong><br>
|
||||||
<a href="{% url 'users:user_detail' object.anesthesiologist.pk %}" class="text-decoration-none">
|
<a href="{% url 'hr:employee_detail' object.anesthesiologist.pk %}" class="text-decoration-none">
|
||||||
Dr. {{ object.anesthesiologist.get_full_name }}
|
Dr. {{ object.anesthesiologist.get_full_name }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@ -179,7 +173,7 @@
|
|||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<strong>Scrub Nurses:</strong><br>
|
<strong>Scrub Nurses:</strong><br>
|
||||||
{% for nurse in object.scrub_nurses.all %}
|
{% for nurse in object.scrub_nurses.all %}
|
||||||
<a href="{% url 'users:user_detail' nurse.pk %}" class="text-decoration-none">
|
<a href="{% url 'hr:employee_detail' nurse.pk %}" class="text-decoration-none">
|
||||||
{{ nurse.get_full_name }}
|
{{ nurse.get_full_name }}
|
||||||
</a>{% if not forloop.last %}, {% endif %}
|
</a>{% if not forloop.last %}, {% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@ -190,7 +184,7 @@
|
|||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<strong>Circulating Nurses:</strong><br>
|
<strong>Circulating Nurses:</strong><br>
|
||||||
{% for nurse in object.circulating_nurses.all %}
|
{% for nurse in object.circulating_nurses.all %}
|
||||||
<a href="{% url 'users:user_detail' nurse.pk %}" class="text-decoration-none">
|
<a href="{% url 'hr:employee_detail' nurse.pk %}" class="text-decoration-none">
|
||||||
{{ nurse.get_full_name }}
|
{{ nurse.get_full_name }}
|
||||||
</a>{% if not forloop.last %}, {% endif %}
|
</a>{% if not forloop.last %}, {% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@ -275,18 +269,18 @@
|
|||||||
<i class="fa fa-edit me-2"></i>Edit Surgery
|
<i class="fa fa-edit me-2"></i>Edit Surgery
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% if object.status == 'scheduled' %}
|
{% if object.status == 'SCHEDULED' %}
|
||||||
<button class="btn btn-success" onclick="updateStatus('in_progress')">
|
<button class="btn btn-success" onclick="updateStatus('IN_PROGRESS')">
|
||||||
<i class="fa fa-play me-2"></i>Start Surgery
|
<i class="fa fa-play me-2"></i>Start Surgery
|
||||||
</button>
|
</button>
|
||||||
{% elif object.status == 'in_progress' %}
|
{% elif object.status == 'IN_PROGRESS' %}
|
||||||
<button class="btn btn-warning" onclick="updateStatus('completed')">
|
<button class="btn btn-warning" onclick="updateStatus('COMPLETED')">
|
||||||
<i class="fa fa-check me-2"></i>Complete Surgery
|
<i class="fa fa-check me-2"></i>Complete Surgery
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if object.status in 'scheduled,in_progress' %}
|
{% if object.status in 'SCHEDULED,IN_PROGRESS' %}
|
||||||
<button class="btn btn-danger" onclick="updateStatus('cancelled')">
|
<button class="btn btn-danger" onclick="updateStatus('CANCELLED')">
|
||||||
<i class="fa fa-times me-2"></i>Cancel Surgery
|
<i class="fa fa-times me-2"></i>Cancel Surgery
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -373,6 +367,9 @@
|
|||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h4 class="panel-title">Patient Information</h4>
|
<h4 class="panel-title">Patient Information</h4>
|
||||||
<div class="panel-heading-btn">
|
<div class="panel-heading-btn">
|
||||||
|
<a href="{% url 'patients:patient_detail' object.patient.pk %}" class="btn btn-xs btn-outline-theme me-2">
|
||||||
|
View Profile
|
||||||
|
</a>
|
||||||
<a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-expand"><i class="fa fa-expand"></i></a>
|
<a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-expand"><i class="fa fa-expand"></i></a>
|
||||||
<a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-collapse"><i class="fa fa-minus"></i></a>
|
<a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-collapse"><i class="fa fa-minus"></i></a>
|
||||||
</div>
|
</div>
|
||||||
@ -381,11 +378,9 @@
|
|||||||
<div class="d-flex align-items-center mb-3">
|
<div class="d-flex align-items-center mb-3">
|
||||||
<div class="flex-fill">
|
<div class="flex-fill">
|
||||||
<div class="fw-bold">{{ object.patient.get_full_name }}</div>
|
<div class="fw-bold">{{ object.patient.get_full_name }}</div>
|
||||||
<div class="text-muted small">{{ object.patient.medical_record_number }}</div>
|
<div class="text-muted small">{{ object.patient.mrn }}</div>
|
||||||
</div>
|
</div>
|
||||||
<a href="{% url 'patients:patient_detail' object.patient.pk %}" class="btn btn-sm btn-outline-primary">
|
|
||||||
View Profile
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table class="table table-sm table-borderless">
|
<table class="table table-sm table-borderless">
|
||||||
@ -426,47 +421,47 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block js %}
|
{% block js %}
|
||||||
<script src="{% static 'assets/plugins/datatables.net/js/jquery.dataTables.min.js' %}"></script>
|
<script src="{% static 'plugins/datatables.net/js/dataTables.min.js' %}"></script>
|
||||||
<script src="{% static 'assets/plugins/datatables.net-bs5/js/dataTables.bootstrap5.min.js' %}"></script>
|
<script src="{% static 'plugins/datatables.net-bs5/js/dataTables.bootstrap5.min.js' %}"></script>
|
||||||
<script src="{% static 'assets/plugins/datatables.net-responsive/js/dataTables.responsive.min.js' %}"></script>
|
<script src="{% static 'plugins/datatables.net-responsive/js/dataTables.responsive.min.js' %}"></script>
|
||||||
<script src="{% static 'assets/plugins/datatables.net-responsive-bs5/js/responsive.bootstrap5.min.js' %}"></script>
|
<script src="{% static 'plugins/datatables.net-responsive-bs5/js/responsive.bootstrap5.min.js' %}"></script>
|
||||||
<script>
|
<script>
|
||||||
function updateStatus(newStatus) {
|
{#function updateStatus(newStatus) {#}
|
||||||
if (confirm('Are you sure you want to update the surgery status?')) {
|
{# if (confirm('Are you sure you want to update the surgery status?')) {#}
|
||||||
$.ajax({
|
{# $.ajax({#}
|
||||||
url: '{% url "inpatients:surgery_update_status" object.pk %}',
|
{# url: '{% url "inpatients:surgery_update_status" object.pk %}',#}
|
||||||
method: 'POST',
|
{# method: 'POST',#}
|
||||||
data: {
|
{# data: {#}
|
||||||
'status': newStatus,
|
{# 'status': newStatus,#}
|
||||||
'csrfmiddlewaretoken': '{{ csrf_token }}'
|
{# 'csrfmiddlewaretoken': '{{ csrf_token }}'#}
|
||||||
},
|
{# },#}
|
||||||
success: function(response) {
|
{# success: function(response) {#}
|
||||||
if (response.success) {
|
{# if (response.success) {#}
|
||||||
toastr.success('Surgery status updated successfully');
|
{# toastr.success('Surgery status updated successfully');#}
|
||||||
location.reload();
|
{# location.reload();#}
|
||||||
} else {
|
{# } else {#}
|
||||||
toastr.error('Failed to update surgery status');
|
{# toastr.error('Failed to update surgery status');#}
|
||||||
}
|
{# }#}
|
||||||
},
|
{# },#}
|
||||||
error: function() {
|
{# error: function() {#}
|
||||||
toastr.error('An error occurred while updating the status');
|
{# toastr.error('An error occurred while updating the status');#}
|
||||||
}
|
{# }#}
|
||||||
});
|
{# });#}
|
||||||
}
|
{# }#}
|
||||||
}
|
{# }#}
|
||||||
|
|
||||||
function printSurgery() {
|
{#function printSurgery() {#}
|
||||||
window.print();
|
{# window.print();#}
|
||||||
}
|
{# }#}
|
||||||
|
{##}
|
||||||
$(document).ready(function() {
|
{#$(document).ready(function() {#}
|
||||||
// Auto-refresh timeline every 30 seconds for active surgeries
|
{# // Auto-refresh timeline every 30 seconds for active surgeries#}
|
||||||
{% if object.status == 'in_progress' %}
|
{# {% if object.status == 'in_progress' %}#}
|
||||||
setInterval(function() {
|
{# setInterval(function() {#}
|
||||||
location.reload();
|
{# location.reload();#}
|
||||||
}, 30000);
|
{# }, 30000);#}
|
||||||
{% endif %}
|
{# {% endif %}#}
|
||||||
});
|
{# });#}
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|||||||
@ -4,21 +4,13 @@
|
|||||||
{% block title %}{{ object|yesno:"Edit,Create" }} Surgery - Inpatients{% endblock %}
|
{% block title %}{{ object|yesno:"Edit,Create" }} Surgery - Inpatients{% endblock %}
|
||||||
|
|
||||||
{% block css %}
|
{% block css %}
|
||||||
<link href="{% static 'assets/plugins/select2/dist/css/select2.min.css' %}" rel="stylesheet" />
|
<link href="{% static 'plugins/select2/dist/css/select2.min.css' %}" rel="stylesheet" />
|
||||||
<link href="{% static 'assets/plugins/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css' %}" rel="stylesheet" />
|
<link href="{% static 'plugins/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css' %}" rel="stylesheet" />
|
||||||
<link href="{% static 'assets/plugins/bootstrap-timepicker/css/bootstrap-timepicker.min.css' %}" rel="stylesheet" />
|
<link href="{% static 'plugins/bootstrap-timepicker/css/bootstrap-timepicker.min.css' %}" rel="stylesheet" />
|
||||||
<link href="{% static 'assets/plugins/summernote/dist/summernote-lite.css' %}" rel="stylesheet" />
|
<link href="{% static 'plugins/summernote/dist/summernote-lite.css' %}" rel="stylesheet" />
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% 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 'inpatients:dashboard' %}">Inpatients</a></li>
|
|
||||||
<li class="breadcrumb-item"><a href="{% url 'inpatients:surgery_list' %}">Surgeries</a></li>
|
|
||||||
<li class="breadcrumb-item active">{{ object|yesno:"Edit,Create" }} Surgery</li>
|
|
||||||
</ol>
|
|
||||||
<!-- END breadcrumb -->
|
|
||||||
|
|
||||||
<!-- BEGIN page-header -->
|
<!-- BEGIN page-header -->
|
||||||
<h1 class="page-header">{{ object|yesno:"Edit,Create" }} Surgery</h1>
|
<h1 class="page-header">{{ object|yesno:"Edit,Create" }} Surgery</h1>
|
||||||
@ -48,10 +40,10 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<label class="form-label" for="{{ form.surgeon.id_for_label }}">Primary Surgeon <span class="text-danger">*</span></label>
|
<label class="form-label" for="{{ form.primary_surgeon.id_for_label }}">Primary Surgeon <span class="text-danger">*</span></label>
|
||||||
{{ form.surgeon }}
|
{{ form.primary_surgeon }}
|
||||||
{% if form.surgeon.errors %}
|
{% if form.primary_surgeon.errors %}
|
||||||
<div class="invalid-feedback d-block">{{ form.surgeon.errors.0 }}</div>
|
<div class="invalid-feedback d-block">{{ form.primary_surgeon.errors.0 }}</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -218,9 +210,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="alert alert-info">
|
<div>
|
||||||
<h6><i class="fa fa-info-circle me-2"></i>Scheduling Guidelines</h6>
|
<div class="note alert-info p-3 note-with-end-icon">
|
||||||
<ul class="mb-0">
|
<div class="note-icon"><i class="fa fa-info-circle"></i></div>
|
||||||
|
<h6>Scheduling Guidelines</h6>
|
||||||
|
<ul class="">
|
||||||
<li>Schedule surgeries at least 24 hours in advance for elective procedures</li>
|
<li>Schedule surgeries at least 24 hours in advance for elective procedures</li>
|
||||||
<li>Emergency surgeries can be scheduled immediately</li>
|
<li>Emergency surgeries can be scheduled immediately</li>
|
||||||
<li>Verify patient consent and pre-operative requirements</li>
|
<li>Verify patient consent and pre-operative requirements</li>
|
||||||
@ -228,18 +222,20 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="alert alert-warning">
|
<div class="note alert-warning p-3 note-with-end-icon">
|
||||||
<h6><i class="fa fa-exclamation-triangle me-2"></i>Urgency Levels</h6>
|
<div class="note-icon"><i class="fa fa-exclamation-triangle"></i></div>
|
||||||
<ul class="mb-0">
|
<h6>Urgency Levels</h6>
|
||||||
|
<ul class="">
|
||||||
<li><strong>Emergency:</strong> Life-threatening, immediate surgery required</li>
|
<li><strong>Emergency:</strong> Life-threatening, immediate surgery required</li>
|
||||||
<li><strong>Urgent:</strong> Surgery needed within 24 hours</li>
|
<li><strong>Urgent:</strong> Surgery needed within 24 hours</li>
|
||||||
<li><strong>Elective:</strong> Planned surgery, can be scheduled in advance</li>
|
<li><strong>Elective:</strong> Planned surgery, can be scheduled in advance</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="alert alert-success">
|
<div class="note alert-success p-3 note-with-end-icon">
|
||||||
<h6><i class="fa fa-check-circle me-2"></i>Pre-operative Checklist</h6>
|
<div class="note-icon"><i class="fa fa-check-circle"></i></div>
|
||||||
<ul class="mb-0">
|
<h6>Pre-operative Checklist</h6>
|
||||||
|
<ul class="">
|
||||||
<li>Patient consent obtained and documented</li>
|
<li>Patient consent obtained and documented</li>
|
||||||
<li>Pre-operative assessment completed</li>
|
<li>Pre-operative assessment completed</li>
|
||||||
<li>Laboratory results reviewed</li>
|
<li>Laboratory results reviewed</li>
|
||||||
@ -248,30 +244,54 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{% if object %}
|
{% if object %}
|
||||||
<div class="alert alert-secondary">
|
<div class="note alert-secondary p-3 note-with-end-icon">
|
||||||
<h6><i class="fa fa-clock me-2"></i>Surgery Timeline</h6>
|
<div class="note-icon"><i class="fa fa-clock"></i></div>
|
||||||
<ul class="mb-0">
|
<h6>Surgery Timeline</h6>
|
||||||
|
<ul class="">
|
||||||
<li><strong>Created:</strong> {{ object.created_at|date:"M d, Y H:i" }}</li>
|
<li><strong>Created:</strong> {{ object.created_at|date:"M d, Y H:i" }}</li>
|
||||||
{% if object.updated_at != object.created_at %}
|
{% if object.updated_at != object.created_at %}
|
||||||
<li><strong>Last Updated:</strong> {{ object.updated_at|date:"M d, Y H:i" }}</li>
|
<li><strong>Last Updated:</strong> {{ object.updated_at|date:"M d, Y H:i" }}</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li><strong>Status:</strong> <span class="badge bg-{{ object.get_status_color }}">{{ object.get_status_display }}</span></li>
|
<li>
|
||||||
|
<strong>Status:</strong>
|
||||||
|
{% if object.status == 'SCHEDULED' %}
|
||||||
|
<span class="badge bg-warning">S
|
||||||
|
{% elif object.status == 'CONFIRMED' %}
|
||||||
|
<span class="badge bg-info">
|
||||||
|
{% elif object.status == 'PREP' %}
|
||||||
|
<span class="badge bg-primary">
|
||||||
|
{% elif object.status == 'IN_PROGRESS' %}
|
||||||
|
<span class="badge bg-success">
|
||||||
|
{% elif object.status == 'COMPLETED' %}
|
||||||
|
<span class="badge bg-success">
|
||||||
|
{% elif object.status == 'CANCELLED' %}
|
||||||
|
<span class="badge bg-danger">
|
||||||
|
{% elif object.status == 'POSTPONED' %}
|
||||||
|
<span class="badge bg-secondary">
|
||||||
|
{% else %}
|
||||||
|
<span class="badge bg-secondary">
|
||||||
|
{% endif %}
|
||||||
|
{{ object.get_status_display }}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<!-- END panel -->
|
<!-- END panel -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block js %}
|
{% block js %}
|
||||||
<script src="{% static 'assets/plugins/select2/dist/js/select2.min.js' %}"></script>
|
<script src="{% static 'plugins/select2/dist/js/select2.min.js' %}"></script>
|
||||||
<script src="{% static 'assets/plugins/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js' %}"></script>
|
<script src="{% static 'plugins/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js' %}"></script>
|
||||||
<script src="{% static 'assets/plugins/bootstrap-timepicker/js/bootstrap-timepicker.min.js' %}"></script>
|
<script src="{% static 'plugins/bootstrap-timepicker/js/bootstrap-timepicker.min.js' %}"></script>
|
||||||
<script src="{% static 'assets/plugins/summernote/dist/summernote-lite.min.js' %}"></script>
|
<script src="{% static 'plugins/summernote/dist/summernote-lite.min.js' %}"></script>
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
// Initialize Select2
|
// Initialize Select2
|
||||||
@ -281,71 +301,71 @@ $(document).ready(function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Initialize date picker
|
// Initialize date picker
|
||||||
$('input[type="date"]').datepicker({
|
{#$('input[type="date"]').datepicker({#}
|
||||||
format: 'yyyy-mm-dd',
|
{# format: 'yyyy-mm-dd',#}
|
||||||
autoclose: true,
|
{# autoclose: true,#}
|
||||||
todayHighlight: true,
|
{# todayHighlight: true,#}
|
||||||
startDate: new Date()
|
{# startDate: new Date()#}
|
||||||
});
|
{# });#}
|
||||||
|
|
||||||
// Initialize time picker
|
// Initialize time picker
|
||||||
$('input[type="time"]').timepicker({
|
{#$('input[type="time"]').timepicker({#}
|
||||||
showMeridian: false,
|
{# showMeridian: false,#}
|
||||||
defaultTime: false
|
{# defaultTime: false#}
|
||||||
});
|
{# });#}
|
||||||
|
|
||||||
// Initialize Summernote
|
// Initialize Summernote
|
||||||
$('.summernote').summernote({
|
{#$('.summernote').summernote({#}
|
||||||
height: 150,
|
{# height: 150,#}
|
||||||
toolbar: [
|
{# toolbar: [#}
|
||||||
['style', ['style']],
|
{# ['style', ['style']],#}
|
||||||
['font', ['bold', 'italic', 'underline', 'clear']],
|
{# ['font', ['bold', 'italic', 'underline', 'clear']],#}
|
||||||
['para', ['ul', 'ol', 'paragraph']],
|
{# ['para', ['ul', 'ol', 'paragraph']],#}
|
||||||
['insert', ['link']],
|
{# ['insert', ['link']],#}
|
||||||
['view', ['fullscreen', 'codeview']]
|
{# ['view', ['fullscreen', 'codeview']]#}
|
||||||
]
|
{# ]#}
|
||||||
});
|
{# });#}
|
||||||
|
|
||||||
// Form validation
|
// Form validation
|
||||||
$('#surgery-form').on('submit', function(e) {
|
{#$('#surgery-form').on('submit', function(e) {#}
|
||||||
var isValid = true;
|
{# var isValid = true;#}
|
||||||
var requiredFields = ['patient', 'surgeon', 'procedure_name', 'scheduled_date', 'scheduled_start_time'];
|
{# var requiredFields = ['patient', 'surgeon', 'procedure_name', 'scheduled_date', 'scheduled_start_time'];#}
|
||||||
|
{# #}
|
||||||
requiredFields.forEach(function(field) {
|
{# requiredFields.forEach(function(field) {#}
|
||||||
var input = $('[name="' + field + '"]');
|
{# var input = $('[name="' + field + '"]');#}
|
||||||
if (!input.val()) {
|
{# if (!input.val()) {#}
|
||||||
input.addClass('is-invalid');
|
{# input.addClass('is-invalid');#}
|
||||||
isValid = false;
|
{# isValid = false;#}
|
||||||
} else {
|
{# } else {#}
|
||||||
input.removeClass('is-invalid');
|
{# input.removeClass('is-invalid');#}
|
||||||
}
|
{# }#}
|
||||||
});
|
{# });#}
|
||||||
|
{##}
|
||||||
if (!isValid) {
|
{# if (!isValid) {#}
|
||||||
e.preventDefault();
|
{# e.preventDefault();#}
|
||||||
toastr.error('Please fill in all required fields.');
|
{# toastr.error('Please fill in all required fields.');#}
|
||||||
}
|
{# }#}
|
||||||
});
|
{# });#}
|
||||||
|
|
||||||
// Real-time validation
|
// Real-time validation
|
||||||
$('input, select, textarea').on('change blur', function() {
|
{#$('input, select, textarea').on('change blur', function() {#}
|
||||||
if ($(this).val()) {
|
{# if ($(this).val()) {#}
|
||||||
$(this).removeClass('is-invalid');
|
{# $(this).removeClass('is-invalid');#}
|
||||||
}
|
{# }#}
|
||||||
});
|
{# });#}
|
||||||
|
|
||||||
// Check for scheduling conflicts
|
// Check for scheduling conflicts
|
||||||
$('#id_scheduled_date, #id_scheduled_start_time, #id_operating_room').on('change', function() {
|
{#$('#id_scheduled_date, #id_scheduled_start_time, #id_operating_room').on('change', function() {#}
|
||||||
var date = $('#id_scheduled_date').val();
|
{# var date = $('#id_scheduled_date').val();#}
|
||||||
var time = $('#id_scheduled_start_time').val();
|
{# var time = $('#id_scheduled_start_time').val();#}
|
||||||
var room = $('#id_operating_room').val();
|
{# var room = $('#id_operating_room').val();#}
|
||||||
|
{# #}
|
||||||
if (date && time && room) {
|
{# if (date && time && room) {#}
|
||||||
// Check for conflicts (this would be an AJAX call in a real implementation)
|
{# // Check for conflicts (this would be an AJAX call in a real implementation)#}
|
||||||
// For now, just show a placeholder message
|
{# // For now, just show a placeholder message#}
|
||||||
console.log('Checking for scheduling conflicts...');
|
{# console.log('Checking for scheduling conflicts...');#}
|
||||||
}
|
{# }#}
|
||||||
});
|
{# });#}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@ -120,7 +120,8 @@
|
|||||||
title="Confirm Surgery"
|
title="Confirm Surgery"
|
||||||
hx-post="{% url 'inpatients:confirm_surgery' surgery.id %}"
|
hx-post="{% url 'inpatients:confirm_surgery' surgery.id %}"
|
||||||
hx-confirm="Confirm this surgery?"
|
hx-confirm="Confirm this surgery?"
|
||||||
hx-swap="none">
|
hx-swap="none"
|
||||||
|
hx-headers='{"X-CSRFToken":"{{ csrf_token }}"}'>
|
||||||
<i class="fas fa-check"></i>
|
<i class="fas fa-check"></i>
|
||||||
</button>
|
</button>
|
||||||
{% elif surgery.status == 'CONFIRMED' %}
|
{% elif surgery.status == 'CONFIRMED' %}
|
||||||
@ -128,7 +129,8 @@
|
|||||||
title="Start Prep"
|
title="Start Prep"
|
||||||
hx-post="{% url 'inpatients:start_surgery_prep' surgery.id %}"
|
hx-post="{% url 'inpatients:start_surgery_prep' surgery.id %}"
|
||||||
hx-confirm="Start surgery prep?"
|
hx-confirm="Start surgery prep?"
|
||||||
hx-swap="none">
|
hx-swap="none"
|
||||||
|
hx-headers='{"X-CSRFToken":"{{ csrf_token }}"}'>
|
||||||
<i class="fas fa-play"></i>
|
<i class="fas fa-play"></i>
|
||||||
</button>
|
</button>
|
||||||
{% elif surgery.status == 'PREP' %}
|
{% elif surgery.status == 'PREP' %}
|
||||||
@ -136,7 +138,8 @@
|
|||||||
title="Start Surgery"
|
title="Start Surgery"
|
||||||
hx-post="{% url 'inpatients:start_surgery' surgery.id %}"
|
hx-post="{% url 'inpatients:start_surgery' surgery.id %}"
|
||||||
hx-confirm="Start surgery?"
|
hx-confirm="Start surgery?"
|
||||||
hx-swap="none">
|
hx-swap="none"
|
||||||
|
hx-headers='{"X-CSRFToken":"{{ csrf_token }}"}'>
|
||||||
<i class="fas fa-procedures"></i>
|
<i class="fas fa-procedures"></i>
|
||||||
</button>
|
</button>
|
||||||
{% elif surgery.status == 'IN_PROGRESS' %}
|
{% elif surgery.status == 'IN_PROGRESS' %}
|
||||||
@ -144,7 +147,8 @@
|
|||||||
title="Complete Surgery"
|
title="Complete Surgery"
|
||||||
hx-post="{% url 'inpatients:complete_surgery' surgery.id %}"
|
hx-post="{% url 'inpatients:complete_surgery' surgery.id %}"
|
||||||
hx-confirm="Complete surgery?"
|
hx-confirm="Complete surgery?"
|
||||||
hx-swap="none">
|
hx-swap="none"
|
||||||
|
hx-headers='{"X-CSRFToken":"{{ csrf_token }}"}'>
|
||||||
<i class="fas fa-check-circle"></i>
|
<i class="fas fa-check-circle"></i>
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -154,18 +158,19 @@
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
{% if surgery.status not in 'COMPLETED,CANCELLED' %}
|
{% if surgery.status not in 'COMPLETED,CANCELLED' %}
|
||||||
<button class="btn btn-outline-warning"
|
{# <button class="btn btn-outline-warning" #}
|
||||||
title="Postpone"
|
{# title="Postpone"#}
|
||||||
hx-post="{% url 'inpatients:postpone_surgery' surgery.id %}"
|
{# hx-post="{% url 'inpatients:s' surgery.id %}"#}
|
||||||
hx-confirm="Postpone this surgery?"
|
{# hx-confirm="Postpone this surgery?"#}
|
||||||
hx-swap="none">
|
{# hx-swap="none">#}
|
||||||
<i class="fas fa-clock"></i>
|
{# <i class="fas fa-clock"></i>#}
|
||||||
</button>
|
{# </button>#}
|
||||||
<button class="btn btn-outline-danger"
|
<button class="btn btn-outline-danger"
|
||||||
title="Cancel"
|
title="Cancel"
|
||||||
hx-post="{% url 'inpatients:cancel_surgery' surgery.id %}"
|
hx-post="{% url 'inpatients:cancel_surgery' surgery.id %}"
|
||||||
hx-confirm="Cancel this surgery?"
|
hx-confirm="Cancel this surgery?"
|
||||||
hx-swap="none">
|
hx-swap="none"
|
||||||
|
hx-headers='{"X-CSRFToken":"{{ csrf_token }}"}'>
|
||||||
<i class="fas fa-times"></i>
|
<i class="fas fa-times"></i>
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Title</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -8,19 +8,31 @@ from . import views
|
|||||||
app_name = 'inpatients'
|
app_name = 'inpatients'
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
# Main views
|
# Main views
|
||||||
path('', views.InpatientDashboardView.as_view(), name='dashboard'),
|
path('', views.InpatientDashboardView.as_view(), name='dashboard'),
|
||||||
|
# wards
|
||||||
path('wards/', views.WardListView.as_view(), name='ward_list'),
|
path('wards/', views.WardListView.as_view(), name='ward_list'),
|
||||||
path('wards/<int:pk>/', views.WardDetailView.as_view(), name='ward_detail'),
|
path('wards/<int:pk>/', views.WardDetailView.as_view(), name='ward_detail'),
|
||||||
path('beds/', views.BedManagementView.as_view(), name='bed_management'),
|
path('wards/stats/', views.ward_stats, name='ward_stats'),
|
||||||
|
|
||||||
|
# Admissions
|
||||||
path('admissions/', views.AdmissionListView.as_view(), name='admission_list'),
|
path('admissions/', views.AdmissionListView.as_view(), name='admission_list'),
|
||||||
path('admissions/<int:pk>/', views.AdmissionDetailView.as_view(), name='admission_detail'),
|
path('admissions/<int:pk>/', views.AdmissionDetailView.as_view(), name='admission_detail'),
|
||||||
path('admissions/create/', views.AdmissionCreateView.as_view(), name='admission_create'),
|
path('admissions/create/', views.AdmissionCreateView.as_view(), name='admission_create'),
|
||||||
path('admissions/<int:pk>/edit/', views.AdmissionUpdateView.as_view(), name='admission_update'),
|
path('admissions/<int:pk>/edit/', views.AdmissionUpdateView.as_view(), name='admission_update'),
|
||||||
|
path('admission/search/', views.admission_search, name='admission_search'),
|
||||||
|
|
||||||
|
path('discharge/<int:admission_id>/', views.discharge_patient, name='discharge_patient'),
|
||||||
|
|
||||||
|
|
||||||
path('transfers/', views.TransferManagementView.as_view(), name='transfer_management'),
|
path('transfers/', views.TransferManagementView.as_view(), name='transfer_management'),
|
||||||
path('surgery/', views.SurgeryScheduleView.as_view(), name='surgery_schedule'),
|
path('transfer/<int:admission_id>/', views.transfer_patient, name='transfer_patient'),
|
||||||
|
path('transfers/<int:transfer_id>/approve/', views.approve_transfer, name='approve_transfer'),
|
||||||
|
path('transfers/<int:transfer_id>/complete/', views.complete_transfer, name='complete_transfer'),
|
||||||
|
|
||||||
|
|
||||||
# Beds
|
# Beds
|
||||||
|
path('beds/', views.BedManagementView.as_view(), name='bed_management'),
|
||||||
path('beds/', views.BedListView.as_view(), name='bed_list'),
|
path('beds/', views.BedListView.as_view(), name='bed_list'),
|
||||||
path('beds/create/', views.BedCreateView.as_view(), name='bed_create'),
|
path('beds/create/', views.BedCreateView.as_view(), name='bed_create'),
|
||||||
path('beds/<int:pk>/', views.BedDetailView.as_view(), name='bed_detail'),
|
path('beds/<int:pk>/', views.BedDetailView.as_view(), name='bed_detail'),
|
||||||
@ -30,19 +42,24 @@ urlpatterns = [
|
|||||||
path('beds/<int:pk>/block/', views.block_bed, name='block_bed'),
|
path('beds/<int:pk>/block/', views.block_bed, name='block_bed'),
|
||||||
path('beds/<int:pk>/unblock/', views.unblock_bed, name='unblock_bed'),
|
path('beds/<int:pk>/unblock/', views.unblock_bed, name='unblock_bed'),
|
||||||
path('beds/<int:pk>/maintenance/', views.maintenance_bed, name='maintenance_bed'),
|
path('beds/<int:pk>/maintenance/', views.maintenance_bed, name='maintenance_bed'),
|
||||||
|
path('beds/grid/', views.bed_grid, name='bed_grid'),
|
||||||
|
path('beds/<int:bed_id>/status/', views.update_bed_status, name='update_bed_status'),
|
||||||
|
|
||||||
# HTMX endpoints
|
|
||||||
path('stats/', views.ward_stats, name='ward_stats'),
|
|
||||||
path('bed-grid/', views.bed_grid, name='bed_grid'),
|
path('surgery/', views.SurgeryScheduleView.as_view(), name='surgery_schedule'),
|
||||||
path('admission-search/', views.admission_search, name='admission_search'),
|
path('surgery/list/', views.SurgeryScheduleListView.as_view(), name='surgery_list'),
|
||||||
path('surgery-calendar/', views.surgery_calendar, name='surgery_calendar'),
|
path('surgery/<int:pk>/', views.SurgeryScheduleDetailView.as_view(), name='surgery_detail'),
|
||||||
|
path('surgery/<int:pk>/edit/', views.SurgeryScheduleUpdateView.as_view(), name='surgery_update'),
|
||||||
|
path('surgery/create/', views.SurgeryScheduleCreateView.as_view(), name='surgery_create'),
|
||||||
|
path('surgery/calendar/', views.surgery_calendar, name='surgery_calendar'),
|
||||||
|
path('surgery/<int:pk>/cancel/', views.cancel_surgery, name='cancel_surgery'),
|
||||||
|
|
||||||
# Actions
|
# Actions
|
||||||
path('transfer/<int:admission_id>/', views.transfer_patient, name='transfer_patient'),
|
|
||||||
path('discharge/<int:pk>/', views.discharge_patient, name='discharge_patient'),
|
|
||||||
path('transfer/<int:transfer_id>/approve/', views.approve_transfer, name='approve_transfer'),
|
|
||||||
path('transfer/<int:transfer_id>/complete/', views.complete_transfer, name='complete_transfer'),
|
|
||||||
path('bed/<int:bed_id>/status/', views.update_bed_status, name='update_bed_status'),
|
|
||||||
|
|
||||||
# API endpoints
|
# API endpoints
|
||||||
# path('api/', include('inpatients.api.urls')),
|
# path('api/', include('inpatients.api.urls')),
|
||||||
|
|||||||
1550
inpatients/views.py
1550
inpatients/views.py
File diff suppressed because it is too large
Load Diff
@ -252,7 +252,7 @@ def create_saudi_admissions(tenants, beds, admissions_per_tenant=100):
|
|||||||
for tenant in tenants:
|
for tenant in tenants:
|
||||||
# Get patients and staff for this tenant
|
# Get patients and staff for this tenant
|
||||||
patients = list(PatientProfile.objects.filter(tenant=tenant))
|
patients = list(PatientProfile.objects.filter(tenant=tenant))
|
||||||
physicians = list(User.objects.filter(tenant=tenant, employee_profile__role='PHYSICIAN'))
|
physicians = list(User.objects.filter(tenant=tenant, employee_profile__role__in=['PHYSICIAN', 'PHYSICIAN_ASSISTANT']))
|
||||||
nurses = list(User.objects.filter(tenant=tenant, employee_profile__role__in=['NURSE', 'NURSE_PRACTITIONER']))
|
nurses = list(User.objects.filter(tenant=tenant, employee_profile__role__in=['NURSE', 'NURSE_PRACTITIONER']))
|
||||||
tenant_beds = [bed for bed in beds if bed.ward.tenant == tenant]
|
tenant_beds = [bed for bed in beds if bed.ward.tenant == tenant]
|
||||||
|
|
||||||
@ -587,7 +587,7 @@ def create_saudi_surgery_schedules(tenants, surgeries_per_tenant=30):
|
|||||||
surgeons = list(User.objects.filter(tenant=tenant, employee_profile__role='PHYSICIAN'))
|
surgeons = list(User.objects.filter(tenant=tenant, employee_profile__role='PHYSICIAN'))
|
||||||
anesthesiologists = list(User.objects.filter(tenant=tenant, employee_profile__role='PHYSICIAN'))
|
anesthesiologists = list(User.objects.filter(tenant=tenant, employee_profile__role='PHYSICIAN'))
|
||||||
nurses = list(User.objects.filter(tenant=tenant, employee_profile__role__in=['NURSE', 'NURSE_PRACTITIONER']))
|
nurses = list(User.objects.filter(tenant=tenant, employee_profile__role__in=['NURSE', 'NURSE_PRACTITIONER']))
|
||||||
admissions = list(Admission.objects.filter(tenant=tenant, status='active'))
|
admissions = list(Admission.objects.filter(tenant=tenant, status='ADMITTED'))
|
||||||
|
|
||||||
if not patients or not surgeons or not nurses or not admissions:
|
if not patients or not surgeons or not nurses or not admissions:
|
||||||
print(f"Insufficient data for tenant {tenant.name}: patients={len(patients)}, surgeons={len(surgeons)}, nurses={len(nurses)}, admissions={len(admissions)}")
|
print(f"Insufficient data for tenant {tenant.name}: patients={len(patients)}, surgeons={len(surgeons)}, nurses={len(nurses)}, admissions={len(admissions)}")
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user