This commit is contained in:
Marwan Alwali 2025-08-24 12:00:10 +03:00
parent 99858b4075
commit 193ee7f34a
19 changed files with 2445 additions and 239 deletions

View File

@ -15,7 +15,43 @@ class User(AbstractUser):
""" """
Extended user model for hospital management system. Extended user model for hospital management system.
""" """
ROLE_CHOICES = [
('SUPER_ADMIN', 'Super Administrator'),
('ADMIN', 'Administrator'),
('PHYSICIAN', 'Physician'),
('NURSE', 'Nurse'),
('NURSE_PRACTITIONER', 'Nurse Practitioner'),
('PHYSICIAN_ASSISTANT', 'Physician Assistant'),
('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'),
]
THEME_CHOICES = [
('LIGHT', 'Light'),
('DARK', 'Dark'),
('AUTO', 'Auto'),
]
# Basic Information # Basic Information
user_id = models.UUIDField( user_id = models.UUIDField(
default=uuid.uuid4, default=uuid.uuid4,
@ -91,38 +127,7 @@ class User(AbstractUser):
# Role and Permissions # Role and Permissions
role = models.CharField( role = models.CharField(
max_length=50, max_length=50,
choices=[ choices=ROLE_CHOICES,
('SUPER_ADMIN', 'Super Administrator'),
('ADMIN', 'Administrator'),
('PHYSICIAN', 'Physician'),
('NURSE', 'Nurse'),
('NURSE_PRACTITIONER', 'Nurse Practitioner'),
('PHYSICIAN_ASSISTANT', 'Physician Assistant'),
('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='CLERICAL' default='CLERICAL'
) )
@ -204,11 +209,7 @@ class User(AbstractUser):
) )
theme = models.CharField( theme = models.CharField(
max_length=20, max_length=20,
choices=[ choices=THEME_CHOICES,
('LIGHT', 'Light'),
('DARK', 'Dark'),
('AUTO', 'Auto'),
],
default='LIGHT' default='LIGHT'
) )

View File

@ -19,6 +19,8 @@ urlpatterns = [
path('users/<int:pk>/', views.UserDetailView.as_view(), name='user_detail'), path('users/<int:pk>/', views.UserDetailView.as_view(), name='user_detail'),
path('profile/', views.UserProfileView.as_view(), name='user_profile'), path('profile/', views.UserProfileView.as_view(), name='user_profile'),
path('sessions/', views.SessionManagementView.as_view(), name='session_management'), path('sessions/', views.SessionManagementView.as_view(), name='session_management'),
# path('reset-password/', views.ResetPasswordView.as_view(), name='reset_password'),
path('profile-picture/', views.upload_avatar, name='upload_avatar'),
# HTMX views # HTMX views

View File

@ -1,6 +1,8 @@
""" """
Accounts app views for hospital management system with comprehensive CRUD operations. Accounts app views for hospital management system with comprehensive CRUD operations.
""" """
import os
from allauth.account.views import LoginView from allauth.account.views import LoginView
from django.shortcuts import render, get_object_or_404, redirect from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth import authenticate, login, logout from django.contrib.auth import authenticate, login, logout
@ -1211,6 +1213,59 @@ def reset_user_password(request, pk):
return redirect('accounts:user_detail', pk=pk) return redirect('accounts:user_detail', pk=pk)
def upload_avatar(request, pk):
tenant = getattr(request, 'tenant', None)
if not tenant:
messages.error(request, 'No tenant found.')
return redirect('accounts:user_list')
user = get_object_or_404(User, pk=pk, tenant=tenant)
if request.method == 'POST':
if 'profile_picture' in request.FILES:
# Delete old profile picture if it exists
if user.profile_picture:
old_picture_path = user.profile_picture.path
if os.path.exists(old_picture_path):
os.remove(old_picture_path)
# Save new profile picture
user.profile_picture = request.FILES['profile_picture']
user.save()
# Log the upload
AuditLogger.log_event(
tenant=tenant,
event_type='UPDATE',
event_category='USER_MANAGEMENT',
action='Upload Profile Picture',
description=f'Uploaded profile picture for user: {user.username}',
user=request.user,
content_object=user,
request=request
)
messages.success(request, f'Profile picture updated successfully for "{user.username}".')
if request.headers.get('HX-Request'):
# Return HTMX response with updated image
return render(request, 'account/partials/profile_picture.html', {
'user_profile': user
})
return redirect('accounts:user_detail', pk=pk)
else:
messages.error(request, 'No image file was uploaded.')
# For GET requests, return the upload form
if request.headers.get('HX-Request'):
return render(request, 'account/partials/upload_avatar_form.html', {
'user_profile': user
})
return redirect('accounts:user_detail', pk=pk)
# """ # """
# Accounts app views for hospital management system with comprehensive CRUD operations. # Accounts app views for hospital management system with comprehensive CRUD operations.
# """ # """

Binary file not shown.

View File

@ -326,9 +326,9 @@ class DischargeSummaryForm(forms.ModelForm):
if user and hasattr(user, 'tenant'): if user and hasattr(user, 'tenant'):
self.fields['admission'].queryset = Admission.objects.filter( self.fields['admission'].queryset = Admission.objects.filter(
tenant=user.tenant, tenant=user.tenant,
status__in=['ADMITTED', 'READY_FOR_DISCHARGE'] status='ADMITTED'
).select_related('patient', 'current_ward', 'current_bed').order_by('patient__last_name', 'patient__first_name') ).select_related('patient', 'current_ward', 'current_bed').order_by('patient__last_name', 'patient__first_name')
self.fields['discharging_physician'].queryset = User.objects.filter( self.fields['discharging_physician'].queryset = User.objects.filter(
tenant=user.tenant, tenant=user.tenant,
is_active=True, is_active=True,

View File

@ -592,7 +592,7 @@ class AdmissionListView(LoginRequiredMixin, ListView):
def get_queryset(self): def get_queryset(self):
queryset = Admission.objects.filter(tenant=self.request.user.tenant) queryset = Admission.objects.filter(tenant=self.request.user.tenant)
# Filter by status # Filter by status
status = self.request.GET.get('status') status = self.request.GET.get('status')
if status: if status:
@ -625,10 +625,15 @@ class AdmissionListView(LoginRequiredMixin, ListView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
tenant = self.request.user.tenant
total_admissions = Admission.objects.filter(tenant=tenant).count()
active_admissions = Admission.objects.filter(tenant=tenant, status='ADMITTED').count()
context.update({ context.update({
'admission_statuses': Admission.STATUS_CHOICES, 'admission_statuses': Admission.STATUS_CHOICES,
'admission_types': Admission.ADMISSION_TYPE_CHOICES, 'admission_types': Admission.ADMISSION_TYPE_CHOICES,
'wards': Ward.objects.filter(tenant=self.request.user.tenant, is_active=True), 'wards': Ward.objects.filter(tenant=tenant, is_active=True),
'total_admissions': total_admissions,
'active_admissions': active_admissions,
}) })
return context return context
@ -909,7 +914,7 @@ def surgery_calendar(request):
'operating_rooms': sorted(set(surgery.operating_room for surgery in surgeries)) 'operating_rooms': sorted(set(surgery.operating_room for surgery in surgeries))
} }
return render(request, 'inpatients/partials/surgery_calendar.html', context) return render(request, 'inpatients/surgery_schedule.html', context)
@login_required @login_required
@ -950,7 +955,7 @@ def transfer_patient(request, admission_id):
transfer.save() transfer.save()
# Log the action # Log the action
AuditLogger.log( AuditLogger.log_event(
actor=request.user, actor=request.user,
action='TRANSFER_REQUESTED', action='TRANSFER_REQUESTED',
target=admission, target=admission,
@ -978,7 +983,7 @@ def transfer_patient(request, admission_id):
'priorities': Transfer._meta.get_field('priority').choices 'priorities': Transfer._meta.get_field('priority').choices
} }
return render(request, 'inpatients/partials/transfer_form.html', context) return render(request, 'inpatients/patient_transfer.html', context)
@login_required @login_required
@ -986,6 +991,7 @@ def approve_transfer(request, transfer_id):
""" """
HTMX endpoint for approving a transfer. HTMX endpoint for approving a transfer.
""" """
print("transfer clicked")
transfer = get_object_or_404(Transfer, id=transfer_id, admission__tenant=request.user.tenant) transfer = get_object_or_404(Transfer, id=transfer_id, admission__tenant=request.user.tenant)
if request.method == 'POST': if request.method == 'POST':
@ -1008,7 +1014,7 @@ def approve_transfer(request, transfer_id):
transfer.save() transfer.save()
# Log the action # Log the action
AuditLogger.log( AuditLogger.log_event(
actor=request.user, actor=request.user,
action='TRANSFER_APPROVED', action='TRANSFER_APPROVED',
target=transfer, target=transfer,
@ -1075,7 +1081,7 @@ def complete_transfer(request, transfer_id):
admission.save() admission.save()
# Log the action # Log the action
AuditLogger.log( AuditLogger.log_event(
actor=request.user, actor=request.user,
action='TRANSFER_COMPLETED', action='TRANSFER_COMPLETED',
target=transfer, target=transfer,
@ -1124,7 +1130,7 @@ def update_bed_status(request, bed_id):
bed.save() bed.save()
# Log the action # Log the action
AuditLogger.log( AuditLogger.log_event(
actor=request.user, actor=request.user,
action='BED_STATUS_UPDATED', action='BED_STATUS_UPDATED',
target=bed, target=bed,
@ -1559,62 +1565,62 @@ def maintenance_bed(request, pk):
# return context # return context
# #
# #
class WardDetailView(LoginRequiredMixin, DetailView): # class WardDetailView(LoginRequiredMixin, DetailView):
""" # """
Detail view for a ward. # Detail view for a ward.
""" # """
model = Ward # model = Ward
template_name = 'inpatients/ward_detail.html' # template_name = 'inpatients/ward_detail.html'
context_object_name = 'ward' # context_object_name = 'ward'
#
def get_queryset(self): # def get_queryset(self):
"""Filter wards by tenant.""" # """Filter wards by tenant."""
return Ward.objects.filter( # return Ward.objects.filter(
tenant=self.request.user.tenant # tenant=self.request.user.tenant
).select_related('nurse_manager') # ).select_related('nurse_manager')
#
def get_context_data(self, **kwargs): # def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) # context = super().get_context_data(**kwargs)
ward = self.get_object() # ward = self.get_object()
#
# Get beds for this ward with patient information # # Get beds for this ward with patient information
context['beds'] = Bed.objects.filter( # context['beds'] = Bed.objects.filter(
ward=ward # ward=ward
).select_related( # ).select_related(
'current_patient', 'current_admission' # 'current_patient', 'current_admission'
).order_by('room_number', 'bed_number') # ).order_by('room_number', 'bed_number')
#
# Group beds by room for display # # Group beds by room for display
rooms = {} # rooms = {}
for bed in context['beds']: # for bed in context['beds']:
room_num = bed.room_number # room_num = bed.room_number
if room_num not in rooms: # if room_num not in rooms:
rooms[room_num] = [] # rooms[room_num] = []
rooms[room_num].append(bed) # rooms[room_num].append(bed)
context['rooms'] = rooms # context['rooms'] = rooms
#
# Get ward statistics # # Get ward statistics
context['total_beds'] = context['beds'].count() # context['total_beds'] = context['beds'].count()
context['available_beds'] = context['beds'].filter(status='AVAILABLE').count() # context['available_beds'] = context['beds'].filter(status='AVAILABLE').count()
context['occupied_beds'] = context['beds'].filter(status='OCCUPIED').count() # context['occupied_beds'] = context['beds'].filter(status='OCCUPIED').count()
context['maintenance_beds'] = context['beds'].filter( # context['maintenance_beds'] = context['beds'].filter(
status__in=['MAINTENANCE', 'OUT_OF_ORDER', 'CLEANING'] # status__in=['MAINTENANCE', 'OUT_OF_ORDER', 'CLEANING']
).count() # ).count()
#
if context['total_beds'] > 0: # if context['total_beds'] > 0:
context['occupancy_rate'] = (context['occupied_beds'] / context['total_beds']) * 100 # context['occupancy_rate'] = (context['occupied_beds'] / context['total_beds']) * 100
else: # else:
context['occupancy_rate'] = 0 # context['occupancy_rate'] = 0
#
# Get recent admissions to this ward # # Get recent admissions to this ward
context['recent_admissions'] = Admission.objects.filter( # context['recent_admissions'] = Admission.objects.filter(
Q(initial_ward=ward) | Q(current_bed__ward=ward), # Q(initial_ward=ward) | Q(current_bed__ward=ward),
status__in=['ADMITTED', 'READY_FOR_DISCHARGE'] # status__in=['ADMITTED', 'READY_FOR_DISCHARGE']
).select_related( # ).select_related(
'patient', 'admitting_physician' # 'patient', 'admitting_physician'
).order_by('-admitted_at')[:10] # ).order_by('-admitted_at')[:10]
#
return context # return context
# #
# #
# class WardCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView): # class WardCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
@ -2139,10 +2145,10 @@ def discharge_patient(request, pk):
pk=pk, pk=pk,
tenant=request.user.tenant tenant=request.user.tenant
) )
print(admission) print(admission.status)
# Only admitted patients can be discharged # Only admitted patients can be discharged
if admission.status not in ['ADMITTED', 'READY_FOR_DISCHARGE']: if not admission.status == 'ADMITTED':
messages.error(request, _('Only admitted patients or patients ready for discharge can be discharged')) messages.error(request, _('Only admitted patients or patients ready for discharge can be discharged'))
return redirect('inpatients:admission_detail', pk=admission.pk) return redirect('inpatients:admission_detail', pk=admission.pk)
@ -2156,6 +2162,7 @@ def discharge_patient(request, pk):
if summary_form.is_valid(): if summary_form.is_valid():
summary = summary_form.save(commit=False) summary = summary_form.save(commit=False)
summary.patient = admission.patient summary.patient = admission.patient
summary.admission = admission
summary.created_by = request.user summary.created_by = request.user
summary.save() summary.save()
@ -2168,41 +2175,42 @@ def discharge_patient(request, pk):
else: else:
initial = { initial = {
'patient': admission.patient, 'patient': admission.patient,
'admission': admission,
'discharge_diagnosis': admission.admitting_diagnosis, 'discharge_diagnosis': admission.admitting_diagnosis,
'doctor_name': request.user.get_full_name() if request.user.role in ['DOCTOR', 'SPECIALIST'] else '' 'doctor_name': request.user.get_full_name() if request.user.role in ['DOCTOR', 'SPECIALIST'] else ''
} }
summary_form = DischargeSummaryForm( summary_form = DischargeSummaryForm(
initial=initial, initial=initial,
user=request.user, user=request.user,
admission=admission # admission=admission
) )
return render(request, 'inpatients/discharges/discharge_form.html', { return render(request, 'inpatients/discharges/discharge_planning.html', {
'admission': admission, 'admission': admission,
'form': summary_form 'form': summary_form
}) })
# #
# #
# @login_required @login_required
# @permission_required('inpatients.change_admission') # @permission_required('inpatients.change_admission')
# def mark_ready_for_discharge(request, pk): def mark_ready_for_discharge(request, pk):
# """ """
# Mark a patient as ready for discharge. Mark a patient as ready for discharge.
# """ """
# admission = get_object_or_404( admission = get_object_or_404(
# Admission, Admission,
# pk=pk, pk=pk,
# tenant=request.user.tenant tenant=request.user.tenant
# ) )
#
# # Only admitted patients can be marked ready for discharge # Only admitted patients can be marked ready for discharge
# if admission.status != 'ADMITTED': if admission.status != 'ADMITTED':
# messages.error(request, _('Only admitted patients can be marked ready for discharge')) messages.error(request, _('Only admitted patients can be marked ready for discharge'))
# return redirect('inpatients:admission_detail', pk=admission.pk) return redirect('inpatients:admission_detail', pk=admission.pk)
#
# admission.mark_ready_for_discharge() admission.mark_ready_for_discharge()
# messages.success(request, _('Patient marked ready for discharge')) messages.success(request, _('Patient marked ready for discharge'))
# return redirect('inpatients:admission_detail', pk=admission.pk) return redirect('inpatients:admission_detail', pk=admission.pk)
# #
# #
# class TransferListView(LoginRequiredMixin, ListView): # class TransferListView(LoginRequiredMixin, ListView):
@ -2977,36 +2985,36 @@ def discharge_patient(request, pk):
# return redirect('inpatients:bed_detail', pk=bed.pk) # return redirect('inpatients:bed_detail', pk=bed.pk)
# #
# #
@login_required # @login_required
# @permission_required('inpatients.change_bed') # @permission_required('inpatients.change_bed')
def maintenance_bed(request, pk): # def maintenance_bed(request, pk):
""" # """
Mark a bed for maintenance. # Mark a bed for maintenance.
""" # """
bed = get_object_or_404( # bed = get_object_or_404(
Bed, # Bed,
pk=pk, # pk=pk,
ward__tenant=request.user.tenant # ward__tenant=request.user.tenant
) # )
#
# Only available beds can be marked for maintenance # # Only available beds can be marked for maintenance
if bed.status != 'AVAILABLE': # if bed.status != 'AVAILABLE':
messages.error(request, _('Only available beds can be marked for maintenance')) # messages.error(request, _('Only available beds can be marked for maintenance'))
return redirect('inpatients:bed_detail', pk=bed.pk) # return redirect('inpatients:bed_detail', pk=bed.pk)
#
if request.method == 'POST': # if request.method == 'POST':
notes = request.POST.get('notes') # notes = request.POST.get('notes')
#
# bed.mark_maintenance(notes) # # bed.mark_maintenance(notes)
bed.status = 'MAINTENANCE' # bed.status = 'MAINTENANCE'
bed.notes = notes # bed.notes = notes
bed.save() # bed.save()
messages.success(request, _('Bed marked for maintenance successfully')) # messages.success(request, _('Bed marked for maintenance successfully'))
return redirect('inpatients:bed_detail', pk=bed.pk) # return redirect('inpatients:bed_detail', pk=bed.pk)
#
return render(request, 'inpatients/maintenance_bed.html', { # return render(request, 'inpatients/maintenance_bed.html', {
'bed': bed # 'bed': bed
}) # })
# #
# #
# @login_required # @login_required

File diff suppressed because it is too large Load Diff

View File

@ -284,7 +284,7 @@
{% elif admission.admission_type == 'DIRECT' %}red {% elif admission.admission_type == 'DIRECT' %}red
{% else %}secondary {% else %}secondary
{% endif %}"> {% endif %}">
{{ admission.admission_type }} {{ admission.get_admission_type_display }}
</div> </div>
</td> </td>
<td> <td>

View File

@ -50,7 +50,7 @@
color: #856404; color: #856404;
} }
.bed-out_of_order { .bed-out_of_order {
background-color: #b6b4b4; background-color: #c5c5c5;
color: #434242; color: #434242;
} }
@ -437,27 +437,24 @@ color: #434242;
</span> </span>
</div> </div>
</div> </div>
<div class="card-footer"> <div class="card-footer">
<div class="btn-group btn-group-sm"> <div class="btn-group btn-group-sm">
<a class="btn btn-sm btn-primary" href="{% url 'inpatients:bed_detail' bed.id %}" title="View Details"> <a class="btn btn-sm btn-outline-primary" href="{% url 'inpatients:bed_detail' bed.id %}" title="View Details">
<i class="fa fa-eye"></i> <i class="fa fa-eye"></i>
</a> </a>
{# <button class="btn btn-outline-primary" onclick="viewBedDetails('{{ bed.id }}')" title="View Details">#} {# <button class="btn btn-outline-primary" onclick="viewBedDetails('{{ bed.id }}')" title="View Details">#}
{# <i class="fa fa-eye"></i>#} {# <i class="fa fa-eye"></i>#}
{# </button>#} {# </button>#}
<a class="btn btn-sm btn-secondary" href="{% url 'inpatients:bed_update' bed.id %}" title="Edit"> <a class="btn btn-sm btn-outline-secondary" href="{% url 'inpatients:bed_update' bed.id %}" title="Edit">
<i class="fa fa-edit"></i> <i class="fa fa-edit"></i>
</a> </a>
{% if bed.status == 'AVAILABLE' %} {% if bed.status == 'AVAILABLE' %}
<a class="btn btn-sm btn-success" href="{% url 'inpatients:admission_create' %}" title="Assign Patient"> <a class="btn btn-sm btn-outline-success" href="{% url 'inpatients:admission_create' %}" title="Assign Patient">
<i class="fa fa-user-plus"></i> <i class="fa fa-user-plus"></i>
</a> </a>
{% elif bed.status == 'OCCUPIED' %} {% elif bed.status == 'OCCUPIED' %}
{% if bed.current_admission %} {% if bed.current_admission %}
<a class="btn btn-sm btn-warning" href="{% url 'inpatients:discharge_patient' bed.current_admission.id %}" title="Discharge"> <a class="btn btn-sm btn-outline-warning" href="{% url 'inpatients:discharge_patient' bed.current_admission.id %}" title="Discharge">
<i class="fa fa-sign-out-alt"></i> <i class="fa fa-sign-out-alt"></i>
</a> </a>
{% endif %} {% endif %}
@ -615,8 +612,8 @@ color: #434242;
</div> </div>
</div> </div>
</div> </div>
</div>
</div>
<!-- Bed Details Modal --> <!-- Bed Details Modal -->
<div class="modal fade" id="bedDetailsModal" tabindex="-1"> <div class="modal fade" id="bedDetailsModal" tabindex="-1">
@ -685,7 +682,8 @@ color: #434242;
</form> </form>
</div> </div>
</div> </div>
</div>
</div>
{% endblock %} {% endblock %}
{% block js %} {% block js %}

View File

@ -176,17 +176,20 @@
<div class="planning-header"> <div class="planning-header">
<div class="row"> <div class="row">
<div class="col-md-8"> <div class="col-md-8">
<h5><i class="fas fa-user"></i> Patient: Robert Davis</h5> <h5><i class="fas fa-user"></i> Patient: {{ admission.patient.get_full_name }}</h5>
<p><strong>MRN:</strong> MRN456789 | <strong>Age:</strong> 68 years | <strong>Gender:</strong> Male</p> <p><strong>MRN:</strong> {{ admission.patient.mrn }} | <strong>Age:</strong> {{ admission.patient.age }} | <strong>Gender:</strong>
<p><strong>Admission Date:</strong> January 15, 2024 | <strong>Length of Stay:</strong> 5 days</p> {{ admission.patient.get_gender_display }}</p>
<p><strong>Primary Diagnosis:</strong> Acute Myocardial Infarction | <strong>Attending:</strong> Dr. Johnson</p> <p><strong>Admission Date:</strong> {{ admission.admission_datetime }} | <strong>Length of Stay:</strong> {{ admission.length_of_stay }} Days</p>
<p><strong>Admitting:</strong> {{ admission.admitting_physician.get_full_name }} | <strong>Attending:</strong>
{{ admission.attending_physician.get_full_name }}</p>
<p><strong>Primary Diagnosis:</strong> {{ admission.admitting_diagnosis }}</p>
</div> </div>
<div class="col-md-4 text-end"> <div class="col-md-4 text-end">
<div class="progress-bar-custom"> <div class="progress-bar-custom">
<div class="progress-fill" style="width: 75%"></div> <div class="progress-fill" style="width: 75%"></div>
<div class="progress-text">75% Complete</div> <div class="progress-text">75% Complete</div>
</div> </div>
<p class="mt-2 mb-0">Expected Discharge: January 22, 2024</p> <p class="mt-2 mb-0">Expected Discharge: {{ admission.anticipated_discharge_date}}</p>
</div> </div>
</div> </div>
</div> </div>

View File

@ -4,8 +4,8 @@
{% block title %}Bed Maintenance Management{% endblock %} {% block title %}Bed Maintenance Management{% endblock %}
{% block extra_css %} {% block extra_css %}
<link href="{% static 'assets/plugins/datatables.net-bs5/css/dataTables.bootstrap5.min.css' %}" rel="stylesheet" /> <link href="{% static 'plugins/datatables.net-bs5/css/dataTables.bootstrap5.min.css' %}" rel="stylesheet" />
<link href="{% static 'assets/plugins/datatables.net-responsive-bs5/css/responsive.bootstrap5.min.css' %}" rel="stylesheet" /> <link href="{% static 'plugins/datatables.net-responsive-bs5/css/responsive.bootstrap5.min.css' %}" rel="stylesheet" />
<style> <style>
.maintenance-status-scheduled { color: #ffc107; } .maintenance-status-scheduled { color: #ffc107; }
.maintenance-status-in-progress { color: #17a2b8; } .maintenance-status-in-progress { color: #17a2b8; }
@ -491,10 +491,10 @@
{% endblock %} {% endblock %}
{% block extra_js %} {% block extra_js %}
<script src="{% static 'assets/plugins/datatables.net/js/jquery.dataTables.min.js' %}"></script> <script src="{% static 'plugins/datatables.net/js/dataTables.min.js' %}"></script>
<script src="{% static 'assets/plugins/datatables.net-bs5/js/dataTables.bootstrap5.min.js' %}"></script> <script src="{% static 'plugins/datatables.net-bs5/js/dataTables.bootstrap5.min.js' %}"></script>
<script src="{% static 'assets/plugins/datatables.net-responsive/js/dataTables.responsive.min.js' %}"></script> <script src="{% static 'plugins/datatables.net-responsive/js/dataTables.responsive.min.js' %}"></script>
<script src="{% static 'assets/plugins/datatables.net-responsive-bs5/js/responsive.bootstrap5.min.js' %}"></script> <script src="{% static 'plugins/datatables.net-responsive-bs5/js/responsive.bootstrap5.min.js' %}"></script>
<script> <script>
$(document).ready(function() { $(document).ready(function() {

View File

@ -86,7 +86,7 @@
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<form id="rejectTransferForm" method="post" action="{% url 'inpatients:reject_transfer' transfer_id=transfer.id %}"> <form id="rejectTransferForm" method="post" action="">
{% csrf_token %} {% csrf_token %}
<div class="mb-3"> <div class="mb-3">

View File

@ -79,7 +79,7 @@
<!-- Patient Information Card --> <!-- Patient Information Card -->
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<div class="card"> <div class="card mb-4">
<div class="card-header"> <div class="card-header">
<h5><i class="fas fa-user"></i> Patient Information</h5> <h5><i class="fas fa-user"></i> Patient Information</h5>
<span class="discharge-status status-pending">Discharge in Progress</span> <span class="discharge-status status-pending">Discharge in Progress</span>
@ -87,16 +87,16 @@
<div class="card-body"> <div class="card-body">
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<p><strong>Patient:</strong> {{ patient.full_name|default:"John Doe" }}</p> <p><strong>Patient:</strong> {{ admission.patient.get_full_name }}</p>
<p><strong>MRN:</strong> {{ patient.medical_record_number|default:"MRN123456" }}</p> <p><strong>MRN:</strong> {{ admission.patient.mrn }}</p>
<p><strong>DOB:</strong> {{ patient.date_of_birth|default:"1980-01-01" }}</p> <p><strong>DOB:</strong> {{ admission.patient.date_of_birth }}</p>
<p><strong>Gender:</strong> {{ patient.gender|default:"Male" }}</p> <p><strong>Gender:</strong> {{ admission.patient.gender }}</p>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<p><strong>Admission Date:</strong> {{ admission.admission_date|default:"2024-01-15" }}</p> <p><strong>Admission Date:</strong> {{ admission.admission_datetime|date:'Y:m:d' }}</p>
<p><strong>Length of Stay:</strong> {{ admission.length_of_stay|default:"5 days" }}</p> <p><strong>Length of Stay:</strong> {{ admission.length_of_stay }}</p>
<p><strong>Attending Physician:</strong> {{ admission.attending_physician|default:"Dr. Smith" }}</p> <p><strong>Attending Physician:</strong> {{ admission.attending_physician }}</p>
<p><strong>Ward/Room:</strong> {{ admission.bed.ward.name|default:"Ward A" }} - {{ admission.bed.room_number|default:"101" }}</p> <p><strong>Ward/Room:</strong> {{ admission.current_bed.ward.name }} - {{ admission.current_bed.room_number }}</p>
</div> </div>
</div> </div>
</div> </div>
@ -107,7 +107,7 @@
<!-- Discharge Checklist --> <!-- Discharge Checklist -->
<div class="row"> <div class="row">
<div class="col-md-8"> <div class="col-md-8">
<div class="card"> <div class="card mb-4">
<div class="card-header"> <div class="card-header">
<h5><i class="fas fa-tasks"></i> Discharge Checklist</h5> <h5><i class="fas fa-tasks"></i> Discharge Checklist</h5>
</div> </div>
@ -182,7 +182,7 @@
</div> </div>
<div class="col-md-4"> <div class="col-md-4">
<div class="card"> <div class="card mb-4">
<div class="card-header"> <div class="card-header">
<h5><i class="fas fa-clock"></i> Discharge Timeline</h5> <h5><i class="fas fa-clock"></i> Discharge Timeline</h5>
</div> </div>
@ -192,14 +192,14 @@
<div class="timeline-marker"></div> <div class="timeline-marker"></div>
<div class="timeline-content"> <div class="timeline-content">
<h6>Discharge Order</h6> <h6>Discharge Order</h6>
<p>09:00 AM - Dr. Smith</p> <p>{{ admission.anticipated_discharge_date }}</p>
</div> </div>
</div> </div>
<div class="timeline-item completed"> <div class="timeline-item completed">
<div class="timeline-marker"></div> <div class="timeline-marker"></div>
<div class="timeline-content"> <div class="timeline-content">
<h6>Medication Review</h6> <h6>Medication Review</h6>
<p>10:30 AM - Pharmacist</p> <p>{{ admission.patient }}</p>
</div> </div>
</div> </div>
<div class="timeline-item active"> <div class="timeline-item active">

View File

@ -121,28 +121,26 @@
<td> <td>
<div class="btn-group btn-group-sm"> <div class="btn-group btn-group-sm">
{% if transfer.status == 'REQUESTED' %} {% if transfer.status == 'REQUESTED' %}
<button class="btn btn-outline-success" <a class="btn btn-outline-success"
title="Approve" title="Approve"
hx-post="{% url 'inpatients:approve_transfer' transfer.id %}" href="{% url 'inpatients:approve_transfer' transfer.id %}">
hx-confirm="Approve this transfer?"
hx-swap="none">
<i class="fas fa-check"></i> <i class="fas fa-check"></i>
</button> </a>
<button class="btn btn-outline-danger" {# <button class="btn btn-outline-danger" #}
title="Reject" {# title="Reject"#}
hx-post="{% url 'inpatients:reject_transfer' transfer.id %}" {# hx-post="{% url 'inpatients:reject_transfer' transfer.id %}"#}
hx-confirm="Reject this transfer?" {# hx-confirm="Reject this transfer?"#}
hx-swap="none"> {# hx-swap="none">#}
<i class="fas fa-times"></i> {# <i class="fas fa-times"></i>#}
</button> {# </button>#}
{% elif transfer.status == 'APPROVED' or transfer.status == 'SCHEDULED' %} {% elif transfer.status == 'APPROVED' or transfer.status == 'SCHEDULED' %}
<button class="btn btn-outline-primary" {# <button class="btn btn-outline-primary" #}
title="Execute Transfer" {# title="Execute Transfer"#}
hx-post="{% url 'inpatients:execute_transfer' transfer.id %}" {# hx-post="{% url 'inpatients:execute_transfer' transfer.id %}"#}
hx-confirm="Execute this transfer?" {# hx-confirm="Execute this transfer?"#}
hx-swap="none"> {# hx-swap="none">#}
<i class="fas fa-play"></i> {# <i class="fas fa-play"></i>#}
</button> {# </button>#}
{% endif %} {% endif %}
<button class="btn btn-outline-info" title="View Details"> <button class="btn btn-outline-info" title="View Details">
@ -176,33 +174,7 @@
<!-- Pagination --> <!-- Pagination -->
{% if is_paginated %} {% if is_paginated %}
<nav aria-label="Transfer pagination"> {% include 'partial/pagination.html'%}
<ul class="pagination justify-content-center">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page=1">First</a>
</li>
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}">Previous</a>
</li>
{% endif %}
<li class="page-item active">
<span class="page-link">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}
</span>
</li>
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}">Next</a>
</li>
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.paginator.num_pages }}">Last</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %} {% endif %}
</div> </div>
</div> </div>