This commit is contained in:
Marwan Alwali 2025-09-17 14:55:43 +03:00
parent 2780a2dc7c
commit 2b4c58aa34
46 changed files with 8030 additions and 2407 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@ -27,6 +27,19 @@ def add_class(field, 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
def sum_values(queryset, field_names):
"""

Binary file not shown.

Binary file not shown.

View File

@ -210,25 +210,25 @@ class CarePlanForm(forms.ModelForm):
'approved', 'approved_by'
]
widgets = {
'start_date': forms.DateInput(attrs={'type': 'date'}),
'end_date': forms.DateInput(attrs={'type': 'date'}),
'target_completion_date': forms.DateInput(attrs={'type': 'date'}),
'last_reviewed': forms.DateInput(attrs={'type': 'date'}),
'next_review_date': forms.DateInput(attrs={'type': 'date'}),
'description': forms.Textarea(attrs={'rows': 3}),
'patient_goals': forms.Textarea(attrs={'rows': 3}),
'patient_preferences': forms.Textarea(attrs={'rows': 3}),
'patient_barriers': forms.Textarea(attrs={'rows': 3}),
'progress_notes': forms.Textarea(attrs={'rows': 3}),
'goals': forms.Textarea(attrs={'rows': 3}),
'objectives': forms.Textarea(attrs={'rows': 3}),
'interventions': forms.Textarea(attrs={'rows': 3}),
'activities': forms.Textarea(attrs={'rows': 3}),
'monitoring_parameters': forms.Textarea(attrs={'rows': 3}),
'evaluation_criteria': forms.Textarea(attrs={'rows': 3}),
'resources_needed': forms.Textarea(attrs={'rows': 3}),
'support_systems': forms.Textarea(attrs={'rows': 3}),
'outcomes_achieved': forms.Textarea(attrs={'rows': 3}),
'start_date': forms.DateInput(attrs={'type': 'date', 'class':'form-control form control-sm'}),
'end_date': forms.DateInput(attrs={'type': 'date', 'class':'form-control form control-sm'}),
'target_completion_date': forms.DateInput(attrs={'type': 'date', 'class':'form-control form control-sm'}),
'last_reviewed': forms.DateInput(attrs={'type': 'date', 'class':'form-control form control-sm'}),
'next_review_date': forms.DateInput(attrs={'type': 'date', 'class':'form-control form control-sm'}),
'description': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
'patient_goals': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
'patient_preferences': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
'patient_barriers': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
'progress_notes': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
'goals': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
'objectives': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
'interventions': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
'activities': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
'monitoring_parameters': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
'evaluation_criteria': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
'resources_needed': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
'support_systems': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
'outcomes_achieved': forms.Textarea(attrs={'rows': 3, 'class':'form-control form control-sm'}),
}
def __init__(self, *args, **kwargs):

View File

@ -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:;">&nbsp;</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 %}

View 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:;">&nbsp;</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 %}

View File

@ -88,16 +88,7 @@
{% 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">
{% if form.instance.id %}Edit Care Plan{% else %}New Care Plan{% endif %}
</li>
</ol>
<!-- end breadcrumb -->
<!-- begin page-header -->
<h1 class="page-header">

View File

@ -4,17 +4,30 @@
{% block title %}Care Plans - {{ block.super }}{% endblock %}
{% 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="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title mb-0">
<i class="fas fa-clipboard-list me-2"></i>Care Plan Management
</h4>
</div>
<div class="card-body">
<div class="panel panel-inverse" data-sortable-id="index-1">
<div class="panel-heading">
<h4 class="panel-title"><i class="fas fa-clipboard-list me-2"></i>All Care Plans</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>
<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">
<!-- Filters -->
<div class="row mb-3">
<div class="col-md-2">
@ -128,20 +141,20 @@
</td>
<td>
<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>
</button>
</a>
{% if plan.status == 'ACTIVE' %}
<button class="btn btn-outline-info" title="Update Progress">
<i class="fas fa-chart-line"></i>
</button>
<button class="btn btn-outline-success"
title="Mark Complete"
hx-post="{% url 'emr:complete_care_plan' plan.id %}"
hx-confirm="Mark this care plan as complete?"
hx-swap="none">
<i class="fas fa-check"></i>
</button>
{# <button class="btn btn-outline-success" #}
{# title="Mark Complete"#}
{# hx-post="{% url 'emr:complete_care_plan' plan.id %}"#}
{# hx-confirm="Mark this care plan as complete?"#}
{# hx-swap="none">#}
{# <i class="fas fa-check"></i>#}
{# </button>#}
{% endif %}
<button class="btn btn-outline-secondary" title="Notes">
<i class="fas fa-sticky-note"></i>
@ -164,33 +177,7 @@
<!-- Pagination -->
{% if is_paginated %}
<nav aria-label="Care plan pagination">
<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>
{% include 'partial/pagination.html' %}
{% endif %}
</div>
</div>

View File

@ -71,14 +71,6 @@
{% 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:problem_list' %}">Problems</a></li>
<li class="breadcrumb-item active">{{ problem.problem_name }}</li>
</ol>
<!-- end breadcrumb -->
<!-- begin page-header -->
<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">
<i class="fa fa-arrow-left me-1"></i> Back to Problem List
</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
</a>
</div>
@ -392,7 +384,7 @@
<h5 class="modal-title" id="resolveModalLabel">Resolve Problem</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form action="{% url 'emr:problem_resolve' problem.id %}" method="post">
<form action="" method="post">
{% csrf_token %}
<div class="modal-body">
<div class="mb-3">

View File

@ -19,8 +19,17 @@ urlpatterns = [
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('vital-signs/<int:pk>/', views.VitalSignsDetailView.as_view(), name='vital_signs_detail'),
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/<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/<int:pk>/', views.ClinicalNoteDetailView.as_view(), name='clinical_note_detail'),
path('notes/<int:pk>/update/', views.ClinicalNoteUpdateView.as_view(), name='clinical_note_update'),

File diff suppressed because it is too large Load Diff

View 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,
),
),
]

View File

@ -56,9 +56,24 @@ class Employee(models.Model):
SUPER_ADMIN = 'SUPER_ADMIN', 'Super Administrator'
ADMIN = 'ADMIN', 'Administrator'
PHYSICIAN = 'PHYSICIAN', 'Physician'
SURGEON = 'SURGEON', 'Surgeon'
NURSE = 'NURSE', 'Nurse'
NURSE_PRACTITIONER = 'NURSE_PRACTITIONER', 'Nurse Practitioner'
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'
PHARMACY_TECH = 'PHARMACY_TECH', 'Pharmacy Technician'
LAB_TECH = 'LAB_TECH', 'Laboratory Technician'

View File

@ -153,7 +153,6 @@ class AdmissionForm(forms.ModelForm):
is_accepting_admissions=True
).order_by('name')
# Initialize empty bed queryset - will be populated via AJAX
self.fields['current_bed'].queryset = Bed.objects.filter(
ward__tenant=user.tenant,
status='AVAILABLE'
@ -162,13 +161,13 @@ class AdmissionForm(forms.ModelForm):
self.fields['admitting_physician'].queryset = User.objects.filter(
tenant=user.tenant,
is_active=True,
role__in=['DOCTOR', 'SPECIALIST']
employee_profile__role__in=['PHYSICIAN', 'PHYSICIAN_ASSISTANT']
).order_by('last_name', 'first_name')
self.fields['attending_physician'].queryset = User.objects.filter(
tenant=user.tenant,
is_active=True,
role__in=['DOCTOR', 'SPECIALIST']
employee_profile__role__in=['PHYSICIAN', 'PHYSICIAN_ASSISTANT']
).order_by('last_name', 'first_name')
def clean_admission_datetime(self):
@ -402,13 +401,13 @@ class SurgeryScheduleForm(forms.ModelForm):
self.fields['primary_surgeon'].queryset = User.objects.filter(
tenant=user.tenant,
is_active=True,
role__in=['DOCTOR', 'SURGEON', 'SPECIALIST']
employee_profile__role__in=['PHYSICIAN', 'SURGEON', 'SPECIALIST']
).order_by('last_name', 'first_name')
self.fields['anesthesiologist'].queryset = User.objects.filter(
tenant=user.tenant,
is_active=True,
role__in=['DOCTOR', 'ANESTHESIOLOGIST']
employee_profile__role__in=['PHYSICIAN', 'ANESTHESIOLOGIST']
).order_by('last_name', 'first_name')
def clean_scheduled_date(self):

View File

@ -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,
),
),
]

View File

@ -849,8 +849,6 @@ class Admission(models.Model):
return self.status in ['PENDING', 'ADMITTED', 'TRANSFERRED']
class Transfer(models.Model):
"""
Patient transfer model for tracking ward/bed changes.
@ -1124,6 +1122,7 @@ class DischargeSummary(models.Model):
('REHAB_FACILITY', 'Rehabilitation Facility'),
('HOSPICE', 'Hospice'),
('TRANSFER', 'Transfer to Another Hospital'),
('MORGUE', 'Morgue'),
('OTHER', 'Other'),
]
TRANSPORTATION_METHOD_CHOICES = [

View File

@ -27,7 +27,7 @@
<i class="fas fa-cog me-2"></i>Quick Actions
</button>
<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
</a></li>
<li><a class="dropdown-item" href="{% url 'inpatients:bed_management' %}">
@ -154,10 +154,10 @@
<span class="visually-hidden">Toggle Dropdown</span>
</button>
<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
</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
</a></li>
<li><a class="dropdown-item" href="#">
@ -297,7 +297,7 @@
<small class="text-muted">{{ ward.get_ward_type_display }}</small>
</div>
<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>
</div>
</div>

View File

@ -1,5 +1,6 @@
{% extends 'base.html' %}
{% load static %}
{% block content %}
<!-- Surgery Calendar Partial -->
<div id="surgery-calendar-container">
<!-- Calendar Controls -->
@ -164,7 +165,7 @@ $(document).ready(function() {
// Event sources
events: function(start, end, timezone, callback) {
$.ajax({
url: '{% url "inpatients:surgery_calendar_data" %}',
url: '',
data: {
start: start.format(),
end: end.format()
@ -242,7 +243,7 @@ $(document).ready(function() {
// Load surgery quick view
function loadSurgeryQuickView(surgeryId) {
$.ajax({
url: '{% url "inpatients:surgery_quick_view" 0 %}'.replace('0', surgeryId),
url: ''.replace('0', surgeryId),
success: function(data) {
$('#surgery-quick-view-content').html(data.html);
$('#view-full-surgery').attr('href', data.detail_url);
@ -269,7 +270,7 @@ $(document).ready(function() {
function loadSelectOptions() {
// Load patients
$.ajax({
url: '{% url "patients:patient_list_api" %}',
url: '',
success: function(data) {
var patientSelect = $('select[name="patient"]');
patientSelect.empty().append('<option value="">Select Patient</option>');
@ -282,7 +283,7 @@ $(document).ready(function() {
// Load surgeons
$.ajax({
url: '{% url "users:surgeon_list_api" %}',
url: '',
success: function(data) {
var surgeonSelect = $('select[name="surgeon"]');
surgeonSelect.empty().append('<option value="">Select Surgeon</option>');
@ -295,7 +296,7 @@ $(document).ready(function() {
// Load operating rooms
$.ajax({
url: '{% url "inpatients:operating_room_list_api" %}',
url: '',
success: function(data) {
var roomSelect = $('select[name="operating_room"]');
roomSelect.empty().append('<option value="">Select OR</option>');
@ -311,7 +312,7 @@ $(document).ready(function() {
var formData = $('#quick-surgery-form').serialize();
$.ajax({
url: '{% url "inpatients:surgery_create_quick" %}',
url: '',
method: 'POST',
data: formData,
success: function(response) {
@ -419,3 +420,4 @@ $(document).ready(function() {
}
</style>
{% endblock %}

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
</html>

View File

@ -4,19 +4,13 @@
{% block title %}Surgery Details - {{ object.procedure_name }}{% endblock %}
{% block css %}
<link href="{% static 'assets/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-bs5/css/dataTables.bootstrap5.min.css' %}" rel="stylesheet" />
<link href="{% static 'plugins/datatables.net-responsive-bs5/css/responsive.bootstrap5.min.css' %}" rel="stylesheet" />
{% endblock %}
{% block content %}
<!-- BEGIN breadcrumb -->
<ol class="breadcrumb float-xl-end">
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
<li class="breadcrumb-item"><a href="{% url '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 -->
<h1 class="page-header">
@ -32,7 +26,7 @@
<div class="panel-heading">
<h4 class="panel-title">Surgery Information</h4>
<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
</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>
<td class="fw-bold">Primary Surgeon:</td>
<td>
<a href="{% url 'users:user_detail' object.surgeon.pk %}" class="text-decoration-none">
Dr. {{ object.surgeon.get_full_name }}
<a href="{% url 'hr:employee_detail' object.primary_surgeon.pk %}" class="text-decoration-none">
Dr. {{ object.primary_surgeon.get_full_name }}
</a>
</td>
</tr>
@ -148,8 +142,8 @@
<h6 class="mb-3">Medical Team</h6>
<div class="mb-3">
<strong>Primary Surgeon:</strong><br>
<a href="{% url 'users:user_detail' object.surgeon.pk %}" class="text-decoration-none">
Dr. {{ object.surgeon.get_full_name }}
<a href="{% url 'hr:employee_detail' object.primary_surgeon.pk %}" class="text-decoration-none">
Dr. {{ object.primary_surgeon.get_full_name }}
</a>
</div>
@ -157,7 +151,7 @@
<div class="mb-3">
<strong>Assistant Surgeons:</strong><br>
{% 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 }}
</a>{% if not forloop.last %}, {% endif %}
{% endfor %}
@ -167,7 +161,7 @@
{% if object.anesthesiologist %}
<div class="mb-3">
<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 }}
</a>
</div>
@ -179,7 +173,7 @@
<div class="mb-3">
<strong>Scrub Nurses:</strong><br>
{% 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 }}
</a>{% if not forloop.last %}, {% endif %}
{% endfor %}
@ -190,7 +184,7 @@
<div class="mb-3">
<strong>Circulating Nurses:</strong><br>
{% 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 }}
</a>{% if not forloop.last %}, {% endif %}
{% endfor %}
@ -275,18 +269,18 @@
<i class="fa fa-edit me-2"></i>Edit Surgery
</a>
{% if object.status == 'scheduled' %}
<button class="btn btn-success" onclick="updateStatus('in_progress')">
{% if object.status == 'SCHEDULED' %}
<button class="btn btn-success" onclick="updateStatus('IN_PROGRESS')">
<i class="fa fa-play me-2"></i>Start Surgery
</button>
{% elif object.status == 'in_progress' %}
<button class="btn btn-warning" onclick="updateStatus('completed')">
{% elif object.status == 'IN_PROGRESS' %}
<button class="btn btn-warning" onclick="updateStatus('COMPLETED')">
<i class="fa fa-check me-2"></i>Complete Surgery
</button>
{% endif %}
{% if object.status in 'scheduled,in_progress' %}
<button class="btn btn-danger" onclick="updateStatus('cancelled')">
{% if object.status in 'SCHEDULED,IN_PROGRESS' %}
<button class="btn btn-danger" onclick="updateStatus('CANCELLED')">
<i class="fa fa-times me-2"></i>Cancel Surgery
</button>
{% endif %}
@ -373,6 +367,9 @@
<div class="panel-heading">
<h4 class="panel-title">Patient Information</h4>
<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-collapse"><i class="fa fa-minus"></i></a>
</div>
@ -381,11 +378,9 @@
<div class="d-flex align-items-center mb-3">
<div class="flex-fill">
<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>
<a href="{% url 'patients:patient_detail' object.patient.pk %}" class="btn btn-sm btn-outline-primary">
View Profile
</a>
</div>
<table class="table table-sm table-borderless">
@ -426,47 +421,47 @@
{% endblock %}
{% block js %}
<script src="{% static 'assets/plugins/datatables.net/js/jquery.dataTables.min.js' %}"></script>
<script src="{% static 'assets/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 'assets/plugins/datatables.net-responsive-bs5/js/responsive.bootstrap5.min.js' %}"></script>
<script src="{% static 'plugins/datatables.net/js/dataTables.min.js' %}"></script>
<script src="{% static 'plugins/datatables.net-bs5/js/dataTables.bootstrap5.min.js' %}"></script>
<script src="{% static 'plugins/datatables.net-responsive/js/dataTables.responsive.min.js' %}"></script>
<script src="{% static 'plugins/datatables.net-responsive-bs5/js/responsive.bootstrap5.min.js' %}"></script>
<script>
function updateStatus(newStatus) {
if (confirm('Are you sure you want to update the surgery status?')) {
$.ajax({
url: '{% url "inpatients:surgery_update_status" object.pk %}',
method: 'POST',
data: {
'status': newStatus,
'csrfmiddlewaretoken': '{{ csrf_token }}'
},
success: function(response) {
if (response.success) {
toastr.success('Surgery status updated successfully');
location.reload();
} else {
toastr.error('Failed to update surgery status');
}
},
error: function() {
toastr.error('An error occurred while updating the status');
}
});
}
}
{#function updateStatus(newStatus) {#}
{# if (confirm('Are you sure you want to update the surgery status?')) {#}
{# $.ajax({#}
{# url: '{% url "inpatients:surgery_update_status" object.pk %}',#}
{# method: 'POST',#}
{# data: {#}
{# 'status': newStatus,#}
{# 'csrfmiddlewaretoken': '{{ csrf_token }}'#}
{# },#}
{# success: function(response) {#}
{# if (response.success) {#}
{# toastr.success('Surgery status updated successfully');#}
{# location.reload();#}
{# } else {#}
{# toastr.error('Failed to update surgery status');#}
{# }#}
{# },#}
{# error: function() {#}
{# toastr.error('An error occurred while updating the status');#}
{# }#}
{# });#}
{# }#}
{# }#}
function printSurgery() {
window.print();
}
$(document).ready(function() {
// Auto-refresh timeline every 30 seconds for active surgeries
{% if object.status == 'in_progress' %}
setInterval(function() {
location.reload();
}, 30000);
{% endif %}
});
{#function printSurgery() {#}
{# window.print();#}
{# }#}
{##}
{#$(document).ready(function() {#}
{# // Auto-refresh timeline every 30 seconds for active surgeries#}
{# {% if object.status == 'in_progress' %}#}
{# setInterval(function() {#}
{# location.reload();#}
{# }, 30000);#}
{# {% endif %}#}
{# });#}
</script>
{% endblock %}

View File

@ -4,21 +4,13 @@
{% block title %}{{ object|yesno:"Edit,Create" }} Surgery - Inpatients{% endblock %}
{% block css %}
<link href="{% static 'assets/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 'assets/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/select2/dist/css/select2.min.css' %}" rel="stylesheet" />
<link href="{% static 'plugins/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css' %}" rel="stylesheet" />
<link href="{% static 'plugins/bootstrap-timepicker/css/bootstrap-timepicker.min.css' %}" rel="stylesheet" />
<link href="{% static 'plugins/summernote/dist/summernote-lite.css' %}" rel="stylesheet" />
{% endblock %}
{% block content %}
<!-- BEGIN breadcrumb -->
<ol class="breadcrumb float-xl-end">
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
<li class="breadcrumb-item"><a href="{% url '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 -->
<h1 class="page-header">{{ object|yesno:"Edit,Create" }} Surgery</h1>
@ -48,10 +40,10 @@
{% endif %}
</div>
<div class="col-md-6">
<label class="form-label" for="{{ form.surgeon.id_for_label }}">Primary Surgeon <span class="text-danger">*</span></label>
{{ form.surgeon }}
{% if form.surgeon.errors %}
<div class="invalid-feedback d-block">{{ form.surgeon.errors.0 }}</div>
<label class="form-label" for="{{ form.primary_surgeon.id_for_label }}">Primary Surgeon <span class="text-danger">*</span></label>
{{ form.primary_surgeon }}
{% if form.primary_surgeon.errors %}
<div class="invalid-feedback d-block">{{ form.primary_surgeon.errors.0 }}</div>
{% endif %}
</div>
</div>
@ -218,9 +210,11 @@
</div>
</div>
<div class="panel-body">
<div class="alert alert-info">
<h6><i class="fa fa-info-circle me-2"></i>Scheduling Guidelines</h6>
<ul class="mb-0">
<div>
<div class="note alert-info p-3 note-with-end-icon">
<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>Emergency surgeries can be scheduled immediately</li>
<li>Verify patient consent and pre-operative requirements</li>
@ -228,18 +222,20 @@
</ul>
</div>
<div class="alert alert-warning">
<h6><i class="fa fa-exclamation-triangle me-2"></i>Urgency Levels</h6>
<ul class="mb-0">
<div class="note alert-warning p-3 note-with-end-icon">
<div class="note-icon"><i class="fa fa-exclamation-triangle"></i></div>
<h6>Urgency Levels</h6>
<ul class="">
<li><strong>Emergency:</strong> Life-threatening, immediate surgery required</li>
<li><strong>Urgent:</strong> Surgery needed within 24 hours</li>
<li><strong>Elective:</strong> Planned surgery, can be scheduled in advance</li>
</ul>
</div>
<div class="alert alert-success">
<h6><i class="fa fa-check-circle me-2"></i>Pre-operative Checklist</h6>
<ul class="mb-0">
<div class="note alert-success p-3 note-with-end-icon">
<div class="note-icon"><i class="fa fa-check-circle"></i></div>
<h6>Pre-operative Checklist</h6>
<ul class="">
<li>Patient consent obtained and documented</li>
<li>Pre-operative assessment completed</li>
<li>Laboratory results reviewed</li>
@ -248,19 +244,43 @@
</ul>
</div>
{% if object %}
<div class="alert alert-secondary">
<h6><i class="fa fa-clock me-2"></i>Surgery Timeline</h6>
<ul class="mb-0">
<div class="note alert-secondary p-3 note-with-end-icon">
<div class="note-icon"><i class="fa fa-clock"></i></div>
<h6>Surgery Timeline</h6>
<ul class="">
<li><strong>Created:</strong> {{ object.created_at|date:"M d, Y H:i" }}</li>
{% if object.updated_at != object.created_at %}
<li><strong>Last Updated:</strong> {{ object.updated_at|date:"M d, Y H:i" }}</li>
{% 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>
</div>
{% endif %}
</div>
</div>
</div>
<!-- END panel -->
</div>
@ -268,10 +288,10 @@
{% endblock %}
{% block js %}
<script src="{% static 'assets/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 'assets/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/select2/dist/js/select2.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap-timepicker/js/bootstrap-timepicker.min.js' %}"></script>
<script src="{% static 'plugins/summernote/dist/summernote-lite.min.js' %}"></script>
<script>
$(document).ready(function() {
// Initialize Select2
@ -281,71 +301,71 @@ $(document).ready(function() {
});
// Initialize date picker
$('input[type="date"]').datepicker({
format: 'yyyy-mm-dd',
autoclose: true,
todayHighlight: true,
startDate: new Date()
});
{#$('input[type="date"]').datepicker({#}
{# format: 'yyyy-mm-dd',#}
{# autoclose: true,#}
{# todayHighlight: true,#}
{# startDate: new Date()#}
{# });#}
// Initialize time picker
$('input[type="time"]').timepicker({
showMeridian: false,
defaultTime: false
});
{#$('input[type="time"]').timepicker({#}
{# showMeridian: false,#}
{# defaultTime: false#}
{# });#}
// Initialize Summernote
$('.summernote').summernote({
height: 150,
toolbar: [
['style', ['style']],
['font', ['bold', 'italic', 'underline', 'clear']],
['para', ['ul', 'ol', 'paragraph']],
['insert', ['link']],
['view', ['fullscreen', 'codeview']]
]
});
{#$('.summernote').summernote({#}
{# height: 150,#}
{# toolbar: [#}
{# ['style', ['style']],#}
{# ['font', ['bold', 'italic', 'underline', 'clear']],#}
{# ['para', ['ul', 'ol', 'paragraph']],#}
{# ['insert', ['link']],#}
{# ['view', ['fullscreen', 'codeview']]#}
{# ]#}
{# });#}
// Form validation
$('#surgery-form').on('submit', function(e) {
var isValid = true;
var requiredFields = ['patient', 'surgeon', 'procedure_name', 'scheduled_date', 'scheduled_start_time'];
requiredFields.forEach(function(field) {
var input = $('[name="' + field + '"]');
if (!input.val()) {
input.addClass('is-invalid');
isValid = false;
} else {
input.removeClass('is-invalid');
}
});
if (!isValid) {
e.preventDefault();
toastr.error('Please fill in all required fields.');
}
});
{#$('#surgery-form').on('submit', function(e) {#}
{# var isValid = true;#}
{# var requiredFields = ['patient', 'surgeon', 'procedure_name', 'scheduled_date', 'scheduled_start_time'];#}
{# #}
{# requiredFields.forEach(function(field) {#}
{# var input = $('[name="' + field + '"]');#}
{# if (!input.val()) {#}
{# input.addClass('is-invalid');#}
{# isValid = false;#}
{# } else {#}
{# input.removeClass('is-invalid');#}
{# }#}
{# });#}
{##}
{# if (!isValid) {#}
{# e.preventDefault();#}
{# toastr.error('Please fill in all required fields.');#}
{# }#}
{# });#}
// Real-time validation
$('input, select, textarea').on('change blur', function() {
if ($(this).val()) {
$(this).removeClass('is-invalid');
}
});
{#$('input, select, textarea').on('change blur', function() {#}
{# if ($(this).val()) {#}
{# $(this).removeClass('is-invalid');#}
{# }#}
{# });#}
// Check for scheduling conflicts
$('#id_scheduled_date, #id_scheduled_start_time, #id_operating_room').on('change', function() {
var date = $('#id_scheduled_date').val();
var time = $('#id_scheduled_start_time').val();
var room = $('#id_operating_room').val();
if (date && time && room) {
// Check for conflicts (this would be an AJAX call in a real implementation)
// For now, just show a placeholder message
console.log('Checking for scheduling conflicts...');
}
});
{#$('#id_scheduled_date, #id_scheduled_start_time, #id_operating_room').on('change', function() {#}
{# var date = $('#id_scheduled_date').val();#}
{# var time = $('#id_scheduled_start_time').val();#}
{# var room = $('#id_operating_room').val();#}
{# #}
{# if (date && time && room) {#}
{# // Check for conflicts (this would be an AJAX call in a real implementation)#}
{# // For now, just show a placeholder message#}
{# console.log('Checking for scheduling conflicts...');#}
{# }#}
{# });#}
});
</script>
{% endblock %}

View File

@ -120,7 +120,8 @@
title="Confirm Surgery"
hx-post="{% url 'inpatients:confirm_surgery' surgery.id %}"
hx-confirm="Confirm this surgery?"
hx-swap="none">
hx-swap="none"
hx-headers='{"X-CSRFToken":"{{ csrf_token }}"}'>
<i class="fas fa-check"></i>
</button>
{% elif surgery.status == 'CONFIRMED' %}
@ -128,7 +129,8 @@
title="Start Prep"
hx-post="{% url 'inpatients:start_surgery_prep' surgery.id %}"
hx-confirm="Start surgery prep?"
hx-swap="none">
hx-swap="none"
hx-headers='{"X-CSRFToken":"{{ csrf_token }}"}'>
<i class="fas fa-play"></i>
</button>
{% elif surgery.status == 'PREP' %}
@ -136,7 +138,8 @@
title="Start Surgery"
hx-post="{% url 'inpatients:start_surgery' surgery.id %}"
hx-confirm="Start surgery?"
hx-swap="none">
hx-swap="none"
hx-headers='{"X-CSRFToken":"{{ csrf_token }}"}'>
<i class="fas fa-procedures"></i>
</button>
{% elif surgery.status == 'IN_PROGRESS' %}
@ -144,7 +147,8 @@
title="Complete Surgery"
hx-post="{% url 'inpatients:complete_surgery' surgery.id %}"
hx-confirm="Complete surgery?"
hx-swap="none">
hx-swap="none"
hx-headers='{"X-CSRFToken":"{{ csrf_token }}"}'>
<i class="fas fa-check-circle"></i>
</button>
{% endif %}
@ -154,18 +158,19 @@
</button>
{% if surgery.status not in 'COMPLETED,CANCELLED' %}
<button class="btn btn-outline-warning"
title="Postpone"
hx-post="{% url 'inpatients:postpone_surgery' surgery.id %}"
hx-confirm="Postpone this surgery?"
hx-swap="none">
<i class="fas fa-clock"></i>
</button>
{# <button class="btn btn-outline-warning" #}
{# title="Postpone"#}
{# hx-post="{% url 'inpatients:s' surgery.id %}"#}
{# hx-confirm="Postpone this surgery?"#}
{# hx-swap="none">#}
{# <i class="fas fa-clock"></i>#}
{# </button>#}
<button class="btn btn-outline-danger"
title="Cancel"
hx-post="{% url 'inpatients:cancel_surgery' surgery.id %}"
hx-confirm="Cancel this surgery?"
hx-swap="none">
hx-swap="none"
hx-headers='{"X-CSRFToken":"{{ csrf_token }}"}'>
<i class="fas fa-times"></i>
</button>
{% endif %}

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
</html>

View File

@ -8,19 +8,31 @@ from . import views
app_name = 'inpatients'
urlpatterns = [
# Main views
# Main views
path('', views.InpatientDashboardView.as_view(), name='dashboard'),
# wards
path('wards/', views.WardListView.as_view(), name='ward_list'),
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/<int:pk>/', views.AdmissionDetailView.as_view(), name='admission_detail'),
path('admissions/create/', views.AdmissionCreateView.as_view(), name='admission_create'),
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('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
path('beds/', views.BedManagementView.as_view(), name='bed_management'),
path('beds/', views.BedListView.as_view(), name='bed_list'),
path('beds/create/', views.BedCreateView.as_view(), name='bed_create'),
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>/unblock/', views.unblock_bed, name='unblock_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('admission-search/', views.admission_search, name='admission_search'),
path('surgery-calendar/', views.surgery_calendar, name='surgery_calendar'),
path('surgery/', views.SurgeryScheduleView.as_view(), name='surgery_schedule'),
path('surgery/list/', views.SurgeryScheduleListView.as_view(), name='surgery_list'),
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
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
# path('api/', include('inpatients.api.urls')),

File diff suppressed because it is too large Load Diff

View File

@ -252,7 +252,7 @@ def create_saudi_admissions(tenants, beds, admissions_per_tenant=100):
for tenant in tenants:
# Get patients and staff for this 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']))
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'))
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']))
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:
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